Skip to content

Feat/camera proxy#548

Open
fe51 wants to merge 14 commits intomainfrom
feat/camera-proxy
Open

Feat/camera proxy#548
fe51 wants to merge 14 commits intomainfrom
feat/camera-proxy

Conversation

@fe51
Copy link
Member

@fe51 fe51 commented Feb 26, 2026

Summary

This PR introduces camera device proxy endpoints.
It secures api camera interaction, by using same right as in the API, and forwwarding request to devices via the VPN.

  • Add proxy endpoints to forward PTZ camera control commands from pyro-api to the physical device API, without ever exposing internal network addresses (device_ip, camera_ip) to clients
  • Add admin-only configuration endpoint to store device connection details per camera
  • Add a thin async HTTP client wrapping the camera device API

Changes

New files

  • src/app/api/api_v1/endpoints/camera_proxy.py — 20 proxy routes under /cameras/{camera_id}/...; two dependency helpers enforcing read (ADMIN/AGENT/USER) and write (ADMIN/AGENT) access with org isolation; raises 409 if the camera has no device config

Endpoints use api-camera client from pyro-engine

Modified files

  • src/app/models.py — added device_ip and camera_ip nullable fields to Camera (DB-only, never serialized in public responses)
  • src/app/schemas/cameras.py — added CameraDeviceConfig (admin input only); split the response schema into CameraOut (mutation endpoints — matches pre-PR shape) and CameraRead(CameraOut) (read endpoints — adds last_image_url and poses)
  • src/app/crud/crud_camera.py — added CameraDeviceConfig to the update union
  • src/app/api/api_v1/endpoints/cameras.py — added PATCH /{camera_id}/device_config (ADMIN only); mutation endpoints now return CameraOut instead of the raw ORM model to prevent device_ip/camera_ip leakage
  • src/app/api/api_v1/router.py — registered camera_proxy.router under /cameras
    pyproject.toml — suppressed ANN401 for camera_client.py and camera_proxy.py; these functions return opaque third-party JSON, so Any is correct by design, not a laziness
  • add api-camera pyro-engine client as dep

Tests

  • src/tests/endpoints/test_camera_proxy.py — auth/org isolation, 409 on unconfigured device (all routes), device error forwarding (502/504), JPEG binary responses, 204 no-content passthrough, device_ip/camera_ip leak prevention
  • src/tests/endpoints/test_cameras.py — updated assertions to align with the new CameraOut response shape on mutation endpoints

Design decisions

  • device_ip/camera_ip are absent from CameraCreate and CameraRead — they cannot appear in any public response by construction, even if camera_ip appears in some device API responses
  • All device API POST endpoints use query params (not body); capture and latest_image return raw JPEG bytes
  • stop_stream and stream_status are device-global (no camera_ip forwarded); camera_id in the path is used for auth/routing only
  • Port 8081 is hardcoded as DEVICE_PORT constant in camera_client.py for now

Happy to discuss it

@codecov
Copy link

codecov bot commented Feb 26, 2026

Codecov Report

❌ Patch coverage is 89.17197% with 17 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.16%. Comparing base (2e33027) to head (ce0fe5e).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/app/api/api_v1/endpoints/camera_proxy.py 93.12% 9 Missing ⚠️
src/app/api/api_v1/endpoints/cameras.py 46.66% 8 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #548      +/-   ##
==========================================
+ Coverage   88.14%   88.16%   +0.02%     
==========================================
  Files          50       51       +1     
  Lines        1990     2138     +148     
==========================================
+ Hits         1754     1885     +131     
- Misses        236      253      +17     
Flag Coverage Δ
backend 88.18% <89.17%> (+0.02%) ⬆️
client 87.80% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions github-actions bot added the topic: build Related to build, installation & CI label Feb 27, 2026
@fe51 fe51 marked this pull request as ready for review February 27, 2026 13:41
@fe51 fe51 requested a review from MateoLostanlen February 27, 2026 13:41
@fe51
Copy link
Member Author

fe51 commented Feb 27, 2026

@MateoLostanlen can you review and test it ?
Stills last some coverage issue but only about "complexity". Happy to discuss it because I have no real clue to solve it and still not a big issue. Hope will be able to merge quickly to unblock livestream features

Copy link
Member

@MateoLostanlen MateoLostanlen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello Felix,

Thanks for the PR. I tested it and everything works great except for run_focus_finder, because of the times out (see my coment)

However, I’m not a huge fan of duplicating the client code. In my opinion it would be cleaner to install it directly from pyro-engine. Did you do it this way for a specific reason?

@socket-security
Copy link

socket-security bot commented Mar 13, 2026

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedpillow@​12.1.18610010010070

View full report

@fe51
Copy link
Member Author

fe51 commented Mar 13, 2026

You are right about client usage. I have updated the script to use pyro-engine api-camera client -> Note using from branch develop because not yet merged on main ! We might need to update dependencies to main in the near future once develop is merged on main

@fe51 fe51 requested a review from MateoLostanlen March 13, 2026 13:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants