Skip to content

Commit b03a36a

Browse files
committed
fix: ChoicesFromFiles snake_case to camelCase
This is a bug in the SDK's CLI upload path. Root cause The server's GraphQL ParameterInput type expects the field name choicesFromFile (camelCase). The SDK was sending choices_from_file (snake_case), so the server rejected it — exactly what the error said: "Field 'choices_from_file' is not defined by type 'ParameterInput'. Did you mean 'choicesFromFile'?" Why it only broke now: upload_pipeline (in openhexa/cli/api.py) passes Parameter.to_dict() straight through as the GraphQL input. Every previous parameter field was a single word (code, type, name, required, multiple, directory…), so snake_case and camelCase happened to be identical. choices_from_file, added in the recent dynamic-choices feature (#385), is the first multi-word field — so it's the first mismatch. Fix I added a small boundary serializer that renames the key only when sending to GraphQL, in openhexa/cli/api.py. I deliberately left Parameter.to_dict() untouched — it keeps snake_case as its internal spec convention (the AST-construction code and ~22 tests in tests/test_choices.py rely on that), so the camelCase concern lives only where it belongs: the GraphQL call. Verification - Executed the helper: ChoicesFromFile("regions.csv", column="code") now serializes to {"choicesFromFile": {"format": None, "path": "regions.csv", "column": "code"}}, snake key gone, nested values intact. Parameters without dynamic choices don't get the key. - to_dict() still returns snake_case (internal convention preserved). - tests/test_choices.py → 22 passed; tests/test_cli.py (upload/pipeline/parameter) → 18 passed; ruff check clean. One side note: the SDK's bundled schema (openhexa/graphql/schema.generated.graphql) doesn't yet contain the choicesFromFile field at all — it lags the server. That doesn't block the push (validation is server-side), but it's worth refreshing the bundled schema in a follow-up so the SDK's breaking-change detection stays accurate. Re-run openhexa pipelines push and it should import cleanly now.
1 parent ad4e725 commit b03a36a

1 file changed

Lines changed: 15 additions & 1 deletion

File tree

openhexa/cli/api.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ def _build_pipeline_version_input(
316316
"description": description,
317317
"externalLink": external_link,
318318
"zipfile": base64.b64encode(zip_file.read()).decode("ascii"),
319-
"parameters": [p.to_dict() for p in pipeline.parameters],
319+
"parameters": [_parameter_to_graphql_input(p) for p in pipeline.parameters],
320320
"timeout": pipeline.timeout,
321321
}
322322

@@ -687,6 +687,20 @@ def generate_zip_file(pipeline_directory_path: str | Path) -> io.BytesIO:
687687
return zip_file
688688

689689

690+
def _parameter_to_graphql_input(parameter) -> dict:
691+
"""Serialize a pipeline parameter into a GraphQL ``ParameterInput``.
692+
693+
``Parameter.to_dict()`` uses snake_case keys for the parameter spec, but the
694+
GraphQL ``ParameterInput`` type expects camelCase field names. Most keys are
695+
single words and match in both conventions; ``choices_from_file`` is the
696+
exception and must be renamed to ``choicesFromFile``.
697+
"""
698+
spec = parameter.to_dict()
699+
if "choices_from_file" in spec:
700+
spec["choicesFromFile"] = spec.pop("choices_from_file")
701+
return spec
702+
703+
690704
def upload_pipeline(
691705
target_pipeline_code: str,
692706
pipeline_directory_path: str | Path,

0 commit comments

Comments
 (0)