Skip to content

Commit 0e74b59

Browse files
authored
Merge pull request #45 from triaxtec/binary_format_strings
- Add support for uploading files with multipart/form-data - Split unit and e2e tests
2 parents 36637c6 + e672139 commit 0e74b59

Some content is hidden

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

49 files changed

+770
-222
lines changed

.circleci/config.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ jobs:
2626
poetry run isort
2727
poetry run safety check --json > test-reports/safety/results.json
2828
poetry run mypy openapi_python_client --junit-xml=test-reports/mypy/results.xml
29-
poetry run pytest --junitxml=test-reports/pytest/results.xml --cov=openapi_python_client
29+
poetry run pytest --junitxml=test-reports/pytest/results.xml --cov=openapi_python_client tests
30+
poetry run pytest end_to_end_tests
3031
poetry run coverage xml
3132
- store_test_results:
3233
path: test-reports

.run/pytest.run.xml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<component name="ProjectRunConfigurationManager">
2+
<configuration default="false" name="pytest" type="tests" factoryName="py.test">
3+
<module name="openapi-python-client" />
4+
<option name="INTERPRETER_OPTIONS" value="" />
5+
<option name="PARENT_ENVS" value="true" />
6+
<option name="SDK_HOME" value="" />
7+
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/../tests" />
8+
<option name="IS_MODULE_SDK" value="true" />
9+
<option name="ADD_CONTENT_ROOTS" value="true" />
10+
<option name="ADD_SOURCE_ROOTS" value="true" />
11+
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
12+
<option name="_new_keywords" value="&quot;&quot;" />
13+
<option name="_new_parameters" value="&quot;&quot;" />
14+
<option name="_new_additionalArguments" value="&quot;&quot;" />
15+
<option name="_new_target" value="&quot;$PROJECT_DIR$/../tests&quot;" />
16+
<option name="_new_targetType" value="&quot;PATH&quot;" />
17+
<method v="2" />
18+
</configuration>
19+
</component>

