]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
:building_construction: Fix same function names in different modules with composite...
authorSebastián Ramírez <tiangolo@gmail.com>
Fri, 28 Jun 2019 17:35:16 +0000 (19:35 +0200)
committerGitHub <noreply@github.com>
Fri, 28 Jun 2019 17:35:16 +0000 (19:35 +0200)
* :building_construction: Implement unique IDs for dynamic models

like those used for composite bodies and responses. IDs based on path (not only on function name, as it can be duplicated in a different module).

* :white_check_mark: Add tests for same function name and composite body

* :white_check_mark: Update OpenAPI in tests with new dynamic model ID generation

25 files changed:
fastapi/openapi/utils.py
fastapi/routing.py
fastapi/utils.py
tests/test_modules_same_name_body/__init__.py [new file with mode: 0644]
tests/test_modules_same_name_body/app/__init__.py [new file with mode: 0644]
tests/test_modules_same_name_body/app/a.py [new file with mode: 0644]
tests/test_modules_same_name_body/app/b.py [new file with mode: 0644]
tests/test_modules_same_name_body/app/main.py [new file with mode: 0644]
tests/test_modules_same_name_body/test_main.py [new file with mode: 0644]
tests/test_security_oauth2.py
tests/test_security_oauth2_optional.py
tests/test_tutorial/test_async_sql_databases/test_tutorial001.py
tests/test_tutorial/test_body_multiple_params/test_tutorial003.py
tests/test_tutorial/test_body_schema/test_tutorial001.py
tests/test_tutorial/test_extra_data_types/test_tutorial001.py
tests/test_tutorial/test_extra_models/test_tutorial003.py
tests/test_tutorial/test_extra_models/test_tutorial004.py
tests/test_tutorial/test_extra_models/test_tutorial005.py
tests/test_tutorial/test_request_files/test_tutorial001.py
tests/test_tutorial/test_request_files/test_tutorial002.py
tests/test_tutorial/test_request_forms/test_tutorial001.py
tests/test_tutorial/test_request_forms_and_files/test_tutorial001.py
tests/test_tutorial/test_security/test_tutorial003.py
tests/test_tutorial/test_security/test_tutorial005.py
tests/test_tutorial/test_sql_databases/test_sql_databases.py

index 8d02a47512d2328dd990ca8045c98cd7ea6d521a..7786e2527a81a8d21af5ab9f3a1607657b98ee3b 100644 (file)
@@ -8,7 +8,11 @@ from fastapi.encoders import jsonable_encoder
 from fastapi.openapi.constants import METHODS_WITH_BODY, REF_PREFIX
 from fastapi.openapi.models import OpenAPI
 from fastapi.params import Body, Param
-from fastapi.utils import get_flat_models_from_routes, get_model_definitions
+from fastapi.utils import (
+    generate_operation_id_for_path,
+    get_flat_models_from_routes,
+    get_model_definitions,
+)
 from pydantic.fields import Field
 from pydantic.schema import field_schema, get_model_name_map
 from pydantic.utils import lenient_issubclass
@@ -113,10 +117,7 @@ def generate_operation_id(*, route: routing.APIRoute, method: str) -> str:
     if route.operation_id:
         return route.operation_id
     path: str = route.path_format
-    operation_id = route.name + path
-    operation_id = operation_id.replace("{", "_").replace("}", "_").replace("/", "_")
-    operation_id = operation_id + "_" + method.lower()
-    return operation_id
+    return generate_operation_id_for_path(name=route.name, path=path, method=method)
 
 
 def generate_operation_summary(*, route: routing.APIRoute, method: str) -> str:
index e349787d71ed90fccf6fac759e08c70130597df2..8eb6f47fa578e40729ebbb60d8b3bbd2f06816bc 100644 (file)
@@ -13,7 +13,7 @@ from fastapi.dependencies.utils import (
 )
 from fastapi.encoders import jsonable_encoder
 from fastapi.exceptions import RequestValidationError, WebSocketRequestValidationError
