| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- """Pydantic schemas for the MakerWorld integration routes."""
- from __future__ import annotations
- from typing import Any
- from pydantic import BaseModel, Field
- class MakerWorldResolveRequest(BaseModel):
- """Body for POST /makerworld/resolve."""
- url: str = Field(..., description="Any MakerWorld model URL (scheme optional)")
- class MakerWorldResolvedModel(BaseModel):
- """Structured result of URL resolution.
- ``design`` and ``instances`` are passed through verbatim from MakerWorld's
- API — we don't re-shape them because the frontend needs access to fields
- MakerWorld may add over time (badges, license variants, etc.). Keeping
- them as opaque dicts avoids brittle coupling.
- """
- model_id: int
- profile_id: int | None = Field(
- default=None,
- description="Specific profile from the URL's #profileId- fragment, if any",
- )
- design: dict[str, Any]
- instances: list[dict[str, Any]]
- already_imported_library_ids: list[int] = Field(
- default_factory=list,
- description="LibraryFile IDs that were previously imported from this model URL",
- )
- class MakerWorldImportRequest(BaseModel):
- """Body for POST /makerworld/import."""
- model_id: int = Field(
- ...,
- description="The MakerWorld design ID (the number in /models/{id}).",
- )
- profile_id: int | None = Field(
- default=None,
- description=(
- "The profileId of the selected instance (plate configuration). Each "
- "instance in `/design/{id}/instances` carries a `profileId` field — "
- "the frontend forwards the picked one here. If omitted, the backend "
- "falls back to the first available instance of the model."
- ),
- )
- instance_id: int | None = Field(
- default=None,
- description="Retained for backwards compatibility; no longer used by the download flow.",
- )
- folder_id: int | None = Field(default=None, description="Target library folder; null = root")
- class MakerWorldRecentImport(BaseModel):
- """One row in the 'recent MakerWorld imports' list."""
- library_file_id: int
- filename: str
- folder_id: int | None
- thumbnail_path: str | None = Field(
- default=None,
- description="Relative path under /api/v1/library/files/{id}/thumbnail — "
- "the frontend wraps it with a stream token to render.",
- )
- source_url: str | None = Field(
- default=None,
- description="Canonical MakerWorld URL (``https://makerworld.com/models/{id}"
- "#profileId-{pid}``). The frontend uses it to build an 'Open on MakerWorld' "
- "link and to extract model/profile ids without a second API round-trip.",
- )
- created_at: str
- class MakerWorldImportResponse(BaseModel):
- """Result of a MakerWorld import."""
- library_file_id: int
- filename: str
- folder_id: int | None = Field(
- default=None,
- description=(
- "Folder the file was saved to — the auto-created 'MakerWorld' folder "
- "by default, or whichever folder the caller specified. Surfaced so the "
- "frontend can deep-link to File Manager → that folder after import."
- ),
- )
- profile_id: int | None = Field(
- default=None,
- description=(
- "The MakerWorld profile (plate) id that was imported. Surfaced so the "
- "frontend can match the response back to the plate row in the UI and "
- "render inline 'view in library' / 'open in slicer' controls there."
- ),
- )
- was_existing: bool = Field(
- description="True if a prior import from the same source URL was reused (no re-download)"
- )
- class MakerWorldStatus(BaseModel):
- """Integration health + auth status surfaced to the frontend."""
- has_cloud_token: bool = Field(description="Whether the caller's account has a stored Bambu Cloud token")
- can_download: bool = Field(description="Shortcut: has_cloud_token AND it looks valid. Downloads require it.")
|