Skip to content

default to httpx2 and drop support for httpx entirely - #1461

Open
s-sajid-ali wants to merge 6 commits into
openapi-generators:mainfrom
s-sajid-ali:httpx-switch-default-to-2
Open

s-sajid-ali wants to merge 6 commits into
openapi-generators:mainfrom
s-sajid-ali:httpx-switch-default-to-2

Conversation

@s-sajid-ali

@s-sajid-ali s-sajid-ali commented Jun 29, 2026

Copy link
Copy Markdown

This PR assumes that the deprecation of generating clients with httpx is imminent and updates all golden records to use httpx2 instead. This leaves the client generation process with legacy httpx untested. This will cause issues when httpx2 introduces breaking changes and it is assumed that the option to use httpx will be removed by that time.

Additionally, this leaves the generated methodget_httpx_client as is, preferring to update it to get_httpx2_client when support for httpx is removed.

@johnthagen

Copy link
Copy Markdown
Collaborator

@s-sajid-ali
s-sajid-ali force-pushed the httpx-switch-default-to-2 branch from 2ec5db8 to 60f98e9 Compare August 4, 2026 20:04
@s-sajid-ali

Copy link
Copy Markdown
Author

Split the commit to exclude the changes to pdm.lock file as that was causing merge conflicts and rebased the changes over the current state of main. Let me know if you need anything else!

@johnthagen

Copy link
Copy Markdown
Collaborator

@s-sajid-ali Per discussion here

Would you be willing to modify this PR to target only httpx2? We can skip the complexities of trying to support both given the way the community is moving.

@s-sajid-ali

Copy link
Copy Markdown
Author

