Skip to content

Multipart Form-data body does not support  {{variables}}  templating (API Connect recipe) #82

Description

@danydossantos63

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

  1. Create an API Connect recipe with an input dataset containing a column, e.g. id_client.
  2. Add id_client to "Columns to use as variables".
  3. Set HTTP method = POST and Body = Multipart Form-data.
  4. Add a body entry: key client_id, value {{id_client}}.
  5. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions