diff --git a/CHANGELOG.md b/CHANGELOG.md index c6cccf8c..8a15906a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## 0.8.0 - Unreleased +### Breaking Changes + +- Generated clients will no longer pass through `None` to query parameters. Previously, any query params set to `None` would surface as empty strings (per the default behavior of `httpx`). This is contrary to the defaults indicated by the OpenAPI 3.0.3 spec. Ommitting these parameters makes us more compliant. If you require a style of `null` to be passed to your query parameters, please request support for the OpenAPI "style" attribute. Thank you to @forest-benchling and @bowenwr for a ton of input on this. + ### Additions - New `--meta` command line option for specifying what type of metadata should be generated: diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/defaults_tests_defaults_post.py b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/defaults_tests_defaults_post.py index 574d5018..466b1498 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/defaults_tests_defaults_post.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/defaults_tests_defaults_post.py @@ -89,27 +89,19 @@ def httpx_request( if not isinstance(enum_prop, Unset): json_enum_prop = enum_prop - params: Dict[str, Any] = {} - if string_prop is not UNSET: - params["string_prop"] = string_prop - if datetime_prop is not UNSET: - params["datetime_prop"] = json_datetime_prop - if date_prop is not UNSET: - params["date_prop"] = json_date_prop - if float_prop is not UNSET: - params["float_prop"] = float_prop - if int_prop is not UNSET: - params["int_prop"] = int_prop - if boolean_prop is not UNSET: - params["boolean_prop"] = boolean_prop - if list_prop is not UNSET: - params["list_prop"] = json_list_prop - if union_prop is not UNSET: - params["union_prop"] = json_union_prop - if union_prop_with_ref is not UNSET: - params["union_prop_with_ref"] = json_union_prop_with_ref - if enum_prop is not UNSET: - params["enum_prop"] = json_enum_prop + params: Dict[str, Any] = { + "string_prop": string_prop, + "datetime_prop": json_datetime_prop, + "date_prop": json_date_prop, + "float_prop": float_prop, + "int_prop": int_prop, + "boolean_prop": boolean_prop, + "list_prop": json_list_prop, + "union_prop": json_union_prop, + "union_prop_with_ref": json_union_prop_with_ref, + "enum_prop": json_enum_prop, + } + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} response = client.request( "post", diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/get_user_list.py b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/get_user_list.py index 72758fd7..eaa389ac 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/get_user_list.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/get_user_list.py @@ -62,6 +62,7 @@ def httpx_request( "an_enum_value": json_an_enum_value, "some_date": json_some_date, } + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} response = client.request( "get", diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/int_enum_tests_int_enum_post.py b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/int_enum_tests_int_enum_post.py index 855a8d99..6043d72c 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/int_enum_tests_int_enum_post.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/int_enum_tests_int_enum_post.py @@ -44,6 +44,7 @@ def httpx_request( params: Dict[str, Any] = { "int_enum": json_int_enum, } + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} response = client.request( "post", diff --git a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/optional_value_tests_optional_query_param.py b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/optional_value_tests_optional_query_param.py index bff43cc1..78413711 100644 --- a/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/optional_value_tests_optional_query_param.py +++ b/end_to_end_tests/golden-record-custom/custom_e2e/api/tests/optional_value_tests_optional_query_param.py @@ -43,9 +43,10 @@ def httpx_request( if not isinstance(query_param, Unset): json_query_param = query_param - params: Dict[str, Any] = {} - if query_param is not UNSET: - params["query_param"] = json_query_param + params: Dict[str, Any] = { + "query_param": json_query_param, + } + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} response = client.request( "get", diff --git a/end_to_end_tests/golden-record/my_test_api_client/api/tests/defaults_tests_defaults_post.py b/end_to_end_tests/golden-record/my_test_api_client/api/tests/defaults_tests_defaults_post.py index 9242cdda..b3e6d6df 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/api/tests/defaults_tests_defaults_post.py +++ b/end_to_end_tests/golden-record/my_test_api_client/api/tests/defaults_tests_defaults_post.py @@ -65,27 +65,19 @@ def _get_kwargs( if not isinstance(enum_prop, Unset): json_enum_prop = enum_prop - params: Dict[str, Any] = {} - if string_prop is not UNSET: - params["string_prop"] = string_prop - if datetime_prop is not UNSET: - params["datetime_prop"] = json_datetime_prop - if date_prop is not UNSET: - params["date_prop"] = json_date_prop - if float_prop is not UNSET: - params["float_prop"] = float_prop - if int_prop is not UNSET: - params["int_prop"] = int_prop - if boolean_prop is not UNSET: - params["boolean_prop"] = boolean_prop - if list_prop is not UNSET: - params["list_prop"] = json_list_prop - if union_prop is not UNSET: - params["union_prop"] = json_union_prop - if union_prop_with_ref is not UNSET: - params["union_prop_with_ref"] = json_union_prop_with_ref - if enum_prop is not UNSET: - params["enum_prop"] = json_enum_prop + params: Dict[str, Any] = { + "string_prop": string_prop, + "datetime_prop": json_datetime_prop, + "date_prop": json_date_prop, + "float_prop": float_prop, + "int_prop": int_prop, + "boolean_prop": boolean_prop, + "list_prop": json_list_prop, + "union_prop": json_union_prop, + "union_prop_with_ref": json_union_prop_with_ref, + "enum_prop": json_enum_prop, + } + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} return { "url": url, diff --git a/end_to_end_tests/golden-record/my_test_api_client/api/tests/get_user_list.py b/end_to_end_tests/golden-record/my_test_api_client/api/tests/get_user_list.py index e43c92d9..1ae8b4c1 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/api/tests/get_user_list.py +++ b/end_to_end_tests/golden-record/my_test_api_client/api/tests/get_user_list.py @@ -7,7 +7,7 @@ from ...models.a_model import AModel from ...models.an_enum import AnEnum from ...models.http_validation_error import HTTPValidationError -from ...types import Response +from ...types import UNSET, Response def _get_kwargs( @@ -35,6 +35,7 @@ def _get_kwargs( "an_enum_value": json_an_enum_value, "some_date": json_some_date, } + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} return { "url": url, diff --git a/end_to_end_tests/golden-record/my_test_api_client/api/tests/int_enum_tests_int_enum_post.py b/end_to_end_tests/golden-record/my_test_api_client/api/tests/int_enum_tests_int_enum_post.py index cace678f..7472d8ee 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/api/tests/int_enum_tests_int_enum_post.py +++ b/end_to_end_tests/golden-record/my_test_api_client/api/tests/int_enum_tests_int_enum_post.py @@ -5,7 +5,7 @@ from ...client import Client from ...models.an_int_enum import AnIntEnum from ...models.http_validation_error import HTTPValidationError -from ...types import Response +from ...types import UNSET, Response def _get_kwargs( @@ -22,6 +22,7 @@ def _get_kwargs( params: Dict[str, Any] = { "int_enum": json_int_enum, } + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} return { "url": url, diff --git a/end_to_end_tests/golden-record/my_test_api_client/api/tests/optional_value_tests_optional_query_param.py b/end_to_end_tests/golden-record/my_test_api_client/api/tests/optional_value_tests_optional_query_param.py index 751f48e0..3de18244 100644 --- a/end_to_end_tests/golden-record/my_test_api_client/api/tests/optional_value_tests_optional_query_param.py +++ b/end_to_end_tests/golden-record/my_test_api_client/api/tests/optional_value_tests_optional_query_param.py @@ -20,9 +20,10 @@ def _get_kwargs( if not isinstance(query_param, Unset): json_query_param = query_param - params: Dict[str, Any] = {} - if query_param is not UNSET: - params["query_param"] = json_query_param + params: Dict[str, Any] = { + "query_param": json_query_param, + } + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} return { "url": url, diff --git a/openapi_python_client/templates/endpoint_macros.py.jinja b/openapi_python_client/templates/endpoint_macros.py.jinja index 5819714d..2b86668e 100644 --- a/openapi_python_client/templates/endpoint_macros.py.jinja +++ b/openapi_python_client/templates/endpoint_macros.py.jinja @@ -22,25 +22,14 @@ if {{ parameter.python_name }} is not UNSET: {% endfor %} params: Dict[str, Any] = { {% for property in endpoint.query_parameters %} - {% if property.required %} - {% if property.template %} + {% if property.template %} "{{ property.name }}": {{ "json_" + property.python_name }}, - {% else %} + {% else %} "{{ property.name }}": {{ property.python_name }}, - {% endif %} {% endif %} {% endfor %} } - {% for property in endpoint.query_parameters %} - {% if not property.required %} -if {{ property.python_name }} is not UNSET: - {% if property.template %} - params["{{ property.name }}"] = {{ "json_" + property.python_name }} - {% else %} - params["{{ property.name }}"] = {{ property.python_name }} - {% endif %} - {% endif %} - {% endfor %} +params = {k: v for k, v in params.items() if v is not UNSET and v is not None} {% endif %} {% endmacro %} diff --git a/openapi_python_client/templates/endpoint_module.py.jinja b/openapi_python_client/templates/endpoint_module.py.jinja index cd08ad2c..7d74cdb8 100644 --- a/openapi_python_client/templates/endpoint_module.py.jinja +++ b/openapi_python_client/templates/endpoint_module.py.jinja @@ -4,7 +4,7 @@ import httpx from attr import asdict from ...client import AuthenticatedClient, Client -from ...types import Response +from ...types import Response, UNSET {% for relative in endpoint.relative_imports %} {{ relative }} diff --git a/tests/test_templates/endpoint_module.py b/tests/test_templates/endpoint_module.py index def57a78..c08fe74e 100644 --- a/tests/test_templates/endpoint_module.py +++ b/tests/test_templates/endpoint_module.py @@ -4,7 +4,7 @@ from attr import asdict from ...client import AuthenticatedClient, Client -from ...types import Response +from ...types import Response, UNSET import this from __future__ import braces