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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 33 additions & 15 deletions src/ansys/openapi/common/_api_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,26 +136,15 @@ def __call_api(

# path parameters
if path_params:
path_params_sanitized = self.sanitize_for_serialization(path_params)
path_params_tuples = self.parameters_to_tuples(
path_params_sanitized, collection_formats
resource_path = self.__handle_path_params(
resource_path, path_params, collection_formats
)
for k, v in path_params_tuples:
# specified safe chars, encode everything
resource_path = resource_path.replace(
f"{k}",
quote(str(v), safe=self.configuration.safe_chars_for_path_param),
)

# query parameters
query_params_str = ""
if query_params:
query_params_sanitized = self.sanitize_for_serialization(query_params)
query_params_tuples = self.parameters_to_tuples(
query_params_sanitized, collection_formats
)
query_params_str = "&".join(
["=".join(param) for param in query_params_tuples]
query_params_str = self.__handle_query_params(
query_params, collection_formats
)

# post parameters
Expand Down Expand Up @@ -200,6 +189,35 @@ def __call_api(
else:
return return_data, response_data.status_code, response_data.headers

def __handle_path_params(
self,
resource_path: str,
path_params: Union[Dict[str, Union[str, int]], List[Tuple], None],
collection_formats: Optional[Dict[str, str]],
) -> str:
path_params_sanitized = self.sanitize_for_serialization(path_params)
path_params_tuples = self.parameters_to_tuples(
path_params_sanitized, collection_formats
)
for k, v in path_params_tuples:
# specified safe chars, encode everything
resource_path = resource_path.replace(
f"{{{k}}}",
quote(str(v), safe=self.configuration.safe_chars_for_path_param),
)
return resource_path

def __handle_query_params(
self,
query_params: Union[Dict[str, Union[str, int]], List[Tuple], None],
collection_formats: Optional[Dict[str, str]],
) -> str:
query_params_sanitized = self.sanitize_for_serialization(query_params)
query_params_tuples = self.parameters_to_tuples(
query_params_sanitized, collection_formats
)
return "&".join(["=".join(param) for param in query_params_tuples])

def sanitize_for_serialization(self, obj: Any) -> Any:
"""Build a JSON POST object.

Expand Down
62 changes: 61 additions & 1 deletion tests/test_api_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,66 @@ def test_repr(blank_client):
assert type(blank_client).__name__ in str(blank_client)


class TestParameterHandling:
@pytest.fixture(autouse=True)
def _blank_client(self, blank_client):
self._client = blank_client

def test_simple_path_rewrite(self):
id_ = str(uuid.uuid4())
single_path = "/resource/{id}"
result = self._client._ApiClient__handle_path_params(
single_path, {"id": id_}, None
)
assert single_path.replace("{id}", id_) == result

def test_multiple_path_rewrites(self):
id_ = str(uuid.uuid4())
name = "TestResource"
multiple_path = "/resource/{id}/name/{name}"
result = self._client._ApiClient__handle_path_params(
multiple_path, {"id": id_, "name": name}, None
)
assert multiple_path.replace("{id}", id_).replace("{name}", name) == result

def test_path_with_naughty_characters(self):
name = '"Na,ughty!P,ath.'
naughty_path = "/resource/{name}"
result = self._client._ApiClient__handle_path_params(
naughty_path, {"name": name}, None
)
assert "/resource/%22Na%2Cughty%21P%2Cath." == result

def test_path_with_naughty_characters_allowed(self):
name = "<SpecialName>"
naughty_path = "/resource/{name}"
self._client.configuration.safe_chars_for_path_param = "<>"
result = self._client._ApiClient__handle_path_params(
naughty_path, {"name": name}, None
)
assert "/resource/<SpecialName>" == result

def test_single_query(self):
query = {"name": "Spamalot"}
result = self._client._ApiClient__handle_query_params(query, None)
assert "name=Spamalot" == result

def test_multiple_queries(self):
query = {"bird": "swallow", "type": "african"}
result = self._client._ApiClient__handle_query_params(query, None)
assert "bird=swallow&type=african" == result

def test_simple_query_with_collection(self):
query = {"bird": "swallow", "type": ("african", "european")}
result = self._client._ApiClient__handle_query_params(query, {"type": "pipes"})
assert "bird=swallow&type=african|european" == result

def test_query_with_naughty_characters(self):
query = {"search": '"A &Naughty#Qu,ery@100%'}
result = self._client._ApiClient__handle_query_params(query, None)
assert 'search="A &Naughty#Qu,ery@100%' == result


class TestSerialization:
_test_value_list = ["foo", int(2), 2.0, True]
_test_value_types = [str, int, float, bool]
Expand Down Expand Up @@ -603,7 +663,7 @@ def content_json_matcher(request: requests.Request):
json_obj = json.loads(json_body)
return json_obj == expected_request

resource_path = "/models/ID"
resource_path = "/models/{ID}"
method = "PATCH"
record_id = str(uuid.uuid4())
path_params = {"ID": record_id}
Expand Down
2 changes: 1 addition & 1 deletion tests/test_integration_anonymous.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def test_patch_model(self):
bool_property=False,
)

resource_path = "/models/ID"
resource_path = "/models/{ID}"
method = "PATCH"
path_params = {"ID": TEST_MODEL_ID}

Expand Down
2 changes: 1 addition & 1 deletion tests/test_integration_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def test_patch_model(self):
bool_property=False,
)

resource_path = "/models/ID"
resource_path = "/models/{ID}"
method = "PATCH"
path_params = {"ID": TEST_MODEL_ID}

Expand Down
2 changes: 1 addition & 1 deletion tests/test_integration_negotiate.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def test_patch_model(self):
bool_property=False,
)

resource_path = "/models/ID"
resource_path = "/models/{ID}"
method = "PATCH"
path_params = {"ID": TEST_MODEL_ID}

Expand Down