Save progress on backend app

This commit is contained in:
Tyler 2025-06-29 15:58:28 -04:00
parent eb4ac3e7c4
commit dcca6ba556
Signed by: tyler
GPG Key ID: 03B27509E17EFDC8
3 changed files with 119 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.idea/

View File

@ -0,0 +1,89 @@
import io
from fastapi import FastAPI, Response
import uvicorn
from picamera2 import Picamera2, Preview
from threading import Condition
import logging
from picamera2.encoders import MJPEGEncoder, Quality
from picamera2.outputs import FileOutput
from starlette.background import BackgroundTask
from starlette.responses import StreamingResponse
app = FastAPI()
@app.get("/image")
def get_image():
"""
Obtain a still image from the camera
:return:
"""
picam2 = Picamera2()
capture_config = picam2.create_still_configuration(main={"size": (1920,1080)})
picam2.configure(capture_config)
data = io.BytesIO()
picam2.start()
picam2.capture_image(data, format="jpeg")
picam2.stop()
picam2.close()
return Response(content=data.getvalue(), media_type="image/jpeg")
class StreamingOutput(io.BufferedIOBase):
def __init(self):
self.frame = None
self.condition = Condition()
def write(self, buffer):
with self.condition:
self.frame = buffer
self.condition.notify_all()
def read(self):
with self.condition:
self.condition.wait()
return self.frame
def generate_frames(output):
while True:
try:
frame = output.read()
yield (b"--frame\r\n" b"Content-Type: image/jpeg\r\n\r\n" + frame + b"\r\n")
except Exception as e:
logging.error(f"Error in generate_frames: {str(e)}")
break
print("done")
@app.get("/mjpeg")
async def mjpeg():
picam2 = Picamera2()
capture_config = picam2.create_still_configuration(main={"size": (1920,1080)})
picam2.configure(capture_config)
output = StreamingOutput()
picam2.start_recording(MJPEGEncoder(), FileOutput(output), Quality.VERY_HIGH)
def stop():
logging.info("Stopping recording")
picam2.stop_recording()
picam2.close()
return StreamingResponse(
generate_frames(output),
media_type="multipare/x-mixed-replace; boundry=frame",
background=BackgroundTask(stop)
)
def main():
uvicorn.run(
"main:app",
host="0.0.0.0",
port=8080
)
if __name__ == "__main__":
main()

29
requirements.txt Normal file
View File

@ -0,0 +1,29 @@
annotated-types==0.7.0
anyio==4.9.0
attrs==25.3.0
av==14.4.0
click==8.2.1
fastapi==0.115.14
h11==0.16.0
idna==3.10
jsonschema==4.24.0
jsonschema-specifications==2025.4.1
libarchive-c==5.3
numpy==2.3.1
picamera2==0.3.27
pidng==4.0.9
piexif==1.1.3
pillow==11.2.1
pydantic==2.11.7
pydantic_core==2.33.2
python-prctl==1.8.1
referencing==0.36.2
rpds-py==0.25.1
simplejpeg==1.8.2
sniffio==1.3.1
starlette==0.46.2
tqdm==4.67.1
typing-inspection==0.4.1
typing_extensions==4.14.0
uvicorn==0.35.0
v4l2-python3==0.3.5