Skip to content

Conversation

@ahouseholder
Copy link
Contributor

@ahouseholder ahouseholder commented Oct 9, 2025

This PR complements #1002. Starting it as a draft for discussion purposes.

Still TODO:

  • add tests for api endpoints
  • add readme to src/ssvc/api

This pull request introduces a new examples API router, improves the organization and documentation of the SSVC API, and refines serialization logic for several models. The main changes include adding endpoints for retrieving and validating example SSVC objects, updating the API documentation, and enhancing how falsy fields are handled in model serialization.

API Improvements

  • Added a new examples router (src/ssvc/api/v1/routers/examples.py) that provides GET and POST endpoints for sample and validation of SSVC objects (Decision Points, Decision Tables, Selections, References, etc.), making it easier to test and understand the API.
  • Registered the examples router in the main v1 API router (src/ssvc/api/v1/routers/v1_router.py), and updated the main API router registration to include a versioned prefix and tags for better organization. [1] [2] [3]

Documentation

  • Added a comprehensive README for the SSVC API (src/ssvc/api/README.md) with setup instructions for development and production environments.

Example Data

  • Added a new module (src/ssvc/examples.py) containing reusable example objects for Decision Points, Decision Tables, Selections, and References, used by the examples API endpoints.

Serialization Logic

  • Improved serialization of Reference and SelectionList models to automatically remove falsy fields when dumping to JSON, and ensured default values for missing fields, leading to cleaner API responses. [1] [2]
  • Refactored and removed legacy post-processing methods in SelectionList to rely on the new model serializer approach, simplifying the codebase and improving maintainability.

Let me know if you want to walk through any specific endpoint or serialization logic in more detail!

@ahouseholder ahouseholder added this to the 2025-12 milestone Oct 9, 2025
@ahouseholder ahouseholder self-assigned this Oct 9, 2025
@ahouseholder ahouseholder added the tech/backend Back-end tools, code, infrastructure label Oct 9, 2025
@ahouseholder
Copy link
Contributor Author

Screenshot 2025-10-09 at 3 59 58 PM

@sei-vsarvepalli
Copy link
Contributor

Screenshot 2025-10-09 at 3 59 58 PM

Don't see this when I run this current branch. It looks like the landing /docs url does not have the examples?

@ahouseholder
Copy link
Contributor Author

Don't see this when I run this current branch. It looks like the landing /docs url does not have the examples?

Are you running the docker image? If so, you might need to add --build to the docker-compose up --build api to reconstruct the image with the latest code.

Otherwise, uv --project=src run uvicorn ssvc.api.main:app --reload --port=7777 should give you a "live" (reload on changes to code) server.

Right now, the docker api target is static. I want to add a separate api-dev target that mounts the code from the host and runs the --reload command above. But as I've learned over on Vultron, that takes a bit of wrangling to avoid corruption of the uv-managed .venv between the container and the host OS (you want them to remain separate, so mounting the whole project directory doesn't work). I'll spawn a separate issue to capture that though, and it's unlikely to happen for this PR. So the workarounds above are hopefully sufficient.

@sei-vsarvepalli
Copy link
Contributor

Don't see this when I run this current branch. It looks like the landing /docs url does not have the examples?

Are you running the docker image? If so, you might need to add --build to the docker-compose up --build api to reconstruct the image with the latest code.

Otherwise, uv --project=src run uvicorn ssvc.api.main:app --reload --port=7777 should give you a "live" (reload on changes to code) server.

Right now, the docker api target is static. I want to add a separate api-dev target that mounts the code from the host and runs the --reload command above. But as I've learned over on Vultron, that takes a bit of wrangling to avoid corruption of the uv-managed .venv between the container and the host OS (you want them to remain separate, so mounting the whole project directory doesn't work). I'll spawn a separate issue to capture that though, and it's unlikely to happen for this PR. So the workarounds above are hopefully sufficient.

All works proper now. visit https://api.democert.org/ssvc/ site experiment. Because of reverse proxy setup, my startup script looks like below - I am mapping all the requests to /ssvc so if we have other api's we can run them under a distinct path on the same reverse proxy.

uv --project=src run uvicorn ssvc.api.main:app --root-path /ssvc --forwarded-allow-ips=127.0.0.1 --reload

Thanks
Vijay

@ahouseholder
Copy link
Contributor Author

All works proper now. visit https://api.democert.org/ssvc/ site experiment. Because of reverse proxy setup, my startup script looks like below - I am mapping all the requests to /ssvc so if we have other api's we can run them under a distinct path on the same reverse proxy.

uv --project=src run uvicorn ssvc.api.main:app --root-path /ssvc --forwarded-allow-ips=127.0.0.1 --reload

Good point, I will add an "ssvc" prefix to the FastAPI app.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overridingmodel_dump and model_dump_json works when you're interacting directly with the Python objects. But when you add FastAPI to the mix, it turns out that FastAPI tries to outsmart you by creating parallel class definitions on the return trip through how the response_model interacts with jsonable_encoder, which bypasses these overrides. So instead, a more universal solution is to add the @model_serializer decorated method here (which I also needed to handle missing/empty Reference.summary values too).

)

app.include_router(router_v1)
app.include_router(router_v1, prefix="/ssvc/api/v1", tags=["SSVC API v1"])
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

This changes the prefix for the whole API. If we don't want to force the /ssvc/api prefix (or we'd rather it just be /ssvc/v1), we should change this line.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, instead of having ssvc.api.v1.routers.v1_router.router assign the /v1 part of the prefix, this PR changes it so the /v1 prefix is added by the include_router call. I'm not sure which way is preferable.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no preference really. I think it is fine the way you have it.

@ahouseholder ahouseholder marked this pull request as ready for review October 10, 2025 17:57
Copilot AI review requested due to automatic review settings October 10, 2025 17:57
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds a new examples router to the SSVC API that provides endpoints for retrieving and validating sample objects for decision points, decision tables, selections, and related types. This helps users understand expected data formats and test their payloads.

  • Added example object instances in a new examples.py module
  • Created new API router with GET/POST endpoints for validation
  • Refactored model serialization to handle empty fields consistently

Reviewed Changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/ssvc/examples.py Defines example instances for all SSVC object types used by the API
src/ssvc/api/v1/routers/examples.py New router providing GET/POST endpoints for each object type
src/ssvc/api/v1/routers/v1_router.py Integration of examples router into main v1 API
src/ssvc/api/main.py Updated app configuration with proper prefix and tags
src/ssvc/selection.py Refactored serialization logic using model_serializer decorator
src/test/test_selections.py Enhanced test coverage for Reference and SelectionList models
src/test/api/test_main.py Added examples router to expected routers test
src/test/api/routers/test_examples.py Comprehensive test suite for new examples endpoints
src/ssvc/api/README.md Added documentation for running the API locally

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@ahouseholder ahouseholder requested a review from Copilot October 10, 2025 18:08
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Copy link
Contributor

@sei-vsarvepalli sei-vsarvepalli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly looks good. Once it is out of draft I will run a few more test.

Copy link
Contributor

@sei-vsarvepalli sei-vsarvepalli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All good. Optionally accept co-pilot suggestions, some cleanness in quotes usage. They don't seem significant.

ahouseholder and others added 3 commits October 10, 2025 14:30
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@ahouseholder ahouseholder merged commit 4d5b597 into main Oct 10, 2025
5 checks passed
@ahouseholder ahouseholder deleted the api-examples branch October 10, 2025 18:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

tech/backend Back-end tools, code, infrastructure

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add /examples/* to basic FastAPI

3 participants