[python][fastapi] various minor improvements (#9672)

* fix python fastapi tests, update readme, add CI test

* update FILES

* use virtualenv

* fix pom.xml

* skip flake8
This commit is contained in:
William Cheng 2021-06-07 11:55:26 +08:00 committed by GitHub
parent 8c268c9578
commit 088bca1580
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 246 additions and 120 deletions

View File

@ -285,7 +285,7 @@ public class PythonFastAPIServerCodegen extends AbstractPythonCodegen {
System.out.println("# https://opencollective.com/openapi_generator/donate #");
System.out.println("# #");
System.out.println("# This generator's contributed by Nikita Vakula (https://github.com/krjakbrjak)#");
System.out.println("# Please support his work directly via https://paypal.me/krjakbrjaki \uD83D\uDE4F #");
System.out.println("# Please support his work directly via https://paypal.me/krjakbrjak \uD83D\uDE4F #");
System.out.println("################################################################################");
}

View File

@ -16,9 +16,9 @@ Python >= 3.6
To run the server, please execute the following from the root directory:
```
pip3 install -r requirements.txt
uvicorn main:app --host 0.0.0.0 --port {{serverPort}}
```bash
pip3 install -r requirements.txt
uvicorn main:app --host 0.0.0.0 --port {{serverPort}}
```
and open your browser at `http://localhost:{{serverPort}}/docs/` to see the docs.
@ -30,3 +30,12 @@ To run the server on a Docker container, please execute the following from the r
```bash
docker-compose up --build
```
## Tests
To run the tests:
```bash
pip3 install pytest
PYTHONPATH=src pytest tests
```

View File

@ -47,7 +47,8 @@ def test_{{operationId}}(client: TestClient):
params=params,{{/-first}}{{/queryParams}}
)
assert response.status_code == 200
# uncomment below to assert the status code of the HTTP response
#assert response.status_code == 200
{{/operation}}
{{/operations}}

View File

@ -1187,6 +1187,7 @@
<!-- servers -->
<module>samples/server/petstore/python-aiohttp</module>
<module>samples/server/petstore/python-aiohttp-srclayout</module>
<module>samples/server/petstore/python-fastapi</module>
<module>samples/server/petstore/python-flask</module>
<!-- TODO: will move these to Github action
<module>samples/server/petstore/php-slim4</module>

View File

@ -13,9 +13,9 @@ Python >= 3.6
To run the server, please execute the following from the root directory:
```
pip3 install -r requirements.txt
uvicorn main:app --host 0.0.0.0 --port 8080
```bash
pip3 install -r requirements.txt
uvicorn main:app --host 0.0.0.0 --port 8080
```
and open your browser at `http://localhost:8080/docs/` to see the docs.
@ -27,3 +27,12 @@ To run the server on a Docker container, please execute the following from the r
```bash
docker-compose up --build
```
## Tests
To run the tests:
```bash
pip3 install pytest
PYTHONPATH=src pytest tests
```

View File

@ -0,0 +1,43 @@
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>org.openapitools</groupId>
<artifactId>PythonFastAPITests</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<name>Python FastAPI Server</name>
<build>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<id>test</id>
<phase>integration-test</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>./test_python3.sh</executable>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,33 @@
#!/bin/bash
set -e
REQUIREMENTS_FILE=requirements.txt
REQUIREMENTS_OUT=requirements.txt.log
SETUP_OUT=*.egg-info
VENV=.venv
DEACTIVE=false
export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8
### set virtualenv
if [ -z "$VIRTUAL_ENV" ]; then
virtualenv $VENV --no-site-packages --always-copy --python python3
source $VENV/bin/activate
DEACTIVE=true
fi
### install dependencies
pip install -r $REQUIREMENTS_FILE | tee -a $REQUIREMENTS_OUT
### run tests
PYTHONPATH=src pytest tests
### static analysis of code
#flake8 --show-source src/
### deactivate virtualenv
if [ $DEACTIVE == true ]; then
deactivate
fi

View File

