Skip to content

Commit eb26c87

Browse files
authored
Merge branch 'main' into fix/delims
2 parents a64fd30 + 5de5920 commit eb26c87

File tree

89 files changed

+2326
-379
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

89 files changed

+2326
-379
lines changed

.github/workflows/checks.yml

+63
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ jobs:
6161
- name: Run pylint
6262
run: poetry run pylint openapi_python_client
6363

64+
- name: Regenerate Golden Record
65+
run: poetry run task regen_e2e
66+
6467
- name: Run pytest
6568
run: poetry run pytest --cov=openapi_python_client --cov-report=term-missing tests end_to_end_tests/test_end_to_end.py --basetemp=tests/tmp
6669
env:
@@ -73,3 +76,63 @@ jobs:
7376
- uses: codecov/codecov-action@v2
7477
with:
7578
files: ./coverage.xml
79+
80+
- uses: stefanzweifel/git-auto-commit-action@v4
81+
if: runner.os == 'Linux'
82+
with:
83+
commit_message: "chore: Regenerate E2E Golden Record"
84+
file_pattern: end_to_end_tests/golden-record end_to_end_tests/custom-templates-golden-record
85+
86+
integration:
87+
name: Integration Tests
88+
runs-on: ubuntu-latest
89+
services:
90+
openapi-test-server:
91+
image: ghcr.io/openapi-generators/openapi-test-server:latest
92+
ports:
93+
- "3000:3000"
94+
steps:
95+
- uses: actions/checkout@v2
96+
- name: Set up Python
97+
uses: actions/setup-python@v2
98+
with:
99+
python-version: "3.10"
100+
- name: Get Python Version
101+
id: get_python_version
102+
run: echo "::set-output name=python_version::$(python --version)"
103+
- name: Cache dependencies
104+
uses: actions/cache@v2
105+
with:
106+
path: .venv
107+
key: ${{ runner.os }}-${{ steps.get_python_version.outputs.python_version }}-dependencies-${{ hashFiles('**/poetry.lock') }}
108+
restore-keys: |
109+
${{ runner.os }}-${{ steps.get_python_version.outputs.python_version }}-dependencies
110+
- name: Install dependencies
111+
run: |
112+
pip install poetry
113+
python -m venv .venv
114+
poetry run python -m pip install --upgrade pip
115+
poetry install
116+
- name: Regenerate Integration Client
117+
run: |
118+
poetry run openapi-python-client update --url http://localhost:3000/openapi.json --config integration-tests-config.yaml
119+
- name: Cache Generated Client Dependencies
120+
uses: actions/cache@v2
121+
with:
122+
path: integration-tests/.venv
123+
key: ${{ runner.os }}-${{ steps.get_python_version.outputs.python_version }}-integration-dependencies-${{ hashFiles('**/poetry.lock') }}
124+
restore-keys: |
125+
${{ runner.os }}-${{ steps.get_python_version.outputs.python_version }}-integration-dependencies
126+
- name: Install Integration Dependencies
127+
run: |
128+
cd integration-tests
129+
python -m venv .venv
130+
poetry run python -m pip install --upgrade pip
131+
poetry install
132+
- name: Run Tests
133+
run: |
134+
cd integration-tests
135+
poetry run pytest
136+
- uses: stefanzweifel/git-auto-commit-action@v4
137+
with:
138+
commit_message: "chore: Regenerate Integration Client"

CHANGELOG.md

+9
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file.
44

55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
Breaking changes to any of the following will cause the **minor** version to be incremented (as long as this project is 0.x). Only these pieces are considered part of the public API:
8+
9+
- The _behavior_ of the generated code. Specifically, the way in which generated endpoints and classes are called and the way in which those calls communicate with an OpenAPI server. Any other property of the generated code is not considered part of the versioned, public API (e.g., code formatting, comments).
10+
- The invocation of the CLI (e.g., commands or arguments).
11+
12+
Programmatic usage of this project (e.g., importing it as a Python module) and the usage of custom templates are not considered part of the public API and therefore may change behavior at any time without notice.
13+
14+
The 0.x prefix used in versions for this project is to indicate that breaking changes are expected frequently (several times a year). Breaking changes will increment the minor number, all other changes will increment the patch number. You can track the progress toward 1.0 [here](https://github.com/openapi-generators/openapi-python-client/projects/2).
15+
716
## 0.10.8
817

918
### Features

CONTRIBUTING.md

+5-4
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,14 @@
2121

2222
2. When in a Poetry shell (`poetry shell`) run `task check` in order to run most of the same checks CI runs. This will auto-reformat the code, check type annotations, run unit tests, check code coverage, and lint the code.
2323

24-
### Rework end to end tests
24+
### Rework end-to-end tests
2525

26-
3. If you're writing a new feature, try to add it to the end to end test.
26+
3. If you're writing a new feature, try to add it to the end-to-end test.
2727
1. If adding support for a new OpenAPI feature, add it somewhere in `end_to_end_tests/openapi.json`
28-
2. Regenerate the "golden records" with `task regen`. This client is generated from the OpenAPI document used for end to end testing.
28+
2. Regenerate the "golden records" with `task regen`. This client is generated from the OpenAPI document used for end-to-end testing.
2929
3. Check the changes to `end_to_end_tests/golden-record` to confirm only what you intended to change did change and that the changes look correct.
30-
4. Run the end to end tests with `task e2e`. This will generate clients against `end_to_end_tests/openapi.json` and compare them with the golden record. The tests will fail if **anything is different**. The end to end tests are not included in `task check` as they take longer to run and don't provide very useful feedback in the event of failure. If an e2e test does fail, the easiest way to check what's wrong is to run `task regen` and check the diffs. You can also use `task re` which will run `regen` and `e2e` in that order.
30+
4. **If you added a test above OR modified the templates**: Run the end-to-end tests with `task e2e`. This will generate clients against `end_to_end_tests/openapi.json` and compare them with the golden record. The tests will fail if **anything is different**. The end-to-end tests are not included in `task check` as they take longer to run and don't provide very useful feedback in the event of failure. If an e2e test does fail, the easiest way to check what's wrong is to run `task regen` and check the diffs. You can also use `task re` which will run `regen` and `e2e` in that order.
31+
3132

3233
## Creating a Pull Request
3334

end_to_end_tests/custom-templates-golden-record/my_test_api_client/api/location/__init__.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,14 @@
22

33
import types
44

5-
from . import get_location_query_optionality
5+
from . import get_location_header_types, get_location_query_optionality
66

77

88
class LocationEndpoints:
99
@classmethod
1010
def get_location_query_optionality(cls) -> types.ModuleType:
1111
return get_location_query_optionality
12+
13+
@classmethod
14+
def get_location_header_types(cls) -> types.ModuleType:
15+
return get_location_header_types

end_to_end_tests/golden-record/my_test_api_client/api/default/get_common_parameters.py

+7-6
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,16 @@ def _get_kwargs(
1313
) -> Dict[str, Any]:
1414
url = "{}/common_parameters".format(client.base_url)
1515

16-
headers: Dict[str, Any] = client.get_headers()
16+
headers: Dict[str, str] = client.get_headers()
1717
cookies: Dict[str, Any] = client.get_cookies()
1818

19-
params: Dict[str, Any] = {
20-
"common": common,
21-
}
19+
params: Dict[str, Any] = {}
20+
params["common"] = common
21+
2222
params = {k: v for k, v in params.items() if v is not UNSET and v is not None}
2323

2424
return {
25+
"method": "get",
2526
"url": url,
2627
"headers": headers,
2728
"cookies": cookies,
@@ -57,7 +58,7 @@ def sync_detailed(
5758
common=common,
5859
)
5960

60-
response = httpx.get(
61+
response = httpx.request(
6162
verify=client.verify_ssl,
6263
**kwargs,
6364
)
@@ -84,6 +85,6 @@ async def asyncio_detailed(
8485
)
8586

8687
async with httpx.AsyncClient(verify=client.verify_ssl) as _client:
87-
response = await _client.get(**kwargs)
88+
response = await _client.request(**kwargs)
8889

8990
return _build_response(response=response)

end_to_end_tests/golden-record/my_test_api_client/api/default/post_common_parameters.py

+7-6
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,16 @@ def _get_kwargs(
1313
) -> Dict[str, Any]:
1414
url = "{}/common_parameters".format(client.base_url)
1515

16-
headers: Dict[str, Any] = client.get_headers()
16+
headers: Dict[str, str] = client.get_headers()
1717
cookies: Dict[str, Any] = client.get_cookies()
1818

19-
params: Dict[str, Any] = {
20-
"common": common,
21-
}
19+
params: Dict[str, Any] = {}
20+
params["common"] = common
21+
2222
params = {k: v for k, v in params.items() if v is not UNSET and v is not None}
2323

2424
return {
25+
"method": "post",
2526
"url": url,
2627
"headers": headers,
2728
"cookies": cookies,
@@ -57,7 +58,7 @@ def sync_detailed(
5758
common=common,
5859
)
5960

60-
response = httpx.post(
61+
response = httpx.request(
6162
verify=client.verify_ssl,
6263
**kwargs,
6364
)
@@ -84,6 +85,6 @@ async def asyncio_detailed(
8485
)
8586

8687
async with httpx.AsyncClient(verify=client.verify_ssl) as _client:
87-
response = await _client.post(**kwargs)
88+
response = await _client.request(**kwargs)
8889

8990
return _build_response(response=response)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
from typing import Any, Dict, Union
2+
3+
import httpx
4+
5+
from ...client import Client
6+
from ...types import UNSET, Response, Unset
7+
8+
9+
def _get_kwargs(
10+
*,
11+
client: Client,
12+
boolean_header: Union[Unset, bool] = UNSET,
13+
string_header: Union[Unset, str] = UNSET,
14+
number_header: Union[Unset, float] = UNSET,
15+
integer_header: Union[Unset, int] = UNSET,
16+
) -> Dict[str, Any]:
17+
url = "{}/location/header/types".format(client.base_url)
18+
19+
headers: Dict[str, str] = client.get_headers()
20+
cookies: Dict[str, Any] = client.get_cookies()
21+
22+
if not isinstance(boolean_header, Unset):
23+
headers["Boolean-Header"] = "true" if boolean_header else "false"
24+
25+
if not isinstance(string_header, Unset):
26+
headers["String-Header"] = string_header
27+
28+
if not isinstance(number_header, Unset):
29+
headers["Number-Header"] = str(number_header)
30+
31+
if not isinstance(integer_header, Unset):
32+
headers["Integer-Header"] = str(integer_header)
33+
34+
return {
35+
"method": "get",
36+
"url": url,
37+
"headers": headers,
38+
"cookies": cookies,
39+
"timeout": client.get_timeout(),
40+
}
41+
42+
43+
def _build_response(*, response: httpx.Response) -> Response[Any]:
44+
return Response(
45+
status_code=response.status_code,
46+
content=response.content,
47+
headers=response.headers,
48+
parsed=None,
49+
)
50+
51+
52+
def sync_detailed(
53+
*,
54+
client: Client,
55+
boolean_header: Union[Unset, bool] = UNSET,
56+
string_header: Union[Unset, str] = UNSET,
57+
number_header: Union[Unset, float] = UNSET,
58+
integer_header: Union[Unset, int] = UNSET,
59+
) -> Response[Any]:
60+
"""
61+
Args:
62+
boolean_header (Union[Unset, bool]):
63+
string_header (Union[Unset, str]):
64+
number_header (Union[Unset, float]):
65+
integer_header (Union[Unset, int]):
66+
67+
Returns:
68+
Response[Any]
69+
"""
70+
71+
kwargs = _get_kwargs(
72+
client=client,
73+
boolean_header=boolean_header,
74+
string_header=string_header,
75+
number_header=number_header,
76+
integer_header=integer_header,
77+
)
78+
79+
response = httpx.request(
80+
verify=client.verify_ssl,
81+
**kwargs,
82+
)
83+
84+
return _build_response(response=response)
85+
86+
87+
async def asyncio_detailed(
88+
*,
89+
client: Client,
90+
boolean_header: Union[Unset, bool] = UNSET,
91+
string_header: Union[Unset, str] = UNSET,
92+
number_header: Union[Unset, float] = UNSET,
93+
integer_header: Union[Unset, int] = UNSET,
94+
) -> Response[Any]:
95+
"""
96+
Args:
97+
boolean_header (Union[Unset, bool]):
98+
string_header (Union[Unset, str]):
99+
number_header (Union[Unset, float]):
100+
integer_header (Union[Unset, int]):
101+
102+
Returns:
103+
Response[Any]
104+
"""
105+
106+
kwargs = _get_kwargs(
107+
client=client,
108+
boolean_header=boolean_header,
109+
string_header=string_header,
110+
number_header=number_header,
111+
integer_header=integer_header,
112+
)
113+
114+
async with httpx.AsyncClient(verify=client.verify_ssl) as _client:
115+
response = await _client.request(**kwargs)
116+
117+
return _build_response(response=response)

end_to_end_tests/golden-record/my_test_api_client/api/location/get_location_query_optionality.py

+13-9
Original file line numberDiff line numberDiff line change
@@ -17,32 +17,36 @@ def _get_kwargs(
1717
) -> Dict[str, Any]:
1818
url = "{}/location/query/optionality".format(client.base_url)
1919

20-
headers: Dict[str, Any] = client.get_headers()
20+
headers: Dict[str, str] = client.get_headers()
2121
cookies: Dict[str, Any] = client.get_cookies()
2222

23+
params: Dict[str, Any] = {}
2324
json_not_null_required = not_null_required.isoformat()
2425

26+
params["not_null_required"] = json_not_null_required
27+
2528
json_null_required: Union[Unset, None, str] = UNSET
2629
if not isinstance(null_required, Unset):
2730
json_null_required = null_required.isoformat() if null_required else None
2831

32+
params["null_required"] = json_null_required
33+
2934
json_null_not_required: Union[Unset, None, str] = UNSET
3035
if not isinstance(null_not_required, Unset):
3136
json_null_not_required = null_not_required.isoformat() if null_not_required else None
3237

38+
params["null_not_required"] = json_null_not_required
39+
3340
json_not_null_not_required: Union[Unset, None, str] = UNSET
3441
if not isinstance(not_null_not_required, Unset):
3542
json_not_null_not_required = not_null_not_required.isoformat() if not_null_not_required else None
3643

37-
params: Dict[str, Any] = {
38-
"not_null_required": json_not_null_required,
39-
"null_required": json_null_required,
40-
"null_not_required": json_null_not_required,
41-
"not_null_not_required": json_not_null_not_required,
42-
}
44+
params["not_null_not_required"] = json_not_null_not_required
45+
4346
params = {k: v for k, v in params.items() if v is not UNSET and v is not None}
4447

4548
return {
49+
"method": "get",
4650
"url": url,
4751
"headers": headers,
4852
"cookies": cookies,
@@ -87,7 +91,7 @@ def sync_detailed(
8791
not_null_not_required=not_null_not_required,
8892
)
8993

90-
response = httpx.get(
94+
response = httpx.request(
9195
verify=client.verify_ssl,
9296
**kwargs,
9397
)
@@ -123,6 +127,6 @@ async def asyncio_detailed(
123127
)
124128

125129
async with httpx.AsyncClient(verify=client.verify_ssl) as _client:
126-
response = await _client.get(**kwargs)
130+
response = await _client.request(**kwargs)
127131

128132
return _build_response(response=response)

0 commit comments

Comments
 (0)