Sure, it should be much easier to move everything over to httpx2 and not support both. I'll get the change in place by the middle of the upcoming week.

	new file:   .changeset/default_to_httpx2.md
	modified:   end_to_end_tests/functional_tests/generated_code_execution/test_path_parameters.py
	modified:   end_to_end_tests/golden-records/docstrings-on-attributes-golden-record/README.md
	modified:   end_to_end_tests/golden-records/docstrings-on-attributes-golden-record/my_test_api_client/client.py
	modified:   end_to_end_tests/golden-records/docstrings-on-attributes-golden-record/my_test_api_client/types.py
	modified:   end_to_end_tests/golden-records/docstrings-on-attributes-golden-record/pyproject.toml
	modified:   end_to_end_tests/golden-records/escapes-client/README.md
	modified:   end_to_end_tests/golden-records/escapes-client/escapes_client/api/default/get_weird_responses.py
	modified:   end_to_end_tests/golden-records/escapes-client/escapes_client/api/default/misc_metadata_escapes.py
	modified:   end_to_end_tests/golden-records/escapes-client/escapes_client/api/default/non_string_example.py
	modified:   end_to_end_tests/golden-records/escapes-client/escapes_client/api/default/property_escapes.py
	modified:   end_to_end_tests/golden-records/escapes-client/escapes_client/api/printtag_escape/with_braces_path.py
	modified:   end_to_end_tests/golden-records/escapes-client/escapes_client/client.py
	modified:   end_to_end_tests/golden-records/escapes-client/escapes_client/types.py
	modified:   end_to_end_tests/golden-records/escapes-client/pyproject.toml
	modified:   end_to_end_tests/golden-records/my-enum-api-client/README.md
	modified:   end_to_end_tests/golden-records/my-enum-api-client/my_enum_api_client/api/enums/bool_enum_tests_bool_enum_post.py
	modified:   end_to_end_tests/golden-records/my-enum-api-client/my_enum_api_client/api/enums/int_enum_tests_int_enum_post.py
	modified:   end_to_end_tests/golden-records/my-enum-api-client/my_enum_api_client/api/tests/get_user_list.py
	modified:   end_to_end_tests/golden-records/my-enum-api-client/my_enum_api_client/api/tests/post_user_list.py
	modified:   end_to_end_tests/golden-records/my-enum-api-client/my_enum_api_client/client.py
	modified:   end_to_end_tests/golden-records/my-enum-api-client/my_enum_api_client/types.py
	modified:   end_to_end_tests/golden-records/my-enum-api-client/pyproject.toml
	modified:   end_to_end_tests/golden-records/my-test-api-client/README.md
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/bodies/json_like.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/bodies/optional_body.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/bodies/post_bodies_multiple.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/bodies/refs.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/config/content_type_override.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/default/get_common_parameters.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/default/get_models_allof.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/default/get_models_oneof_with_required_const.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/default/post_common_parameters.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/default/post_types_unions_duplicate_types.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/default/reserved_parameters.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/defaults/defaults_tests_defaults_post.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/enums/bool_enum_tests_bool_enum_post.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/enums/int_enum_tests_int_enum_post.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/location/get_location_header_types.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/location/get_location_query_optionality.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/naming/hyphen_in_path.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/naming/mixed_case.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/naming/post_naming_property_conflict_with_import.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/parameter_references/get_parameter_references_path_param.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/parameters/delete_common_parameters_overriding_param.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/parameters/get_common_parameters_overriding_param.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/parameters/get_same_name_multiple_locations_param.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/parameters/multiple_path_parameters.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/responses/default_status_code.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/responses/post_responses_unions_simple_before_complex.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/responses/reference_response.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/responses/status_code_patterns.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/responses/status_code_precedence.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/responses/text_response.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/tag1/get_tag_with_number.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/tag2/get_tag_with_number.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/tests/callback_test.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/tests/description_with_backslash.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/tests/get_basic_list_of_booleans.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/tests/get_basic_list_of_floats.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/tests/get_basic_list_of_integers.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/tests/get_basic_list_of_strings.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/tests/get_user_list.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/tests/json_body_tests_json_body_post.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/tests/no_response_tests_no_response_get.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/tests/octet_stream_tests_octet_stream_get.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/tests/octet_stream_tests_octet_stream_post.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/tests/post_form_data.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/tests/post_form_data_inline.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/tests/post_tests_json_body_string.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/tests/test_inline_objects.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/tests/token_with_cookie_auth_token_with_cookie_get.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/tests/unsupported_content_tests_unsupported_content_get.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/tests/upload_file_tests_upload_post.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/api/true_/false_.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/client.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/my_test_api_client/types.py
	modified:   end_to_end_tests/golden-records/my-test-api-client/pyproject.toml
	modified:   end_to_end_tests/golden-records/test-3-1-features-client/README.md
	modified:   end_to_end_tests/golden-records/test-3-1-features-client/pyproject.toml
	modified:   end_to_end_tests/golden-records/test-3-1-features-client/test_3_1_features_client/api/const/post_const_path.py
	modified:   end_to_end_tests/golden-records/test-3-1-features-client/test_3_1_features_client/api/prefix_items/post_prefix_items.py
	modified:   end_to_end_tests/golden-records/test-3-1-features-client/test_3_1_features_client/client.py
	modified:   end_to_end_tests/golden-records/test-3-1-features-client/test_3_1_features_client/types.py
	modified:   end_to_end_tests/metadata_snapshots/pdm.pyproject.toml
	modified:   end_to_end_tests/metadata_snapshots/poetry.pyproject.toml
	modified:   end_to_end_tests/metadata_snapshots/setup.py
	modified:   end_to_end_tests/metadata_snapshots/uv.pyproject.toml
	modified:   integration-tests/README.md
	modified:   integration-tests/integration_tests/api/body/post_body_multipart.py
	modified:   integration-tests/integration_tests/api/parameters/post_parameters_header.py
	modified:   integration-tests/integration_tests/client.py
	modified:   integration-tests/integration_tests/types.py
	modified:   integration-tests/pyproject.toml
	modified:   integration-tests/tests/test_api/test_body/test_post_body_multipart.py
	modified:   openapi_python_client/__init__.py
	modified:   openapi_python_client/parser/responses.py
	modified:   openapi_python_client/templates/README.md.jinja
	modified:   openapi_python_client/templates/client.py.jinja
	modified:   openapi_python_client/templates/endpoint_macros.py.jinja
	modified:   openapi_python_client/templates/endpoint_module.py.jinja
	modified:   openapi_python_client/templates/pyproject_pdm.toml.jinja
	modified:   openapi_python_client/templates/pyproject_poetry.toml.jinja
	modified:   openapi_python_client/templates/pyproject_uv.toml.jinja
	modified:   openapi_python_client/templates/setup.py.jinja
	modified:   openapi_python_client/templates/types.py.jinja
	modified:   pyproject.toml
	modified:   integration-tests/pdm.lock
	modified:   integration-tests/pdm.minimal.lock
	modified:   pdm.lock
	modified:   pdm.minimal.lock
