import logging from collections.abc import Generator from datetime import UTC, datetime from typing import Any from flask import Flask, Response, jsonify, render_template from src.camera import camera app = Flask(__name__) logging.basicConfig(level=logging.INFO) @app.get("/heartbeat") def heartbeat() -> tuple[Response, int]: return ( jsonify( { "status": "ok", "timestamp": datetime.now(UTC).isoformat(), } ), 200, ) @app.get("/") def index() -> str: return render_template("index.html") @app.post("/camera/start") def camera_start() -> tuple[Response, int]: camera.start() return jsonify({"status": "started"}), 200 @app.post("/camera/stop") def camera_stop() -> tuple[Response, int]: camera.stop() return jsonify({"status": "stopped"}), 200 @app.get("/camera/stream") def camera_stream() -> Response: def generate() -> Generator[bytes, Any, Any]: for frame in camera.frames(): yield (b"--frame\r\n" b"Content-Type: image/jpeg\r\n\r\n" + frame + b"\r\n") return Response( generate(), mimetype="multipart/x-mixed-replace; boundary=frame", ) if __name__ == "__main__": app.run(host="0.0.0.0", port=5000, debug=True, threaded=True)