Skip to content

feat(application): read shared runs via --share-token - #688

Merged
olivermeyer merged 6 commits into
mainfrom
feat/PYSDK-145-read-run-with-share-token
Aug 6, 2026
Merged

feat(application): read shared runs via --share-token#688
olivermeyer merged 6 commits into
mainfrom
feat/PYSDK-145-read-run-with-share-token

Conversation

@dima-aignostics

@dima-aignosticsdima-aignostics commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Why?
Enable an authenticated user who holds a share-token secret to read an application run shared with them via the CLI (PYSDK-145, UC2 token-based sharing). OAuth login remains required — the share token is additive, elevating the authenticated user's access to a run they could not otherwise read. Follow-up to PYSDK-132; design per ADR-PAPI-0004 (token forwarded as a share_token query parameter alongside the OAuth Bearer).

How?
Add an optional --share-token option to run describe, run dump-metadata, run dump-item-metadata, and run result download, threading it through Service into Run/Artifact where it is forwarded URL-encoded as the share_token query parameter on the run, items, and artifact-file requests, and folded into the operation-cache key so share-token reads stay isolated from authenticated reads of the same run. A 403 propagates unchanged through the download path (rather than being wrapped into RuntimeError) so the CLI surfaces a token-omitting "access denied" message and exits 1; omitting the flag is a pure no-op passthrough.

@dima-aignostics
dima-aignostics requested a review from a team as a code ownerJune 22, 2026 08:46
@dima-aignostics
dima-aignosticsforce-pushed the feat/PYSDK-145-read-run-with-share-token branch 4 times, most recently from b524be7 to 9510e92CompareJune 22, 2026 11:36
@dima-aignostics
dima-aignosticsforce-pushed the feat/PYSDK-132-add-run-sharing-to-python-sdk branch 6 times, most recently from 6ae872e to 0bc4980CompareJune 23, 2026 21:15
Base automatically changed from feat/PYSDK-132-add-run-sharing-to-python-sdk to mainJune 29, 2026 08:04
@dima-aignostics
dima-aignosticsforce-pushed the feat/PYSDK-145-read-run-with-share-token branch 3 times, most recently from 5ab4c44 to 23c6793CompareJune 30, 2026 14:04
@codecov

codecovBot commented Jun 30, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.00000% with 3 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing linesPatch %Lines
src/aignostics/application/_cli.py91.30%1 Missing and 1 partial ⚠️
src/aignostics/application/_utils.py80.00%0 Missing and 1 partial ⚠️
Files with missing linesCoverage Δ
src/aignostics/application/_service.py64.06% <100.00%> (+0.25%)⬆️
src/aignostics/platform/resources/runs.py86.48% <100.00%> (+0.96%)⬆️
src/aignostics/application/_utils.py88.66% <80.00%> (-0.22%)⬇️
src/aignostics/application/_cli.py79.43% <91.30%> (+1.21%)⬆️

... and 1 file with indirect coverage changes

@dima-aignostics
dima-aignosticsforce-pushed the feat/PYSDK-145-read-run-with-share-token branch from 23c6793 to c3c99efCompareJune 30, 2026 15:38
@dima-aignosticsdima-aignostics changed the title feat(application): add --share-token to run describe CLI command (PYS…feat(application): add --share-token to run commandsJul 1, 2026
@dima-aignostics
dima-aignosticsforce-pushed the feat/PYSDK-145-read-run-with-share-token branch from 01154f0 to 8bad631CompareJuly 1, 2026 11:23
@sonarqubecloud

Copy link
Copy Markdown

@olivermeyer
olivermeyerforce-pushed the feat/PYSDK-145-read-run-with-share-token branch 2 times, most recently from d8936d0 to b2023b8CompareAugust 5, 2026 08:55
olivermeyer added a commit that referenced this pull request Aug 5, 2026
Address code-review findings on PR #688:
- Fix two _service.py docstrings that wrongly described share-token access as
"without OAuth"/"unauthenticated"; share tokens elevate an already
OAuth-authenticated user's access.
- Rewrite the three forbidden CLI tests to raise ForbiddenException from the
real source (run.details()/run.results()) instead of application_run, which
wraps all exceptions into RuntimeError in production.
- Normalize an empty --share-token to None at the application_run choke point
so a blank value falls back to the normal authenticated read; add service
tests for both branches.
- Make share_token_access_denied_message a pure builder and move the warning
log to the four CLI call sites (command-query separation).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@olivermeyer
olivermeyerforce-pushed the feat/PYSDK-145-read-run-with-share-token branch from 48c83d8 to 65027bbCompareAugust 6, 2026 08:32
@olivermeyerolivermeyer changed the title feat(application): add --share-token to run commandsfeat(application): read shared runs via --share-tokenAug 6, 2026

@arne-aignxarne-aignx left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM. I added two smaller nits

Comment threadsrc/aignostics/application/_utils.py Outdated
raise RuntimeError(message)


def share_token_access_denied_message(run_id: str, share_token: str | None) -> str:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

nit: run_access_denied_message might be a better wording here.
I was a bit confused reading through the initial code wondering "Why do we provide a share_token related error message, when a 403 is returned by the API and no share token was provided

if self._share_token is not None:
# Percent-encode the secret so reserved characters (& # = space) cannot
# corrupt the URL or inject extra query parameters.
endpoint_url += f"?{urlencode({'share_token': self._share_token})}"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

nit: Alternatively, self._share_token could also be forwarded to _fetch_redirect_url as an argument, and we let requests.get handle the URL construction from the provided query paramters

@olivermeyer
olivermeyer enabled auto-merge (squash) August 6, 2026 09:45
dima-aignosticsand others added 3 commits August 6, 2026 11:50
…DK-145)
Recipients holding a share token secret can now describe a run without
OAuth login by passing --share-token <secret> to `application run describe`.
The token is used directly as the Bearer token for platform API requests.
- Adds `--share-token` option to `run describe`; when set, creates a
`Client(token_provider=…)` bypassing OAuth, with `hide_platform_queue_position=True`
- Catches `UnauthorizedException` and `ForbiddenException` when using a share
token and surfaces a clear "Access denied" message with exit code 1
- Adds 5 integration tests covering success (text + JSON), not-found,
unauthorized, and forbidden paths
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a --share-token option to `application run describe / dump-metadata /
dump-item-metadata / result download` (PYSDK-145), granting an authenticated
user access to a run that has been shared with them.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
olivermeyerand others added 3 commits August 6, 2026 11:51
Address code-review findings on PR #688:
- Fix two _service.py docstrings that wrongly described share-token access as
"without OAuth"/"unauthenticated"; share tokens elevate an already
OAuth-authenticated user's access.
- Rewrite the three forbidden CLI tests to raise ForbiddenException from the
real source (run.details()/run.results()) instead of application_run, which
wraps all exceptions into RuntimeError in production.
- Normalize an empty --share-token to None at the application_run choke point
so a blank value falls back to the normal authenticated read; add service
tests for both branches.
- Make share_token_access_denied_message a pure builder and move the warning
log to the four CLI call sites (command-query separation).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@olivermeyer
olivermeyerforce-pushed the feat/PYSDK-145-read-run-with-share-token branch from 99f4bc6 to cd81e88CompareAugust 6, 2026 11:02
@sonarqubecloud

Copy link
Copy Markdown

@olivermeyer
olivermeyer merged commit 69122cc into mainAug 6, 2026
24 checks passed
@olivermeyer
olivermeyer deleted the feat/PYSDK-145-read-run-with-share-token branch August 6, 2026 11:39
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@dima-aignostics@arne-aignx@olivermeyer