@ -2,11 +2,9 @@
from fastapi.testclient import TestClient
import json
import pytest
from openapi_server.models.api_response import ApiResponse
from openapi_server.models.pet import Pet
from openapi_server.models.api_response import ApiResponse # noqa: F401
from openapi_server.models.pet import Pet # noqa: F401
def test_add_pet(client: TestClient):
@ -15,17 +13,19 @@ def test_add_pet(client: TestClient):
Add a new pet to the store
"""
pet = {"photo_urls":["photoUrls","photoUrls"],"name":"doggie","id":0,"category":{"name":"name","id":6},"tags":[{"name":"name","id":1},{"name":"name","id":1}],"status":"available"}
headers = {
'Authorization': 'Bearer special-key',
headers = {
"Authorization": "Bearer special-key",
}
response = client.request(
'POST',
'/pet',
"POST",
"/pet",
headers=headers,
json=pet,
)
assert response.status_code == 200
# uncomment below to assert the status code of the HTTP response
#assert response.status_code == 200
def test_delete_pet(client: TestClient):
@ -33,17 +33,19 @@ def test_delete_pet(client: TestClient):
Deletes a pet
"""
headers = {
'api_key': 'api_key_example',
'Authorization': 'Bearer special-key',
headers = {
"api_key": 'api_key_example',
"Authorization": "Bearer special-key",
}
response = client.request(
'DELETE',
'/pet/{petId}'.format(petId=56),
"DELETE",
"/pet/{petId}".format(petId=56),
headers=headers,
)
assert response.status_code == 200
# uncomment below to assert the status code of the HTTP response
#assert response.status_code == 200
def test_find_pets_by_status(client: TestClient):
@ -52,17 +54,18 @@ def test_find_pets_by_status(client: TestClient):
Finds Pets by status
"""
params = [("status", ['status_example'])]
headers = {
'Authorization': 'Bearer special-key',
headers = {
"Authorization": "Bearer special-key",
}
response = client.request(
'GET',
'/pet/findByStatus',
"GET",
"/pet/findByStatus",
headers=headers,
params=params,
)
assert response.status_code == 200
# uncomment below to assert the status code of the HTTP response
#assert response.status_code == 200
def test_find_pets_by_tags(client: TestClient):
@ -71,17 +74,18 @@ def test_find_pets_by_tags(client: TestClient):
Finds Pets by tags
"""
params = [("tags", ['tags_example'])]
headers = {
'Authorization': 'Bearer special-key',
headers = {
"Authorization": "Bearer special-key",
}
response = client.request(
'GET',
'/pet/findByTags',
"GET",
"/pet/findByTags",
headers=headers,
params=params,
)
assert response.status_code == 200
# uncomment below to assert the status code of the HTTP response
#assert response.status_code == 200
def test_get_pet_by_id(client: TestClient):
@ -89,16 +93,18 @@ def test_get_pet_by_id(client: TestClient):
Find pet by ID
"""
headers = {
'api_key': 'special-key',
headers = {
"api_key": "special-key",
}
response = client.request(
'GET',
'/pet/{petId}'.format(petId=56),
"GET",
"/pet/{petId}".format(petId=56),
headers=headers,
)
assert response.status_code == 200
# uncomment below to assert the status code of the HTTP response
#assert response.status_code == 200
def test_update_pet(client: TestClient):
@ -107,17 +113,19 @@ def test_update_pet(client: TestClient):
Update an existing pet
"""
pet = {"photo_urls":["photoUrls","photoUrls"],"name":"doggie","id":0,"category":{"name":"name","id":6},"tags":[{"name":"name","id":1},{"name":"name","id":1}],"status":"available"}
headers = {
'Authorization': 'Bearer special-key',
headers = {
"Authorization": "Bearer special-key",
}
response = client.request(
'PUT',
'/pet',
"PUT",
"/pet",
headers=headers,
json=pet,
)
assert response.status_code == 200
# uncomment below to assert the status code of the HTTP response
#assert response.status_code == 200
def test_update_pet_with_form(client: TestClient):
@ -125,21 +133,23 @@ def test_update_pet_with_form(client: TestClient):
Updates a pet in the store with form data
"""
headers = {
'Authorization': 'Bearer special-key',
headers = {
"Authorization": "Bearer special-key",
}
data = {
'name': 'name_example',
'status': 'status_example'
"name": 'name_example',
"status": 'status_example'
}
response = client.request(
'POST',
'/pet/{petId}'.format(petId=56),
"POST",
"/pet/{petId}".format(petId=56),
headers=headers,
data=data,
)
assert response.status_code == 200
# uncomment below to assert the status code of the HTTP response
#assert response.status_code == 200
def test_upload_file(client: TestClient):
@ -147,19 +157,21 @@ def test_upload_file(client: TestClient):
uploads an image
"""
headers = {
'Authorization': 'Bearer special-key',
headers = {
"Authorization": "Bearer special-key",
}
data = {
'additional_metadata': 'additional_metadata_example',
'file': '/path/to/file'
"additional_metadata": 'additional_metadata_example',
"file": '/path/to/file'
}
response = client.request(
'POST',
'/pet/{petId}/uploadImage'.format(petId=56),
"POST",
"/pet/{petId}/uploadImage".format(petId=56),
headers=headers,
data=data,
)
assert response.status_code == 200
# uncomment below to assert the status code of the HTTP response
#assert response.status_code == 200

View File

@ -2,10 +2,8 @@
from fastapi.testclient import TestClient
import json
import pytest
from openapi_server.models.order import Order
from openapi_server.models.order import Order # noqa: F401
def test_delete_order(client: TestClient):
@ -13,15 +11,17 @@ def test_delete_order(client: TestClient):
Delete purchase order by ID
"""
headers = {
headers = {
}
response = client.request(
'DELETE',
'/store/order/{orderId}'.format(orderId='order_id_example'),
"DELETE",
"/store/order/{orderId}".format(orderId='order_id_example'),
headers=headers,
)
assert response.status_code == 200
# uncomment below to assert the status code of the HTTP response
#assert response.status_code == 200
def test_get_inventory(client: TestClient):
@ -29,16 +29,18 @@ def test_get_inventory(client: TestClient):
Returns pet inventories by status
"""
headers = {
'api_key': 'special-key',
headers = {
"api_key": "special-key",
}
response = client.request(
'GET',
'/store/inventory',
"GET",
"/store/inventory",
headers=headers,
)
assert response.status_code == 200
# uncomment below to assert the status code of the HTTP response
#assert response.status_code == 200
def test_get_order_by_id(client: TestClient):
@ -46,15 +48,17 @@ def test_get_order_by_id(client: TestClient):
Find purchase order by ID
"""
headers = {
headers = {
}
response = client.request(
'GET',
'/store/order/{orderId}'.format(orderId=56),
"GET",
"/store/order/{orderId}".format(orderId=56),
headers=headers,
)
assert response.status_code == 200
# uncomment below to assert the status code of the HTTP response
#assert response.status_code == 200
def test_place_order(client: TestClient):
@ -63,14 +67,16 @@ def test_place_order(client: TestClient):
Place an order for a pet
"""
order = {"pet_id":6,"quantity":1,"id":0,"ship_date":"2000-01-23T04:56:07.000+00:00","complete":0,"status":"placed"}
headers = {
headers = {
}
response = client.request(
'POST',
'/store/order',
"POST",
"/store/order",
headers=headers,
json=order,
)
assert response.status_code == 200
# uncomment below to assert the status code of the HTTP response
#assert response.status_code == 200

View File

@ -2,10 +2,8 @@
from fastapi.testclient import TestClient
import json
import pytest
from openapi_server.models.user import User
from openapi_server.models.user import User # noqa: F401
def test_create_user(client: TestClient):
@ -14,17 +12,19 @@ def test_create_user(client: TestClient):
Create user
"""
user = {"first_name":"firstName","last_name":"lastName","password":"password","user_status":6,"phone":"phone","id":0,"email":"email","username":"username"}
headers = {
'api_key': 'special-key',
headers = {
"api_key": "special-key",
}
response = client.request(
'POST',
'/user',
"POST",
"/user",
headers=headers,
json=user,
)
assert response.status_code == 200
# uncomment below to assert the status code of the HTTP response
#assert response.status_code == 200
def test_create_users_with_array_input(client: TestClient):
@ -33,17 +33,19 @@ def test_create_users_with_array_input(client: TestClient):
Creates list of users with given input array
"""
user = [{"first_name":"firstName","last_name":"lastName","password":"password","user_status":6,"phone":"phone","id":0,"email":"email","username":"username"}]
headers = {
'api_key': 'special-key',
headers = {
"api_key": "special-key",
}
response = client.request(
'POST',
'/user/createWithArray',
"POST",
"/user/createWithArray",
headers=headers,
json=user,
)
assert response.status_code == 200
# uncomment below to assert the status code of the HTTP response
#assert response.status_code == 200
def test_create_users_with_list_input(client: TestClient):
@ -52,17 +54,19 @@ def test_create_users_with_list_input(client: TestClient):
Creates list of users with given input array
"""
user = [{"first_name":"firstName","last_name":"lastName","password":"password","user_status":6,"phone":"phone","id":0,"email":"email","username":"username"}]
headers = {
'api_key': 'special-key',
headers = {
"api_key": "special-key",
}
response = client.request(
'POST',
'/user/createWithList',
"POST",
"/user/createWithList",
headers=headers,
json=user,
)
assert response.status_code == 200
# uncomment below to assert the status code of the HTTP response
#assert response.status_code == 200
def test_delete_user(client: TestClient):
@ -70,16 +74,18 @@ def test_delete_user(client: TestClient):
Delete user
"""
headers = {
'api_key': 'special-key',
headers = {
"api_key": "special-key",
}
response = client.request(
'DELETE',
'/user/{username}'.format(username='username_example'),
"DELETE",
"/user/{username}".format(username='username_example'),
headers=headers,
)
assert response.status_code == 200
# uncomment below to assert the status code of the HTTP response
#assert response.status_code == 200
def test_get_user_by_name(client: TestClient):
@ -87,15 +93,17 @@ def test_get_user_by_name(client: TestClient):
Get user by user name
"""
headers = {
headers = {
}
response = client.request(
'GET',
'/user/{username}'.format(username='username_example'),
"GET",
"/user/{username}".format(username='username_example'),
headers=headers,
)
assert response.status_code == 200
# uncomment below to assert the status code of the HTTP response
#assert response.status_code == 200
def test_login_user(client: TestClient):
@ -103,18 +111,18 @@ def test_login_user(client: TestClient):
Logs user into the system
"""
params = [("username", 'username_example'),
("password", 'password_example')]
headers = {
params = [("username", 'username_example'), ("password", 'password_example')]
headers = {
}
response = client.request(
'GET',
'/user/login',
"GET",
"/user/login",
headers=headers,
params=params,
)
assert response.status_code == 200
# uncomment below to assert the status code of the HTTP response
#assert response.status_code == 200
def test_logout_user(client: TestClient):
@ -122,16 +130,18 @@ def test_logout_user(client: TestClient):
Logs out current logged in user session
"""
headers = {
'api_key': 'special-key',
headers = {
"api_key": "special-key",
}
response = client.request(
'GET',
'/user/logout',
"GET",
"/user/logout",
headers=headers,
)
assert response.status_code == 200
# uncomment below to assert the status code of the HTTP response
#assert response.status_code == 200
def test_update_user(client: TestClient):
@ -140,15 +150,17 @@ def test_update_user(client: TestClient):
Updated user
"""
user = {"first_name":"firstName","last_name":"lastName","password":"password","user_status":6,"phone":"phone","id":0,"email":"email","username":"username"}
headers = {
'api_key': 'special-key',
headers = {
"api_key": "special-key",
}
response = client.request(
'PUT',
'/user/{username}'.format(username='username_example'),
"PUT",
"/user/{username}".format(username='username_example'),
headers=headers,
json=user,
)
assert response.status_code == 200
# uncomment below to assert the status code of the HTTP response
#assert response.status_code == 200