Skip to content

feat(SOF-8032): embed the workflow when a job is created with a workflow reference - #48

Merged
k0stik merged 6 commits into
mainfrom
feature/SOF-8032
Oct 7, 2026
Merged

k0stik merged 6 commits into
mainfrom
feature/SOF-8032

Conversation

@k0stik

@k0stik k0stik commented Oct 6, 2026 •

Copy link
Copy Markdown
Member

Why this PR is needed

jobs.create is rejected by the platform with 422 when the job gives its workflow only by _id. The api-examples notebooks do that (create_and_submit_job), and so does create_by_ids, whose build_config builds exactly "workflow": {"_id": ...} (get-file-from-job). Nothing in the notebooks is wrong; the server contract changed, and the client sends the old shape.

The cause: after the job endpoints were migrated to validated use cases, JobsCreate checks the job against the job schema, which needs the full workflow document embedded in the job (the job keeps a snapshot of what it ran). A reference by _id is deliberately not supported (JobDAO.resolveWorkflow).

What it changes

Only JobEndpoints.create (endpoints/jobs.py): if config["workflow"] is a reference (it has an _id but no subworkflows), the workflow is fetched with GET workflows/<id> and embedded before the job is created. The caller's dict is not modified. A full workflow, or no workflow, is sent as before. create_by_ids goes through create, so it is fixed too.

Cost: one extra GET, and only when the workflow is a reference.

What it does not change

  • list() is untouched. The web-app list endpoints accept the query and projection params again (web-app chore/SOF-8032-5), so no client-side translation is needed.
  • jobs.create_set without a projectId (equation_of_state) is fixed in the web-app as well: JobsCreateSet falls back to the account's default project, so the client needs nothing.

Order of merge

Merge after the web-app change is deployed. It is what makes list() and jobs.create_set work with the released client.

Verification

  • 4 new unit tests in tests/py/unit/test_jobs.py (embedding a referenced workflow, a full workflow left untouched, no workflow, create_by_ids). 41 unit tests pass, ruff is clean.
  • Against a local web-app, jobs.create with a workflow reference and create_by_ids return 422 with the released client and succeed with this one.
  • Cypress, with the unmodified main api-examples notebooks: create_and_submit_job fails with the released client and passes with this one. equation_of_state, get_materials_by_formula_org, get_workflows_org and convex_hull pass.
  • get-file-from-job is only covered by the create_by_ids call and its unit test: its Cypress feature needs an organization account that the local database does not have.

Alternative

The same fix could live in the web-app (resolve a {_id} workflow in JobsCreate), which would make this PR unnecessary. That reverses a server contract that was changed on purpose, so this PR keeps it in the client.

🤖 Generated with Claude Code

k0stik and others added 4 commits October 6, 2026 18:17
`client.materials`, `client.workflows` and `client.projects` can now ask the
platform for an account's default entity with `show_default(account_id=None)`,
which calls `GET <entity>/default` (defaulting to the user's default account).

This replaces the flat-param `.request("GET", ..., {"isDefault": ...})`
workaround notebooks needed after the list endpoints stopped accepting the
`query=<json>` blob.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…translates Mongo-style queries

The migrated list endpoints validate their parameters against the flat keys of
their list use case and silently drop everything else, including the
`query=<json>` blob `list()` sent. `client.materials.list({...})[0]` therefore
returned an arbitrary entity instead of the one asked for.

- Endpoints declare `list_parameters` (the keys of their list use case, plus
  `limit`/`skip`/`sort`); `list({"ownerId": id, "formula": "Si"})` passes them on
  as they are. Booleans are sent as "true"/"false", lists as repeated parameters.
- Endpoints declare `query_fields` (Mongo path -> parameter); a Mongo-style query
  such as `{"owner._id": id, "hash": h}` is translated (value, `$eq`, `$in`, and
  `$ne` on booleans; `limit`/`skip`/`sort` from the options). The `query` blob is
  still sent for servers that read it. Charges and metaproperties are unchanged.
- A Mongo-style query that does not mention a set means "anywhere", as before
  (`globalSearch`); a query of list parameters means what the endpoint says.
  Jobs requested by id are left as they are.
- An unknown field or condition raises ValueError naming the supported ones
  instead of being dropped, and `$in: []` returns [] without a request (an empty
  parameter would be dropped and match everything).
- `get_for_job` and `get_property` filter on `unitId` on the server.

Needs the web-app list use cases from SOF-8032: `formula` (materials) and
`unitId`/`precisionValue` (properties). Older servers drop those silently.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The migrated list endpoints ignore the query=<json> blob. list() keeps
sending it for older servers and now also sends the query as
advancedSearches, plus limit, skip and sort from the projection, for
materials, workflows, jobs, projects, properties and the bank endpoints.

Materials, workflows and jobs also get setId when the query names
inSet._id, and globalSearch otherwise. An unsupported projection option
raises ValueError before any request. Charges and metaproperties are
unchanged.

Replaces the show_default and list-parameter translation commits.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ing jobs and job sets

The server takes a full workflow document in a job and a project for a job
set, while the notebooks give a workflow by its _id and a job set only a
name and an owner. jobs.create (and create_by_ids) now fetches and embeds a
workflow given by _id, and jobs.create_set uses the owner's default project
when the config has no projectId, so the notebooks keep their original
calls.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The web-app list endpoints accept the query and projection params again, so
list() no longer translates them into advancedSearches and list parameters.
Restores list() and the endpoint classes to main and removes utils/query.py
with its tests.

Keeps the job fixes: jobs.create embeds a workflow given by _id and
jobs.create_set defaults the project, which are separate contract changes.
The default project lookup now sends the query and projection params.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@k0stik k0stik changed the title feat(SOF-8032): add show_default to the defaultable endpoints feat(SOF-8032): keep job creation working against the migrated endpoints Oct 7, 2026
The web-app now makes projectId optional for jobs/create-set and falls back
to the account's default project, so the client no longer looks it up.
jobs.create keeps embedding a workflow given by _id.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@k0stik k0stik changed the title feat(SOF-8032): keep job creation working against the migrated endpoints feat(SOF-8032): embed the workflow when a job is created with a workflow reference Oct 7, 2026
@k0stik
k0stik merged commit beb5a5c into main Oct 7, 2026
3 checks passed
@k0stik
k0stik deleted the feature/SOF-8032 branch October 7, 2026 19:16
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