orca_cloud.py 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. """Schemas for Orca Cloud device-pairing auth + profile sync endpoints."""
  2. from typing import Literal
  3. from pydantic import BaseModel, Field
  4. class OrcaDeviceStartResponse(BaseModel):
  5. """Returned by ``POST /orca-cloud/device/start``. The frontend shows
  6. ``user_code`` and a clickable/QR ``verification_uri_complete``; the user
  7. approves in their Orca Cloud settings. The ``device_code`` itself is a
  8. secret and stays server-side — it is deliberately NOT in this response."""
  9. user_code: str = Field(..., description="Short code the user confirms on the approval page")
  10. verification_uri: str = Field(..., description="Approval page URL")
  11. verification_uri_complete: str = Field(..., description="Approval page URL with the code pre-filled")
  12. interval: int = Field(..., description="Seconds the frontend should wait between poll calls")
  13. expires_in: int = Field(..., description="Seconds until this pairing attempt expires")
  14. # Poll outcomes surfaced to the frontend. ``authorization_pending`` /
  15. # ``slow_down`` mean keep polling; ``access_denied`` / ``expired_token`` are
  16. # terminal (restart the flow); ``complete`` means paired.
  17. OrcaDevicePollStatus = Literal[
  18. "authorization_pending",
  19. "slow_down",
  20. "access_denied",
  21. "expired_token",
  22. "complete",
  23. ]
  24. class OrcaDevicePollResponse(BaseModel):
  25. """Returned by ``POST /orca-cloud/device/poll`` — one poll attempt."""
  26. status: OrcaDevicePollStatus
  27. connected: bool = False
  28. email: str | None = None
  29. user_id: str | None = None
  30. class OrcaAuthStatusResponse(BaseModel):
  31. """Connection status for the Orca Cloud tab."""
  32. connected: bool
  33. email: str | None = None
  34. user_id: str | None = None
  35. class OrcaProfileMeta(BaseModel):
  36. """A single profile, shaped to match the Bambu Cloud ``SlicerSetting``
  37. schema so the frontend can render Orca profiles with the existing
  38. Bambu Cloud visual components (cards, filter bar, grouping). Per-source
  39. differences (Orca's IDs are UUIDs not Bambu's ``PFU...`` prefix; Orca
  40. types are ``machine`` / ``process`` / ``filament`` whereas Bambu uses
  41. ``printer`` / ``process`` / ``filament``) are normalized at the route
  42. layer before the response leaves the backend."""
  43. setting_id: str
  44. name: str
  45. type: str
  46. version: str | None = None
  47. user_id: str | None = None
  48. updated_time: str | None = None
  49. is_custom: bool = True
  50. class OrcaProfileListResponse(BaseModel):
  51. """Groups Orca profiles by type, matching ``SlicerSettingsResponse``."""
  52. filament: list[OrcaProfileMeta] = []
  53. printer: list[OrcaProfileMeta] = []
  54. process: list[OrcaProfileMeta] = []
  55. class OrcaProfileDetail(BaseModel):
  56. """Single profile's full content, shaped to match ``SlicerSettingDetail``
  57. so the frontend's detail modal can render it without translation."""
  58. setting_id: str
  59. name: str
  60. type: str
  61. version: str | None = None
  62. base_id: str | None = None
  63. update_time: str | None = None
  64. setting: dict