Repository navigation
feat(SOF-8032): embed the workflow when a job is created with a workflow reference - #48
Merged
Merged
Conversation
`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>
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>
timurbazhirov
approved these changes
Oct 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why this PR is needed
jobs.createis rejected by the platform with422when the job gives its workflow only by_id. The api-examples notebooks do that (create_and_submit_job), and so doescreate_by_ids, whosebuild_configbuilds 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,
JobsCreatechecks 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_idis deliberately not supported (JobDAO.resolveWorkflow).What it changes
Only
JobEndpoints.create(endpoints/jobs.py): ifconfig["workflow"]is a reference (it has an_idbut nosubworkflows), the workflow is fetched withGET 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_idsgoes throughcreate, 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 thequeryandprojectionparams again (web-appchore/SOF-8032-5), so no client-side translation is needed.jobs.create_setwithout aprojectId(equation_of_state) is fixed in the web-app as well:JobsCreateSetfalls 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()andjobs.create_setwork with the released client.Verification
tests/py/unit/test_jobs.py(embedding a referenced workflow, a full workflow left untouched, no workflow,create_by_ids). 41 unit tests pass,ruffis clean.jobs.createwith a workflow reference andcreate_by_idsreturn422with the released client and succeed with this one.mainapi-examples notebooks:create_and_submit_jobfails with the released client and passes with this one.equation_of_state,get_materials_by_formula_org,get_workflows_organdconvex_hullpass.get-file-from-jobis only covered by thecreate_by_idscall 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 inJobsCreate), 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