forked from attevon-llc/OpenTranscribe
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbase.py
More file actions
94 lines (72 loc) · 3.32 KB
/
Copy pathbase.py
File metadata and controls
94 lines (72 loc) · 3.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
"""
Base Pydantic schemas for hybrid ID system.
Provides automatic UUID exposure for all response schemas.
Internal database uses integer IDs for fast queries, external API uses UUIDs.
"""
import builtins
import contextlib
from typing import Any
from uuid import UUID
from pydantic import BaseModel
from pydantic import ConfigDict
from pydantic import model_validator
class UUIDBaseSchema(BaseModel):
"""
Base schema for models with UUID public identifiers.
All response schemas should inherit from this to get automatic
UUID exposure to the external API.
The SQLAlchemy model must have both:
- id: Integer (internal primary key, NOT exposed to API)
- uuid: UUID (public identifier, exposed to API)
The schema exposes 'uuid' as the public identifier.
Internal integer 'id' is never sent to the frontend.
"""
uuid: UUID # Public UUID identifier
model_config = ConfigDict(from_attributes=True)
@classmethod
def _convert_to_dict(cls, data: Any) -> dict[str, Any]:
"""Convert SQLAlchemy model to dict, excluding internal id."""
if isinstance(data.__dict__, dict):
# Exclude internal 'id' field - only expose 'uuid'
return {k: v for k, v in data.__dict__.items() if not k.startswith("_") and k != "id"}
data_dict = {}
for attr in dir(data):
if not attr.startswith("_") and attr != "id":
with contextlib.suppress(builtins.BaseException):
data_dict[attr] = getattr(data, attr)
return data_dict
@classmethod
def _map_foreign_key_uuids(cls, data: Any, data_dict: dict[str, Any]) -> None:
"""Map foreign key UUIDs from related objects to the data dict."""
# Map user relationship
if hasattr(data, "user") and hasattr(data.user, "uuid"):
data_dict["user_id"] = data.user.uuid
# Map media_file relationship
if hasattr(data, "media_file") and hasattr(data.media_file, "uuid"):
data_dict["media_file_id"] = data.media_file.uuid
# Map speaker relationship
if hasattr(data, "speaker") and hasattr(data.speaker, "uuid"):
data_dict["speaker_id"] = data.speaker.uuid
# Map profile relationship
if hasattr(data, "profile") and hasattr(data.profile, "uuid"):
data_dict["profile_id"] = data.profile.uuid
@model_validator(mode="before")
@classmethod
def prepare_uuid_response(cls, data: Any) -> Any:
"""
Prepare model data for API response, ensuring uuid is properly exposed.
Also maps foreign key UUIDs (user_id, media_file_id, etc.) from related models.
This runs before Pydantic validation, allowing us to transform
the SQLAlchemy model's data structure.
"""
# Handle SQLAlchemy models
if hasattr(data, "uuid") and hasattr(data, "__dict__"):
data_dict = cls._convert_to_dict(data)
# Include computed properties that aren't in __dict__
# has_api_key is a property on UserLLMSettings model
if hasattr(data, "has_api_key") and "has_api_key" not in data_dict:
data_dict["has_api_key"] = data.has_api_key
# Map foreign key UUIDs from related objects
cls._map_foreign_key_uuids(data, data_dict)
return data_dict
return data