-from fastapi.utils import create_cloned_field
+from fastapi.utils import create_cloned_field, generate_operation_id_for_path
 from pydantic import BaseConfig, BaseModel, Schema
 from pydantic.error_wrappers import ErrorWrapper, ValidationError
 from pydantic.fields import Field
@@ -205,12 +205,19 @@ class APIRoute(routing.Route):
         self.path = path
         self.endpoint = endpoint
         self.name = get_name(endpoint) if name is None else name
+        self.path_regex, self.path_format, self.param_convertors = compile_path(path)
+        if methods is None:
+            methods = ["GET"]
+        self.methods = set([method.upper() for method in methods])
+        self.unique_id = generate_operation_id_for_path(
+            name=self.name, path=self.path_format, method=list(methods)[0]
+        )
         self.response_model = response_model
         if self.response_model:
             assert lenient_issubclass(
                 response_class, JSONResponse
             ), "To declare a type the response must be a JSON response"
-            response_name = "Response_" + self.name
+            response_name = "Response_" + self.unique_id
             self.response_field: Optional[Field] = Field(
                 name=response_name,
                 type_=self.response_model,
@@ -251,7 +258,7 @@ class APIRoute(routing.Route):
                 assert lenient_issubclass(
                     model, BaseModel
                 ), "A response model must be a Pydantic model"
-                response_name = f"Response_{additional_status_code}_{self.name}"
+                response_name = f"Response_{additional_status_code}_{self.unique_id}"
                 response_field = Field(
                     name=response_name,
                     type_=model,
@@ -267,9 +274,6 @@ class APIRoute(routing.Route):
         else:
             self.response_fields = {}
         self.deprecated = deprecated
-        if methods is None:
-            methods = ["GET"]
-        self.methods = set([method.upper() for method in methods])
         self.operation_id = operation_id
         self.response_model_include = response_model_include
         self.response_model_exclude = response_model_exclude
@@ -278,7 +282,6 @@ class APIRoute(routing.Route):
         self.include_in_schema = include_in_schema
         self.response_class = response_class
 
-        self.path_regex, self.path_format, self.param_convertors = compile_path(path)
         assert inspect.isfunction(endpoint) or inspect.ismethod(
             endpoint
         ), f"An endpoint must be a function or method"
@@ -288,7 +291,7 @@ class APIRoute(routing.Route):
                 0,
                 get_parameterless_sub_dependant(depends=depends, path=self.path_format),
             )
-        self.body_field = get_body_field(dependant=self.dependant, name=self.name)
+        self.body_field = get_body_field(dependant=self.dependant, name=self.unique_id)
         self.dependency_overrides_provider = dependency_overrides_provider
         self.app = request_response(
             get_app(
index 21bca1d3f30d81fd5853496112d3df0075909ef1..fc3bc72893a4bd3e8ddc3100554e8928e1c0fc06 100644 (file)
@@ -93,3 +93,10 @@ def create_cloned_field(field: Field) -> Field:
     new_field.shape = field.shape
     new_field._populate_validators()
     return new_field
+
+
+def generate_operation_id_for_path(*, name: str, path: str, method: str) -> str:
+    operation_id = name + path
+    operation_id = operation_id.replace("{", "_").replace("}", "_").replace("/", "_")
+    operation_id = operation_id + "_" + method.lower()
+    return operation_id
diff --git a/tests/test_modules_same_name_body/__init__.py b/tests/test_modules_same_name_body/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/test_modules_same_name_body/app/__init__.py b/tests/test_modules_same_name_body/app/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/test_modules_same_name_body/app/a.py b/tests/test_modules_same_name_body/app/a.py
new file mode 100644 (file)
index 0000000..3c86c18
--- /dev/null
@@ -0,0 +1,8 @@
+from fastapi import APIRouter, Body
+
+router = APIRouter()
+
+
+@router.post("/compute")
+def compute(a: int = Body(...), b: str = Body(...)):
+    return {"a": a, "b": b}
diff --git a/tests/test_modules_same_name_body/app/b.py b/tests/test_modules_same_name_body/app/b.py
new file mode 100644 (file)
index 0000000..f7c7fdf
--- /dev/null
@@ -0,0 +1,8 @@
+from fastapi import APIRouter, Body
+
+router = APIRouter()
+
+
+@router.post("/compute/")
+def compute(a: int = Body(...), b: str = Body(...)):
+    return {"a": a, "b": b}
diff --git a/tests/test_modules_same_name_body/app/main.py b/tests/test_modules_same_name_body/app/main.py
new file mode 100644 (file)
index 0000000..3923608
--- /dev/null
@@ -0,0 +1,8 @@
+from fastapi import FastAPI
+
+from . import a, b
+
+app = FastAPI()
+
+app.include_router(a.router, prefix="/a")
+app.include_router(b.router, prefix="/b")
diff --git a/tests/test_modules_same_name_body/test_main.py b/tests/test_modules_same_name_body/test_main.py
new file mode 100644 (file)
index 0000000..bf50b75
--- /dev/null
@@ -0,0 +1,155 @@
+from starlette.testclient import TestClient
+
+from .app.main import app
+
+client = TestClient(app)
+
+openapi_schema = {
+    "openapi": "3.0.2",
+    "info": {"title": "Fast API", "version": "0.1.0"},
+    "paths": {
+        "/a/compute": {
+            "post": {
+                "responses": {
+                    "200": {
+                        "description": "Successful Response",
+                        "content": {"application/json": {"schema": {}}},
+                    },
+                    "422": {
+                        "description": "Validation Error",
+                        "content": {
+                            "application/json": {
+                                "schema": {
+                                    "$ref": "#/components/schemas/HTTPValidationError"
+                                }
+                            }
+                        },
+                    },
+                },
+                "summary": "Compute",
+                "operationId": "compute_a_compute_post",
+                "requestBody": {
+                    "content": {
+                        "application/json": {
+                            "schema": {
+                                "$ref": "#/components/schemas/Body_compute_a_compute_post"
+                            }
+                        }
+                    },
+                    "required": True,
+                },
+            }
+        },
+        "/b/compute/": {
+            "post": {
+                "responses": {
+                    "200": {
+                        "description": "Successful Response",
+                        "content": {"application/json": {"schema": {}}},
+                    },
+                    "422": {
+                        "description": "Validation Error",
+                        "content": {
+                            "application/json": {
+                                "schema": {
+                                    "$ref": "#/components/schemas/HTTPValidationError"
+                                }
+                            }
+                        },
+                    },
+                },
+                "summary": "Compute",
+                "operationId": "compute_b_compute__post",
+                "requestBody": {
+                    "content": {
+                        "application/json": {
+                            "schema": {
+                                "$ref": "#/components/schemas/Body_compute_b_compute__post"
+                            }
+                        }
+                    },
+                    "required": True,
+                },
+            }
+        },
+    },
+    "components": {
+        "schemas": {
+            "Body_compute_b_compute__post": {
+                "title": "Body_compute_b_compute__post",
+                "required": ["a", "b"],
+                "type": "object",
+                "properties": {
+                    "a": {"title": "A", "type": "integer"},
+                    "b": {"title": "B", "type": "string"},
+                },
+            },
+            "Body_compute_a_compute_post": {
+                "title": "Body_compute_a_compute_post",
+                "required": ["a", "b"],
+                "type": "object",
+                "properties": {
+                    "a": {"title": "A", "type": "integer"},
+                    "b": {"title": "B", "type": "string"},
+                },
+            },
+            "ValidationError": {
+                "title": "ValidationError",
+                "required": ["loc", "msg", "type"],
+                "type": "object",
+                "properties": {
+                    "loc": {
+                        "title": "Location",
+                        "type": "array",
+                        "items": {"type": "string"},
+                    },
+                    "msg": {"title": "Message", "type": "string"},
+                    "type": {"title": "Error Type", "type": "string"},
+                },
+            },
+            "HTTPValidationError": {
+                "title": "HTTPValidationError",
+                "type": "object",
+                "properties": {
+                    "detail": {
+                        "title": "Detail",
+                        "type": "array",
+                        "items": {"$ref": "#/components/schemas/ValidationError"},
+                    }
+                },
+            },
+        }
+    },
+}
+
+
+def test_openapi_schema():
+    response = client.get("/openapi.json")
+    assert response.status_code == 200
+    assert response.json() == openapi_schema
+
+
+def test_post_a():
+    data = {"a": 2, "b": "foo"}
+    response = client.post("/a/compute", json=data)
+    assert response.status_code == 200
+    data = response.json()
+
+
+def test_post_a_invalid():
+    data = {"a": "bar", "b": "foo"}
+    response = client.post("/a/compute", json=data)
+    assert response.status_code == 422
+
+
+def test_post_b():
+    data = {"a": 2, "b": "foo"}
+    response = client.post("/b/compute/", json=data)
+    assert response.status_code == 200
+    data = response.json()
+
+
+def test_post_b_invalid():
+    data = {"a": "bar", "b": "foo"}
+    response = client.post("/b/compute/", json=data)
+    assert response.status_code == 422
index 08f610f937c8cd98b15da3319b60f1a392ee66a9..890613b2909341815fd830043d2d9ce73ad2a9fe 100644 (file)
@@ -66,7 +66,7 @@ openapi_schema = {
                     "content": {
                         "application/x-www-form-urlencoded": {
                             "schema": {
-                                "$ref": "#/components/schemas/Body_read_current_user"
+                                "$ref": "#/components/schemas/Body_read_current_user_login_post"
                             }
                         }
                     },
@@ -90,8 +90,8 @@ openapi_schema = {
     },
     "components": {
         "schemas": {
-            "Body_read_current_user": {
-                "title": "Body_read_current_user",
+            "Body_read_current_user_login_post": {
+                "title": "Body_read_current_user_login_post",
                 "required": ["grant_type", "username", "password"],
                 "type": "object",
                 "properties": {
index e585e29274192959d9b02dcd9e135f5e6fcd4a3e..f85db00d34519a850461fbba91a3cbecc15b5279 100644 (file)
@@ -73,7 +73,7 @@ openapi_schema = {
                     "content": {
                         "application/x-www-form-urlencoded": {
                             "schema": {
-                                "$ref": "#/components/schemas/Body_read_current_user"
+                                "$ref": "#/components/schemas/Body_read_current_user_login_post"
                             }
                         }
                     },
@@ -97,8 +97,8 @@ openapi_schema = {
     },
     "components": {
         "schemas": {
-            "Body_read_current_user": {
-                "title": "Body_read_current_user",
+            "Body_read_current_user_login_post": {
+                "title": "Body_read_current_user_login_post",
                 "required": ["grant_type", "username", "password"],
                 "type": "object",
                 "properties": {
index d7ceb6642146c5a8b66f97e981ba6f09cfd86a7f..be5f56dbd5daa076f79130d9075c813991004463 100644 (file)
@@ -14,7 +14,7 @@ openapi_schema = {
                         "content": {
                             "application/json": {
                                 "schema": {
-                                    "title": "Response_Read_Notes",
+                                    "title": "Response_Read_Notes_Notes__Get",
                                     "type": "array",
                                     "items": {"$ref": "#/components/schemas/Note"},
                                 }
index 9a1c56bc204b47ab70865880d97ea643732c97bb..dc7e518e249a15d178df05858d4a3d69d498b123 100644 (file)
@@ -40,7 +40,9 @@ openapi_schema = {
                 "requestBody": {
                     "content": {
                         "application/json": {
-                            "schema": {"$ref": "#/components/schemas/Body_update_item"}
+                            "schema": {
+                                "$ref": "#/components/schemas/Body_update_item_items__item_id__put"
+                            }
                         }
                     },
                     "required": True,
@@ -70,8 +72,8 @@ openapi_schema = {
                     "full_name": {"title": "Full_Name", "type": "string"},
                 },
             },
-            "Body_update_item": {
-                "title": "Body_update_item",
+            "Body_update_item_items__item_id__put": {
+                "title": "Body_update_item_items__item_id__put",
                 "required": ["item", "user", "importance"],
                 "type": "object",
                 "properties": {
index c213fab1ca3f606adf40455ae3b9e7d0c6cfa5fa..eb938839684f44d638eff498ba283e60aa0c9c61 100644 (file)
@@ -41,7 +41,9 @@ openapi_schema = {
                 "requestBody": {
                     "content": {
                         "application/json": {
-                            "schema": {"$ref": "#/components/schemas/Body_update_item"}
+                            "schema": {
+                                "$ref": "#/components/schemas/Body_update_item_items__item_id__put"
+                            }
                         }
                     },
                     "required": True,
@@ -71,8 +73,8 @@ openapi_schema = {
                     "tax": {"title": "Tax", "type": "number"},
                 },
             },
-            "Body_update_item": {
-                "title": "Body_update_item",
+            "Body_update_item_items__item_id__put": {
+                "title": "Body_update_item_items__item_id__put",
                 "required": ["item"],
                 "type": "object",
                 "properties": {"item": {"$ref": "#/components/schemas/Item"}},
index 921b24aadc41abe371e8a130b9136439f8f767d4..6c53b7adcf3df2bfac9a09e71298bcbe319b075f 100644 (file)
@@ -44,7 +44,9 @@ openapi_schema = {
                 "requestBody": {
                     "content": {
                         "application/json": {
-                            "schema": {"$ref": "#/components/schemas/Body_read_items"}
+                            "schema": {
+                                "$ref": "#/components/schemas/Body_read_items_items__item_id__put"
+                            }
                         }
                     }
                 },
@@ -53,8 +55,8 @@ openapi_schema = {
     },
     "components": {
         "schemas": {
-            "Body_read_items": {
-                "title": "Body_read_items",
+            "Body_read_items_items__item_id__put": {
+                "title": "Body_read_items_items__item_id__put",
                 "type": "object",
                 "properties": {
                     "start_datetime": {
index 9a1c8a146c043007a552ff311e185314529f348b..95aef55cb7fbebe1634c94401174bc0fb8d384ac 100644 (file)
@@ -16,7 +16,7 @@ openapi_schema = {
                         "content": {
                             "application/json": {
                                 "schema": {
-                                    "title": "Response_Read_Item",
+                                    "title": "Response_Read_Item_Items__Item_Id__Get",
                                     "anyOf": [
                                         {"$ref": "#/components/schemas/PlaneItem"},
                                         {"$ref": "#/components/schemas/CarItem"},
index 82a609e01e997773c2ec190b2ad4ec7b7c4c2c42..17ea0e1be3ac8e41241c8989fb1930da380914c7 100644 (file)
@@ -16,7 +16,7 @@ openapi_schema = {
                         "content": {
                             "application/json": {
                                 "schema": {
-                                    "title": "Response_Read_Items",
+                                    "title": "Response_Read_Items_Items__Get",
                                     "type": "array",
                                     "items": {"$ref": "#/components/schemas/Item"},
                                 }
index efb319bd2aef031fc05a426b99ca5fd75b49ed08..d8259f1cdcdd0da531f71a4943e1848a698c094b 100644 (file)
@@ -16,7 +16,7 @@ openapi_schema = {
                         "content": {
                             "application/json": {
                                 "schema": {
-                                    "title": "Response_Read_Keyword_Weights",
+                                    "title": "Response_Read_Keyword_Weights_Keyword-Weights__Get",
                                     "type": "object",
                                     "additionalProperties": {"type": "number"},
                                 }
index 726691662e09bc2bd352940ee3e8fa39a46836dd..b5f64af959da6cad9587f114c942b4c623a5ecda 100644 (file)
@@ -33,7 +33,9 @@ openapi_schema = {
                 "requestBody": {
                     "content": {
                         "multipart/form-data": {
-                            "schema": {"$ref": "#/components/schemas/Body_create_file"}
+                            "schema": {
+                                "$ref": "#/components/schemas/Body_create_file_files__post"
+                            }
                         }
                     },
                     "required": True,
@@ -64,7 +66,7 @@ openapi_schema = {
                     "content": {
                         "multipart/form-data": {
                             "schema": {
-                                "$ref": "#/components/schemas/Body_create_upload_file"
+                                "$ref": "#/components/schemas/Body_create_upload_file_uploadfile__post"
                             }
                         }
                     },
@@ -75,16 +77,16 @@ openapi_schema = {
     },
     "components": {
         "schemas": {
-            "Body_create_file": {
-                "title": "Body_create_file",
+            "Body_create_upload_file_uploadfile__post": {
+                "title": "Body_create_upload_file_uploadfile__post",
                 "required": ["file"],
                 "type": "object",
                 "properties": {
                     "file": {"title": "File", "type": "string", "format": "binary"}
                 },
             },
-            "Body_create_upload_file": {
-                "title": "Body_create_upload_file",
+            "Body_create_file_files__post": {
+                "title": "Body_create_file_files__post",
                 "required": ["file"],
                 "type": "object",
                 "properties": {
index 15ea952ba93ead6f87656c3f071159e286db2f25..092b9901c7d1cdfb2c2088159c1e6cbf9268c082 100644 (file)
@@ -33,7 +33,9 @@ openapi_schema = {
                 "requestBody": {
                     "content": {
                         "multipart/form-data": {
-                            "schema": {"$ref": "#/components/schemas/Body_create_files"}
+                            "schema": {
+                                "$ref": "#/components/schemas/Body_create_files_files__post"
+                            }
                         }
                     },
                     "required": True,
@@ -64,7 +66,7 @@ openapi_schema = {
                     "content": {
                         "multipart/form-data": {
                             "schema": {
-                                "$ref": "#/components/schemas/Body_create_upload_files"
+                                "$ref": "#/components/schemas/Body_create_upload_files_uploadfiles__post"
                             }
                         }
                     },
@@ -87,8 +89,8 @@ openapi_schema = {
     },
     "components": {
         "schemas": {
-            "Body_create_files": {
-                "title": "Body_create_files",
+            "Body_create_upload_files_uploadfiles__post": {
+                "title": "Body_create_upload_files_uploadfiles__post",
                 "required": ["files"],
                 "type": "object",
                 "properties": {
@@ -99,8 +101,8 @@ openapi_schema = {
                     }
                 },
             },
-            "Body_create_upload_files": {
-                "title": "Body_create_upload_files",
+            "Body_create_files_files__post": {
+                "title": "Body_create_files_files__post",
                 "required": ["files"],
                 "type": "object",
                 "properties": {
index fe85628acdd2928716d6e9ab3dec1e0df504ca76..46c92676703ca9271eee9d303a93cac0c7375e9d 100644 (file)
@@ -32,7 +32,9 @@ openapi_schema = {
                 "requestBody": {
                     "content": {
                         "application/x-www-form-urlencoded": {
-                            "schema": {"$ref": "#/components/schemas/Body_login"}
+                            "schema": {
+                                "$ref": "#/components/schemas/Body_login_login__post"
+                            }
                         }
                     },
                     "required": True,
@@ -42,8 +44,8 @@ openapi_schema = {
     },
     "components": {
         "schemas": {
-            "Body_login": {
-                "title": "Body_login",
+            "Body_login_login__post": {
+                "title": "Body_login_login__post",
                 "required": ["username", "password"],
                 "type": "object",
                 "properties": {
index eea94593764cccb074918d40c00a9306151a4e86..a30fbf60fc9ce1997ab007348f77dfcd3db14b27 100644 (file)
@@ -34,7 +34,9 @@ openapi_schema = {
                 "requestBody": {
                     "content": {
                         "multipart/form-data": {
-                            "schema": {"$ref": "#/components/schemas/Body_create_file"}
+                            "schema": {
+                                "$ref": "#/components/schemas/Body_create_file_files__post"
+                            }
                         }
                     },
                     "required": True,
@@ -44,8 +46,8 @@ openapi_schema = {
     },
     "components": {
         "schemas": {
-            "Body_create_file": {
-                "title": "Body_create_file",
+            "Body_create_file_files__post": {
+                "title": "Body_create_file_files__post",
                 "required": ["file", "fileb", "token"],
                 "type": "object",
                 "properties": {
index c55e7b7a6bbbc9c4d1c3d8bde93e5b488772c5c9..ebd8731aba5750efdc777020a0bbb80832099235 100644 (file)
@@ -31,7 +31,9 @@ openapi_schema = {
                 "requestBody": {
                     "content": {
                         "application/x-www-form-urlencoded": {
-                            "schema": {"$ref": "#/components/schemas/Body_login"}
+                            "schema": {
+                                "$ref": "#/components/schemas/Body_login_token_post"
+                            }
                         }
                     },
                     "required": True,
@@ -54,8 +56,8 @@ openapi_schema = {
     },
     "components": {
         "schemas": {
-            "Body_login": {
-                "title": "Body_login",
+            "Body_login_token_post": {
+                "title": "Body_login_token_post",
                 "required": ["username", "password"],
                 "type": "object",
                 "properties": {
index 403130e49143d9ee47f019d08abb3d6cb269937e..786fbc3ac577df11f16794c62eb88b905e7e69e1 100644 (file)
@@ -42,7 +42,7 @@ openapi_schema = {
                     "content": {
                         "application/x-www-form-urlencoded": {
                             "schema": {
-                                "$ref": "#/components/schemas/Body_login_for_access_token"
+                                "$ref": "#/components/schemas/Body_login_for_access_token_token_post"
                             }
                         }
                     },
@@ -116,8 +116,8 @@ openapi_schema = {
                     "token_type": {"title": "Token_Type", "type": "string"},
                 },
             },
-            "Body_login_for_access_token": {
-                "title": "Body_login_for_access_token",
+            "Body_login_for_access_token_token_post": {
+                "title": "Body_login_for_access_token_token_post",
                 "required": ["username", "password"],
                 "type": "object",
                 "properties": {
@@ -177,6 +177,12 @@ openapi_schema = {
 }
 
 
+def test_openapi_schema():
+    response = client.get("/openapi.json")
+    assert response.status_code == 200
+    assert response.json() == openapi_schema
+
+
 def get_access_token(username="johndoe", password="secret", scope=None):
     data = {"username": username, "password": password}
     if scope:
@@ -187,12 +193,6 @@ def get_access_token(username="johndoe", password="secret", scope=None):
     return access_token
 
 
-def test_openapi_schema():
-    response = client.get("/openapi.json")
-    assert response.status_code == 200
-    assert response.json() == openapi_schema
-
-
 def test_login():
     response = client.post("/token", data={"username": "johndoe", "password": "secret"})
     assert response.status_code == 200
index 9e1dcc2bb406fe0b31cda73573d000602afa1631..8f46a94376fc4932c9f8ed5191a592ae88945b86 100644 (file)
@@ -16,7 +16,7 @@ openapi_schema = {
                         "content": {
                             "application/json": {
                                 "schema": {
-                                    "title": "Response_Read_Users",
+                                    "title": "Response_Read_Users_Users__Get",
                                     "type": "array",
                                     "items": {"$ref": "#/components/schemas/User"},
                                 }
@@ -168,7 +168,7 @@ openapi_schema = {
                         "content": {
                             "application/json": {
                                 "schema": {
-                                    "title": "Response_Read_Items",
+                                    "title": "Response_Read_Items_Items__Get",
                                     "type": "array",
                                     "items": {"$ref": "#/components/schemas/Item"},
                                 }