Skip to content

feat(preprod): Set up snapshot get API#108199

Merged
rbro112 merged 9 commits intomasterfrom
ryan/wireup_snapshot_get_api
Feb 20, 2026
Merged

feat(preprod): Set up snapshot get API#108199
rbro112 merged 9 commits intomasterfrom
ryan/wireup_snapshot_get_api

Conversation

@rbro112
Copy link
Copy Markdown
Member

@rbro112 rbro112 commented Feb 13, 2026

Wires up the snapshots GET api that we'll use for both snapshots and snapshot diffs. Frontend implemented in #108278

@rbro112 rbro112 requested a review from a team as a code owner February 13, 2026 01:55
Copy link
Copy Markdown
Member Author

rbro112 commented Feb 13, 2026

This stack of pull requests is managed by Graphite. Learn more about stacking.

@github-actions github-actions bot added the Scope: Backend Automatically applied to PRs that change backend components label Feb 13, 2026
@rbro112 rbro112 changed the title Wireup snapshot get API [WIP] Wireup snapshot get API Feb 13, 2026
T = TypeVar("T")


def parse_request_with_pydantic(request: Request, model: type[T]) -> T:
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Wanted to share this as I like the idea of using pydantic over the current schemas



class SnapshotImageResponse(BaseModel):
id: str
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I'll need to add objectstore key here

@rbro112 rbro112 changed the title [WIP] Wireup snapshot get API feat(preprod): Set up snapshot get API Feb 13, 2026
@rbro112 rbro112 force-pushed the ryan/wireup_snapshot_get_api branch from f0bf87f to af96c5b Compare February 14, 2026 00:16
)

offset = request_data.offset
limit = request_data.limit
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

should we use the standardized OffsetPaginator for pagination like we do in list build endpoints we already have? I remember @ryan953 pushing for it

Copy link
Copy Markdown
Member

@ryan953 ryan953 Feb 19, 2026

Choose a reason for hiding this comment

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

I still recommend it! It helps with all parts of pagination. It works well enough with our ui components to show prev/next buttons by returning the Link header in a common format that includes a cursor value, and you can also optionally return the X-Hits header which makes it possible to know how many items there are in total.

As-is I don't see this endpoint returning a cursor, so the ui would need to presumably adjust the offset itself to make requests for the 2nd and 3rd pages, and you'd have no idea how many pages there are in total.

head_artifact_id: str
base_artifact_id: str | None = None # Only present for diffs
state: PreprodArtifact.ArtifactState
comparison_type: SnapshotComparisonType
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

im fine keeping this but curious if it's even necessary since if base_artifact_id is missing, doesn't that imply it's a diff?

…shot endpoint

The snapshot GET endpoint was using parse_request_with_pydantic which
parses request.body as JSON, causing 400 errors on GET requests. Switch
to constructing SnapshotGetRequest from request.GET query params. Also
add validation bounds on offset/limit, make ImageMetadata.display_name
optional for backwards compat, and update test assertions for key field.
Comment on lines +7 to +8
display_name: str | None = None
file_name: str
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Bug: The ImageMetadata model now requires the file_name field. Loading old snapshot manifests that lack this field will cause a validation error and fail.
Severity: CRITICAL

Suggested Fix

To maintain backwards compatibility, the file_name field in the ImageMetadata model should be made optional. For example, change file_name: str to file_name: str | None = None. This will allow the system to successfully parse old manifests that do not contain this field.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: src/sentry/preprod/snapshots/manifest.py#L7-L8

Potential issue: The `ImageMetadata` Pydantic model has been updated to make the
`file_name` field mandatory. However, existing snapshot manifests stored in object
storage were created with an older schema and do not contain this field. When the GET
endpoint for snapshots attempts to load and parse one of these old manifests, Pydantic
will raise a `ValidationError` because the required `file_name` is missing. This
exception is caught and results in a 500 error, effectively making all pre-existing
snapshots inaccessible.

@rbro112 rbro112 merged commit 9724a44 into master Feb 20, 2026
78 of 79 checks passed
@rbro112 rbro112 deleted the ryan/wireup_snapshot_get_api branch February 20, 2026 21:15
wedamija pushed a commit that referenced this pull request Feb 20, 2026
Wires up the snapshots GET api that we'll use for both snapshots and
snapshot diffs. Frontend implemented in #108278
priscilawebdev pushed a commit that referenced this pull request Feb 24, 2026
Wires up the snapshots GET api that we'll use for both snapshots and
snapshot diffs. Frontend implemented in #108278
mchen-sentry pushed a commit that referenced this pull request Feb 24, 2026
Wires up the snapshots GET api that we'll use for both snapshots and
snapshot diffs. Frontend implemented in #108278
@github-actions github-actions bot locked and limited conversation to collaborators Mar 8, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

claude-code-assisted Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants