Fixing ruff and mypy issues (#18)
CI / black (push) Failing after 1m34s
CI / ruff (push) Successful in 1m31s
CI / mypy (push) Successful in 1m44s
CI / pytest (push) Failing after 1m42s
Dependency update / dependency-update (push) Successful in 1m51s

Reviewed-on: #18
Co-authored-by: Andrew Kettel <andrew.kettel@gmail.com>
Co-committed-by: Andrew Kettel <andrew.kettel@gmail.com>
This commit was merged in pull request #18.
This commit is contained in:
2026-05-12 15:34:17 -07:00
committed by letteka
parent d8a0b544e5
commit fb1d7fec37
3 changed files with 36 additions and 30 deletions
+3 -3
View File
@@ -13,14 +13,14 @@ from flask import (
from werkzeug.middleware.proxy_fix import ProxyFix
from src.camera import camera
from src.database import db, CameraStatus, CameraEvent
from src.database import CameraEvent, CameraStatus, db
logging.basicConfig(level=logging.WARNING)
def create_app() -> Flask:
flask_app = Flask(__name__, template_folder="templates")
flask_app.wsgi_app = ProxyFix( # type: ignore[assignment, method-assign]
flask_app.wsgi_app = ProxyFix( # type: ignore[method-assign]
flask_app.wsgi_app, x_for=2, x_proto=2, x_host=2
)
flask_app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///birdcam.db"
@@ -110,7 +110,7 @@ def camera_status() -> tuple[Response, int]:
@app.get("/camera/log")
def camera_log() -> tuple:
def camera_log() -> tuple[Response, int]:
events = CameraEvent.recent(limit=50)
return (
jsonify(
+30 -24
View File
@@ -1,22 +1,26 @@
from __future__ import annotations
from datetime import datetime, timezone
from datetime import UTC, datetime
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.orm import DeclarativeBase, Mapped
db = SQLAlchemy()
db: SQLAlchemy = SQLAlchemy()
class CameraStatus(db.Model):
class Base(DeclarativeBase):
pass
class CameraStatus(Base):
__tablename__ = "camera_status"
id: db.Mapped[int] = db.mapped_column(db.Integer, primary_key=True)
running: db.Mapped[bool] = db.mapped_column(
db.Boolean, nullable=False, default=False
)
updated_at: db.Mapped[datetime] = db.mapped_column(
id: Mapped[int] = db.mapped_column(db.Integer, primary_key=True)
running: Mapped[bool] = db.mapped_column(db.Boolean, nullable=False, default=False)
updated_at: Mapped[datetime] = db.mapped_column(
db.DateTime(timezone=True),
nullable=False,
default=lambda: datetime.now(timezone.utc),
default=lambda: datetime.now(UTC),
)
@staticmethod
@@ -33,23 +37,23 @@ class CameraStatus(db.Model):
def set_running(running: bool) -> CameraStatus:
status = CameraStatus.get()
status.running = running
status.updated_at = datetime.now(timezone.utc)
status.updated_at = datetime.now(UTC)
db.session.commit()
return status
class CameraEvent(db.Model):
class CameraEvent(Base):
__tablename__ = "camera_events"
id: db.Mapped[int] = db.mapped_column(db.Integer, primary_key=True)
action: db.Mapped[str] = db.mapped_column(
id: Mapped[int] = db.mapped_column(db.Integer, primary_key=True)
action: Mapped[str] = db.mapped_column(
db.String(10), nullable=False
) # 'start' | 'stop'
ip_address: db.Mapped[str] = db.mapped_column(db.String(45), nullable=False)
timestamp: db.Mapped[datetime] = db.mapped_column(
ip_address: Mapped[str] = db.mapped_column(db.String(45), nullable=False)
timestamp: Mapped[datetime] = db.mapped_column(
db.DateTime(timezone=True),
nullable=False,
default=lambda: datetime.now(timezone.utc),
default=lambda: datetime.now(UTC),
)
@staticmethod
@@ -61,12 +65,14 @@ class CameraEvent(db.Model):
@staticmethod
def recent(limit: int = 50) -> list[CameraEvent]:
return (
db.session.execute(
db.select(CameraEvent)
.order_by(CameraEvent.timestamp.desc())
.limit(limit)
)
.scalars()
.all()
return list(
db.session.execute(
db.select(CameraEvent)
.order_by(CameraEvent.timestamp.desc())
.limit(limit)
)
.scalars()
.all()
)