|
15 | 15 |
|
16 | 16 | from ...common.graph import graph_from_edge_list_v2, graph_to_dict |
17 | 17 | from ...common.logging import LOGGER |
| 18 | +from ...common.timestamp import element_time |
18 | 19 | from ...db.campaigns_v2 import Campaign, CampaignUpdate, Edge, Node |
19 | 20 | from ...db.manifests_v2 import CampaignManifest |
20 | 21 | from ...db.session import db_session_dependency |
@@ -42,10 +43,16 @@ async def read_campaign_collection( |
42 | 43 | offset: Annotated[int, Query()] = 0, |
43 | 44 | ) -> Sequence[Campaign]: |
44 | 45 | """A paginated API returning a list of all Campaigns known to the |
45 | | - application. |
| 46 | + application, from newest to oldest. |
46 | 47 | """ |
47 | 48 | try: |
48 | | - campaigns = await session.exec(select(Campaign).offset(offset).limit(limit)) |
| 49 | + statement = ( |
| 50 | + select(Campaign) |
| 51 | + .order_by(Campaign.metadata_["crtime"].desc().nulls_last()) |
| 52 | + .offset(offset) |
| 53 | + .limit(limit) |
| 54 | + ) |
| 55 | + campaigns = await session.exec(statement) |
49 | 56 |
|
50 | 57 | response.headers["Next"] = str( |
51 | 58 | request.url_for("read_campaign_collection").include_query_params( |
@@ -196,15 +203,16 @@ async def read_campaign_node_collection( |
196 | 203 |
|
197 | 204 | # The input could be a campaign UUID or it could be a literal name. |
198 | 205 | # TODO this could just as well be a campaign query with a join to nodes |
199 | | - s = select(Node) |
| 206 | + statement = select(Node).order_by(Node.metadata_["crtime"].asc().nulls_last()) |
| 207 | + |
200 | 208 | try: |
201 | 209 | if campaign_id := UUID(campaign_name): |
202 | | - s = s.where(Node.namespace == campaign_id) |
| 210 | + statement = statement.where(Node.namespace == campaign_id) |
203 | 211 | except ValueError: |
204 | 212 | # FIXME get an id from a name |
205 | 213 | raise HTTPException(status_code=422, detail="campaign_name must be a uuid") |
206 | | - s = s.offset(offset).limit(limit) |
207 | | - nodes = await session.exec(s) |
| 214 | + statement = statement.offset(offset).limit(limit) |
| 215 | + nodes = await session.exec(statement) |
208 | 216 | response.headers["Next"] = str( |
209 | 217 | request.url_for( |
210 | 218 | "read_campaign_node_collection", |
@@ -252,7 +260,7 @@ async def read_campaign_edge_collection( |
252 | 260 | .join_from(Edge, target_nodes, Edge.target == target_nodes.id) |
253 | 261 | ) |
254 | 262 | else: |
255 | | - s = select(Edge) |
| 263 | + s = select(Edge).order_by(col(Edge.name).asc().nulls_last()) |
256 | 264 | try: |
257 | 265 | if campaign_id := UUID(campaign_name): |
258 | 266 | s = s.where(Edge.namespace == campaign_id) |
@@ -313,10 +321,12 @@ async def create_campaign_resource( |
313 | 321 | # Create a campaign spec from the manifest, delegating the creation of new |
314 | 322 | # dynamic fields to the model validation method, -OR- create new dynamic |
315 | 323 | # fields here. |
| 324 | + campaign_metadata = manifest.metadata_.model_dump() |
| 325 | + campaign_metadata |= {"crtime": element_time()} |
316 | 326 | campaign = Campaign.model_validate( |
317 | 327 | dict( |
318 | | - name=manifest.metadata_.name, |
319 | | - metadata_=manifest.metadata_.model_dump(), |
| 328 | + name=campaign_metadata.pop("name"), |
| 329 | + metadata_=campaign_metadata, |
320 | 330 | # owner = ... # TODO Get username from gafaelfawr # noqa: ERA001 |
321 | 331 | ) |
322 | 332 | ) |
@@ -376,12 +386,8 @@ async def read_campaign_graph( |
376 | 386 | edges = (await session.exec(statement)).all() |
377 | 387 |
|
378 | 388 | # Organize the edges into a graph. The graph nodes are annotated with their |
379 | | - # current database attributes. |
380 | | - # TODO it makes sense for the graph to include expunged Nodes in the meta- |
381 | | - # data for campaign processing, but for the purposes of this api route, |
382 | | - # only the most relevant information should be associated with each node, |
383 | | - # e.g., its name, status, id, and its URL |
| 389 | + # current database attributes according to the "simple" node view. |
384 | 390 | graph = await graph_from_edge_list_v2(edges=edges, node_type=Node, session=session, node_view="simple") |
385 | 391 |
|
386 | | - response.headers["Self"] = "" |
| 392 | + response.headers["Self"] = str(request.url_for("read_campaign_resource", campaign_name=campaign_id)) |
387 | 393 | return graph_to_dict(graph) |
0 commit comments