.run/run_fastapi.run.xml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<component name="ProjectRunConfigurationManager">
2+
<configuration default="false" name="run_fastapi" type="PythonConfigurationType" factoryName="Python">
3+
<module name="openapi-python-client" />
4+
<option name="INTERPRETER_OPTIONS" value="" />
5+
<option name="PARENT_ENVS" value="true" />
6+
<envs>
7+
<env name="PYTHONUNBUFFERED" value="1" />
8+
</envs>
9+
<option name="SDK_HOME" value="" />
10+
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/tests/test_end_to_end/fastapi_app" />
11+
<option name="IS_MODULE_SDK" value="true" />
12+
<option name="ADD_CONTENT_ROOTS" value="true" />
13+
<option name="ADD_SOURCE_ROOTS" value="true" />
14+
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
15+
<EXTENSION ID="net.ashald.envfile">
16+
<option name="IS_ENABLED" value="false" />
17+
<option name="IS_SUBST" value="false" />
18+
<option name="IS_PATH_MACRO_SUPPORTED" value="false" />
19+
<option name="IS_IGNORE_MISSING_FILES" value="false" />
20+
<option name="IS_ENABLE_EXPERIMENTAL_INTEGRATIONS" value="false" />
21+
<ENTRIES>
22+
<ENTRY IS_ENABLED="true" PARSER="runconfig" />
23+
</ENTRIES>
24+
</EXTENSION>
25+
<option name="SCRIPT_NAME" value="tests.test_end_to_end.fastapi_app" />
26+
<option name="PARAMETERS" value="" />
27+
<option name="SHOW_COMMAND_LINE" value="false" />
28+
<option name="EMULATE_TERMINAL" value="false" />
29+
<option name="MODULE_MODE" value="true" />
30+
<option name="REDIRECT_INPUT" value="false" />
31+
<option name="INPUT_FILE" value="" />
32+
<method v="2" />
33+
</configuration>
34+
</component>
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<component name="ProjectRunConfigurationManager">
2+
<configuration default="false" name="regen_golden_master" type="PythonConfigurationType" factoryName="Python">
3+
<module name="openapi-python-client" />
4+
<option name="INTERPRETER_OPTIONS" value="" />
5+
<option name="PARENT_ENVS" value="true" />
6+
<envs>
7+
<env name="PYTHONUNBUFFERED" value="1" />
8+
</envs>
9+
<option name="SDK_HOME" value="" />
10+
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/../end_to_end_tests" />
11+
<option name="IS_MODULE_SDK" value="true" />
12+
<option name="ADD_CONTENT_ROOTS" value="true" />
13+
<option name="ADD_SOURCE_ROOTS" value="true" />
14+
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
15+
<EXTENSION ID="net.ashald.envfile">
16+
<option name="IS_ENABLED" value="false" />
17+
<option name="IS_SUBST" value="false" />
18+
<option name="IS_PATH_MACRO_SUPPORTED" value="false" />
19+
<option name="IS_IGNORE_MISSING_FILES" value="false" />
20+
<option name="IS_ENABLE_EXPERIMENTAL_INTEGRATIONS" value="false" />
21+
<ENTRIES>
22+
<ENTRY IS_ENABLED="true" PARSER="runconfig" />
23+
</ENTRIES>
24+
</EXTENSION>
25+
<option name="SCRIPT_NAME" value="end_to_end_tests.regen_golden_master" />
26+
<option name="PARAMETERS" value="" />
27+
<option name="SHOW_COMMAND_LINE" value="false" />
28+
<option name="EMULATE_TERMINAL" value="false" />
29+
<option name="MODULE_MODE" value="true" />
30+
<option name="REDIRECT_INPUT" value="false" />
31+
<option name="INPUT_FILE" value="" />
32+
<method v="2" />
33+
</configuration>
34+
</component>

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
8+
## 0.4.0 - Unreleased
9+
### Additions
10+
- Add support for binary format strings (file payloads)
11+
- Add support for multipart/form bodies
12+
713
## 0.3.0 - 2020-04-25
814
### Additions
915
- Link to the GitHub repository from PyPI (#26). Thanks @theY4Kman!
Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from pathlib import Path
66
from typing import List
77

8-
from fastapi import APIRouter, FastAPI, Query
8+
from fastapi import APIRouter, FastAPI, File, Query, UploadFile
99
from pydantic import BaseModel
1010

1111
app = FastAPI(title="My Test API", description="An API for testing openapi-python-client",)
@@ -50,12 +50,24 @@ class AModel(BaseModel):
5050

5151
@test_router.get("/", response_model=List[AModel], operation_id="getUserList")
5252
def get_list(statuses: List[AnEnum] = Query(...), some_date: date = Query(...), some_datetime: datetime = Query(...)):
53-
""" Get users, filtered by statuses """
53+
""" Get a list of things """
5454
return
5555

5656

57+
@test_router.post("/upload")
58+
async def upload_file(some_file: UploadFile = File(...)):
59+
""" Upload a file """
60+
data = await some_file.read()
61+
return (some_file.filename, some_file.content_type, data)
62+
63+
5764
app.include_router(test_router, prefix="/tests", tags=["users"])
5865

59-
if __name__ == "__main__":
66+
67+
def generate_openapi_json():
6068
path = Path(__file__).parent / "openapi.json"
6169
path.write_text(json.dumps(app.openapi(), indent=4))
70+
71+
72+
if __name__ == "__main__":
73+
generate_openapi_json()
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import uvicorn
2+
3+
from . import app
4+
5+
uvicorn.run(app)

tests/test_end_to_end/fastapi/openapi.json renamed to end_to_end_tests/fastapi_app/openapi.json

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
"users"
3232
],
3333
"summary": "Get List",
34-
"description": "Get users, filtered by statuses ",
34+
"description": "Get a list of things ",
3535
"operationId": "getUserList",
3636
"parameters": [
3737
{
@@ -97,6 +97,46 @@
9797
}
9898
}
9999
}
100+
},
101+
"/tests/upload": {
102+
"post": {
103+
"tags": [
104+
"users"
105+
],
106+
"summary": "Upload File",
107+
"description": "Upload a file ",
108+
"operationId": "upload_file_tests_upload_post",
109+
"requestBody": {
110+
"content": {
111+
"multipart/form-data": {
112+
"schema": {
113+
"$ref": "#/components/schemas/Body_upload_file_tests_upload_post"
114+
}
115+
}
116+
},
117+
"required": true
118+
},
119+
"responses": {
120+
"200": {
121+
"description": "Successful Response",
122+
"content": {
123+
"application/json": {
124+
"schema": {}
125+
}
126+
}
127+
},
128+
"422": {
129+
"description": "Validation Error",
130+
"content": {
131+
"application/json": {
132+
"schema": {
133+
"$ref": "#/components/schemas/HTTPValidationError"
134+
}
135+
}
136+
}
137+
}
138+
}
139+
}
100140
}
101141
},
102142
"components": {
@@ -157,6 +197,20 @@
157197
},
158198
"description": "A Model for testing all the ways custom objects can be used "
159199
},
200+
"Body_upload_file_tests_upload_post": {
201+
"title": "Body_upload_file_tests_upload_post",
202+
"required": [
203+
"some_file"
204+
],
205+
"type": "object",
206+
"properties": {
207+
"some_file": {
208+
"title": "Some File",
209+
"type": "string",
210+
"format": "binary"
211+
}
212+
}
213+
},
160214
"HTTPValidationError": {
161215
"title": "HTTPValidationError",
162216
"type": "object",

0 commit comments

Comments
 (0)