diff --git a/modules/openapi-generator/src/main/resources/python-fastapi/endpoint_argument_definition.mustache b/modules/openapi-generator/src/main/resources/python-fastapi/endpoint_argument_definition.mustache
index e1a76b210fd7..e398eca12c82 100644
--- a/modules/openapi-generator/src/main/resources/python-fastapi/endpoint_argument_definition.mustache
+++ b/modules/openapi-generator/src/main/resources/python-fastapi/endpoint_argument_definition.mustache
@@ -1 +1 @@
-{{#isPathParam}}{{baseName}}{{/isPathParam}}{{^isPathParam}}{{paramName}}{{/isPathParam}}: {{>param_type}} = {{#isPathParam}}Path{{/isPathParam}}{{#isHeaderParam}}Header{{/isHeaderParam}}{{#isFormParam}}{{#isFile}}File{{/isFile}}{{^isFile}}Form{{/isFile}}{{/isFormParam}}{{#isQueryParam}}Query{{/isQueryParam}}{{#isCookieParam}}Cookie{{/isCookieParam}}{{#isBodyParam}}Body{{/isBodyParam}}({{&defaultValue}}{{^defaultValue}}{{#isPathParam}}...{{/isPathParam}}{{^isPathParam}}{{#isFile}}{{#required}}...{{/required}}{{^required}}None{{/required}}{{/isFile}}{{^isFile}}None{{/isFile}}{{/isPathParam}}{{/defaultValue}}, description="{{description}}"{{#isQueryParam}}, alias="{{baseName}}"{{/isQueryParam}}{{#isFormParam}}, alias="{{baseName}}"{{/isFormParam}}{{#isLong}}{{#minimum}}, ge={{.}}{{/minimum}}{{#maximum}}, le={{.}}{{/maximum}}{{/isLong}}{{#isInteger}}{{#minimum}}, ge={{.}}{{/minimum}}{{#maximum}}, le={{.}}{{/maximum}}{{/isInteger}}{{#vendorExtensions.x-regex}}, regex=r"{{.}}"{{/vendorExtensions.x-regex}}{{#minLength}}, min_length={{.}}{{/minLength}}{{#maxLength}}, max_length={{.}}{{/maxLength}}{{^isBodyParam}}{{#vendorExtensions.x-py-example}}, examples=[{{{.}}}]{{/vendorExtensions.x-py-example}}{{/isBodyParam}}{{#isBodyParam}}{{#vendorExtensions.x-py-fastapi-example}}, examples=[{{{.}}}]{{/vendorExtensions.x-py-fastapi-example}}{{/isBodyParam}})
\ No newline at end of file
+{{#isPathParam}}{{baseName}}{{/isPathParam}}{{^isPathParam}}{{paramName}}{{/isPathParam}}: {{>param_type}} = {{#isPathParam}}Path{{/isPathParam}}{{#isHeaderParam}}Header{{/isHeaderParam}}{{#isFormParam}}{{#isFile}}File{{/isFile}}{{^isFile}}Form{{/isFile}}{{/isFormParam}}{{#isQueryParam}}Query{{/isQueryParam}}{{#isCookieParam}}Cookie{{/isCookieParam}}{{#isBodyParam}}Body{{/isBodyParam}}({{&defaultValue}}{{^defaultValue}}{{#required}}...{{/required}}{{^required}}None{{/required}}{{/defaultValue}}, description="{{description}}"{{#isQueryParam}}, alias="{{baseName}}"{{/isQueryParam}}{{#isFormParam}}, alias="{{baseName}}"{{/isFormParam}}{{#isLong}}{{#minimum}}, ge={{.}}{{/minimum}}{{#maximum}}, le={{.}}{{/maximum}}{{/isLong}}{{#isInteger}}{{#minimum}}, ge={{.}}{{/minimum}}{{#maximum}}, le={{.}}{{/maximum}}{{/isInteger}}{{#vendorExtensions.x-regex}}, regex=r"{{.}}"{{/vendorExtensions.x-regex}}{{#minLength}}, min_length={{.}}{{/minLength}}{{#maxLength}}, max_length={{.}}{{/maxLength}}{{^isBodyParam}}{{#vendorExtensions.x-py-example}}, examples=[{{{.}}}]{{/vendorExtensions.x-py-example}}{{/isBodyParam}}{{#isBodyParam}}{{#vendorExtensions.x-py-fastapi-example}}, examples=[{{{.}}}]{{/vendorExtensions.x-py-fastapi-example}}{{/isBodyParam}})
diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/python/PythonFastAPIServerCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/python/PythonFastAPIServerCodegenTest.java
index 34d19499cec7..26b9f73e20be 100644
--- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/python/PythonFastAPIServerCodegenTest.java
+++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/python/PythonFastAPIServerCodegenTest.java
@@ -71,7 +71,7 @@ public void testRequestBodyExampleInBodyMetadata() throws IOException {
final Path p = Paths.get(outputPath + "src/openapi_server/apis/user_api.py");
assertFileExists(p);
- assertFileContains(p, "user: Annotated[List[User], Field(description=\"List of user object\")] = Body(None, description=\"List of user object\", examples=[[{\"username\": \"foo\"}, {\"username\": \"bar\"}]])");
+ assertFileContains(p, "user: Annotated[List[User], Field(description=\"List of user object\")] = Body(..., description=\"List of user object\", examples=[[{\"username\": \"foo\"}, {\"username\": \"bar\"}]])");
assertFileNotContains(p, "examples=[[[],");
}
@@ -122,7 +122,7 @@ public void testBinaryMultipartFieldUsesUploadFile() throws IOException {
assertFileContains(api, "image: Optional[UploadFile] = File(None, description=\"Optional image upload\", alias=\"image\")");
// Sibling non-binary form fields still use Form()
- assertFileContains(api, "collection_name: Annotated[StrictStr, Field(description=\"Name of the collection\")] = Form(None, description=\"Name of the collection\", alias=\"collection_name\")");
+ assertFileContains(api, "collection_name: Annotated[StrictStr, Field(description=\"Name of the collection\")] = Form(..., description=\"Name of the collection\", alias=\"collection_name\")");
// The legacy client-side bytes union must not appear for the server signature
assertFileNotContains(api, "Union[StrictBytes, StrictStr, Tuple[StrictStr, StrictBytes]]");
diff --git a/samples/server/petstore/kotlin-spring-cloud-4/build.gradle.kts b/samples/server/petstore/kotlin-spring-cloud-4/build.gradle.kts
index ce19f0a90dab..e05be7009335 100644
--- a/samples/server/petstore/kotlin-spring-cloud-4/build.gradle.kts
+++ b/samples/server/petstore/kotlin-spring-cloud-4/build.gradle.kts
@@ -43,7 +43,7 @@ dependencies {
implementation("org.springframework.boot:spring-boot-starter-webmvc")
implementation("com.google.code.findbugs:jsr305:3.0.2")
- val jackson3Version = "3.1.0"
+ val jackson3Version = "3.1.5"
implementation("tools.jackson.dataformat:jackson-dataformat-yaml:$jackson3Version")
implementation("tools.jackson.dataformat:jackson-dataformat-xml:$jackson3Version")
implementation("tools.jackson.module:jackson-module-kotlin:$jackson3Version")
diff --git a/samples/server/petstore/kotlin-spring-cloud-4/gradle/wrapper/gradle-wrapper.properties b/samples/server/petstore/kotlin-spring-cloud-4/gradle/wrapper/gradle-wrapper.properties
index ca025c83a7cc..4f5eb9dcc0ef 100644
--- a/samples/server/petstore/kotlin-spring-cloud-4/gradle/wrapper/gradle-wrapper.properties
+++ b/samples/server/petstore/kotlin-spring-cloud-4/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.5-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
diff --git a/samples/server/petstore/kotlin-spring-cloud-4/pom.xml b/samples/server/petstore/kotlin-spring-cloud-4/pom.xml
index 54f1e792ebad..1d70ea0f2049 100644
--- a/samples/server/petstore/kotlin-spring-cloud-4/pom.xml
+++ b/samples/server/petstore/kotlin-spring-cloud-4/pom.xml
@@ -8,7 +8,7 @@
1.0.0
3.0.2
- 3.1.0
+ 3.1.5
3.0.0
2.2.0
diff --git a/samples/server/petstore/python-fastapi/src/openapi_server/apis/fake_api.py b/samples/server/petstore/python-fastapi/src/openapi_server/apis/fake_api.py
index 0e3f8d51b319..966ef8084147 100644
--- a/samples/server/petstore/python-fastapi/src/openapi_server/apis/fake_api.py
+++ b/samples/server/petstore/python-fastapi/src/openapi_server/apis/fake_api.py
@@ -46,8 +46,10 @@
response_model_by_alias=True,
)
async def fake_query_param_default(
- has_default: Annotated[Optional[StrictStr], Field(description="has default value")] = Query('Hello World', description="has default value", alias="hasDefault"),
- no_default: Annotated[Optional[StrictStr], Field(description="no default value")] = Query(None, description="no default value", alias="noDefault"),
+ has_default: Annotated[Optional[StrictStr], Field(description="has default value")] = Query('Hello World', description="has default value", alias="hasDefault")
+,
+ no_default: Annotated[Optional[StrictStr], Field(description="no default value")] = Query(None, description="no default value", alias="noDefault")
+,
) -> None:
""""""
if not BaseFakeApi.subclasses:
diff --git a/samples/server/petstore/python-fastapi/src/openapi_server/apis/pet_api.py b/samples/server/petstore/python-fastapi/src/openapi_server/apis/pet_api.py
index 7e9fe5def812..7a6d8bdc4ea7 100644
--- a/samples/server/petstore/python-fastapi/src/openapi_server/apis/pet_api.py
+++ b/samples/server/petstore/python-fastapi/src/openapi_server/apis/pet_api.py
@@ -51,7 +51,8 @@
response_model_by_alias=True,
)
async def update_pet(
- pet: Annotated[Pet, Field(description="Pet object that needs to be added to the store")] = Body(None, description="Pet object that needs to be added to the store"),
+ pet: Annotated[Pet, Field(description="Pet object that needs to be added to the store")] = Body(..., description="Pet object that needs to be added to the store")
+,
token_petstore_auth: TokenModel = Security(
get_token_petstore_auth, scopes=["write:pets", "read:pets"]
),
@@ -73,7 +74,8 @@ async def update_pet(
response_model_by_alias=True,
)
async def add_pet(
- pet: Annotated[Pet, Field(description="Pet object that needs to be added to the store")] = Body(None, description="Pet object that needs to be added to the store"),
+ pet: Annotated[Pet, Field(description="Pet object that needs to be added to the store")] = Body(..., description="Pet object that needs to be added to the store")
+,
token_petstore_auth: TokenModel = Security(
get_token_petstore_auth, scopes=["write:pets", "read:pets"]
),
@@ -95,7 +97,8 @@ async def add_pet(
response_model_by_alias=True,
)
async def find_pets_by_status(
- status: Annotated[List[StrictStr], Field(description="Status values that need to be considered for filter")] = Query(None, description="Status values that need to be considered for filter", alias="status"),
+ status: Annotated[List[StrictStr], Field(description="Status values that need to be considered for filter")] = Query(..., description="Status values that need to be considered for filter", alias="status")
+,
token_petstore_auth: TokenModel = Security(
get_token_petstore_auth, scopes=["read:pets"]
),
@@ -117,7 +120,8 @@ async def find_pets_by_status(
response_model_by_alias=True,
)
async def find_pets_by_tags(
- tags: Annotated[List[StrictStr], Field(description="Tags to filter by")] = Query(None, description="Tags to filter by", alias="tags"),
+ tags: Annotated[List[StrictStr], Field(description="Tags to filter by")] = Query(..., description="Tags to filter by", alias="tags")
+,
token_petstore_auth: TokenModel = Security(
get_token_petstore_auth, scopes=["read:pets"]
),
@@ -140,7 +144,8 @@ async def find_pets_by_tags(
response_model_by_alias=True,
)
async def get_pet_by_id(
- petId: Annotated[StrictInt, Field(description="ID of pet to return")] = Path(..., description="ID of pet to return"),
+ petId: Annotated[StrictInt, Field(description="ID of pet to return")] = Path(..., description="ID of pet to return")
+,
token_api_key: TokenModel = Security(
get_token_api_key
),
@@ -161,9 +166,12 @@ async def get_pet_by_id(
response_model_by_alias=True,
)
async def update_pet_with_form(
- petId: Annotated[StrictInt, Field(description="ID of pet that needs to be updated")] = Path(..., description="ID of pet that needs to be updated"),
- name: Annotated[Optional[StrictStr], Field(description="Updated name of the pet")] = Form(None, description="Updated name of the pet", alias="name"),
- status: Annotated[Optional[StrictStr], Field(description="Updated status of the pet")] = Form(None, description="Updated status of the pet", alias="status"),
+ petId: Annotated[StrictInt, Field(description="ID of pet that needs to be updated")] = Path(..., description="ID of pet that needs to be updated")
+,
+ name: Annotated[Optional[StrictStr], Field(description="Updated name of the pet")] = Form(None, description="Updated name of the pet", alias="name")
+,
+ status: Annotated[Optional[StrictStr], Field(description="Updated status of the pet")] = Form(None, description="Updated status of the pet", alias="status")
+,
token_petstore_auth: TokenModel = Security(
get_token_petstore_auth, scopes=["write:pets", "read:pets"]
),
@@ -184,8 +192,10 @@ async def update_pet_with_form(
response_model_by_alias=True,
)
async def delete_pet(
- petId: Annotated[StrictInt, Field(description="Pet id to delete")] = Path(..., description="Pet id to delete"),
- api_key: Optional[StrictStr] = Header(None, description=""),
+ petId: Annotated[StrictInt, Field(description="Pet id to delete")] = Path(..., description="Pet id to delete")
+,
+ api_key: Optional[StrictStr] = Header(None, description="")
+,
token_petstore_auth: TokenModel = Security(
get_token_petstore_auth, scopes=["write:pets", "read:pets"]
),
@@ -206,9 +216,12 @@ async def delete_pet(
response_model_by_alias=True,
)
async def upload_file(
- petId: Annotated[StrictInt, Field(description="ID of pet to update")] = Path(..., description="ID of pet to update"),
- additional_metadata: Annotated[Optional[StrictStr], Field(description="Additional data to pass to server")] = Form(None, description="Additional data to pass to server", alias="additionalMetadata"),
- file: Optional[UploadFile] = File(None, description="file to upload", alias="file"),
+ petId: Annotated[StrictInt, Field(description="ID of pet to update")] = Path(..., description="ID of pet to update")
+,
+ additional_metadata: Annotated[Optional[StrictStr], Field(description="Additional data to pass to server")] = Form(None, description="Additional data to pass to server", alias="additionalMetadata")
+,
+ file: Optional[UploadFile] = File(None, description="file to upload", alias="file")
+,
token_petstore_auth: TokenModel = Security(
get_token_petstore_auth, scopes=["write:pets", "read:pets"]
),
diff --git a/samples/server/petstore/python-fastapi/src/openapi_server/apis/store_api.py b/samples/server/petstore/python-fastapi/src/openapi_server/apis/store_api.py
index 3d2744c2e028..6dbefdcaa1a9 100644
--- a/samples/server/petstore/python-fastapi/src/openapi_server/apis/store_api.py
+++ b/samples/server/petstore/python-fastapi/src/openapi_server/apis/store_api.py
@@ -67,7 +67,8 @@ async def get_inventory(
response_model_by_alias=True,
)
async def place_order(
- order: Annotated[Order, Field(description="order placed for purchasing the pet")] = Body(None, description="order placed for purchasing the pet"),
+ order: Annotated[Order, Field(description="order placed for purchasing the pet")] = Body(..., description="order placed for purchasing the pet")
+,
) -> Order:
""""""
if not BaseStoreApi.subclasses:
@@ -87,7 +88,8 @@ async def place_order(
response_model_by_alias=True,
)
async def get_order_by_id(
- orderId: Annotated[int, Field(le=5, strict=True, ge=1, description="ID of pet that needs to be fetched")] = Path(..., description="ID of pet that needs to be fetched", ge=1, le=5),
+ orderId: Annotated[int, Field(le=5, strict=True, ge=1, description="ID of pet that needs to be fetched")] = Path(..., description="ID of pet that needs to be fetched", ge=1, le=5)
+,
) -> Order:
"""For valid response try integer IDs with value <= 5 or > 10. Other values will generate exceptions"""
if not BaseStoreApi.subclasses:
@@ -106,7 +108,8 @@ async def get_order_by_id(
response_model_by_alias=True,
)
async def delete_order(
- orderId: Annotated[StrictStr, Field(description="ID of the order that needs to be deleted")] = Path(..., description="ID of the order that needs to be deleted"),
+ orderId: Annotated[StrictStr, Field(description="ID of the order that needs to be deleted")] = Path(..., description="ID of the order that needs to be deleted")
+,
) -> None:
"""For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors"""
if not BaseStoreApi.subclasses:
diff --git a/samples/server/petstore/python-fastapi/src/openapi_server/apis/user_api.py b/samples/server/petstore/python-fastapi/src/openapi_server/apis/user_api.py
index e7d5ea8011b5..06634461bfa4 100644
--- a/samples/server/petstore/python-fastapi/src/openapi_server/apis/user_api.py
+++ b/samples/server/petstore/python-fastapi/src/openapi_server/apis/user_api.py
@@ -46,7 +46,8 @@
response_model_by_alias=True,
)
async def create_user(
- user: Annotated[User, Field(description="Created user object")] = Body(None, description="Created user object"),
+ user: Annotated[User, Field(description="Created user object")] = Body(..., description="Created user object")
+,
token_api_key: TokenModel = Security(
get_token_api_key
),
@@ -67,7 +68,8 @@ async def create_user(
response_model_by_alias=True,
)
async def create_users_with_array_input(
- user: Annotated[List[User], Field(description="List of user object")] = Body(None, description="List of user object"),
+ user: Annotated[List[User], Field(description="List of user object")] = Body(..., description="List of user object")
+,
token_api_key: TokenModel = Security(
get_token_api_key
),
@@ -88,7 +90,8 @@ async def create_users_with_array_input(
response_model_by_alias=True,
)
async def create_users_with_list_input(
- user: Annotated[List[User], Field(description="List of user object")] = Body(None, description="List of user object"),
+ user: Annotated[List[User], Field(description="List of user object")] = Body(..., description="List of user object")
+,
token_api_key: TokenModel = Security(
get_token_api_key
),
@@ -110,8 +113,10 @@ async def create_users_with_list_input(
response_model_by_alias=True,
)
async def login_user(
- username: Annotated[str, Field(strict=True, description="The user name for login")] = Query(None, description="The user name for login", alias="username", regex=r"^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$"),
- password: Annotated[StrictStr, Field(description="The password for login in clear text")] = Query(None, description="The password for login in clear text", alias="password"),
+ username: Annotated[str, Field(strict=True, description="The user name for login")] = Query(..., description="The user name for login", alias="username", regex=r"^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$")
+,
+ password: Annotated[StrictStr, Field(description="The password for login in clear text")] = Query(..., description="The password for login in clear text", alias="password")
+,
) -> str:
""""""
if not BaseUserApi.subclasses:
@@ -151,7 +156,8 @@ async def logout_user(
response_model_by_alias=True,
)
async def get_user_by_name(
- username: Annotated[StrictStr, Field(description="The name that needs to be fetched. Use user1 for testing.")] = Path(..., description="The name that needs to be fetched. Use user1 for testing."),
+ username: Annotated[StrictStr, Field(description="The name that needs to be fetched. Use user1 for testing.")] = Path(..., description="The name that needs to be fetched. Use user1 for testing.")
+,
) -> User:
""""""
if not BaseUserApi.subclasses:
@@ -170,8 +176,10 @@ async def get_user_by_name(
response_model_by_alias=True,
)
async def update_user(
- username: Annotated[StrictStr, Field(description="name that need to be deleted")] = Path(..., description="name that need to be deleted"),
- user: Annotated[User, Field(description="Updated user object")] = Body(None, description="Updated user object"),
+ username: Annotated[StrictStr, Field(description="name that need to be deleted")] = Path(..., description="name that need to be deleted")
+,
+ user: Annotated[User, Field(description="Updated user object")] = Body(..., description="Updated user object")
+,
token_api_key: TokenModel = Security(
get_token_api_key
),
@@ -193,7 +201,8 @@ async def update_user(
response_model_by_alias=True,
)
async def delete_user(
- username: Annotated[StrictStr, Field(description="The name that needs to be deleted")] = Path(..., description="The name that needs to be deleted"),
+ username: Annotated[StrictStr, Field(description="The name that needs to be deleted")] = Path(..., description="The name that needs to be deleted")
+,
token_api_key: TokenModel = Security(
get_token_api_key
),