Skip to content

Commit 97b611c

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 fcd6ede commit 97b611c

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
@@ -611,6 +611,20 @@ def generate_zip_file(pipeline_directory_path: str | Path) -> io.BytesIO:
611611
return zip_file
612612

613613

614+
def _parameter_to_graphql_input(parameter) -> dict:
615+
"""Serialize a pipeline parameter into a GraphQL ``ParameterInput``.
616+
617+
``Parameter.to_dict()`` uses snake_case keys for the parameter spec, but the
618+
GraphQL ``ParameterInput`` type expects camelCase field names. Most keys are
619+
single words and match in both conventions; ``choices_from_file`` is the
620+
exception and must be renamed to ``choicesFromFile``.
621+
"""
622+
spec = parameter.to_dict()
623+
if "choices_from_file" in spec:
624+
spec["choicesFromFile"] = spec.pop("choices_from_file")
625+
return spec
626+
627+
614628
def upload_pipeline(
615629
target_pipeline_code: str,
616630
pipeline_directory_path: str | Path,
@@ -647,7 +661,7 @@ def upload_pipeline(
647661
"description": description,
648662
"externalLink": link,
649663
"zipfile": base64_content,
650-
"parameters": [p.to_dict() for p in pipeline.parameters],
664+
"parameters": [_parameter_to_graphql_input(p) for p in pipeline.parameters],
651665
"timeout": pipeline.timeout,
652666
}
653667

0 commit comments

Comments
 (0)