@s-sajid-ali
s-sajid-ali force-pushed the httpx-switch-default-to-2 branch from 60f98e9 to 182ab12 Compare September 15, 2026 21:58
@s-sajid-ali

s-sajid-ali commented Sep 15, 2026

Copy link
Copy Markdown
Author

Updated to only use httpx2 and ready for another review.

This now includes breaking API changes as noted in the changeset:

  • set_httpx_client -> set_httpx2_client
  • get_httpx_client -> get_httpx2_client
  • set_async_httpx_client -> set_async_httpx2_client
  • get_async_httpx_client -> get_async_httpx2_client

Since this is a major version change that breaks with httpx, I'm assuming that this API change is acceptable. If not, these APIs can be kept as is.

@johnthagen

Copy link
Copy Markdown
Collaborator

I think migrating to *_httpx2_client function names makes sense. It's probably safer to be explicit about this and it's nicer longer term. This change can be easily detected by type checkers and IDEs, so hopefully that makes the migration straight forward.

@johnthagen
johnthagen self-requested a review September 22, 2026 12:01

@johnthagen johnthagen left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

CI failures need fixed.

@s-sajid-ali

Copy link
Copy Markdown
Author

CI needs permission to re-run but format checks are now clean:

~/D/p/openapi-python-client (httpx-switch-default-to-2)> git log -n 1
commit cd3b41cb0aeec512779f34c6763f79ee1254d3d4 (HEAD -> httpx-switch-default-to-2, origin/httpx-switch-default-to-2)
Author: Sajid Ali <sajidsyed2021@u.northwestern.edu>
Date:   Tue Sep 22 19:43:01 2026 -0400

    ruff format in integration-tests/ to fix formatting error from CI
~/D/p/openapi-python-client (httpx-switch-default-to-2)> pdm run ruff format . --check
130 files already formatted

@johnthagen

johnthagen commented Sep 23, 2026

Copy link
Copy Markdown
Collaborator

Since this isn't merged yet, perhaps we bump the minimum version to 2.13.1 that was just released

@s-sajid-ali

Copy link
Copy Markdown
Author

Updated to 2.13.1 as requested and I see that the CI failures from the last run are unrelated to this branch, with the following being a representative failure:


PLR0917 Too many positional arguments (8 > 5)
  --> tests/test_parser/test_properties/test_union.py:34:5
   |
34 | def test_union_oneOf_descriptive_type_name(
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
35 |     union_property_factory,
36 |     date_time_property_factory,
   |

This would be best addressed in a separate PR with two commits capturing the changes from:

pdm ruff check --fix .

and

pdm ruff check --fix --unsafe-fixes .

with a review focused on the changes introduced by the second commit.

@johnthagen
johnthagen requested a review from dbanty September 23, 2026 15:34
@s-sajid-ali s-sajid-ali changed the title draft: default to httpx2 default to httpx2 and drop support for httpx entirely Sep 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants