Skip to content

Commit cdb6e17

Browse files
committed
feat(api): Add campaign_v2 and manifest_v2 routes
bugfix(manifests): correct manifest name determination chore(tests): Implement tests for manifest routes feat(api): Extend and update v2 manifest routes
1 parent 813c287 commit cdb6e17

13 files changed

Lines changed: 1159 additions & 27 deletions

File tree

.github/workflows/ci.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ name: "CI"
1212

1313
env:
1414
UV_FROZEN: "1"
15+
TEST__LOCAL_DB: "1" # signals test fixtures to not use testcontainers
1516

1617
jobs:
1718
rebase-checker:

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ max-doc-length = 79
169169
convention = "numpy"
170170

171171
[tool.pytest.ini_options]
172-
asyncio_mode = "strict"
172+
asyncio_mode = "auto"
173173
asyncio_default_fixture_loop_scope="function"
174174
# The python_files setting is not for test detection (pytest will pick up any
175175
# test files named *_test.py without this setting) but to enable special

src/lsst/cmservice/db/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""Database table definitions and utility functions"""
22

3+
from . import campaigns_v2
34
from .base import Base
45
from .campaign import Campaign
56
from .element import ElementMixin

src/lsst/cmservice/db/campaigns_v2.py

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ def jsonb_column(name: str, aliases: list[str] | None = None) -> Any:
6969
"""
7070

7171

72+
type StatusField = Annotated[StatusEnum, StatusEnumValidator, EnumSerializer]
73+
type KindField = Annotated[ManifestKind, ManifestKindEnumValidator, EnumSerializer]
74+
75+
7276
class BaseSQLModel(SQLModel):
7377
__table_args__ = {"schema": config.db.table_schema}
7478

@@ -80,7 +84,7 @@ class CampaignBase(BaseSQLModel):
8084
name: str
8185
namespace: UUID
8286
owner: str | None = Field(default=None)
83-
status: Annotated[StatusEnum, StatusEnumValidator, EnumSerializer] | None = Field(
87+
status: StatusField | None = Field(
8488
default=StatusEnum.waiting,
8589
sa_column=Column("status", Enum(StatusEnum, length=20, native_enum=False, create_constraint=False)),
8690
)
@@ -115,18 +119,27 @@ class Campaign(CampaignModel, table=True):
115119
machine: UUID | None
116120

117121

122+
class CampaignUpdate(SQLModel):
123+
"""Model representing updatable fields for a PATCH operation on a Campaign
124+
using RFC7396.
125+
"""
126+
127+
owner: str | None = None
128+
status: StatusField | None = None
129+
130+
118131
class NodeBase(BaseSQLModel):
119132
"""nodes_v2 db table"""
120133

121134
id: UUID = Field(primary_key=True)
122135
name: str
123136
namespace: UUID
124137
version: int
125-
kind: Annotated[ManifestKind, ManifestKindEnumValidator, EnumSerializer] = Field(
138+
kind: KindField = Field(
126139
default=ManifestKind.other,
127140
sa_column=Column("kind", Enum(ManifestKind, length=20, native_enum=False, create_constraint=False)),
128141
)
129-
status: Annotated[StatusEnum, StatusEnumValidator, EnumSerializer] | None = Field(
142+
status: StatusField | None = Field(
130143
default=StatusEnum.waiting,
131144
sa_column=Column("status", Enum(StatusEnum, length=20, native_enum=False, create_constraint=False)),
132145
)
@@ -209,7 +222,7 @@ class ManifestBase(BaseSQLModel):
209222
name: str
210223
version: int
211224
namespace: UUID
212-
kind: Annotated[ManifestKind, EnumSerializer] = Field(
225+
kind: KindField = Field(
213226
default=ManifestKind.other,
214227
sa_column=Column("kind", Enum(ManifestKind, length=20, native_enum=False, create_constraint=False)),
215228
)
@@ -270,8 +283,16 @@ class ActivityLogBase(BaseSQLModel):
270283
namespace: UUID
271284
node: UUID
272285
operator: str
273-
from_status: Annotated[StatusEnum, EnumSerializer]
274-
to_status: Annotated[StatusEnum, EnumSerializer]
286+
to_status: StatusField = Field(
287+
sa_column=Column(
288+
"to_status", Enum(StatusEnum, length=20, native_enum=False, create_constraint=False)
289+
),
290+
)
291+
from_status: StatusField = Field(
292+
sa_column=Column(
293+
"from_status", Enum(StatusEnum, length=20, native_enum=False, create_constraint=False)
294+
),
295+
)
275296
detail: dict = jsonb_column("detail")
276297

277298

src/lsst/cmservice/main.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
index,
1616
tags_metadata,
1717
v1,
18+
v2,
1819
)
1920
from .web_app import web_app
2021

@@ -53,6 +54,7 @@ async def lifespan(app: FastAPI) -> AsyncGenerator:
5354
app.include_router(healthz.health_router, prefix="")
5455
app.include_router(index.router, prefix="")
5556
app.include_router(v1.router, prefix=config.asgi.prefix)
57+
app.include_router(v2.router, prefix=config.asgi.prefix)
5658

5759
# Start the frontend web application.
5860
if config.asgi.enable_frontend:
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from fastapi import APIRouter
2+
3+
from . import (
4+
campaigns,
5+
manifests,
6+
)
7+
8+
router = APIRouter(
9+
prefix="/v2",
10+
)
11+
12+
router.include_router(campaigns.router)
13+
router.include_router(manifests.router)

0 commit comments

Comments
 (0)