Coverage for /usr/lib/python3.10/site-packages/hyd/backend/tag/models.py: 100%
35 statements
« prev ^ index » next coverage.py v7.0.3, created at 2023-01-05 16:38 +0000
« prev ^ index » next coverage.py v7.0.3, created at 2023-01-05 16:38 +0000
1import datetime as dt
2from typing import TypedDict
4from fastapi import status
5from sqlalchemy import (
6 Boolean,
7 Column,
8 ForeignKey,
9 ForeignKeyConstraint,
10 Integer,
11 String,
12)
13from sqlalchemy.orm import Mapped, relationship
15from hyd.backend.db import EXTEND_EXISTING, DeclarativeMeta
16from hyd.backend.project.models import ProjectEntry
17from hyd.backend.util.const import MAX_LENGTH_STR_ID
18from hyd.backend.util.models import (
19 BASE_API_RESPONSE_SCHEMA,
20 DETAIL_STR,
21 NameStr,
22 PrimaryKey,
23 TimeStampMixin,
24)
25from hyd.backend.version.models import VersionEntry
27####################################################################################################
28#### SQLAlchemy table definitions
29####################################################################################################
32class TagEntry(DeclarativeMeta, TimeStampMixin):
33 __tablename__ = "tag_table"
34 __table_args__ = (
35 ForeignKeyConstraint(
36 ["project_id", "version"], [VersionEntry.project_id, VersionEntry.version]
37 ),
38 {"extend_existing": EXTEND_EXISTING},
39 )
40 project_id: Mapped[PrimaryKey] = Column(Integer, ForeignKey(ProjectEntry.id), primary_key=True)
41 version: Mapped[NameStr | None] = Column(
42 String(length=MAX_LENGTH_STR_ID), nullable=True, default=None
43 )
45 tag: Mapped[NameStr] = Column(String(length=MAX_LENGTH_STR_ID), primary_key=True)
46 primary: Mapped[bool] = Column(Boolean) # primary == False will be marked as copy for google
48 project_entry: Mapped[ProjectEntry] = relationship(
49 ProjectEntry, back_populates="tag_entries", viewonly=True
50 )
51 version_entry: Mapped[VersionEntry] = relationship(
52 VersionEntry, back_populates="tag_entries", viewonly=True
53 )
54 # no cascade="delete" because delete has to be done manually to remove files from disc
57class PrimaryTagEntry(DeclarativeMeta, TimeStampMixin):
58 __tablename__ = "primary_tag_table"
59 __table_args__ = (
60 ForeignKeyConstraint(["project_id", "primary_tag"], [TagEntry.project_id, TagEntry.tag]),
61 {"extend_existing": EXTEND_EXISTING},
62 )
64 project_id: Mapped[PrimaryKey] = Column(Integer, primary_key=True)
65 primary_tag: Mapped[NameStr] = Column(String(length=MAX_LENGTH_STR_ID))
68####################################################################################################
69#### Response schema
70####################################################################################################
73class TagResponseSchema(TypedDict):
74 project_id: PrimaryKey
75 tag: NameStr
76 created_at: dt.datetime
77 updated_at: dt.datetime | None
78 version: NameStr | None
79 primary: bool
82####################################################################################################
83#### OpenAPI definitions
84####################################################################################################
87API_V1_CREATE__POST = {
88 **BASE_API_RESPONSE_SCHEMA,
89 status.HTTP_200_OK: {"model": TagResponseSchema},
90 status.HTTP_400_BAD_REQUEST: DETAIL_STR,
91}
94API_V1_LIST__GET = {
95 **BASE_API_RESPONSE_SCHEMA,
96 status.HTTP_200_OK: {"model": list[TagResponseSchema]},
97}
100API_V1_MOVE__PATCH = {
101 **BASE_API_RESPONSE_SCHEMA,
102 status.HTTP_200_OK: {"model": TagResponseSchema},
103 status.HTTP_400_BAD_REQUEST: DETAIL_STR,
104}
107API_V1_DELETE__DELETE = {
108 **BASE_API_RESPONSE_SCHEMA,
109 status.HTTP_200_OK: {"model": TagResponseSchema},
110 status.HTTP_400_BAD_REQUEST: DETAIL_STR,
111}