Skip to content

Python: fix OpenAPI plugin sending array and boolean parameters as Python repr - #14789

Open
Jeevan Babu Gotru (jeevan1098) wants to merge 2 commits into
microsoft:mainfrom
jeevan1098:fix/openapi-query-array-bool-14788
Open

Jeevan Babu Gotru (jeevan1098) wants to merge 2 commits into
microsoft:mainfrom
jeevan1098:fix/openapi-query-array-bool-14788

Conversation

@jeevan1098

Copy link
Copy Markdown
Contributor

Purpose

Fixes #14788

The Python OpenAPI plugin built query strings with urlencode(segments) and passed argument values through unchanged. Without doseq=True, urlencode calls str() on each value, so an array query parameter was sent as the Python list repr (tags=%5B%27red%27%2C+%27blue%27%5D) and a boolean as active=True — neither is parseable by the API. OpenAPI's default for query parameters is style: form, explode: true, i.e. ?tags=red&tags=blue&active=true, which is also how the .NET plugin serializes arrays.

Description

  • RestApiOperation.build_query_string now encodes with doseq=True, so list/tuple values become repeated keys.
  • A new _serialize_parameter_value helper serializes booleans with the JSON spelling (true/false); it is applied to query values (including items inside arrays), and to path and header parameters, which had the same str(argument) boolean problem.
  • style/explode from the spec are still not parsed (as noted on the issue); this implements the OpenAPI default only.

Reproduced with the issue's offline repro (httpx MockTransport) on main at 25bd1bb: before the fix the captured URL was https://93.184.216.34/items?tags=%5B%27red%27%2C+%27blue%27%5D&active=True; after the fix it is https://93.184.216.34/items?tags=red&tags=blue&active=true.

Regression tests

Four new tests in test_sk_openapi.py: array + boolean query parameters, false + boolean-array query parameters, a boolean path parameter, and a boolean header parameter. All four fail without the source fix. The mapped test file passes (83 tests); the full tests/unit/connectors/openapi_plugin/ suite shows only the pre-existing DNS-pinning failures, which are identical on clean main in this sandbox. Ruff check and format are clean on both changed files.

This change was prepared with AI assistance; all steps above were run and verified by the contributor.

Copilot AI balanced review requested due to automatic review settings November 12, 2026 15:42
@semantic-kernel-automation semantic-kernel-automation Bot added the python Pull requests for the Python Semantic Kernel label Nov 12, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

There are no active review issues for the query-array and boolean serialization changes.

No open issues 🎉

What changed in this PR

Fixes #14788 by updating the Python OpenAPI plugin to serialize array query parameters and booleans in wire-compatible formats rather than Python representations.

Changes:

  • Encodes query arrays as repeated keys using doseq=True.
  • Serializes booleans as lowercase true/false in query, path, and header parameters.
  • Adds four regression tests. Parsing explicit OpenAPI style/explode settings remains out of scope.
File Description
python/​tests/​unit/​connectors/​openapi_plugin/​test_sk_openapi.py Adds regression coverage for query arrays and boolean query, path, and header values.
python/​semantic_kernel/​connectors/​openapi_plugin/​models/​rest_api_operation.py Adds boolean serialization and repeated-key query array encoding.

Review effort: Balanced

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The query-string fix is right, but arrays in path and header parameters still go out as the Python list repr, which is the same bug in the other two functions this PR changes.

The issue: build_path and build_headers still str() a list. Both now call _serialize_parameter_value(argument) (rest_api_operation.py:229 and :343), but that helper only maps bool and returns everything else unchanged. An array header such as {"X-Tags": ["red", "blue"]} is still sent as ['red', 'blue']. An array path parameter becomes %5B%27red%27%2C%20%27blue%27%5D. A boolean inside a list isn't converted either ([True]). run_openapi_operation passes the kernel arguments through unchanged (openapi_manager.py:138-148), so a list from function calling reaches these functions as a list. The OpenAPI default for path and header parameters is style: simple, which is comma-separated (red,blue).

Suggested fix: handle sequences in the helper, so each call site doesn't need its own branch. For example, add a _serialize_simple that returns ",".join(str(self._serialize_parameter_value(v)) for v in value) for a list or tuple, and use it in build_path and build_headers. build_query_string keeps its own list branch for the form/explode case. A header test and a path test with ["red", "blue"] would cover it. If arrays in path and header are out of scope, a sentence in the description saying so would help, since the PR title and body talk about array parameters in general.

What I checked that is fine:

  • The query path is the one the runner uses. openapi_runner.py:123 builds the URL with operation.build_query_string(arguments), and nothing else encodes query parameters.
  • doseq=True only changes sequence values. urlencode treats str and bytes as scalars even with doseq=True, so string arguments encode as before. Ints go through str() as before. An empty list now leaves the key out instead of sending %5B%5D, which matches form/explode.
  • bool is checked before anything else, so True/False never fall through to str(). isinstance(1, bool) is false, so integer 0/1 values are left alone.
  • git merge-tree against main is clean.

I didn't run the tests.

Reviewed with help from Claude Code.

This branch was successfully deployed

1 active deployment
github-app-auth — 14bba68c Deployed Nov 12, 2026 by jeevan1098 via add_label #29676
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

python Pull requests for the Python Semantic Kernel

Projects

None yet

Development

Successfully merging this pull request may close these issues.

.Net: Python: Bug: OpenAPI plugin sends array and boolean query parameters as Python repr (tags=['a', 'b'], active=True)

3 participants