FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

fix!: URL-encode path parameters in generated endpoints by Robbie-Palmer · Pull Request #1349 · openapi-generators/openapi-python-client · GitHub

Repository navigation

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .jinja  (1) .py  (8) All 2 file types selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
from unittest.mock import MagicMock

import httpx
import pytest

from end_to_end_tests.functional_tests.helpers import (
with_generated_client_fixture,
with_generated_code_import,
)


@with_generated_client_fixture(
"""
paths:
"/items/{item_id}/details/{detail_id}":
get:
operationId: getItemDetail
parameters:
- name: item_id
in: path
required: true
schema:
type: string
- name: detail_id
in: path
required: true
schema:
type: string
responses:
"200":
description: Success
content:
application/json:
schema:
type: object
properties:
id:
type: string
""")
@with_generated_code_import(".api.default.get_item_detail.sync_detailed")
@with_generated_code_import(".client.Client")
class TestPathParameterEncoding:
"""Test that path parameters are properly URL-encoded"""

def test_path_params_with_normal_chars_work(self, sync_detailed, Client):
"""Test that normal alphanumeric path parameters still work correctly"""
mock_httpx_client = MagicMock(spec=httpx.Client)
mock_response = MagicMock(spec=httpx.Response)
mock_response.status_code = 200
mock_response.json.return_value = {"id": "test"}
mock_response.content = b'{"id": "test"}'
mock_response.headers = {}
mock_httpx_client.request.return_value = mock_response

client = Client(base_url="https://api.example.com")
client.set_httpx_client(mock_httpx_client)

sync_detailed(
item_id="item123",
detail_id="detail456",
client=client,
)

mock_httpx_client.request.assert_called_once()
call_kwargs = mock_httpx_client.request.call_args[1]

# Normal characters should remain unchanged
expected_url = "/items/item123/details/detail456"
assert call_kwargs["url"] == expected_url

def test_path_params_with_reserved_chars_are_encoded(self, sync_detailed, Client):
"""Test that path parameters with reserved characters are properly URL-encoded"""
# Create a mock httpx client
mock_httpx_client = MagicMock(spec=httpx.Client)
mock_response = MagicMock(spec=httpx.Response)
mock_response.status_code = 200
mock_response.json.return_value = {"id": "test"}
mock_response.content = b'{"id": "test"}'
mock_response.headers = {}
mock_httpx_client.request.return_value = mock_response

# Create a client with the mock httpx client
client = Client(base_url="https://api.example.com")
client.set_httpx_client(mock_httpx_client)

# Call the endpoint with path parameters containing reserved characters
sync_detailed(
item_id="item/with/slashes",
detail_id="detail?with=query&chars",
client=client,
)

# Verify the request was made with properly encoded URL
mock_httpx_client.request.assert_called_once()
call_kwargs = mock_httpx_client.request.call_args[1]

# The URL should have encoded slashes and query characters
expected_url = "/items/item%2Fwith%2Fslashes/details/detail%3Fwith%3Dquery%26chars"
assert call_kwargs["url"] == expected_url

def test_path_params_with_spaces_are_encoded(self, sync_detailed, Client):
"""Test that path parameters with spaces are properly URL-encoded"""
mock_httpx_client = MagicMock(spec=httpx.Client)
mock_response = MagicMock(spec=httpx.Response)
mock_response.status_code = 200
mock_response.json.return_value = {"id": "test"}
mock_response.content = b'{"id": "test"}'
mock_response.headers = {}
mock_httpx_client.request.return_value = mock_response

client = Client(base_url="https://api.example.com")
client.set_httpx_client(mock_httpx_client)

sync_detailed(
item_id="item with spaces",
detail_id="detail with spaces",
client=client,
)

mock_httpx_client.request.assert_called_once()
call_kwargs = mock_httpx_client.request.call_args[1]

# Spaces should be encoded as %20
expected_url = "/items/item%20with%20spaces/details/detail%20with%20spaces"
assert call_kwargs["url"] == expected_url

def test_path_params_with_hash_are_encoded(self, sync_detailed, Client):
"""Test that path parameters with hash/fragment characters are properly URL-encoded"""
mock_httpx_client = MagicMock(spec=httpx.Client)
mock_response = MagicMock(spec=httpx.Response)
mock_response.status_code = 200
mock_response.json.return_value = {"id": "test"}
mock_response.content = b'{"id": "test"}'
mock_response.headers = {}
mock_httpx_client.request.return_value = mock_response

