Summary
In the API Connect plugin (v1.4.2), when running the recipe (input dataset → one request per row), {{variables}} are correctly substituted in the URL, headers, query params, Raw body, and Form-data (Json) body — but not in the Multipart Form-data body. Row/column values injected via {{ColumnName}} are sent to the API literally (e.g. {{id_client}}) instead of the actual row value.
Environment
- Plugin:
dss-plugin-api-connect
- Version:
v1.4.2
- Component: recipe
api-connect
Steps to reproduce
- Create an API Connect recipe with an input dataset containing a column, e.g.
id_client.
- Add
id_client to "Columns to use as variables".
- Set HTTP method =
POST and Body = Multipart Form-data.
- Add a body entry: key
client_id, value {{id_client}}.
- Run the recipe.
Expected behavior
Each request sends the row value, e.g. client_id=42, consistent with Raw and Form-data (Json) bodies.
Actual behavior
Each request sends the literal template string client_id={{id_client}}; the variable is never resolved.
Root cause
In python-lib/rest_api_client.py, the Multipart body values are stored as tuples (None, v):
elif body_format in [DKUConstants.MULTIPART_FORM_DATA_BODY_FORMAT]:
key_value_body = endpoint.get("key_value_body", {})
self.requests_kwargs.update({"files": {k: (None, v) for k, v in get_dku_key_values(key_value_body).items()}})
The templating engine template_dict() (applied in request()) only resolves {{...}} inside str and dict values. Tuple contents are skipped, so Multipart values are never templated — unlike data (Raw) and json (Form-data), which are strings/dicts and get resolved.
Proposed fix
Template the Multipart values at build time using the already-populated self.presets_variables:
elif body_format in [DKUConstants.MULTIPART_FORM_DATA_BODY_FORMAT]:
key_value_body = endpoint.get("key_value_body", {})
self.requests_kwargs.update({"files": {
k: (None, format_template(v, **self.presets_variables))
for k, v in get_dku_key_values(key_value_body).items()
}})
(format_template is already imported in rest_api_client.py.)
Additional note (documentation)
The recipe's variable-section help text (custom-recipes/api-connect/recipe.json) states "URL, headers and parameters can be templated using {{variables}}", omitting the body. It should be updated to include the body to avoid confusion.
Verification
End-to-end test (mocked HTTP layer, 2 input rows) after the fix:
POST -> MULTIPART: {'client_id': (None, '42'), 'nom': (None, 'Dupont'), 'statique': (None, 'const')}
POST -> MULTIPART: {'client_id': (None, '99'), 'nom': (None, 'Martin'), 'statique': (None, 'const')}
Variables are resolved per row; static values are preserved.
Summary
In the API Connect plugin (v1.4.2), when running the recipe (input dataset → one request per row),
{{variables}}are correctly substituted in the URL, headers, query params, Raw body, and Form-data (Json) body — but not in the Multipart Form-data body. Row/column values injected via{{ColumnName}}are sent to the API literally (e.g.{{id_client}}) instead of the actual row value.Environment
dss-plugin-api-connectv1.4.2api-connectSteps to reproduce
id_client.id_clientto "Columns to use as variables".POSTand Body = Multipart Form-data.client_id, value{{id_client}}.Expected behavior
Each request sends the row value, e.g.
client_id=42, consistent with Raw and Form-data (Json) bodies.Actual behavior
Each request sends the literal template string
client_id={{id_client}}; the variable is never resolved.Root cause
In
python-lib/rest_api_client.py, the Multipart body values are stored as tuples(None, v):The templating engine
template_dict()(applied inrequest()) only resolves{{...}}insidestranddictvalues. Tuple contents are skipped, so Multipart values are never templated — unlikedata(Raw) andjson(Form-data), which are strings/dicts and get resolved.Proposed fix
Template the Multipart values at build time using the already-populated
self.presets_variables:(
format_templateis already imported inrest_api_client.py.)Additional note (documentation)
The recipe's variable-section help text (
custom-recipes/api-connect/recipe.json) states "URL, headers and parameters can be templated using {{variables}}", omitting the body. It should be updated to include the body to avoid confusion.Verification
End-to-end test (mocked HTTP layer, 2 input rows) after the fix:
Variables are resolved per row; static values are preserved.