Skip to content

UN-2190 [FEAT] Auto-capture execution ID in the API deployment Postman collection#2031

Open
athul-rs wants to merge 3 commits into
mainfrom
UN-2190-postman-collection-scripts
Open

UN-2190 [FEAT] Auto-capture execution ID in the API deployment Postman collection#2031
athul-rs wants to merge 3 commits into
mainfrom
UN-2190-postman-collection-scripts

Conversation

@athul-rs

@athul-rs athul-rs commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

What

  • The downloaded Postman collection for API deployments now wires the two requests together: the Process document request stores execution_id from its response into a collection variable via a post-response script, and the Execution status request reads {{execution_id}} from that variable. No more manual copy-pasting of execution IDs.

Why

UN-2190 — minor UX gap: after executing a document asynchronously, users had to copy the execution ID from the response and paste it into the status request's REPLACE_WITH_EXECUTION_ID placeholder. The LLMWhisperer Postman collection already does this with whisper_hash; this applies the same pattern.

How

  • postman_collection/dto.py: new ScriptItem/EventItem/VariableItem dataclasses; PostmanItem gets an optional event; the execute request carries a post-response script (pm.collectionVariables.set("execution_id", ...), guarded so non-JSON/error responses are ignored); the status URL uses {{execution_id}} (urlencode with safe="{}" so Postman's braces survive); collection-level variable block added with a REPLACE_WITH_EXECUTION_ID default so manual use still works.
  • to_dict() strips event: null from items that have no scripts.
  • Pipeline collections (single request, no status call) are unchanged.

Can this PR break any existing features. If yes, please list possible items. If no, please explain why. (PS: Admins do not merge the PR without this section filled)

  • No. This only changes the generated Postman collection JSON (a download artifact), not any API behavior. The status request still works manually: if the script never ran, the variable resolves to the REPLACE_WITH_EXECUTION_ID default — identical to today's placeholder. The script is defensive (checks response.message.execution_id exists before setting).

Database Migrations

  • None

Env Config

  • None

Relevant Docs

  • N/A

Related Issues or PRs

  • Jira: UN-2190

Notes on Testing

  • ruff check + format clean.
  • Verified generated JSON structure with a stubbed-Django harness: execute item carries the event block, status item has none, status URL contains execution_id={{execution_id}} unescaped, and the collection-level variable is present.
  • Manual: download a collection from an API deployment, import into Postman, run Process document then Execution status — the second request uses the captured ID.

Screenshots

N/A

Checklist

I have read and understood the Contribution Guidelines.

🤖 Generated with Claude Code

Add a post-response script to the 'Process document' request that
stores message.execution_id into a collection variable, and point the
'Execution status' request's execution_id query param at that variable.
Users no longer copy-paste execution IDs between requests (mirrors the
LLMWhisperer collection's whisper_hash pattern).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3a9f5dbd-f056-4814-99f0-48ad01c1215a

📥 Commits

Reviewing files that changed from the base of the PR and between fe248a4 and 4bafbf7.

📒 Files selected for processing (1)
  • backend/api_v2/serializers.py

Summary by CodeRabbit

  • New Features
    • Postman collections now include collection-level variables and test-event scripting to capture and propagate an execution identifier automatically.
    • Status requests are wired to use the captured execution identifier via an encoded variable placeholder for end-to-end execution tracking.
    • API responses for execution now include an execution identifier field so callers can correlate execute and status flows.

Walkthrough

Adds constants and DTOs for Postman script events and collection variables, extends collection/item models, seeds collection variables via APIBase, and wires a test event on the execute request to capture execution_id for use in status requests.

Changes

Postman Execution ID Variable Flow

Layer / File(s) Summary
DTOs and constants (contracts)
backend/api_v2/postman_collection/dto.py, backend/api_v2/postman_collection/constants.py
Adds ScriptItem, EventItem, VariableItem dataclasses; adds CollectionKey.EXEC_ID_VARIABLE_NAME and CollectionKey.STATUS_EXEC_ID_VARIABLE; adds variable field to PostmanCollection.
Collection & item model updates
backend/api_v2/postman_collection/dto.py
PostmanItem adds optional event; PostmanCollection.create() populates variable from get_collection_variables(); to_dict() omits event when None.
APIBase hook and collection initialization
backend/api_v2/postman_collection/dto.py
Adds APIBase.get_collection_variables() hook returning list of VariableItem (default empty).
Execute -> status wiring and URL encoding
backend/api_v2/postman_collection/dto.py
Status URL encoding preserves {{execution_id}}; execute request item is augmented with a Postman test event that parses response.message.execution_id and stores it into the collection variable referenced by the status request.
Serializer: expose execution_id
backend/api_v2/serializers.py
APIExecutionResponseSerializer adds execution_id = CharField() to serialized execute responses.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 44.44% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: auto-capturing execution ID in the API deployment Postman collection by wiring together two requests via a post-response script.
Description check ✅ Passed The PR description is comprehensive and complete, covering all template sections: What, Why, How, breakage analysis, migrations, env config, docs, related issues, testing notes, and checklist.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch UN-2190-postman-collection-scripts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps

greptile-apps Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR wires together the two API-deployment requests in the downloaded Postman collection so that the execution_id returned by the execute request is automatically captured and fed into the status-polling request — eliminating the manual copy-paste step. All three previous review threads (unguarded pm.response.json(), spurious variable on Pipeline collections, missing execution_id field in the serializer) have been addressed in the current diff.

  • dto.py: Adds ScriptItem/EventItem/VariableItem dataclasses; PostmanItem gains an optional event list; APIDeploymentDto attaches a defensive post-response test script and overrides get_collection_variables() to seed the fallback default; PostmanCollection.to_dict() strips event: null entries; PipelineDto inherits the no-op base implementation and serialises with "variable": [].
  • serializers.py: Adds execution_id = CharField() to APIExecutionResponseSerializer so the field is present in the response body that the Postman script reads from response.message.execution_id.

Confidence Score: 5/5

Safe to merge — changes only affect the generated Postman collection JSON, not any live API behaviour; the serializer addition is purely additive.

The three substantive issues identified in the previous review round (unguarded JSON parse, spurious Pipeline variable, missing execution_id field) have all been resolved cleanly. The execute response structure matches what the Postman script reads. The Pipeline code path inherits a no-op get_collection_variables() and emits an empty "variable": [] which Postman accepts without issue. The serializer change exposes a field that was already present on ExecutionResponse but previously omitted from the output — additive and non-breaking.

No files require special attention.

Important Files Changed

Filename Overview
backend/api_v2/postman_collection/dto.py Core change: adds new dataclasses, attaches a try/catch-guarded Postman test script to the execute item, seeds a collection variable with a fallback default, and strips null event blocks in to_dict(). Logic is sound after previous-round fixes.
backend/api_v2/serializers.py Adds execution_id = CharField() to APIExecutionResponseSerializer; additive and non-breaking since ExecutionResponse.execution_id is always a non-null UUID string.
backend/api_v2/postman_collection/constants.py Adds two constants (EXEC_ID_VARIABLE_NAME and STATUS_EXEC_ID_VARIABLE) used to avoid magic strings; straightforward and correct.

Sequence Diagram

sequenceDiagram
    participant User as Postman User
    participant Execute as Process Document Request
    participant Script as Post-Response Script
    participant CollVar as Collection Variable (execution_id)
    participant Status as Execution Status Request
    participant API as Unstract API

    User->>Execute: "POST /api/{name} (multipart file)"
    Execute->>API: HTTP POST
    API-->>Execute: "{"message": {"execution_id": "uuid", "execution_status": "..."}}"
    Execute->>Script: Run test script
    Script->>Script: "try { pm.response.json() }"
    Script->>CollVar: pm.collectionVariables.set("execution_id", uuid)
    User->>Status: "GET /api/{name}?execution_id={{execution_id}}"
    Status->>CollVar: "Resolve {{execution_id}} to uuid"
    Status->>API: HTTP GET with resolved UUID
    API-->>User: Execution status response
Loading

Reviews (3): Last reviewed commit: "UN-2190 Expose execution_id in the API e..." | Re-trigger Greptile

Comment thread backend/api_v2/postman_collection/dto.py
Comment thread backend/api_v2/postman_collection/dto.py Outdated
…PI deployments

- Wrap pm.response.json() in try/catch so error pages (non-JSON) don't
  surface a Postman test error
- Move collection variables behind APIBase.get_collection_variables()
  so Pipeline collections (no status request) stay variable-free

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Comment thread backend/api_v2/postman_collection/dto.py
The ExecutionResponse DTO carries execution_id but
APIExecutionResponseSerializer dropped it, so the Postman capture
script (and any API consumer) had to parse it out of status_api.
Add it as a first-class response field; the collection script's
message.execution_id lookup now matches the real payload.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

@github-actions

Copy link
Copy Markdown
Contributor

Unstract test results

Per-group results

Status Group Tier Passed Failed Errors Skipped Duration (s)
unit-connectors unit 64 12 0 3 16.7
unit-core unit 0 0 2 0 1.2
unit-platform-service unit 9 0 1 0 1.3
unit-prompt-service unit 15 0 0 0 19.5
unit-rig unit 53 0 0 0 3.3
unit-runner unit 11 0 0 0 3.1
unit-sdk1 unit 381 0 0 0 23.6
unit-tool-registry unit 0 0 1 0 1.3
unit-workers unit 0 0 0 0 17.5
TOTAL 533 12 4 3 87.5

Critical paths

⚠️ Critical paths not yet covered

  • auth-login — User can log in and obtain a session cookie. (entry: POST /api/v1/auth/login; declared coverage: no groups declared)
  • adapter-register-llm — Register and validate an LLM adapter. (entry: POST /api/v1/adapter/; declared coverage: no groups declared)
  • workflow-create-execute — Create a workflow, configure source+destination, execute, poll, fetch result. (entry: POST /api/v1/workflow/{id}/execute/; declared coverage: e2e-workflow)
  • api-deployment-run — Deploy a workflow as an API, POST a document, receive structured JSON. (entry: POST /deployment/api/{org}/{name}/; declared coverage: e2e-api-deployment)
  • prompt-studio-fetch-response — Prompt Studio: create project, add prompt, run single-pass, get response. (entry: POST /api/v1/prompt-studio/prompt-studio-tool/{id}/fetch_response/; declared coverage: e2e-prompt-studio)
  • pipeline-etl-execute — Run an ETL pipeline from source connector to destination. (entry: POST /api/v1/pipeline/{id}/execute/; declared coverage: no groups declared)
  • usage-token-tracking — Per-execution token usage is recorded and retrievable. (entry: GET /api/v1/usage/get_token_usage/; declared coverage: no groups declared)
  • workflow-execution-fan-out — Multi-file workflow execution fans out to file-processing workers and rejoins. (entry: internal: backend → rabbitmq → workers/file_processing; declared coverage: no groups declared)
  • callback-result-delivery — Async results are posted back via the callback worker. (entry: internal: workers/callback → backend /internal endpoints; declared coverage: no groups declared)
✅ Covered critical paths
  • tool-sandbox-exec — covered by unit-runner

Sign up for free to 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.

2 participants