client = Client(base_url="https://api.example.com")
client.set_httpx_client(mock_httpx_client)

sync_detailed(
item_id="item#1",
detail_id="detail#id",
client=client,
)

mock_httpx_client.request.assert_called_once()
call_kwargs = mock_httpx_client.request.call_args[1]

# Hash should be encoded as %23
expected_url = "/items/item%231/details/detail%23id"
assert call_kwargs["url"] == expected_url
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from http import HTTPStatus
from typing import Any
from urllib.parse import quote

import httpx

Expand All @@ -13,7 +14,9 @@ def _get_kwargs(
) -> dict[str, Any]:
_kwargs: dict[str, Any] = {
"method": "get",
"url": f"/naming/{hyphen_in_path}",
"url": "/naming/{hyphen_in_path}".format(
hyphen_in_path=quote(str(hyphen_in_path), safe=""),
),
}

return _kwargs
Expand Down
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from http import HTTPStatus
from typing import Any
from urllib.parse import quote

import httpx

Expand Down Expand Up @@ -34,7 +35,9 @@ def _get_kwargs(

_kwargs: dict[str, Any] = {
"method": "get",
"url": f"/parameter-references/{path_param}",
"url": "/parameter-references/{path_param}".format(
path_param=quote(str(path_param), safe=""),
),
"params": params,
"cookies": cookies,
}
Expand Down
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from http import HTTPStatus
from typing import Any
from urllib.parse import quote

import httpx

Expand All @@ -21,7 +22,9 @@ def _get_kwargs(

_kwargs: dict[str, Any] = {
"method": "delete",
"url": f"/common_parameters_overriding/{param_path}",
"url": "/common_parameters_overriding/{param_path}".format(
param_path=quote(str(param_path), safe=""),
),
"params": params,
}

Expand Down
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from http import HTTPStatus
from typing import Any
from urllib.parse import quote

import httpx

Expand All @@ -21,7 +22,9 @@ def _get_kwargs(

_kwargs: dict[str, Any] = {
"method": "get",
"url": f"/common_parameters_overriding/{param_path}",
"url": "/common_parameters_overriding/{param_path}".format(
param_path=quote(str(param_path), safe=""),
),
"params": params,
}

Expand Down
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from http import HTTPStatus
from typing import Any
from urllib.parse import quote

import httpx

Expand Down Expand Up @@ -31,7 +32,9 @@ def _get_kwargs(

_kwargs: dict[str, Any] = {
"method": "get",
"url": f"/same-name-multiple-locations/{param_path}",
"url": "/same-name-multiple-locations/{param_path}".format(
param_path=quote(str(param_path), safe=""),
),
"params": params,
"cookies": cookies,
}
Expand Down
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from http import HTTPStatus
from typing import Any
from urllib.parse import quote

import httpx

Expand All @@ -16,7 +17,12 @@ def _get_kwargs(
) -> dict[str, Any]:
_kwargs: dict[str, Any] = {
"method": "get",
"url": f"/multiple-path-parameters/{param4}/something/{param2}/{param1}/{param3}",
"url": "/multiple-path-parameters/{param4}/something/{param2}/{param1}/{param3}".format(
param4=quote(str(param4), safe=""),
param2=quote(str(param2), safe=""),
param1=quote(str(param1), safe=""),
param3=quote(str(param3), safe=""),
),
}

return _kwargs
Expand Down
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from http import HTTPStatus
from typing import Any, Literal, cast
from urllib.parse import quote

import httpx

Expand Down Expand Up @@ -28,7 +29,9 @@ def _get_kwargs(

_kwargs: dict[str, Any] = {
"method": "post",
"url": f"/const/{path}",
"url": "/const/{path}".format(
path=quote(str(path), safe=""),
),
"params": params,
}

Expand Down
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from http import HTTPStatus
from typing import Any, cast
from urllib.parse import quote

import httpx

Expand Down Expand Up @@ -31,7 +32,7 @@ def _get_kwargs(
{% if endpoint.path_parameters %}
"url": "{{ endpoint.path }}".format(
{%- for parameter in endpoint.path_parameters -%}
{{parameter.python_name}}={{parameter.python_name}},
{{parameter.python_name}}=quote(str({{parameter.python_name}}), safe=""),
{%- endfor -%}
),
{% else %}
Expand Down

Back | FazBrowse Home | New Git URL