diff --git a/Project.toml b/Project.toml
index 0e3e3fb..0702f3b 100644
--- a/Project.toml
+++ b/Project.toml
@@ -4,7 +4,7 @@ keywords = ["Swagger", "OpenAPI", "REST"]
license = "MIT"
desc = "OpenAPI server and client helper for Julia"
authors = ["JuliaHub Inc."]
-version = "0.1.13"
+version = "0.1.14"
[deps]
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
diff --git a/test/client/openapigenerator_petstore_v3/generate.sh b/test/client/openapigenerator_petstore_v3/generate.sh
new file mode 100755
index 0000000..b2dae6e
--- /dev/null
+++ b/test/client/openapigenerator_petstore_v3/generate.sh
@@ -0,0 +1,7 @@
+java -jar openapi-generator-cli.jar generate \
+ -i ../../specs/openapigenerator_petstore_v3.json \
+ -g julia-client \
+ -o petstore \
+ --additional-properties=packageName=OpenAPIGenPetStoreClient \
+ --additional-properties=exportModels=true \
+ --additional-properties=exportOperations=true
diff --git a/test/client/openapigenerator_petstore_v3/petstore/.openapi-generator-ignore b/test/client/openapigenerator_petstore_v3/petstore/.openapi-generator-ignore
new file mode 100644
index 0000000..7484ee5
--- /dev/null
+++ b/test/client/openapigenerator_petstore_v3/petstore/.openapi-generator-ignore
@@ -0,0 +1,23 @@
+# OpenAPI Generator Ignore
+# Generated by openapi-generator https://github.com/openapitools/openapi-generator
+
+# Use this file to prevent files from being overwritten by the generator.
+# The patterns follow closely to .gitignore or .dockerignore.
+
+# As an example, the C# client generator defines ApiClient.cs.
+# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
+#ApiClient.cs
+
+# You can match any string of characters against a directory, file or extension with a single asterisk (*):
+#foo/*/qux
+# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
+
+# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
+#foo/**/qux
+# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
+
+# You can also negate patterns with an exclamation (!).
+# For example, you can ignore all files in a docs folder with the file extension .md:
+#docs/*.md
+# Then explicitly reverse the ignore rule for a single file:
+#!docs/README.md
diff --git a/test/client/openapigenerator_petstore_v3/petstore/.openapi-generator/FILES b/test/client/openapigenerator_petstore_v3/petstore/.openapi-generator/FILES
new file mode 100644
index 0000000..0a37d59
--- /dev/null
+++ b/test/client/openapigenerator_petstore_v3/petstore/.openapi-generator/FILES
@@ -0,0 +1,21 @@
+README.md
+docs/ApiResponse.md
+docs/Category.md
+docs/Order.md
+docs/Pet.md
+docs/PetApi.md
+docs/StoreApi.md
+docs/Tag.md
+docs/User.md
+docs/UserApi.md
+src/OpenAPIGenPetStoreClient.jl
+src/apis/api_PetApi.jl
+src/apis/api_StoreApi.jl
+src/apis/api_UserApi.jl
+src/modelincludes.jl
+src/models/model_ApiResponse.jl
+src/models/model_Category.jl
+src/models/model_Order.jl
+src/models/model_Pet.jl
+src/models/model_Tag.jl
+src/models/model_User.jl
diff --git a/test/client/openapigenerator_petstore_v3/petstore/.openapi-generator/VERSION b/test/client/openapigenerator_petstore_v3/petstore/.openapi-generator/VERSION
new file mode 100644
index 0000000..757e674
--- /dev/null
+++ b/test/client/openapigenerator_petstore_v3/petstore/.openapi-generator/VERSION
@@ -0,0 +1 @@
+7.0.0-SNAPSHOT
\ No newline at end of file
diff --git a/test/client/openapigenerator_petstore_v3/petstore/README.md b/test/client/openapigenerator_petstore_v3/petstore/README.md
new file mode 100644
index 0000000..eb433b9
--- /dev/null
+++ b/test/client/openapigenerator_petstore_v3/petstore/README.md
@@ -0,0 +1,95 @@
+# Julia API client for OpenAPIGenPetStoreClient
+
+This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
+
+## Overview
+This API client was generated by the [OpenAPI Generator](https://openapi-generator.tech) project. By using the [openapi-spec](https://openapis.org) from a remote server, you can easily generate an API client.
+
+- API version: 1.0.0
+- Build package: org.openapitools.codegen.languages.JuliaClientCodegen
+
+
+## Installation
+Place the Julia files generated under the `src` folder in your Julia project. Include OpenAPIGenPetStoreClient.jl in the project code.
+It would include the module named OpenAPIGenPetStoreClient.
+
+Documentation is generated as markdown files under the `docs` folder. You can include them in your project documentation.
+Documentation is also embedded in Julia which can be used with a Julia specific documentation generator.
+
+## API Endpoints
+
+Class | Method
+------------ | -------------
+*PetApi* | [**add_pet**](docs/PetApi.md#add_pet)
**POST** /pet
Add a new pet to the store
+*PetApi* | [**delete_pet**](docs/PetApi.md#delete_pet)
**DELETE** /pet/{petId}
Deletes a pet
+*PetApi* | [**find_pets_by_status**](docs/PetApi.md#find_pets_by_status)
**GET** /pet/findByStatus
Finds Pets by status
+*PetApi* | [**find_pets_by_tags**](docs/PetApi.md#find_pets_by_tags)
**GET** /pet/findByTags
Finds Pets by tags
+*PetApi* | [**get_pet_by_id**](docs/PetApi.md#get_pet_by_id)
**GET** /pet/{petId}
Find pet by ID
+*PetApi* | [**update_pet**](docs/PetApi.md#update_pet)
**PUT** /pet
Update an existing pet
+*PetApi* | [**update_pet_with_form**](docs/PetApi.md#update_pet_with_form)
**POST** /pet/{petId}
Updates a pet in the store with form data
+*PetApi* | [**upload_file**](docs/PetApi.md#upload_file)
**POST** /pet/{petId}/uploadImage
uploads an image
+*StoreApi* | [**delete_order**](docs/StoreApi.md#delete_order)
**DELETE** /store/order/{orderId}
Delete purchase order by ID
+*StoreApi* | [**get_inventory**](docs/StoreApi.md#get_inventory)
**GET** /store/inventory
Returns pet inventories by status
+*StoreApi* | [**get_order_by_id**](docs/StoreApi.md#get_order_by_id)
**GET** /store/order/{orderId}
Find purchase order by ID
+*StoreApi* | [**place_order**](docs/StoreApi.md#place_order)
**POST** /store/order
Place an order for a pet
+*UserApi* | [**create_user**](docs/UserApi.md#create_user)
**POST** /user
Create user
+*UserApi* | [**create_users_with_array_input**](docs/UserApi.md#create_users_with_array_input)
**POST** /user/createWithArray
Creates list of users with given input array
+*UserApi* | [**create_users_with_list_input**](docs/UserApi.md#create_users_with_list_input)
**POST** /user/createWithList
Creates list of users with given input array
+*UserApi* | [**delete_user**](docs/UserApi.md#delete_user)
**DELETE** /user/{username}
Delete user
+*UserApi* | [**get_user_by_name**](docs/UserApi.md#get_user_by_name)
**GET** /user/{username}
Get user by user name
+*UserApi* | [**login_user**](docs/UserApi.md#login_user)
**GET** /user/login
Logs user into the system
+*UserApi* | [**logout_user**](docs/UserApi.md#logout_user)
**GET** /user/logout
Logs out current logged in user session
+*UserApi* | [**update_user**](docs/UserApi.md#update_user)
**PUT** /user/{username}
Updated user
+
+
+## Models
+
+ - [ApiResponse](docs/ApiResponse.md)
+ - [Category](docs/Category.md)
+ - [Order](docs/Order.md)
+ - [Pet](docs/Pet.md)
+ - [Tag](docs/Tag.md)
+ - [User](docs/User.md)
+
+
+
+## Authorization
+
+Authentication schemes defined for the API:
+
+### petstore_auth
+- **Type**: OAuth
+- **Flow**: implicit
+- **Authorization URL**: http://petstore.swagger.io/api/oauth/dialog
+- **Scopes**:
+ - **read:pets**: read your pets
+ - **write:pets**: modify pets in your account
+
+Example
+```
+ using OpenAPI
+ using OpenAPI.Clients
+ import OpenAPI.Clients: Client, set_header
+ client = Client(server_uri)
+ set_header(client, "Authorization", "Bearer $bearer_auth")
+ api = MyApi(client)
+ result = callApi(api, args...; api_key)
+```
+
+### api_key
+- **Type**: API key
+
+Example
+```
+ using OpenAPI
+ using OpenAPI.Clients
+ import OpenAPI.Clients: Client
+ client = Client(server_uri)
+ api = MyApi(client)
+ result = callApi(api, args...; api_key)
+```
+
+## Author
+
+
+
diff --git a/test/client/openapigenerator_petstore_v3/petstore/docs/ApiResponse.md b/test/client/openapigenerator_petstore_v3/petstore/docs/ApiResponse.md
new file mode 100644
index 0000000..a7a2c11
--- /dev/null
+++ b/test/client/openapigenerator_petstore_v3/petstore/docs/ApiResponse.md
@@ -0,0 +1,14 @@
+# ApiResponse
+
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**message** | **String** | | [optional] [default to nothing]
+**code** | **Int64** | | [optional] [default to nothing]
+**type** | **String** | | [optional] [default to nothing]
+
+
+[[Back to Model list]](../README.md#models) [[Back to API list]](../README.md#api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/test/client/openapigenerator_petstore_v3/petstore/docs/Category.md b/test/client/openapigenerator_petstore_v3/petstore/docs/Category.md
new file mode 100644
index 0000000..e454c3b
--- /dev/null
+++ b/test/client/openapigenerator_petstore_v3/petstore/docs/Category.md
@@ -0,0 +1,13 @@
+# Category
+
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**name** | **String** | | [optional] [default to nothing]
+**id** | **Int64** | | [optional] [default to nothing]
+
+
+[[Back to Model list]](../README.md#models) [[Back to API list]](../README.md#api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/test/client/openapigenerator_petstore_v3/petstore/docs/Order.md b/test/client/openapigenerator_petstore_v3/petstore/docs/Order.md
new file mode 100644
index 0000000..98c1bae
--- /dev/null
+++ b/test/client/openapigenerator_petstore_v3/petstore/docs/Order.md
@@ -0,0 +1,17 @@
+# Order
+
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**petId** | **Int64** | | [optional] [default to nothing]
+**shipDate** | **ZonedDateTime** | | [optional] [default to nothing]
+**status** | **String** | Order Status | [optional] [default to nothing]
+**id** | **Int64** | | [optional] [default to nothing]
+**complete** | **Bool** | | [optional] [default to false]
+**quantity** | **Int64** | | [optional] [default to nothing]
+
+
+[[Back to Model list]](../README.md#models) [[Back to API list]](../README.md#api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/test/client/openapigenerator_petstore_v3/petstore/docs/Pet.md b/test/client/openapigenerator_petstore_v3/petstore/docs/Pet.md
new file mode 100644
index 0000000..dbdd2db
--- /dev/null
+++ b/test/client/openapigenerator_petstore_v3/petstore/docs/Pet.md
@@ -0,0 +1,17 @@
+# Pet
+
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**name** | **String** | | [default to nothing]
+**status** | **String** | pet status in the store | [optional] [default to nothing]
+**id** | **Int64** | | [optional] [default to nothing]
+**photoUrls** | **Vector{String}** | | [default to nothing]
+**tags** | [**Vector{Tag}**](Tag.md) | | [optional] [default to nothing]
+**category** | [***Category**](Category.md) | | [optional] [default to nothing]
+
+
+[[Back to Model list]](../README.md#models) [[Back to API list]](../README.md#api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/test/client/openapigenerator_petstore_v3/petstore/docs/PetApi.md b/test/client/openapigenerator_petstore_v3/petstore/docs/PetApi.md
new file mode 100644
index 0000000..12643bf
--- /dev/null
+++ b/test/client/openapigenerator_petstore_v3/petstore/docs/PetApi.md
@@ -0,0 +1,276 @@
+# PetApi
+
+All URIs are relative to */v3*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**add_pet**](PetApi.md#add_pet) | **POST** /pet | Add a new pet to the store
+[**delete_pet**](PetApi.md#delete_pet) | **DELETE** /pet/{petId} | Deletes a pet
+[**find_pets_by_status**](PetApi.md#find_pets_by_status) | **GET** /pet/findByStatus | Finds Pets by status
+[**find_pets_by_tags**](PetApi.md#find_pets_by_tags) | **GET** /pet/findByTags | Finds Pets by tags
+[**get_pet_by_id**](PetApi.md#get_pet_by_id) | **GET** /pet/{petId} | Find pet by ID
+[**update_pet**](PetApi.md#update_pet) | **PUT** /pet | Update an existing pet
+[**update_pet_with_form**](PetApi.md#update_pet_with_form) | **POST** /pet/{petId} | Updates a pet in the store with form data
+[**upload_file**](PetApi.md#upload_file) | **POST** /pet/{petId}/uploadImage | uploads an image
+
+
+# **add_pet**
+> add_pet(_api::PetApi, pet::Pet; _mediaType=nothing) -> Pet, OpenAPI.Clients.ApiResponse
+> add_pet(_api::PetApi, response_stream::Channel, pet::Pet; _mediaType=nothing) -> Channel{ Pet }, OpenAPI.Clients.ApiResponse
+
+Add a new pet to the store
+
+
+
+### Required Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **_api** | **PetApi** | API context |
+**pet** | [**Pet**](Pet.md)| Pet object that needs to be added to the store |
+
+### Return type
+
+[**Pet**](Pet.md)
+
+### Authorization
+
+[petstore_auth](../README.md#petstore_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/xml, application/json
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md)
+
+# **delete_pet**
+> delete_pet(_api::PetApi, pet_id::Int64; api_key=nothing, _mediaType=nothing) -> Nothing, OpenAPI.Clients.ApiResponse
+> delete_pet(_api::PetApi, response_stream::Channel, pet_id::Int64; api_key=nothing, _mediaType=nothing) -> Channel{ Nothing }, OpenAPI.Clients.ApiResponse
+
+Deletes a pet
+
+
+
+### Required Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **_api** | **PetApi** | API context |
+**pet_id** | **Int64**| Pet id to delete | [default to nothing]
+
+### Optional Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **api_key** | **String**| | [default to nothing]
+
+### Return type
+
+Nothing
+
+### Authorization
+
+[petstore_auth](../README.md#petstore_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md)
+
+# **find_pets_by_status**
+> find_pets_by_status(_api::PetApi, status::Vector{String}; _mediaType=nothing) -> Vector{Pet}, OpenAPI.Clients.ApiResponse
+> find_pets_by_status(_api::PetApi, response_stream::Channel, status::Vector{String}; _mediaType=nothing) -> Channel{ Vector{Pet} }, OpenAPI.Clients.ApiResponse
+
+Finds Pets by status
+
+Multiple status values can be provided with comma separated strings
+
+### Required Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **_api** | **PetApi** | API context |
+**status** | [**Vector{String}**](String.md)| Status values that need to be considered for filter | [default to nothing]
+
+### Return type
+
+[**Vector{Pet}**](Pet.md)
+
+### Authorization
+
+[petstore_auth](../README.md#petstore_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md)
+
+# **find_pets_by_tags**
+> find_pets_by_tags(_api::PetApi, tags::Vector{String}; _mediaType=nothing) -> Vector{Pet}, OpenAPI.Clients.ApiResponse
+> find_pets_by_tags(_api::PetApi, response_stream::Channel, tags::Vector{String}; _mediaType=nothing) -> Channel{ Vector{Pet} }, OpenAPI.Clients.ApiResponse
+
+Finds Pets by tags
+
+Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
+
+### Required Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **_api** | **PetApi** | API context |
+**tags** | [**Vector{String}**](String.md)| Tags to filter by | [default to nothing]
+
+### Return type
+
+[**Vector{Pet}**](Pet.md)
+
+### Authorization
+
+[petstore_auth](../README.md#petstore_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md)
+
+# **get_pet_by_id**
+> get_pet_by_id(_api::PetApi, pet_id::Int64; _mediaType=nothing) -> Pet, OpenAPI.Clients.ApiResponse
+> get_pet_by_id(_api::PetApi, response_stream::Channel, pet_id::Int64; _mediaType=nothing) -> Channel{ Pet }, OpenAPI.Clients.ApiResponse
+
+Find pet by ID
+
+Returns a single pet
+
+### Required Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **_api** | **PetApi** | API context |
+**pet_id** | **Int64**| ID of pet to return | [default to nothing]
+
+### Return type
+
+[**Pet**](Pet.md)
+
+### Authorization
+
+[api_key](../README.md#api_key)
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md)
+
+# **update_pet**
+> update_pet(_api::PetApi, pet::Pet; _mediaType=nothing) -> Pet, OpenAPI.Clients.ApiResponse
+> update_pet(_api::PetApi, response_stream::Channel, pet::Pet; _mediaType=nothing) -> Channel{ Pet }, OpenAPI.Clients.ApiResponse
+
+Update an existing pet
+
+
+
+### Required Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **_api** | **PetApi** | API context |
+**pet** | [**Pet**](Pet.md)| Pet object that needs to be added to the store |
+
+### Return type
+
+[**Pet**](Pet.md)
+
+### Authorization
+
+[petstore_auth](../README.md#petstore_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/xml, application/json
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md)
+
+# **update_pet_with_form**
+> update_pet_with_form(_api::PetApi, pet_id::Int64; name=nothing, status=nothing, _mediaType=nothing) -> Nothing, OpenAPI.Clients.ApiResponse
+> update_pet_with_form(_api::PetApi, response_stream::Channel, pet_id::Int64; name=nothing, status=nothing, _mediaType=nothing) -> Channel{ Nothing }, OpenAPI.Clients.ApiResponse
+
+Updates a pet in the store with form data
+
+
+
+### Required Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **_api** | **PetApi** | API context |
+**pet_id** | **Int64**| ID of pet that needs to be updated | [default to nothing]
+
+### Optional Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **name** | **String**| Updated name of the pet | [default to nothing]
+ **status** | **String**| Updated status of the pet | [default to nothing]
+
+### Return type
+
+Nothing
+
+### Authorization
+
+[petstore_auth](../README.md#petstore_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/x-www-form-urlencoded
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md)
+
+# **upload_file**
+> upload_file(_api::PetApi, pet_id::Int64; file=nothing, additional_metadata=nothing, _mediaType=nothing) -> ApiResponse, OpenAPI.Clients.ApiResponse
+> upload_file(_api::PetApi, response_stream::Channel, pet_id::Int64; file=nothing, additional_metadata=nothing, _mediaType=nothing) -> Channel{ ApiResponse }, OpenAPI.Clients.ApiResponse
+
+uploads an image
+
+
+
+### Required Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **_api** | **PetApi** | API context |
+**pet_id** | **Int64**| ID of pet to update | [default to nothing]
+
+### Optional Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **file** | **String****String**| file to upload | [default to nothing]
+ **additional_metadata** | **String**| Additional data to pass to server | [default to nothing]
+
+### Return type
+
+[**ApiResponse**](ApiResponse.md)
+
+### Authorization
+
+[petstore_auth](../README.md#petstore_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: multipart/form-data
+ - **Accept**: application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md)
+
diff --git a/test/client/openapigenerator_petstore_v3/petstore/docs/StoreApi.md b/test/client/openapigenerator_petstore_v3/petstore/docs/StoreApi.md
new file mode 100644
index 0000000..5e8bae0
--- /dev/null
+++ b/test/client/openapigenerator_petstore_v3/petstore/docs/StoreApi.md
@@ -0,0 +1,128 @@
+# StoreApi
+
+All URIs are relative to */v3*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**delete_order**](StoreApi.md#delete_order) | **DELETE** /store/order/{orderId} | Delete purchase order by ID
+[**get_inventory**](StoreApi.md#get_inventory) | **GET** /store/inventory | Returns pet inventories by status
+[**get_order_by_id**](StoreApi.md#get_order_by_id) | **GET** /store/order/{orderId} | Find purchase order by ID
+[**place_order**](StoreApi.md#place_order) | **POST** /store/order | Place an order for a pet
+
+
+# **delete_order**
+> delete_order(_api::StoreApi, order_id::String; _mediaType=nothing) -> Nothing, OpenAPI.Clients.ApiResponse
+> delete_order(_api::StoreApi, response_stream::Channel, order_id::String; _mediaType=nothing) -> Channel{ Nothing }, OpenAPI.Clients.ApiResponse
+
+Delete purchase order by ID
+
+For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors
+
+### Required Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **_api** | **StoreApi** | API context |
+**order_id** | **String**| ID of the order that needs to be deleted | [default to nothing]
+
+### Return type
+
+Nothing
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md)
+
+# **get_inventory**
+> get_inventory(_api::StoreApi; _mediaType=nothing) -> Dict{String, Int64}, OpenAPI.Clients.ApiResponse
+> get_inventory(_api::StoreApi, response_stream::Channel; _mediaType=nothing) -> Channel{ Dict{String, Int64} }, OpenAPI.Clients.ApiResponse
+
+Returns pet inventories by status
+
+Returns a map of status codes to quantities
+
+### Required Parameters
+This endpoint does not need any parameter.
+
+### Return type
+
+**Dict{String, Int64}**
+
+### Authorization
+
+[api_key](../README.md#api_key)
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md)
+
+# **get_order_by_id**
+> get_order_by_id(_api::StoreApi, order_id::Int64; _mediaType=nothing) -> Order, OpenAPI.Clients.ApiResponse
+> get_order_by_id(_api::StoreApi, response_stream::Channel, order_id::Int64; _mediaType=nothing) -> Channel{ Order }, OpenAPI.Clients.ApiResponse
+
+Find purchase order by ID
+
+For valid response try integer IDs with value <= 5 or > 10. Other values will generate exceptions
+
+### Required Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **_api** | **StoreApi** | API context |
+**order_id** | **Int64**| ID of pet that needs to be fetched | [default to nothing]
+
+### Return type
+
+[**Order**](Order.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md)
+
+# **place_order**
+> place_order(_api::StoreApi, order::Order; _mediaType=nothing) -> Order, OpenAPI.Clients.ApiResponse
+> place_order(_api::StoreApi, response_stream::Channel, order::Order; _mediaType=nothing) -> Channel{ Order }, OpenAPI.Clients.ApiResponse
+
+Place an order for a pet
+
+
+
+### Required Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **_api** | **StoreApi** | API context |
+**order** | [**Order**](Order.md)| order placed for purchasing the pet |
+
+### Return type
+
+[**Order**](Order.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md)
+
diff --git a/test/client/openapigenerator_petstore_v3/petstore/docs/Tag.md b/test/client/openapigenerator_petstore_v3/petstore/docs/Tag.md
new file mode 100644
index 0000000..ee2633c
--- /dev/null
+++ b/test/client/openapigenerator_petstore_v3/petstore/docs/Tag.md
@@ -0,0 +1,13 @@
+# Tag
+
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**name** | **String** | | [optional] [default to nothing]
+**id** | **Int64** | | [optional] [default to nothing]
+
+
+[[Back to Model list]](../README.md#models) [[Back to API list]](../README.md#api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/test/client/openapigenerator_petstore_v3/petstore/docs/User.md b/test/client/openapigenerator_petstore_v3/petstore/docs/User.md
new file mode 100644
index 0000000..3db4060
--- /dev/null
+++ b/test/client/openapigenerator_petstore_v3/petstore/docs/User.md
@@ -0,0 +1,19 @@
+# User
+
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**password** | **String** | | [optional] [default to nothing]
+**id** | **Int64** | | [optional] [default to nothing]
+**username** | **String** | | [optional] [default to nothing]
+**firstName** | **String** | | [optional] [default to nothing]
+**lastName** | **String** | | [optional] [default to nothing]
+**phone** | **String** | | [optional] [default to nothing]
+**userStatus** | **Int64** | User Status | [optional] [default to nothing]
+**email** | **String** | | [optional] [default to nothing]
+
+
+[[Back to Model list]](../README.md#models) [[Back to API list]](../README.md#api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/test/client/openapigenerator_petstore_v3/petstore/docs/UserApi.md b/test/client/openapigenerator_petstore_v3/petstore/docs/UserApi.md
new file mode 100644
index 0000000..d839da1
--- /dev/null
+++ b/test/client/openapigenerator_petstore_v3/petstore/docs/UserApi.md
@@ -0,0 +1,254 @@
+# UserApi
+
+All URIs are relative to */v3*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**create_user**](UserApi.md#create_user) | **POST** /user | Create user
+[**create_users_with_array_input**](UserApi.md#create_users_with_array_input) | **POST** /user/createWithArray | Creates list of users with given input array
+[**create_users_with_list_input**](UserApi.md#create_users_with_list_input) | **POST** /user/createWithList | Creates list of users with given input array
+[**delete_user**](UserApi.md#delete_user) | **DELETE** /user/{username} | Delete user
+[**get_user_by_name**](UserApi.md#get_user_by_name) | **GET** /user/{username} | Get user by user name
+[**login_user**](UserApi.md#login_user) | **GET** /user/login | Logs user into the system
+[**logout_user**](UserApi.md#logout_user) | **GET** /user/logout | Logs out current logged in user session
+[**update_user**](UserApi.md#update_user) | **PUT** /user/{username} | Updated user
+
+
+# **create_user**
+> create_user(_api::UserApi, user::User; _mediaType=nothing) -> Nothing, OpenAPI.Clients.ApiResponse
+> create_user(_api::UserApi, response_stream::Channel, user::User; _mediaType=nothing) -> Channel{ Nothing }, OpenAPI.Clients.ApiResponse
+
+Create user
+
+This can only be done by the logged in user.
+
+### Required Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **_api** | **UserApi** | API context |
+**user** | [**User**](User.md)| Created user object |
+
+### Return type
+
+Nothing
+
+### Authorization
+
+[api_key](../README.md#api_key)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md)
+
+# **create_users_with_array_input**
+> create_users_with_array_input(_api::UserApi, user::Vector{User}; _mediaType=nothing) -> Nothing, OpenAPI.Clients.ApiResponse
+> create_users_with_array_input(_api::UserApi, response_stream::Channel, user::Vector{User}; _mediaType=nothing) -> Channel{ Nothing }, OpenAPI.Clients.ApiResponse
+
+Creates list of users with given input array
+
+
+
+### Required Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **_api** | **UserApi** | API context |
+**user** | [**Vector{User}**](User.md)| List of user object |
+
+### Return type
+
+Nothing
+
+### Authorization
+
+[api_key](../README.md#api_key)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md)
+
+# **create_users_with_list_input**
+> create_users_with_list_input(_api::UserApi, user::Vector{User}; _mediaType=nothing) -> Nothing, OpenAPI.Clients.ApiResponse
+> create_users_with_list_input(_api::UserApi, response_stream::Channel, user::Vector{User}; _mediaType=nothing) -> Channel{ Nothing }, OpenAPI.Clients.ApiResponse
+
+Creates list of users with given input array
+
+
+
+### Required Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **_api** | **UserApi** | API context |
+**user** | [**Vector{User}**](User.md)| List of user object |
+
+### Return type
+
+Nothing
+
+### Authorization
+
+[api_key](../README.md#api_key)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md)
+
+# **delete_user**
+> delete_user(_api::UserApi, username::String; _mediaType=nothing) -> Nothing, OpenAPI.Clients.ApiResponse
+> delete_user(_api::UserApi, response_stream::Channel, username::String; _mediaType=nothing) -> Channel{ Nothing }, OpenAPI.Clients.ApiResponse
+
+Delete user
+
+This can only be done by the logged in user.
+
+### Required Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **_api** | **UserApi** | API context |
+**username** | **String**| The name that needs to be deleted | [default to nothing]
+
+### Return type
+
+Nothing
+
+### Authorization
+
+[api_key](../README.md#api_key)
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md)
+
+# **get_user_by_name**
+> get_user_by_name(_api::UserApi, username::String; _mediaType=nothing) -> User, OpenAPI.Clients.ApiResponse
+> get_user_by_name(_api::UserApi, response_stream::Channel, username::String; _mediaType=nothing) -> Channel{ User }, OpenAPI.Clients.ApiResponse
+
+Get user by user name
+
+
+
+### Required Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **_api** | **UserApi** | API context |
+**username** | **String**| The name that needs to be fetched. Use user1 for testing. | [default to nothing]
+
+### Return type
+
+[**User**](User.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md)
+
+# **login_user**
+> login_user(_api::UserApi, username::String, password::String; _mediaType=nothing) -> String, OpenAPI.Clients.ApiResponse
+> login_user(_api::UserApi, response_stream::Channel, username::String, password::String; _mediaType=nothing) -> Channel{ String }, OpenAPI.Clients.ApiResponse
+
+Logs user into the system
+
+
+
+### Required Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **_api** | **UserApi** | API context |
+**username** | **String**| The user name for login | [default to nothing]
+**password** | **String**| The password for login in clear text | [default to nothing]
+
+### Return type
+
+**String**
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md)
+
+# **logout_user**
+> logout_user(_api::UserApi; _mediaType=nothing) -> Nothing, OpenAPI.Clients.ApiResponse
+> logout_user(_api::UserApi, response_stream::Channel; _mediaType=nothing) -> Channel{ Nothing }, OpenAPI.Clients.ApiResponse
+
+Logs out current logged in user session
+
+
+
+### Required Parameters
+This endpoint does not need any parameter.
+
+### Return type
+
+Nothing
+
+### Authorization
+
+[api_key](../README.md#api_key)
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md)
+
+# **update_user**
+> update_user(_api::UserApi, username::String, user::User; _mediaType=nothing) -> Nothing, OpenAPI.Clients.ApiResponse
+> update_user(_api::UserApi, response_stream::Channel, username::String, user::User; _mediaType=nothing) -> Channel{ Nothing }, OpenAPI.Clients.ApiResponse
+
+Updated user
+
+This can only be done by the logged in user.
+
+### Required Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **_api** | **UserApi** | API context |
+**username** | **String**| name that need to be deleted | [default to nothing]
+**user** | [**User**](User.md)| Updated user object |
+
+### Return type
+
+Nothing
+
+### Authorization
+
+[api_key](../README.md#api_key)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md)
+
diff --git a/test/client/openapigenerator_petstore_v3/petstore/src/OpenAPIGenPetStoreClient.jl b/test/client/openapigenerator_petstore_v3/petstore/src/OpenAPIGenPetStoreClient.jl
new file mode 100644
index 0000000..b4effe4
--- /dev/null
+++ b/test/client/openapigenerator_petstore_v3/petstore/src/OpenAPIGenPetStoreClient.jl
@@ -0,0 +1,31 @@
+# This file was generated by the Julia OpenAPI Code Generator
+# Do not modify this file directly. Modify the OpenAPI specification instead.
+
+module OpenAPIGenPetStoreClient
+
+using Dates, TimeZones
+using OpenAPI
+using OpenAPI.Clients
+
+const API_VERSION = "1.0.0"
+
+include("modelincludes.jl")
+
+include("apis/api_PetApi.jl")
+include("apis/api_StoreApi.jl")
+include("apis/api_UserApi.jl")
+
+# export models
+export ApiResponse
+export Category
+export Order
+export Pet
+export Tag
+export User
+
+# export operations
+export PetApi
+export StoreApi
+export UserApi
+
+end # module OpenAPIGenPetStoreClient
diff --git a/test/client/openapigenerator_petstore_v3/petstore/src/apis/api_PetApi.jl b/test/client/openapigenerator_petstore_v3/petstore/src/apis/api_PetApi.jl
new file mode 100644
index 0000000..2d66bf1
--- /dev/null
+++ b/test/client/openapigenerator_petstore_v3/petstore/src/apis/api_PetApi.jl
@@ -0,0 +1,285 @@
+# This file was generated by the Julia OpenAPI Code Generator
+# Do not modify this file directly. Modify the OpenAPI specification instead.
+
+struct PetApi <: OpenAPI.APIClientImpl
+ client::OpenAPI.Clients.Client
+end
+
+"""
+The default API base path for APIs in `PetApi`.
+This can be used to construct the `OpenAPI.Clients.Client` instance.
+"""
+basepath(::Type{ PetApi }) = "/v3"
+
+const _returntypes_add_pet_PetApi = Dict{Regex,Type}(
+ Regex("^" * replace("405", "x"=>".") * "\$") => Nothing,
+ Regex("^" * replace("200", "x"=>".") * "\$") => Pet,
+)
+
+function _oacinternal_add_pet(_api::PetApi, pet::Pet; _mediaType=nothing)
+ _ctx = OpenAPI.Clients.Ctx(_api.client, "POST", _returntypes_add_pet_PetApi, "/pet", ["petstore_auth", ], pet)
+ OpenAPI.Clients.set_header_accept(_ctx, ["application/xml", "application/json", ])
+ OpenAPI.Clients.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/xml", "application/json", ] : [_mediaType])
+ return _ctx
+end
+
+@doc raw"""Add a new pet to the store
+
+
+
+Params:
+- pet::Pet (required)
+
+Return: Pet, OpenAPI.Clients.ApiResponse
+"""
+function add_pet(_api::PetApi, pet::Pet; _mediaType=nothing)
+ _ctx = _oacinternal_add_pet(_api, pet; _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx)
+end
+
+function add_pet(_api::PetApi, response_stream::Channel, pet::Pet; _mediaType=nothing)
+ _ctx = _oacinternal_add_pet(_api, pet; _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx, response_stream)
+end
+
+const _returntypes_delete_pet_PetApi = Dict{Regex,Type}(
+ Regex("^" * replace("400", "x"=>".") * "\$") => Nothing,
+)
+
+function _oacinternal_delete_pet(_api::PetApi, pet_id::Int64; api_key=nothing, _mediaType=nothing)
+ _ctx = OpenAPI.Clients.Ctx(_api.client, "DELETE", _returntypes_delete_pet_PetApi, "/pet/{petId}", ["petstore_auth", ])
+ OpenAPI.Clients.set_param(_ctx.path, "petId", pet_id) # type Int64
+ OpenAPI.Clients.set_param(_ctx.header, "api_key", api_key) # type String
+ OpenAPI.Clients.set_header_accept(_ctx, [])
+ OpenAPI.Clients.set_header_content_type(_ctx, (_mediaType === nothing) ? [] : [_mediaType])
+ return _ctx
+end
+
+@doc raw"""Deletes a pet
+
+
+
+Params:
+- pet_id::Int64 (required)
+- api_key::String
+
+Return: Nothing, OpenAPI.Clients.ApiResponse
+"""
+function delete_pet(_api::PetApi, pet_id::Int64; api_key=nothing, _mediaType=nothing)
+ _ctx = _oacinternal_delete_pet(_api, pet_id; api_key=api_key, _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx)
+end
+
+function delete_pet(_api::PetApi, response_stream::Channel, pet_id::Int64; api_key=nothing, _mediaType=nothing)
+ _ctx = _oacinternal_delete_pet(_api, pet_id; api_key=api_key, _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx, response_stream)
+end
+
+const _returntypes_find_pets_by_status_PetApi = Dict{Regex,Type}(
+ Regex("^" * replace("400", "x"=>".") * "\$") => Nothing,
+ Regex("^" * replace("200", "x"=>".") * "\$") => Vector{Pet},
+)
+
+function _oacinternal_find_pets_by_status(_api::PetApi, status::Vector{String}; _mediaType=nothing)
+ _ctx = OpenAPI.Clients.Ctx(_api.client, "GET", _returntypes_find_pets_by_status_PetApi, "/pet/findByStatus", ["petstore_auth", ])
+ OpenAPI.Clients.set_param(_ctx.query, "status", status) # type Vector{String}
+ OpenAPI.Clients.set_header_accept(_ctx, ["application/xml", "application/json", ])
+ OpenAPI.Clients.set_header_content_type(_ctx, (_mediaType === nothing) ? [] : [_mediaType])
+ return _ctx
+end
+
+@doc raw"""Finds Pets by status
+
+Multiple status values can be provided with comma separated strings
+
+Params:
+- status::Vector{String} (required)
+
+Return: Vector{Pet}, OpenAPI.Clients.ApiResponse
+"""
+function find_pets_by_status(_api::PetApi, status::Vector{String}; _mediaType=nothing)
+ _ctx = _oacinternal_find_pets_by_status(_api, status; _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx)
+end
+
+function find_pets_by_status(_api::PetApi, response_stream::Channel, status::Vector{String}; _mediaType=nothing)
+ _ctx = _oacinternal_find_pets_by_status(_api, status; _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx, response_stream)
+end
+
+const _returntypes_find_pets_by_tags_PetApi = Dict{Regex,Type}(
+ Regex("^" * replace("400", "x"=>".") * "\$") => Nothing,
+ Regex("^" * replace("200", "x"=>".") * "\$") => Vector{Pet},
+)
+
+function _oacinternal_find_pets_by_tags(_api::PetApi, tags::Vector{String}; _mediaType=nothing)
+ _ctx = OpenAPI.Clients.Ctx(_api.client, "GET", _returntypes_find_pets_by_tags_PetApi, "/pet/findByTags", ["petstore_auth", ])
+ OpenAPI.Clients.set_param(_ctx.query, "tags", tags) # type Vector{String}
+ OpenAPI.Clients.set_header_accept(_ctx, ["application/xml", "application/json", ])
+ OpenAPI.Clients.set_header_content_type(_ctx, (_mediaType === nothing) ? [] : [_mediaType])
+ return _ctx
+end
+
+@doc raw"""Finds Pets by tags
+
+Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
+
+Params:
+- tags::Vector{String} (required)
+
+Return: Vector{Pet}, OpenAPI.Clients.ApiResponse
+"""
+function find_pets_by_tags(_api::PetApi, tags::Vector{String}; _mediaType=nothing)
+ _ctx = _oacinternal_find_pets_by_tags(_api, tags; _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx)
+end
+
+function find_pets_by_tags(_api::PetApi, response_stream::Channel, tags::Vector{String}; _mediaType=nothing)
+ _ctx = _oacinternal_find_pets_by_tags(_api, tags; _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx, response_stream)
+end
+
+const _returntypes_get_pet_by_id_PetApi = Dict{Regex,Type}(
+ Regex("^" * replace("404", "x"=>".") * "\$") => Nothing,
+ Regex("^" * replace("400", "x"=>".") * "\$") => Nothing,
+ Regex("^" * replace("200", "x"=>".") * "\$") => Pet,
+)
+
+function _oacinternal_get_pet_by_id(_api::PetApi, pet_id::Int64; _mediaType=nothing)
+ _ctx = OpenAPI.Clients.Ctx(_api.client, "GET", _returntypes_get_pet_by_id_PetApi, "/pet/{petId}", ["api_key", ])
+ OpenAPI.Clients.set_param(_ctx.path, "petId", pet_id) # type Int64
+ OpenAPI.Clients.set_header_accept(_ctx, ["application/xml", "application/json", ])
+ OpenAPI.Clients.set_header_content_type(_ctx, (_mediaType === nothing) ? [] : [_mediaType])
+ return _ctx
+end
+
+@doc raw"""Find pet by ID
+
+Returns a single pet
+
+Params:
+- pet_id::Int64 (required)
+
+Return: Pet, OpenAPI.Clients.ApiResponse
+"""
+function get_pet_by_id(_api::PetApi, pet_id::Int64; _mediaType=nothing)
+ _ctx = _oacinternal_get_pet_by_id(_api, pet_id; _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx)
+end
+
+function get_pet_by_id(_api::PetApi, response_stream::Channel, pet_id::Int64; _mediaType=nothing)
+ _ctx = _oacinternal_get_pet_by_id(_api, pet_id; _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx, response_stream)
+end
+
+const _returntypes_update_pet_PetApi = Dict{Regex,Type}(
+ Regex("^" * replace("405", "x"=>".") * "\$") => Nothing,
+ Regex("^" * replace("404", "x"=>".") * "\$") => Nothing,
+ Regex("^" * replace("400", "x"=>".") * "\$") => Nothing,
+ Regex("^" * replace("200", "x"=>".") * "\$") => Pet,
+)
+
+function _oacinternal_update_pet(_api::PetApi, pet::Pet; _mediaType=nothing)
+ _ctx = OpenAPI.Clients.Ctx(_api.client, "PUT", _returntypes_update_pet_PetApi, "/pet", ["petstore_auth", ], pet)
+ OpenAPI.Clients.set_header_accept(_ctx, ["application/xml", "application/json", ])
+ OpenAPI.Clients.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/xml", "application/json", ] : [_mediaType])
+ return _ctx
+end
+
+@doc raw"""Update an existing pet
+
+
+
+Params:
+- pet::Pet (required)
+
+Return: Pet, OpenAPI.Clients.ApiResponse
+"""
+function update_pet(_api::PetApi, pet::Pet; _mediaType=nothing)
+ _ctx = _oacinternal_update_pet(_api, pet; _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx)
+end
+
+function update_pet(_api::PetApi, response_stream::Channel, pet::Pet; _mediaType=nothing)
+ _ctx = _oacinternal_update_pet(_api, pet; _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx, response_stream)
+end
+
+const _returntypes_update_pet_with_form_PetApi = Dict{Regex,Type}(
+ Regex("^" * replace("405", "x"=>".") * "\$") => Nothing,
+)
+
+function _oacinternal_update_pet_with_form(_api::PetApi, pet_id::Int64; name=nothing, status=nothing, _mediaType=nothing)
+ _ctx = OpenAPI.Clients.Ctx(_api.client, "POST", _returntypes_update_pet_with_form_PetApi, "/pet/{petId}", ["petstore_auth", ])
+ OpenAPI.Clients.set_param(_ctx.path, "petId", pet_id) # type Int64
+ OpenAPI.Clients.set_param(_ctx.form, "name", name) # type String
+ OpenAPI.Clients.set_param(_ctx.form, "status", status) # type String
+ OpenAPI.Clients.set_header_accept(_ctx, [])
+ OpenAPI.Clients.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/x-www-form-urlencoded", ] : [_mediaType])
+ return _ctx
+end
+
+@doc raw"""Updates a pet in the store with form data
+
+
+
+Params:
+- pet_id::Int64 (required)
+- name::String
+- status::String
+
+Return: Nothing, OpenAPI.Clients.ApiResponse
+"""
+function update_pet_with_form(_api::PetApi, pet_id::Int64; name=nothing, status=nothing, _mediaType=nothing)
+ _ctx = _oacinternal_update_pet_with_form(_api, pet_id; name=name, status=status, _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx)
+end
+
+function update_pet_with_form(_api::PetApi, response_stream::Channel, pet_id::Int64; name=nothing, status=nothing, _mediaType=nothing)
+ _ctx = _oacinternal_update_pet_with_form(_api, pet_id; name=name, status=status, _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx, response_stream)
+end
+
+const _returntypes_upload_file_PetApi = Dict{Regex,Type}(
+ Regex("^" * replace("200", "x"=>".") * "\$") => ApiResponse,
+)
+
+function _oacinternal_upload_file(_api::PetApi, pet_id::Int64; file=nothing, additional_metadata=nothing, _mediaType=nothing)
+ _ctx = OpenAPI.Clients.Ctx(_api.client, "POST", _returntypes_upload_file_PetApi, "/pet/{petId}/uploadImage", ["petstore_auth", ])
+ OpenAPI.Clients.set_param(_ctx.path, "petId", pet_id) # type Int64
+ OpenAPI.Clients.set_param(_ctx.file, "file", file) # type Vector{UInt8}
+ OpenAPI.Clients.set_param(_ctx.form, "additionalMetadata", additional_metadata) # type String
+ OpenAPI.Clients.set_header_accept(_ctx, ["application/json", ])
+ OpenAPI.Clients.set_header_content_type(_ctx, (_mediaType === nothing) ? ["multipart/form-data", ] : [_mediaType])
+ return _ctx
+end
+
+@doc raw"""uploads an image
+
+
+
+Params:
+- pet_id::Int64 (required)
+- file::String
+- additional_metadata::String
+
+Return: ApiResponse, OpenAPI.Clients.ApiResponse
+"""
+function upload_file(_api::PetApi, pet_id::Int64; file=nothing, additional_metadata=nothing, _mediaType=nothing)
+ _ctx = _oacinternal_upload_file(_api, pet_id; file=file, additional_metadata=additional_metadata, _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx)
+end
+
+function upload_file(_api::PetApi, response_stream::Channel, pet_id::Int64; file=nothing, additional_metadata=nothing, _mediaType=nothing)
+ _ctx = _oacinternal_upload_file(_api, pet_id; file=file, additional_metadata=additional_metadata, _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx, response_stream)
+end
+
+export add_pet
+export delete_pet
+export find_pets_by_status
+export find_pets_by_tags
+export get_pet_by_id
+export update_pet
+export update_pet_with_form
+export upload_file
diff --git a/test/client/openapigenerator_petstore_v3/petstore/src/apis/api_StoreApi.jl b/test/client/openapigenerator_petstore_v3/petstore/src/apis/api_StoreApi.jl
new file mode 100644
index 0000000..0da61e1
--- /dev/null
+++ b/test/client/openapigenerator_petstore_v3/petstore/src/apis/api_StoreApi.jl
@@ -0,0 +1,145 @@
+# This file was generated by the Julia OpenAPI Code Generator
+# Do not modify this file directly. Modify the OpenAPI specification instead.
+
+struct StoreApi <: OpenAPI.APIClientImpl
+ client::OpenAPI.Clients.Client
+end
+
+"""
+The default API base path for APIs in `StoreApi`.
+This can be used to construct the `OpenAPI.Clients.Client` instance.
+"""
+basepath(::Type{ StoreApi }) = "/v3"
+
+const _returntypes_delete_order_StoreApi = Dict{Regex,Type}(
+ Regex("^" * replace("404", "x"=>".") * "\$") => Nothing,
+ Regex("^" * replace("400", "x"=>".") * "\$") => Nothing,
+)
+
+function _oacinternal_delete_order(_api::StoreApi, order_id::String; _mediaType=nothing)
+ _ctx = OpenAPI.Clients.Ctx(_api.client, "DELETE", _returntypes_delete_order_StoreApi, "/store/order/{orderId}", [])
+ OpenAPI.Clients.set_param(_ctx.path, "orderId", order_id) # type String
+ OpenAPI.Clients.set_header_accept(_ctx, [])
+ OpenAPI.Clients.set_header_content_type(_ctx, (_mediaType === nothing) ? [] : [_mediaType])
+ return _ctx
+end
+
+@doc raw"""Delete purchase order by ID
+
+For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors
+
+Params:
+- order_id::String (required)
+
+Return: Nothing, OpenAPI.Clients.ApiResponse
+"""
+function delete_order(_api::StoreApi, order_id::String; _mediaType=nothing)
+ _ctx = _oacinternal_delete_order(_api, order_id; _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx)
+end
+
+function delete_order(_api::StoreApi, response_stream::Channel, order_id::String; _mediaType=nothing)
+ _ctx = _oacinternal_delete_order(_api, order_id; _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx, response_stream)
+end
+
+const _returntypes_get_inventory_StoreApi = Dict{Regex,Type}(
+ Regex("^" * replace("200", "x"=>".") * "\$") => Dict{String, Int64},
+)
+
+function _oacinternal_get_inventory(_api::StoreApi; _mediaType=nothing)
+ _ctx = OpenAPI.Clients.Ctx(_api.client, "GET", _returntypes_get_inventory_StoreApi, "/store/inventory", ["api_key", ])
+ OpenAPI.Clients.set_header_accept(_ctx, ["application/json", ])
+ OpenAPI.Clients.set_header_content_type(_ctx, (_mediaType === nothing) ? [] : [_mediaType])
+ return _ctx
+end
+
+@doc raw"""Returns pet inventories by status
+
+Returns a map of status codes to quantities
+
+Params:
+
+Return: Dict{String, Int64}, OpenAPI.Clients.ApiResponse
+"""
+function get_inventory(_api::StoreApi; _mediaType=nothing)
+ _ctx = _oacinternal_get_inventory(_api; _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx)
+end
+
+function get_inventory(_api::StoreApi, response_stream::Channel; _mediaType=nothing)
+ _ctx = _oacinternal_get_inventory(_api; _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx, response_stream)
+end
+
+const _returntypes_get_order_by_id_StoreApi = Dict{Regex,Type}(
+ Regex("^" * replace("404", "x"=>".") * "\$") => Nothing,
+ Regex("^" * replace("400", "x"=>".") * "\$") => Nothing,
+ Regex("^" * replace("200", "x"=>".") * "\$") => Order,
+)
+
+function _oacinternal_get_order_by_id(_api::StoreApi, order_id::Int64; _mediaType=nothing)
+ OpenAPI.validate_param("order_id", "get_order_by_id", :maximum, order_id, 5, false)
+ OpenAPI.validate_param("order_id", "get_order_by_id", :minimum, order_id, 1, false)
+
+ _ctx = OpenAPI.Clients.Ctx(_api.client, "GET", _returntypes_get_order_by_id_StoreApi, "/store/order/{orderId}", [])
+ OpenAPI.Clients.set_param(_ctx.path, "orderId", order_id) # type Int64
+ OpenAPI.Clients.set_header_accept(_ctx, ["application/xml", "application/json", ])
+ OpenAPI.Clients.set_header_content_type(_ctx, (_mediaType === nothing) ? [] : [_mediaType])
+ return _ctx
+end
+
+@doc raw"""Find purchase order by ID
+
+For valid response try integer IDs with value <= 5 or > 10. Other values will generate exceptions
+
+Params:
+- order_id::Int64 (required)
+
+Return: Order, OpenAPI.Clients.ApiResponse
+"""
+function get_order_by_id(_api::StoreApi, order_id::Int64; _mediaType=nothing)
+ _ctx = _oacinternal_get_order_by_id(_api, order_id; _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx)
+end
+
+function get_order_by_id(_api::StoreApi, response_stream::Channel, order_id::Int64; _mediaType=nothing)
+ _ctx = _oacinternal_get_order_by_id(_api, order_id; _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx, response_stream)
+end
+
+const _returntypes_place_order_StoreApi = Dict{Regex,Type}(
+ Regex("^" * replace("400", "x"=>".") * "\$") => Nothing,
+ Regex("^" * replace("200", "x"=>".") * "\$") => Order,
+)
+
+function _oacinternal_place_order(_api::StoreApi, order::Order; _mediaType=nothing)
+ _ctx = OpenAPI.Clients.Ctx(_api.client, "POST", _returntypes_place_order_StoreApi, "/store/order", [], order)
+ OpenAPI.Clients.set_header_accept(_ctx, ["application/xml", "application/json", ])
+ OpenAPI.Clients.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json", ] : [_mediaType])
+ return _ctx
+end
+
+@doc raw"""Place an order for a pet
+
+
+
+Params:
+- order::Order (required)
+
+Return: Order, OpenAPI.Clients.ApiResponse
+"""
+function place_order(_api::StoreApi, order::Order; _mediaType=nothing)
+ _ctx = _oacinternal_place_order(_api, order; _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx)
+end
+
+function place_order(_api::StoreApi, response_stream::Channel, order::Order; _mediaType=nothing)
+ _ctx = _oacinternal_place_order(_api, order; _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx, response_stream)
+end
+
+export delete_order
+export get_inventory
+export get_order_by_id
+export place_order
diff --git a/test/client/openapigenerator_petstore_v3/petstore/src/apis/api_UserApi.jl b/test/client/openapigenerator_petstore_v3/petstore/src/apis/api_UserApi.jl
new file mode 100644
index 0000000..52dceb8
--- /dev/null
+++ b/test/client/openapigenerator_petstore_v3/petstore/src/apis/api_UserApi.jl
@@ -0,0 +1,273 @@
+# This file was generated by the Julia OpenAPI Code Generator
+# Do not modify this file directly. Modify the OpenAPI specification instead.
+
+struct UserApi <: OpenAPI.APIClientImpl
+ client::OpenAPI.Clients.Client
+end
+
+"""
+The default API base path for APIs in `UserApi`.
+This can be used to construct the `OpenAPI.Clients.Client` instance.
+"""
+basepath(::Type{ UserApi }) = "/v3"
+
+const _returntypes_create_user_UserApi = Dict{Regex,Type}(
+ Regex("^" * replace("0", "x"=>".") * "\$") => Nothing,
+)
+
+function _oacinternal_create_user(_api::UserApi, user::User; _mediaType=nothing)
+ _ctx = OpenAPI.Clients.Ctx(_api.client, "POST", _returntypes_create_user_UserApi, "/user", ["api_key", ], user)
+ OpenAPI.Clients.set_header_accept(_ctx, [])
+ OpenAPI.Clients.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json", ] : [_mediaType])
+ return _ctx
+end
+
+@doc raw"""Create user
+
+This can only be done by the logged in user.
+
+Params:
+- user::User (required)
+
+Return: Nothing, OpenAPI.Clients.ApiResponse
+"""
+function create_user(_api::UserApi, user::User; _mediaType=nothing)
+ _ctx = _oacinternal_create_user(_api, user; _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx)
+end
+
+function create_user(_api::UserApi, response_stream::Channel, user::User; _mediaType=nothing)
+ _ctx = _oacinternal_create_user(_api, user; _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx, response_stream)
+end
+
+const _returntypes_create_users_with_array_input_UserApi = Dict{Regex,Type}(
+ Regex("^" * replace("0", "x"=>".") * "\$") => Nothing,
+)
+
+function _oacinternal_create_users_with_array_input(_api::UserApi, user::Vector{User}; _mediaType=nothing)
+ _ctx = OpenAPI.Clients.Ctx(_api.client, "POST", _returntypes_create_users_with_array_input_UserApi, "/user/createWithArray", ["api_key", ], user)
+ OpenAPI.Clients.set_header_accept(_ctx, [])
+ OpenAPI.Clients.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json", ] : [_mediaType])
+ return _ctx
+end
+
+@doc raw"""Creates list of users with given input array
+
+
+
+Params:
+- user::Vector{User} (required)
+
+Return: Nothing, OpenAPI.Clients.ApiResponse
+"""
+function create_users_with_array_input(_api::UserApi, user::Vector{User}; _mediaType=nothing)
+ _ctx = _oacinternal_create_users_with_array_input(_api, user; _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx)
+end
+
+function create_users_with_array_input(_api::UserApi, response_stream::Channel, user::Vector{User}; _mediaType=nothing)
+ _ctx = _oacinternal_create_users_with_array_input(_api, user; _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx, response_stream)
+end
+
+const _returntypes_create_users_with_list_input_UserApi = Dict{Regex,Type}(
+ Regex("^" * replace("0", "x"=>".") * "\$") => Nothing,
+)
+
+function _oacinternal_create_users_with_list_input(_api::UserApi, user::Vector{User}; _mediaType=nothing)
+ _ctx = OpenAPI.Clients.Ctx(_api.client, "POST", _returntypes_create_users_with_list_input_UserApi, "/user/createWithList", ["api_key", ], user)
+ OpenAPI.Clients.set_header_accept(_ctx, [])
+ OpenAPI.Clients.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json", ] : [_mediaType])
+ return _ctx
+end
+
+@doc raw"""Creates list of users with given input array
+
+
+
+Params:
+- user::Vector{User} (required)
+
+Return: Nothing, OpenAPI.Clients.ApiResponse
+"""
+function create_users_with_list_input(_api::UserApi, user::Vector{User}; _mediaType=nothing)
+ _ctx = _oacinternal_create_users_with_list_input(_api, user; _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx)
+end
+
+function create_users_with_list_input(_api::UserApi, response_stream::Channel, user::Vector{User}; _mediaType=nothing)
+ _ctx = _oacinternal_create_users_with_list_input(_api, user; _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx, response_stream)
+end
+
+const _returntypes_delete_user_UserApi = Dict{Regex,Type}(
+ Regex("^" * replace("404", "x"=>".") * "\$") => Nothing,
+ Regex("^" * replace("400", "x"=>".") * "\$") => Nothing,
+)
+
+function _oacinternal_delete_user(_api::UserApi, username::String; _mediaType=nothing)
+ _ctx = OpenAPI.Clients.Ctx(_api.client, "DELETE", _returntypes_delete_user_UserApi, "/user/{username}", ["api_key", ])
+ OpenAPI.Clients.set_param(_ctx.path, "username", username) # type String
+ OpenAPI.Clients.set_header_accept(_ctx, [])
+ OpenAPI.Clients.set_header_content_type(_ctx, (_mediaType === nothing) ? [] : [_mediaType])
+ return _ctx
+end
+
+@doc raw"""Delete user
+
+This can only be done by the logged in user.
+
+Params:
+- username::String (required)
+
+Return: Nothing, OpenAPI.Clients.ApiResponse
+"""
+function delete_user(_api::UserApi, username::String; _mediaType=nothing)
+ _ctx = _oacinternal_delete_user(_api, username; _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx)
+end
+
+function delete_user(_api::UserApi, response_stream::Channel, username::String; _mediaType=nothing)
+ _ctx = _oacinternal_delete_user(_api, username; _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx, response_stream)
+end
+
+const _returntypes_get_user_by_name_UserApi = Dict{Regex,Type}(
+ Regex("^" * replace("404", "x"=>".") * "\$") => Nothing,
+ Regex("^" * replace("400", "x"=>".") * "\$") => Nothing,
+ Regex("^" * replace("200", "x"=>".") * "\$") => User,
+)
+
+function _oacinternal_get_user_by_name(_api::UserApi, username::String; _mediaType=nothing)
+ _ctx = OpenAPI.Clients.Ctx(_api.client, "GET", _returntypes_get_user_by_name_UserApi, "/user/{username}", [])
+ OpenAPI.Clients.set_param(_ctx.path, "username", username) # type String
+ OpenAPI.Clients.set_header_accept(_ctx, ["application/xml", "application/json", ])
+ OpenAPI.Clients.set_header_content_type(_ctx, (_mediaType === nothing) ? [] : [_mediaType])
+ return _ctx
+end
+
+@doc raw"""Get user by user name
+
+
+
+Params:
+- username::String (required)
+
+Return: User, OpenAPI.Clients.ApiResponse
+"""
+function get_user_by_name(_api::UserApi, username::String; _mediaType=nothing)
+ _ctx = _oacinternal_get_user_by_name(_api, username; _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx)
+end
+
+function get_user_by_name(_api::UserApi, response_stream::Channel, username::String; _mediaType=nothing)
+ _ctx = _oacinternal_get_user_by_name(_api, username; _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx, response_stream)
+end
+
+const _returntypes_login_user_UserApi = Dict{Regex,Type}(
+ Regex("^" * replace("400", "x"=>".") * "\$") => Nothing,
+ Regex("^" * replace("200", "x"=>".") * "\$") => String,
+)
+
+function _oacinternal_login_user(_api::UserApi, username::String, password::String; _mediaType=nothing)
+
+ _ctx = OpenAPI.Clients.Ctx(_api.client, "GET", _returntypes_login_user_UserApi, "/user/login", [])
+ OpenAPI.Clients.set_param(_ctx.query, "username", username) # type String
+ OpenAPI.Clients.set_param(_ctx.query, "password", password) # type String
+ OpenAPI.Clients.set_header_accept(_ctx, ["application/xml", "application/json", ])
+ OpenAPI.Clients.set_header_content_type(_ctx, (_mediaType === nothing) ? [] : [_mediaType])
+ return _ctx
+end
+
+@doc raw"""Logs user into the system
+
+
+
+Params:
+- username::String (required)
+- password::String (required)
+
+Return: String, OpenAPI.Clients.ApiResponse
+"""
+function login_user(_api::UserApi, username::String, password::String; _mediaType=nothing)
+ _ctx = _oacinternal_login_user(_api, username, password; _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx)
+end
+
+function login_user(_api::UserApi, response_stream::Channel, username::String, password::String; _mediaType=nothing)
+ _ctx = _oacinternal_login_user(_api, username, password; _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx, response_stream)
+end
+
+const _returntypes_logout_user_UserApi = Dict{Regex,Type}(
+ Regex("^" * replace("0", "x"=>".") * "\$") => Nothing,
+)
+
+function _oacinternal_logout_user(_api::UserApi; _mediaType=nothing)
+ _ctx = OpenAPI.Clients.Ctx(_api.client, "GET", _returntypes_logout_user_UserApi, "/user/logout", ["api_key", ])
+ OpenAPI.Clients.set_header_accept(_ctx, [])
+ OpenAPI.Clients.set_header_content_type(_ctx, (_mediaType === nothing) ? [] : [_mediaType])
+ return _ctx
+end
+
+@doc raw"""Logs out current logged in user session
+
+
+
+Params:
+
+Return: Nothing, OpenAPI.Clients.ApiResponse
+"""
+function logout_user(_api::UserApi; _mediaType=nothing)
+ _ctx = _oacinternal_logout_user(_api; _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx)
+end
+
+function logout_user(_api::UserApi, response_stream::Channel; _mediaType=nothing)
+ _ctx = _oacinternal_logout_user(_api; _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx, response_stream)
+end
+
+const _returntypes_update_user_UserApi = Dict{Regex,Type}(
+ Regex("^" * replace("404", "x"=>".") * "\$") => Nothing,
+ Regex("^" * replace("400", "x"=>".") * "\$") => Nothing,
+)
+
+function _oacinternal_update_user(_api::UserApi, username::String, user::User; _mediaType=nothing)
+ _ctx = OpenAPI.Clients.Ctx(_api.client, "PUT", _returntypes_update_user_UserApi, "/user/{username}", ["api_key", ], user)
+ OpenAPI.Clients.set_param(_ctx.path, "username", username) # type String
+ OpenAPI.Clients.set_header_accept(_ctx, [])
+ OpenAPI.Clients.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json", ] : [_mediaType])
+ return _ctx
+end
+
+@doc raw"""Updated user
+
+This can only be done by the logged in user.
+
+Params:
+- username::String (required)
+- user::User (required)
+
+Return: Nothing, OpenAPI.Clients.ApiResponse
+"""
+function update_user(_api::UserApi, username::String, user::User; _mediaType=nothing)
+ _ctx = _oacinternal_update_user(_api, username, user; _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx)
+end
+
+function update_user(_api::UserApi, response_stream::Channel, username::String, user::User; _mediaType=nothing)
+ _ctx = _oacinternal_update_user(_api, username, user; _mediaType=_mediaType)
+ return OpenAPI.Clients.exec(_ctx, response_stream)
+end
+
+export create_user
+export create_users_with_array_input
+export create_users_with_list_input
+export delete_user
+export get_user_by_name
+export login_user
+export logout_user
+export update_user
diff --git a/test/client/openapigenerator_petstore_v3/petstore/src/modelincludes.jl b/test/client/openapigenerator_petstore_v3/petstore/src/modelincludes.jl
new file mode 100644
index 0000000..b3a3db8
--- /dev/null
+++ b/test/client/openapigenerator_petstore_v3/petstore/src/modelincludes.jl
@@ -0,0 +1,9 @@
+# This file was generated by the Julia OpenAPI Code Generator
+# Do not modify this file directly. Modify the OpenAPI specification instead.
+
+include("models/model_ApiResponse.jl")
+include("models/model_Category.jl")
+include("models/model_Order.jl")
+include("models/model_Pet.jl")
+include("models/model_Tag.jl")
+include("models/model_User.jl")
diff --git a/test/client/openapigenerator_petstore_v3/petstore/src/models/model_ApiResponse.jl b/test/client/openapigenerator_petstore_v3/petstore/src/models/model_ApiResponse.jl
new file mode 100644
index 0000000..e19464b
--- /dev/null
+++ b/test/client/openapigenerator_petstore_v3/petstore/src/models/model_ApiResponse.jl
@@ -0,0 +1,42 @@
+# This file was generated by the Julia OpenAPI Code Generator
+# Do not modify this file directly. Modify the OpenAPI specification instead.
+
+
+@doc raw"""ApiResponse
+Describes the result of uploading an image resource
+
+ ApiResponse(;
+ message=nothing,
+ code=nothing,
+ type=nothing,
+ )
+
+ - message::String
+ - code::Int64
+ - type::String
+"""
+Base.@kwdef mutable struct ApiResponse <: OpenAPI.APIModel
+ message::Union{Nothing, String} = nothing
+ code::Union{Nothing, Int64} = nothing
+ type::Union{Nothing, String} = nothing
+
+ function ApiResponse(message, code, type, )
+ OpenAPI.validate_property(ApiResponse, Symbol("message"), message)
+ OpenAPI.validate_property(ApiResponse, Symbol("code"), code)
+ OpenAPI.validate_property(ApiResponse, Symbol("type"), type)
+ return new(message, code, type, )
+ end
+end # type ApiResponse
+
+const _property_types_ApiResponse = Dict{Symbol,String}(Symbol("message")=>"String", Symbol("code")=>"Int64", Symbol("type")=>"String", )
+OpenAPI.property_type(::Type{ ApiResponse }, name::Symbol) = Union{Nothing,eval(Base.Meta.parse(_property_types_ApiResponse[name]))}
+
+function check_required(o::ApiResponse)
+ true
+end
+
+function OpenAPI.validate_property(::Type{ ApiResponse }, name::Symbol, val)
+ if name === Symbol("code")
+ OpenAPI.validate_param(name, "ApiResponse", :format, val, "int32")
+ end
+end
diff --git a/test/client/openapigenerator_petstore_v3/petstore/src/models/model_Category.jl b/test/client/openapigenerator_petstore_v3/petstore/src/models/model_Category.jl
new file mode 100644
index 0000000..5224efb
--- /dev/null
+++ b/test/client/openapigenerator_petstore_v3/petstore/src/models/model_Category.jl
@@ -0,0 +1,41 @@
+# This file was generated by the Julia OpenAPI Code Generator
+# Do not modify this file directly. Modify the OpenAPI specification instead.
+
+
+@doc raw"""Category
+A category for a pet
+
+ Category(;
+ name=nothing,
+ id=nothing,
+ )
+
+ - name::String
+ - id::Int64
+"""
+Base.@kwdef mutable struct Category <: OpenAPI.APIModel
+ name::Union{Nothing, String} = nothing
+ id::Union{Nothing, Int64} = nothing
+
+ function Category(name, id, )
+ OpenAPI.validate_property(Category, Symbol("name"), name)
+ OpenAPI.validate_property(Category, Symbol("id"), id)
+ return new(name, id, )
+ end
+end # type Category
+
+const _property_types_Category = Dict{Symbol,String}(Symbol("name")=>"String", Symbol("id")=>"Int64", )
+OpenAPI.property_type(::Type{ Category }, name::Symbol) = Union{Nothing,eval(Base.Meta.parse(_property_types_Category[name]))}
+
+function check_required(o::Category)
+ true
+end
+
+function OpenAPI.validate_property(::Type{ Category }, name::Symbol, val)
+ if name === Symbol("name")
+ OpenAPI.validate_param(name, "Category", :pattern, val, r"^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$")
+ end
+ if name === Symbol("id")
+ OpenAPI.validate_param(name, "Category", :format, val, "int64")
+ end
+end
diff --git a/test/client/openapigenerator_petstore_v3/petstore/src/models/model_Order.jl b/test/client/openapigenerator_petstore_v3/petstore/src/models/model_Order.jl
new file mode 100644
index 0000000..da94163
--- /dev/null
+++ b/test/client/openapigenerator_petstore_v3/petstore/src/models/model_Order.jl
@@ -0,0 +1,66 @@
+# This file was generated by the Julia OpenAPI Code Generator
+# Do not modify this file directly. Modify the OpenAPI specification instead.
+
+
+@doc raw"""Order
+An order for a pets from the pet store
+
+ Order(;
+ petId=nothing,
+ shipDate=nothing,
+ status=nothing,
+ id=nothing,
+ complete=false,
+ quantity=nothing,
+ )
+
+ - petId::Int64
+ - shipDate::ZonedDateTime
+ - status::String : Order Status
+ - id::Int64
+ - complete::Bool
+ - quantity::Int64
+"""
+Base.@kwdef mutable struct Order <: OpenAPI.APIModel
+ petId::Union{Nothing, Int64} = nothing
+ shipDate::Union{Nothing, ZonedDateTime} = nothing
+ status::Union{Nothing, String} = nothing
+ id::Union{Nothing, Int64} = nothing
+ complete::Union{Nothing, Bool} = false
+ quantity::Union{Nothing, Int64} = nothing
+
+ function Order(petId, shipDate, status, id, complete, quantity, )
+ OpenAPI.validate_property(Order, Symbol("petId"), petId)
+ OpenAPI.validate_property(Order, Symbol("shipDate"), shipDate)
+ OpenAPI.validate_property(Order, Symbol("status"), status)
+ OpenAPI.validate_property(Order, Symbol("id"), id)
+ OpenAPI.validate_property(Order, Symbol("complete"), complete)
+ OpenAPI.validate_property(Order, Symbol("quantity"), quantity)
+ return new(petId, shipDate, status, id, complete, quantity, )
+ end
+end # type Order
+
+const _property_types_Order = Dict{Symbol,String}(Symbol("petId")=>"Int64", Symbol("shipDate")=>"ZonedDateTime", Symbol("status")=>"String", Symbol("id")=>"Int64", Symbol("complete")=>"Bool", Symbol("quantity")=>"Int64", )
+OpenAPI.property_type(::Type{ Order }, name::Symbol) = Union{Nothing,eval(Base.Meta.parse(_property_types_Order[name]))}
+
+function check_required(o::Order)
+ true
+end
+
+function OpenAPI.validate_property(::Type{ Order }, name::Symbol, val)
+ if name === Symbol("petId")
+ OpenAPI.validate_param(name, "Order", :format, val, "int64")
+ end
+ if name === Symbol("shipDate")
+ OpenAPI.validate_param(name, "Order", :format, val, "date-time")
+ end
+ if name === Symbol("status")
+ OpenAPI.validate_param(name, "Order", :enum, val, ["placed", "approved", "delivered"])
+ end
+ if name === Symbol("id")
+ OpenAPI.validate_param(name, "Order", :format, val, "int64")
+ end
+ if name === Symbol("quantity")
+ OpenAPI.validate_param(name, "Order", :format, val, "int32")
+ end
+end
diff --git a/test/client/openapigenerator_petstore_v3/petstore/src/models/model_Pet.jl b/test/client/openapigenerator_petstore_v3/petstore/src/models/model_Pet.jl
new file mode 100644
index 0000000..2b4069f
--- /dev/null
+++ b/test/client/openapigenerator_petstore_v3/petstore/src/models/model_Pet.jl
@@ -0,0 +1,59 @@
+# This file was generated by the Julia OpenAPI Code Generator
+# Do not modify this file directly. Modify the OpenAPI specification instead.
+
+
+@doc raw"""Pet
+A pet for sale in the pet store
+
+ Pet(;
+ name=nothing,
+ status=nothing,
+ id=nothing,
+ photoUrls=nothing,
+ tags=nothing,
+ category=nothing,
+ )
+
+ - name::String
+ - status::String : pet status in the store
+ - id::Int64
+ - photoUrls::Vector{String}
+ - tags::Vector{Tag}
+ - category::Category
+"""
+Base.@kwdef mutable struct Pet <: OpenAPI.APIModel
+ name::Union{Nothing, String} = nothing
+ status::Union{Nothing, String} = nothing
+ id::Union{Nothing, Int64} = nothing
+ photoUrls::Union{Nothing, Vector{String}} = nothing
+ tags::Union{Nothing, Vector} = nothing # spec type: Union{ Nothing, Vector{Tag} }
+ category = nothing # spec type: Union{ Nothing, Category }
+
+ function Pet(name, status, id, photoUrls, tags, category, )
+ OpenAPI.validate_property(Pet, Symbol("name"), name)
+ OpenAPI.validate_property(Pet, Symbol("status"), status)
+ OpenAPI.validate_property(Pet, Symbol("id"), id)
+ OpenAPI.validate_property(Pet, Symbol("photoUrls"), photoUrls)
+ OpenAPI.validate_property(Pet, Symbol("tags"), tags)
+ OpenAPI.validate_property(Pet, Symbol("category"), category)
+ return new(name, status, id, photoUrls, tags, category, )
+ end
+end # type Pet
+
+const _property_types_Pet = Dict{Symbol,String}(Symbol("name")=>"String", Symbol("status")=>"String", Symbol("id")=>"Int64", Symbol("photoUrls")=>"Vector{String}", Symbol("tags")=>"Vector{Tag}", Symbol("category")=>"Category", )
+OpenAPI.property_type(::Type{ Pet }, name::Symbol) = Union{Nothing,eval(Base.Meta.parse(_property_types_Pet[name]))}
+
+function check_required(o::Pet)
+ o.name === nothing && (return false)
+ o.photoUrls === nothing && (return false)
+ true
+end
+
+function OpenAPI.validate_property(::Type{ Pet }, name::Symbol, val)
+ if name === Symbol("status")
+ OpenAPI.validate_param(name, "Pet", :enum, val, ["available", "pending", "sold"])
+ end
+ if name === Symbol("id")
+ OpenAPI.validate_param(name, "Pet", :format, val, "int64")
+ end
+end
diff --git a/test/client/openapigenerator_petstore_v3/petstore/src/models/model_Tag.jl b/test/client/openapigenerator_petstore_v3/petstore/src/models/model_Tag.jl
new file mode 100644
index 0000000..f3410e8
--- /dev/null
+++ b/test/client/openapigenerator_petstore_v3/petstore/src/models/model_Tag.jl
@@ -0,0 +1,38 @@
+# This file was generated by the Julia OpenAPI Code Generator
+# Do not modify this file directly. Modify the OpenAPI specification instead.
+
+
+@doc raw"""Tag
+A tag for a pet
+
+ Tag(;
+ name=nothing,
+ id=nothing,
+ )
+
+ - name::String
+ - id::Int64
+"""
+Base.@kwdef mutable struct Tag <: OpenAPI.APIModel
+ name::Union{Nothing, String} = nothing
+ id::Union{Nothing, Int64} = nothing
+
+ function Tag(name, id, )
+ OpenAPI.validate_property(Tag, Symbol("name"), name)
+ OpenAPI.validate_property(Tag, Symbol("id"), id)
+ return new(name, id, )
+ end
+end # type Tag
+
+const _property_types_Tag = Dict{Symbol,String}(Symbol("name")=>"String", Symbol("id")=>"Int64", )
+OpenAPI.property_type(::Type{ Tag }, name::Symbol) = Union{Nothing,eval(Base.Meta.parse(_property_types_Tag[name]))}
+
+function check_required(o::Tag)
+ true
+end
+
+function OpenAPI.validate_property(::Type{ Tag }, name::Symbol, val)
+ if name === Symbol("id")
+ OpenAPI.validate_param(name, "Tag", :format, val, "int64")
+ end
+end
diff --git a/test/client/openapigenerator_petstore_v3/petstore/src/models/model_User.jl b/test/client/openapigenerator_petstore_v3/petstore/src/models/model_User.jl
new file mode 100644
index 0000000..0572483
--- /dev/null
+++ b/test/client/openapigenerator_petstore_v3/petstore/src/models/model_User.jl
@@ -0,0 +1,65 @@
+# This file was generated by the Julia OpenAPI Code Generator
+# Do not modify this file directly. Modify the OpenAPI specification instead.
+
+
+@doc raw"""User
+A User who is purchasing from the pet store
+
+ User(;
+ password=nothing,
+ id=nothing,
+ username=nothing,
+ firstName=nothing,
+ lastName=nothing,
+ phone=nothing,
+ userStatus=nothing,
+ email=nothing,
+ )
+
+ - password::String
+ - id::Int64
+ - username::String
+ - firstName::String
+ - lastName::String
+ - phone::String
+ - userStatus::Int64 : User Status
+ - email::String
+"""
+Base.@kwdef mutable struct User <: OpenAPI.APIModel
+ password::Union{Nothing, String} = nothing
+ id::Union{Nothing, Int64} = nothing
+ username::Union{Nothing, String} = nothing
+ firstName::Union{Nothing, String} = nothing
+ lastName::Union{Nothing, String} = nothing
+ phone::Union{Nothing, String} = nothing
+ userStatus::Union{Nothing, Int64} = nothing
+ email::Union{Nothing, String} = nothing
+
+ function User(password, id, username, firstName, lastName, phone, userStatus, email, )
+ OpenAPI.validate_property(User, Symbol("password"), password)
+ OpenAPI.validate_property(User, Symbol("id"), id)
+ OpenAPI.validate_property(User, Symbol("username"), username)
+ OpenAPI.validate_property(User, Symbol("firstName"), firstName)
+ OpenAPI.validate_property(User, Symbol("lastName"), lastName)
+ OpenAPI.validate_property(User, Symbol("phone"), phone)
+ OpenAPI.validate_property(User, Symbol("userStatus"), userStatus)
+ OpenAPI.validate_property(User, Symbol("email"), email)
+ return new(password, id, username, firstName, lastName, phone, userStatus, email, )
+ end
+end # type User
+
+const _property_types_User = Dict{Symbol,String}(Symbol("password")=>"String", Symbol("id")=>"Int64", Symbol("username")=>"String", Symbol("firstName")=>"String", Symbol("lastName")=>"String", Symbol("phone")=>"String", Symbol("userStatus")=>"Int64", Symbol("email")=>"String", )
+OpenAPI.property_type(::Type{ User }, name::Symbol) = Union{Nothing,eval(Base.Meta.parse(_property_types_User[name]))}
+
+function check_required(o::User)
+ true
+end
+
+function OpenAPI.validate_property(::Type{ User }, name::Symbol, val)
+ if name === Symbol("id")
+ OpenAPI.validate_param(name, "User", :format, val, "int64")
+ end
+ if name === Symbol("userStatus")
+ OpenAPI.validate_param(name, "User", :format, val, "int32")
+ end
+end
diff --git a/test/client/openapigenerator_petstore_v3/petstore_test_petapi.jl b/test/client/openapigenerator_petstore_v3/petstore_test_petapi.jl
new file mode 100644
index 0000000..fb0b080
--- /dev/null
+++ b/test/client/openapigenerator_petstore_v3/petstore_test_petapi.jl
@@ -0,0 +1,77 @@
+module TestPetApi
+
+using ..OpenAPIGenPetStoreClient
+using Test
+using OpenAPI
+using OpenAPI.Clients
+import OpenAPI.Clients: Client
+
+function test(uri; test_file_upload=false)
+ @info("PetApi")
+ client = Client(uri)
+ api = PetApi(client)
+
+ tag1 = Tag(;id=10, name="juliacat")
+ tag2 = Tag(;id=11, name="white")
+ cat = Category(;id=10, name="cat")
+
+ @test_throws OpenAPI.ValidationException Pet(;id=10, category=cat, name="felix", photoUrls=nothing, tags=[tag1, tag2], status="invalid-status")
+
+ pet = Pet(;id=10, category=cat, name="felix", photoUrls=nothing, tags=[tag1,tag2], status="pending")
+
+ @info("PetApi - add_pet")
+ api_return, http_resp = add_pet(api, pet)
+ @test isa(api_return, Pet)
+ @test http_resp.status == 200
+
+ @info("PetApi - update_pet")
+ pet.status = "available"
+ api_return, http_resp = update_pet(api, pet)
+ @test isa(api_return, Pet)
+ @test http_resp.status == 200
+
+ # @info("PetApi - update_pet_with_form")
+ # @test update_pet_with_form(api, 10; in_name="meow") === nothing
+
+ @info("PetApi - get_pet_by_id")
+ pet10, http_resp = get_pet_by_id(api, Int64(10))
+ @test pet10.id == 10
+ @test http_resp.status == 200
+
+ @info("PetApi - find_pets_by_status")
+ unsold = ["available", "pending"]
+ pets, http_resp = find_pets_by_status(api, unsold)
+ @test isa(pets, Vector{Pet})
+ @test http_resp.status == 200
+ @info("PetApi - find_pets_by_status", npets=length(pets))
+ for p in pets
+ @test p.status in unsold
+ end
+
+ @info("PetApi - delete_pet")
+ api_return, http_resp = delete_pet(api, Int64(10))
+ @test api_return === nothing
+ @test http_resp.status == 200
+
+ if test_file_upload
+ @info("PetApi - upload_file")
+ api_return, http_resp = upload_file(api, 1; additional_metadata="my metadata", file=@__FILE__)
+ @test isa(api_return, ApiResponse)
+ @test api_return.code == 1
+ @test api_return.type == "pet"
+ @test api_return.message == "file uploaded"
+ @test http_resp.status == 200
+ end
+
+ # does not work yet. issue: https://github.com/JuliaWeb/Requests.jl/issues/139
+ #@info("PetApi - upload_file")
+ #img = joinpath(dirname(@__FILE__), "cat.png")
+ #resp, http_resp = upload_file(api, 10; additionalMetadata="juliacat pic", file=img)
+ #@test isa(resp, ApiResponse)
+ #@test resp.code == 200
+ #@info("PetApi - upload_file", typ=get_field(resp, "type"), message=get_field(resp, "message"))
+
+ nothing
+end
+
+end # module TestPetApi
diff --git a/test/client/openapigenerator_petstore_v3/petstore_test_storeapi.jl b/test/client/openapigenerator_petstore_v3/petstore_test_storeapi.jl
new file mode 100644
index 0000000..d3f2e1e
--- /dev/null
+++ b/test/client/openapigenerator_petstore_v3/petstore_test_storeapi.jl
@@ -0,0 +1,71 @@
+module TestStoreApi
+
+using ..OpenAPIGenPetStoreClient
+using Test
+using Dates
+using TimeZones
+using OpenAPI
+using OpenAPI.Clients
+import OpenAPI.Clients: Client
+
+function test(uri)
+ @info("StoreApi")
+ client = Client(uri)
+ api = StoreApi(client)
+
+ @info("StoreApi - get_inventory")
+ inventory, http_resp = get_inventory(api)
+ @test http_resp.status == 200
+ @test isa(inventory, Dict{String,Int64})
+ @test !isempty(inventory)
+
+ @info("StoreApi - place_order")
+ @test_throws OpenAPI.ValidationException Order(; id=5, petId=10, quantity=2, shipDate=DateTime(2017, 03, 12), status="invalid_status", complete=false)
+ order = Order(; id=5, petId=10, quantity=2, shipDate=ZonedDateTime(DateTime(2017, 03, 12), localzone()), status="placed", complete=false)
+ neworder, http_resp = place_order(api, order)
+ @test http_resp.status == 200
+ @test neworder.id == 5
+
+ @info("StoreApi - get_order_by_id")
+ @test_throws OpenAPI.ValidationException get_order_by_id(api, Int64(0))
+ order, http_resp = get_order_by_id(api, Int64(5))
+ @test http_resp.status == 200
+ @test isa(order, Order)
+ @test order.id == 5
+ @test isa(order.shipDate, ZonedDateTime)
+
+ @info("StoreApi - get_order_by_id (async)")
+ response_channel = Channel{Order}(1)
+ @test_throws OpenAPI.ValidationException get_order_by_id(api, response_channel, Int64(0))
+ @sync begin
+ @async begin
+ api_return, http_resp = get_order_by_id(api, response_channel, Int64(5))
+ @test (200 <= http_resp.status <= 206)
+ @test api_return === response_channel
+ end
+ @async begin
+ order = take!(response_channel)
+ @test isa(order, Order)
+ @test order.id == 5
+ end
+ end
+
+ # a closed channel is equivalent of cancellation of the call,
+ # no error should be thrown, but response can be nothing if call was interrupted immediately
+ @test !isopen(response_channel)
+ try
+ resp, http_resp = get_order_by_id(api, response_channel, Int64(5))
+ @test (200 <= http_resp.status <= 206)
+ catch ex
+ @test isa(ex, OpenAPI.InvocationException)
+ end
+
+ @info("StoreApi - delete_order")
+ api_return, http_resp = delete_order(api, "5")
+ @test api_return === nothing
+ @test http_resp.status == 200
+
+ nothing
+end
+
+end # module TestStoreApi
diff --git a/test/client/openapigenerator_petstore_v3/petstore_test_userapi.jl b/test/client/openapigenerator_petstore_v3/petstore_test_userapi.jl
new file mode 100644
index 0000000..99d3111
--- /dev/null
+++ b/test/client/openapigenerator_petstore_v3/petstore_test_userapi.jl
@@ -0,0 +1,193 @@
+module TestUserApi
+
+using ..OpenAPIGenPetStoreClient
+using Test
+using Random
+using JSON
+using URIs
+using OpenAPI
+using OpenAPI.Clients
+import OpenAPI.Clients: Client, Ctx, ApiException, DEFAULT_TIMEOUT_SECS, with_timeout, set_timeout, set_user_agent, set_cookie
+
+const TEST_USER = "jloac"
+const TEST_USER1 = "jloac1"
+const TEST_USER2 = "jloac2"
+const TEST_USER3 = "jl oac 3"
+const PRESET_TEST_USER = "user1" # this is the username that works for get user requests (as documented in the test docker container API)
+
+function test_404(uri)
+ @info("Error handling")
+ client = Client(uri*"/invalid")
+ api = UserApi(client)
+
+ api_return, http_resp = login_user(api, TEST_USER, "testpassword")
+ @test api_return === nothing
+ @test http_resp.status == 404
+
+ client = Client("http://_invalid/")
+ api = UserApi(client)
+
+ try
+ login_user(api, TEST_USER, "testpassword")
+ @error("ApiException not thrown")
+ catch ex
+ @test isa(ex, ApiException)
+ @test startswith(ex.reason, "Could not resolve host")
+ end
+end
+
+function test_set_methods()
+ @info("Error handling")
+ client = Client("http://_invalid/")
+
+ @test client.timeout[] == DEFAULT_TIMEOUT_SECS
+
+ with_timeout(client, DEFAULT_TIMEOUT_SECS + 10) do client
+ @test client.timeout[] == DEFAULT_TIMEOUT_SECS + 10
+ end
+ @test client.timeout[] == DEFAULT_TIMEOUT_SECS
+
+ api = UserApi(client)
+ with_timeout(api, DEFAULT_TIMEOUT_SECS + 10) do api
+ @test api.client.timeout[] == DEFAULT_TIMEOUT_SECS + 10
+ end
+ @test client.timeout[] == DEFAULT_TIMEOUT_SECS
+
+ set_timeout(client, DEFAULT_TIMEOUT_SECS + 10)
+ @test client.timeout[] == DEFAULT_TIMEOUT_SECS + 10
+
+ @test isempty(client.headers)
+ set_user_agent(client, "007")
+ set_cookie(client, "crumbly")
+ @test client.headers["User-Agent"] == "007"
+ @test client.headers["Cookie"] == "crumbly"
+end
+
+function test_login_user_hook(ctx::Ctx)
+ ctx.header["actual_password"] = "testpassword"
+ ctx
+end
+
+function test_login_user_hook(resource_path::AbstractString, body::Any, headers::Dict{String,String})
+ uri = URIs.parse_uri(resource_path)
+ qparams = URIs.queryparams(uri)
+ qparams["password"] = headers["actual_password"]
+ delete!(headers, "actual_password")
+ resource_path = string(URIs.URI(uri; query=escapeuri(qparams)))
+
+ (resource_path, body, headers)
+end
+
+function test_userhook(uri)
+ @info("User hook")
+ client = Client(uri; pre_request_hook=test_login_user_hook)
+ api = UserApi(client)
+
+ login_result, http_resp = login_user(api, TEST_USER, "wrongpassword")
+ @test http_resp.status == 200
+ @test !isempty(login_result)
+ @test startswith(login_result, "logged in user session:")
+end
+
+function test_parallel(uri)
+ @info("Parallel usage")
+ client = Client(uri)
+ api = UserApi(client)
+
+ for gcidx in 1:100
+ @sync begin
+ for idx in 1:10^3
+ @async begin
+ @debug("[$idx] UserApi Parallel begin")
+ login_result, http_resp = login_user(api, TEST_USER, "testpassword")
+ @test http_resp.status == 200
+ @test !isempty(login_result)
+ @test startswith(login_result, "logged in user session:")
+
+ @test_throws ApiException get_user_by_name(api, randstring())
+ @test_throws ApiException get_user_by_name(api, TEST_USER)
+
+ logout_result, http_resp = logout_user(api)
+ @test http_resp.status == 200
+ @test logout_result === nothing
+ @debug("[$idx] UserApi Parallel end")
+ end
+ end
+ end
+ GC.gc()
+ @info("outer loop $gcidx")
+ end
+ nothing
+end
+
+function test(uri)
+ @info("UserApi")
+ client = Client(uri)
+ api = UserApi(client)
+
+ @info("UserApi - login_user")
+ login_result, http_resp = login_user(api, TEST_USER, "testpassword")
+ @test http_resp.status == 200
+ @test !isempty(login_result)
+
+ @info("UserApi - create_user")
+ user1 = User(; id=100, username=TEST_USER1, firstName="test1", lastName="user1", email="jloac1@example.com", password="testpass1", phone="1000000001", userStatus=0)
+ create_result, http_resp = create_user(api, user1)
+ @test http_resp.status == 200
+ @test create_result === nothing
+
+ @info("UserApi - create_users_with_array_input")
+ user2 = User(; id=200, username=TEST_USER2, firstName="test2", lastName="user2", email="jloac2@example.com", password="testpass2", phone="1000000002", userStatus=0)
+ create_result, http_resp = create_users_with_array_input(api, [user1, user2])
+ @test http_resp.status == 200
+ @test create_result === nothing
+
+ @info("UserApi - create_users_with_array_input")
+ create_result, http_resp = create_users_with_array_input(api, [user1, user2])
+ @test http_resp.status == 200
+ @test create_result === nothing
+
+ @info("UserApi - get_user_by_name")
+ getuser_result, http_resp = get_user_by_name(api, randstring())
+ @test http_resp.status == 404
+ @test nothing === getuser_result
+ getuser_result, http_resp = get_user_by_name(api, TEST_USER)
+ @test http_resp.status == 404
+ @test nothing === getuser_result
+ getuser_result, http_resp = get_user_by_name(api, PRESET_TEST_USER)
+ @test http_resp.status == 200
+ @test isa(getuser_result, User)
+
+ @info("UserApi - update_user")
+ api_return, http_resp = update_user(api, TEST_USER2, getuser_result)
+ @test http_resp.status == 200
+ @test api_return === nothing
+ @info("UserApi - delete_user")
+ api_return, http_resp = delete_user(api, TEST_USER2)
+ @test http_resp.status == 200
+ @test api_return === nothing
+
+ @info("UserApi - logout_user")
+ logout_result, http_resp = logout_user(api)
+ @test http_resp.status == 200
+ @test logout_result === nothing
+
+ @info("UserApi - Test with spaces in username")
+ user3 = User(; id=300, username=TEST_USER3, firstName="test3", lastName="user3", email="jloac3@example.com", password="testpass3", phone="1000000003", userStatus=0)
+ create_result, http_resp = create_user(api, user3)
+ @test http_resp.status == 200
+ @test create_result === nothing
+
+ user3.firstName = "test3 updated"
+ api_return, http_resp = update_user(api, TEST_USER3, user3)
+ @test http_resp.status == 200
+ @test api_return === nothing
+
+ api_return, http_resp = delete_user(api, TEST_USER3)
+ @test http_resp.status == 200
+ @test api_return === nothing
+
+ nothing
+end
+
+end # module TestUserApi
diff --git a/test/client/openapigenerator_petstore_v3/runtests.jl b/test/client/openapigenerator_petstore_v3/runtests.jl
new file mode 100644
index 0000000..6581f7f
--- /dev/null
+++ b/test/client/openapigenerator_petstore_v3/runtests.jl
@@ -0,0 +1,20 @@
+module OpenAPIGenPetStoreV3Tests
+
+include(joinpath(@__DIR__, "petstore", "src", "OpenAPIGenPetStoreClient.jl"))
+using .OpenAPIGenPetStoreClient
+using Test
+
+include("petstore_test_petapi.jl")
+include("petstore_test_userapi.jl")
+include("petstore_test_storeapi.jl")
+
+const server = "http://127.0.0.1:8081/v3"
+
+function runtests(; test_file_upload=false)
+ @testset "petstore v3" begin
+ TestUserApi.test(server)
+ TestStoreApi.test(server)
+ TestPetApi.test(server; test_file_upload=test_file_upload)
+ end
+end
+end # module OpenAPIGenPetStoreV3Tests
diff --git a/test/client/runtests.jl b/test/client/runtests.jl
index f2c49e8..347be97 100644
--- a/test/client/runtests.jl
+++ b/test/client/runtests.jl
@@ -7,6 +7,7 @@ using Test
include("utilstests.jl")
include("petstore_v3/runtests.jl")
include("petstore_v2/runtests.jl")
+include("openapigenerator_petstore_v3/runtests.jl")
function runtests(; skip_petstore=false, test_file_upload=false)
@testset "Client" begin
@@ -39,4 +40,15 @@ function runtests(; skip_petstore=false, test_file_upload=false)
end
end
+function run_openapigenerator_tests(; test_file_upload=false)
+ @testset "OpenAPIGeneratorPetstoreClient" begin
+ if get(ENV, "RUNNER_OS", "") == "Linux"
+ @info("Running petstore v3 tests")
+ OpenAPIGenPetStoreV3Tests.runtests(; test_file_upload=test_file_upload)
+ else
+ @info("Skipping petstore tests in non Linux environment (can not run petstore docker on OSX or Windows)")
+ end
+ end
+end
+
end # module OpenAPIClientTests
\ No newline at end of file
diff --git a/test/runtests.jl b/test/runtests.jl
index 8d97502..af3707b 100644
--- a/test/runtests.jl
+++ b/test/runtests.jl
@@ -54,6 +54,30 @@ include("forms/forms_client.jl")
end
end
run_tests_with_servers && sleep(20) # avoid port conflicts
+ @testset "Petstore Server (openapi-generator)" begin
+ v3_ret = v3_out = nothing
+ servers_running = true
+
+ try
+ if run_tests_with_servers
+ v3_ret, v3_out = run_server(joinpath(@__DIR__, "server", "openapigenerator_petstore_v3", "petstore_server.jl"))
+ servers_running &= wait_server(8081)
+ else
+ servers_running = false
+ end
+ servers_running && OpenAPIClientTests.run_openapigenerator_tests(; test_file_upload=true)
+ finally
+ if run_tests_with_servers && !servers_running
+ # we probably had an error starting the servers
+ v3_out_str = isnothing(v3_out) ? "" : String(take!(v3_out))
+ @warn("Servers not running", v3_ret=v3_ret, v3_out_str)
+ end
+ if run_tests_with_servers && servers_running
+ stop_server(8081, v3_ret, v3_out)
+ end
+ end
+ end
+ run_tests_with_servers && sleep(20) # avoid port conflicts
@testset "Forms and File Uploads" begin
ret = out = nothing
servers_running = true
diff --git a/test/server/openapigenerator_petstore_v3/generate.sh b/test/server/openapigenerator_petstore_v3/generate.sh
new file mode 100755
index 0000000..e04d311
--- /dev/null
+++ b/test/server/openapigenerator_petstore_v3/generate.sh
@@ -0,0 +1,6 @@
+java -jar openapi-generator-cli.jar generate \
+ -i ../../specs/openapigenerator_petstore_v3.json \
+ -g julia-server \
+ -o petstore \
+ --additional-properties=packageName=OpenAPIGenPetStoreServer \
+ --additional-properties=exportModels=true
diff --git a/test/server/openapigenerator_petstore_v3/petstore/.openapi-generator-ignore b/test/server/openapigenerator_petstore_v3/petstore/.openapi-generator-ignore
new file mode 100644
index 0000000..7484ee5
--- /dev/null
+++ b/test/server/openapigenerator_petstore_v3/petstore/.openapi-generator-ignore
@@ -0,0 +1,23 @@
+# OpenAPI Generator Ignore
+# Generated by openapi-generator https://github.com/openapitools/openapi-generator
+
+# Use this file to prevent files from being overwritten by the generator.
+# The patterns follow closely to .gitignore or .dockerignore.
+
+# As an example, the C# client generator defines ApiClient.cs.
+# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
+#ApiClient.cs
+
+# You can match any string of characters against a directory, file or extension with a single asterisk (*):
+#foo/*/qux
+# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
+
+# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
+#foo/**/qux
+# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
+
+# You can also negate patterns with an exclamation (!).
+# For example, you can ignore all files in a docs folder with the file extension .md:
+#docs/*.md
+# Then explicitly reverse the ignore rule for a single file:
+#!docs/README.md
diff --git a/test/server/openapigenerator_petstore_v3/petstore/.openapi-generator/FILES b/test/server/openapigenerator_petstore_v3/petstore/.openapi-generator/FILES
new file mode 100644
index 0000000..21bc78e
--- /dev/null
+++ b/test/server/openapigenerator_petstore_v3/petstore/.openapi-generator/FILES
@@ -0,0 +1,21 @@
+README.md
+docs/ApiResponse.md
+docs/Category.md
+docs/Order.md
+docs/Pet.md
+docs/PetApi.md
+docs/StoreApi.md
+docs/Tag.md
+docs/User.md
+docs/UserApi.md
+src/OpenAPIGenPetStoreServer.jl
+src/apis/api_PetApi.jl
+src/apis/api_StoreApi.jl
+src/apis/api_UserApi.jl
+src/modelincludes.jl
+src/models/model_ApiResponse.jl
+src/models/model_Category.jl
+src/models/model_Order.jl
+src/models/model_Pet.jl
+src/models/model_Tag.jl
+src/models/model_User.jl
diff --git a/test/server/openapigenerator_petstore_v3/petstore/.openapi-generator/VERSION b/test/server/openapigenerator_petstore_v3/petstore/.openapi-generator/VERSION
new file mode 100644
index 0000000..757e674
--- /dev/null
+++ b/test/server/openapigenerator_petstore_v3/petstore/.openapi-generator/VERSION
@@ -0,0 +1 @@
+7.0.0-SNAPSHOT
\ No newline at end of file
diff --git a/test/server/openapigenerator_petstore_v3/petstore/README.md b/test/server/openapigenerator_petstore_v3/petstore/README.md
new file mode 100644
index 0000000..37e15b3
--- /dev/null
+++ b/test/server/openapigenerator_petstore_v3/petstore/README.md
@@ -0,0 +1,81 @@
+# Julia API server for OpenAPIGenPetStoreServer
+
+This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
+
+## Overview
+This API server was generated by the [OpenAPI Generator](https://openapi-generator.tech) project. By using the [openapi-spec](https://openapis.org) from a remote server, you can easily generate an API client.
+
+- API version: 1.0.0
+- Build package: org.openapitools.codegen.languages.JuliaServerCodegen
+
+
+## Installation
+Place the Julia files generated under the `src` folder in your Julia project. Include OpenAPIGenPetStoreServer.jl in the project code.
+It would include the module named OpenAPIGenPetStoreServer.
+
+Implement the server methods as listed below. They are also documented with the OpenAPIGenPetStoreServer module.
+Launch a HTTP server with a router that has all handlers registered. A `register` method is provided in OpenAPIGenPetStoreServer module for convenience.
+
+```julia
+register(
+ router::HTTP.Router, # Router to register handlers in
+ impl; # Module that implements the server methods
+ path_prefix::String="", # Prefix to be applied to all paths
+ optional_middlewares... # Optional middlewares to be applied to all handlers
+)
+```
+
+Optional middlewares can be one or more of:
+- `init`: called before the request is processed
+- `pre_validation`: called after the request is parsed but before validation
+- `pre_invoke`: called after validation but before the handler is invoked
+- `post_invoke`: called after the handler is invoked but before the response is sent
+
+The order in which middlewares are invoked are:
+`init |> read |> pre_validation |> validate |> pre_invoke |> invoke |> post_invoke`
+
+
+## API Endpoints
+
+The following server methods must be implemented:
+
+Class | Method | HTTP request | Description
+------------ | ------------- | ------------- | -------------
+*PetApi* | [**add_pet**](docs/PetApi.md#add_pet) | **POST** /pet | Add a new pet to the store
+*PetApi* | [**delete_pet**](docs/PetApi.md#delete_pet) | **DELETE** /pet/{petId} | Deletes a pet
+*PetApi* | [**find_pets_by_status**](docs/PetApi.md#find_pets_by_status) | **GET** /pet/findByStatus | Finds Pets by status
+*PetApi* | [**find_pets_by_tags**](docs/PetApi.md#find_pets_by_tags) | **GET** /pet/findByTags | Finds Pets by tags
+*PetApi* | [**get_pet_by_id**](docs/PetApi.md#get_pet_by_id) | **GET** /pet/{petId} | Find pet by ID
+*PetApi* | [**update_pet**](docs/PetApi.md#update_pet) | **PUT** /pet | Update an existing pet
+*PetApi* | [**update_pet_with_form**](docs/PetApi.md#update_pet_with_form) | **POST** /pet/{petId} | Updates a pet in the store with form data
+*PetApi* | [**upload_file**](docs/PetApi.md#upload_file) | **POST** /pet/{petId}/uploadImage | uploads an image
+*StoreApi* | [**delete_order**](docs/StoreApi.md#delete_order) | **DELETE** /store/order/{orderId} | Delete purchase order by ID
+*StoreApi* | [**get_inventory**](docs/StoreApi.md#get_inventory) | **GET** /store/inventory | Returns pet inventories by status
+*StoreApi* | [**get_order_by_id**](docs/StoreApi.md#get_order_by_id) | **GET** /store/order/{orderId} | Find purchase order by ID
+*StoreApi* | [**place_order**](docs/StoreApi.md#place_order) | **POST** /store/order | Place an order for a pet
+*UserApi* | [**create_user**](docs/UserApi.md#create_user) | **POST** /user | Create user
+*UserApi* | [**create_users_with_array_input**](docs/UserApi.md#create_users_with_array_input) | **POST** /user/createWithArray | Creates list of users with given input array
+*UserApi* | [**create_users_with_list_input**](docs/UserApi.md#create_users_with_list_input) | **POST** /user/createWithList | Creates list of users with given input array
+*UserApi* | [**delete_user**](docs/UserApi.md#delete_user) | **DELETE** /user/{username} | Delete user
+*UserApi* | [**get_user_by_name**](docs/UserApi.md#get_user_by_name) | **GET** /user/{username} | Get user by user name
+*UserApi* | [**login_user**](docs/UserApi.md#login_user) | **GET** /user/login | Logs user into the system
+*UserApi* | [**logout_user**](docs/UserApi.md#logout_user) | **GET** /user/logout | Logs out current logged in user session
+*UserApi* | [**update_user**](docs/UserApi.md#update_user) | **PUT** /user/{username} | Updated user
+
+
+
+## Models
+
+ - [ApiResponse](docs/ApiResponse.md)
+ - [Category](docs/Category.md)
+ - [Order](docs/Order.md)
+ - [Pet](docs/Pet.md)
+ - [Tag](docs/Tag.md)
+ - [User](docs/User.md)
+
+
+
+## Author
+
+
+
diff --git a/test/server/openapigenerator_petstore_v3/petstore/docs/ApiResponse.md b/test/server/openapigenerator_petstore_v3/petstore/docs/ApiResponse.md
new file mode 100644
index 0000000..a7a2c11
--- /dev/null
+++ b/test/server/openapigenerator_petstore_v3/petstore/docs/ApiResponse.md
@@ -0,0 +1,14 @@
+# ApiResponse
+
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**message** | **String** | | [optional] [default to nothing]
+**code** | **Int64** | | [optional] [default to nothing]
+**type** | **String** | | [optional] [default to nothing]
+
+
+[[Back to Model list]](../README.md#models) [[Back to API list]](../README.md#api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/test/server/openapigenerator_petstore_v3/petstore/docs/Category.md b/test/server/openapigenerator_petstore_v3/petstore/docs/Category.md
new file mode 100644
index 0000000..e454c3b
--- /dev/null
+++ b/test/server/openapigenerator_petstore_v3/petstore/docs/Category.md
@@ -0,0 +1,13 @@
+# Category
+
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**name** | **String** | | [optional] [default to nothing]
+**id** | **Int64** | | [optional] [default to nothing]
+
+
+[[Back to Model list]](../README.md#models) [[Back to API list]](../README.md#api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/test/server/openapigenerator_petstore_v3/petstore/docs/Order.md b/test/server/openapigenerator_petstore_v3/petstore/docs/Order.md
new file mode 100644
index 0000000..98c1bae
--- /dev/null
+++ b/test/server/openapigenerator_petstore_v3/petstore/docs/Order.md
@@ -0,0 +1,17 @@
+# Order
+
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**petId** | **Int64** | | [optional] [default to nothing]
+**shipDate** | **ZonedDateTime** | | [optional] [default to nothing]
+**status** | **String** | Order Status | [optional] [default to nothing]
+**id** | **Int64** | | [optional] [default to nothing]
+**complete** | **Bool** | | [optional] [default to false]
+**quantity** | **Int64** | | [optional] [default to nothing]
+
+
+[[Back to Model list]](../README.md#models) [[Back to API list]](../README.md#api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/test/server/openapigenerator_petstore_v3/petstore/docs/Pet.md b/test/server/openapigenerator_petstore_v3/petstore/docs/Pet.md
new file mode 100644
index 0000000..dbdd2db
--- /dev/null
+++ b/test/server/openapigenerator_petstore_v3/petstore/docs/Pet.md
@@ -0,0 +1,17 @@
+# Pet
+
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**name** | **String** | | [default to nothing]
+**status** | **String** | pet status in the store | [optional] [default to nothing]
+**id** | **Int64** | | [optional] [default to nothing]
+**photoUrls** | **Vector{String}** | | [default to nothing]
+**tags** | [**Vector{Tag}**](Tag.md) | | [optional] [default to nothing]
+**category** | [***Category**](Category.md) | | [optional] [default to nothing]
+
+
+[[Back to Model list]](../README.md#models) [[Back to API list]](../README.md#api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/test/server/openapigenerator_petstore_v3/petstore/docs/PetApi.md b/test/server/openapigenerator_petstore_v3/petstore/docs/PetApi.md
new file mode 100644
index 0000000..8803bc4
--- /dev/null
+++ b/test/server/openapigenerator_petstore_v3/petstore/docs/PetApi.md
@@ -0,0 +1,268 @@
+# PetApi
+
+All URIs are relative to */v3*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**add_pet**](PetApi.md#add_pet) | **POST** /pet | Add a new pet to the store
+[**delete_pet**](PetApi.md#delete_pet) | **DELETE** /pet/{petId} | Deletes a pet
+[**find_pets_by_status**](PetApi.md#find_pets_by_status) | **GET** /pet/findByStatus | Finds Pets by status
+[**find_pets_by_tags**](PetApi.md#find_pets_by_tags) | **GET** /pet/findByTags | Finds Pets by tags
+[**get_pet_by_id**](PetApi.md#get_pet_by_id) | **GET** /pet/{petId} | Find pet by ID
+[**update_pet**](PetApi.md#update_pet) | **PUT** /pet | Update an existing pet
+[**update_pet_with_form**](PetApi.md#update_pet_with_form) | **POST** /pet/{petId} | Updates a pet in the store with form data
+[**upload_file**](PetApi.md#upload_file) | **POST** /pet/{petId}/uploadImage | uploads an image
+
+
+# **add_pet**
+> add_pet(req::HTTP.Request, pet::Pet;) -> Pet
+
+Add a new pet to the store
+
+
+
+### Required Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **req** | **HTTP.Request** | The HTTP Request object |
+**pet** | [**Pet**](Pet.md)| Pet object that needs to be added to the store |
+
+### Return type
+
+[**Pet**](Pet.md)
+
+### Authorization
+
+[petstore_auth](../README.md#petstore_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/xml, application/json
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **delete_pet**
+> delete_pet(req::HTTP.Request, pet_id::Int64; api_key=nothing,) -> Nothing
+
+Deletes a pet
+
+
+
+### Required Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **req** | **HTTP.Request** | The HTTP Request object |
+**pet_id** | **Int64**| Pet id to delete | [default to nothing]
+
+### Optional Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **api_key** | **String**| | [default to nothing]
+
+### Return type
+
+Nothing
+
+### Authorization
+
+[petstore_auth](../README.md#petstore_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **find_pets_by_status**
+> find_pets_by_status(req::HTTP.Request, status::Vector{String};) -> Vector{Pet}
+
+Finds Pets by status
+
+Multiple status values can be provided with comma separated strings
+
+### Required Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **req** | **HTTP.Request** | The HTTP Request object |
+**status** | [**Vector{String}**](String.md)| Status values that need to be considered for filter | [default to nothing]
+
+### Return type
+
+[**Vector{Pet}**](Pet.md)
+
+### Authorization
+
+[petstore_auth](../README.md#petstore_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **find_pets_by_tags**
+> find_pets_by_tags(req::HTTP.Request, tags::Vector{String};) -> Vector{Pet}
+
+Finds Pets by tags
+
+Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
+
+### Required Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **req** | **HTTP.Request** | The HTTP Request object |
+**tags** | [**Vector{String}**](String.md)| Tags to filter by | [default to nothing]
+
+### Return type
+
+[**Vector{Pet}**](Pet.md)
+
+### Authorization
+
+[petstore_auth](../README.md#petstore_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **get_pet_by_id**
+> get_pet_by_id(req::HTTP.Request, pet_id::Int64;) -> Pet
+
+Find pet by ID
+
+Returns a single pet
+
+### Required Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **req** | **HTTP.Request** | The HTTP Request object |
+**pet_id** | **Int64**| ID of pet to return | [default to nothing]
+
+### Return type
+
+[**Pet**](Pet.md)
+
+### Authorization
+
+[api_key](../README.md#api_key)
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **update_pet**
+> update_pet(req::HTTP.Request, pet::Pet;) -> Pet
+
+Update an existing pet
+
+
+
+### Required Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **req** | **HTTP.Request** | The HTTP Request object |
+**pet** | [**Pet**](Pet.md)| Pet object that needs to be added to the store |
+
+### Return type
+
+[**Pet**](Pet.md)
+
+### Authorization
+
+[petstore_auth](../README.md#petstore_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/xml, application/json
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **update_pet_with_form**
+> update_pet_with_form(req::HTTP.Request, pet_id::Int64; name=nothing, status=nothing,) -> Nothing
+
+Updates a pet in the store with form data
+
+
+
+### Required Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **req** | **HTTP.Request** | The HTTP Request object |
+**pet_id** | **Int64**| ID of pet that needs to be updated | [default to nothing]
+
+### Optional Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **name** | **String**| Updated name of the pet | [default to nothing]
+ **status** | **String**| Updated status of the pet | [default to nothing]
+
+### Return type
+
+Nothing
+
+### Authorization
+
+[petstore_auth](../README.md#petstore_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/x-www-form-urlencoded
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **upload_file**
+> upload_file(req::HTTP.Request, pet_id::Int64; file=nothing, additional_metadata=nothing,) -> ApiResponse
+
+uploads an image
+
+
+
+### Required Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **req** | **HTTP.Request** | The HTTP Request object |
+**pet_id** | **Int64**| ID of pet to update | [default to nothing]
+
+### Optional Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **file** | **String****String**| file to upload | [default to nothing]
+ **additional_metadata** | **String**| Additional data to pass to server | [default to nothing]
+
+### Return type
+
+[**ApiResponse**](ApiResponse.md)
+
+### Authorization
+
+[petstore_auth](../README.md#petstore_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: multipart/form-data
+ - **Accept**: application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
diff --git a/test/server/openapigenerator_petstore_v3/petstore/docs/StoreApi.md b/test/server/openapigenerator_petstore_v3/petstore/docs/StoreApi.md
new file mode 100644
index 0000000..acd3cc5
--- /dev/null
+++ b/test/server/openapigenerator_petstore_v3/petstore/docs/StoreApi.md
@@ -0,0 +1,124 @@
+# StoreApi
+
+All URIs are relative to */v3*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**delete_order**](StoreApi.md#delete_order) | **DELETE** /store/order/{orderId} | Delete purchase order by ID
+[**get_inventory**](StoreApi.md#get_inventory) | **GET** /store/inventory | Returns pet inventories by status
+[**get_order_by_id**](StoreApi.md#get_order_by_id) | **GET** /store/order/{orderId} | Find purchase order by ID
+[**place_order**](StoreApi.md#place_order) | **POST** /store/order | Place an order for a pet
+
+
+# **delete_order**
+> delete_order(req::HTTP.Request, order_id::String;) -> Nothing
+
+Delete purchase order by ID
+
+For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors
+
+### Required Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **req** | **HTTP.Request** | The HTTP Request object |
+**order_id** | **String**| ID of the order that needs to be deleted | [default to nothing]
+
+### Return type
+
+Nothing
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **get_inventory**
+> get_inventory(req::HTTP.Request;) -> Dict{String, Int64}
+
+Returns pet inventories by status
+
+Returns a map of status codes to quantities
+
+### Required Parameters
+This endpoint does not need any parameter.
+
+### Return type
+
+**Dict{String, Int64}**
+
+### Authorization
+
+[api_key](../README.md#api_key)
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **get_order_by_id**
+> get_order_by_id(req::HTTP.Request, order_id::Int64;) -> Order
+
+Find purchase order by ID
+
+For valid response try integer IDs with value <= 5 or > 10. Other values will generate exceptions
+
+### Required Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **req** | **HTTP.Request** | The HTTP Request object |
+**order_id** | **Int64**| ID of pet that needs to be fetched | [default to nothing]
+
+### Return type
+
+[**Order**](Order.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **place_order**
+> place_order(req::HTTP.Request, order::Order;) -> Order
+
+Place an order for a pet
+
+
+
+### Required Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **req** | **HTTP.Request** | The HTTP Request object |
+**order** | [**Order**](Order.md)| order placed for purchasing the pet |
+
+### Return type
+
+[**Order**](Order.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
diff --git a/test/server/openapigenerator_petstore_v3/petstore/docs/Tag.md b/test/server/openapigenerator_petstore_v3/petstore/docs/Tag.md
new file mode 100644
index 0000000..ee2633c
--- /dev/null
+++ b/test/server/openapigenerator_petstore_v3/petstore/docs/Tag.md
@@ -0,0 +1,13 @@
+# Tag
+
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**name** | **String** | | [optional] [default to nothing]
+**id** | **Int64** | | [optional] [default to nothing]
+
+
+[[Back to Model list]](../README.md#models) [[Back to API list]](../README.md#api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/test/server/openapigenerator_petstore_v3/petstore/docs/User.md b/test/server/openapigenerator_petstore_v3/petstore/docs/User.md
new file mode 100644
index 0000000..3db4060
--- /dev/null
+++ b/test/server/openapigenerator_petstore_v3/petstore/docs/User.md
@@ -0,0 +1,19 @@
+# User
+
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**password** | **String** | | [optional] [default to nothing]
+**id** | **Int64** | | [optional] [default to nothing]
+**username** | **String** | | [optional] [default to nothing]
+**firstName** | **String** | | [optional] [default to nothing]
+**lastName** | **String** | | [optional] [default to nothing]
+**phone** | **String** | | [optional] [default to nothing]
+**userStatus** | **Int64** | User Status | [optional] [default to nothing]
+**email** | **String** | | [optional] [default to nothing]
+
+
+[[Back to Model list]](../README.md#models) [[Back to API list]](../README.md#api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/test/server/openapigenerator_petstore_v3/petstore/docs/UserApi.md b/test/server/openapigenerator_petstore_v3/petstore/docs/UserApi.md
new file mode 100644
index 0000000..6f8cbb3
--- /dev/null
+++ b/test/server/openapigenerator_petstore_v3/petstore/docs/UserApi.md
@@ -0,0 +1,246 @@
+# UserApi
+
+All URIs are relative to */v3*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**create_user**](UserApi.md#create_user) | **POST** /user | Create user
+[**create_users_with_array_input**](UserApi.md#create_users_with_array_input) | **POST** /user/createWithArray | Creates list of users with given input array
+[**create_users_with_list_input**](UserApi.md#create_users_with_list_input) | **POST** /user/createWithList | Creates list of users with given input array
+[**delete_user**](UserApi.md#delete_user) | **DELETE** /user/{username} | Delete user
+[**get_user_by_name**](UserApi.md#get_user_by_name) | **GET** /user/{username} | Get user by user name
+[**login_user**](UserApi.md#login_user) | **GET** /user/login | Logs user into the system
+[**logout_user**](UserApi.md#logout_user) | **GET** /user/logout | Logs out current logged in user session
+[**update_user**](UserApi.md#update_user) | **PUT** /user/{username} | Updated user
+
+
+# **create_user**
+> create_user(req::HTTP.Request, user::User;) -> Nothing
+
+Create user
+
+This can only be done by the logged in user.
+
+### Required Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **req** | **HTTP.Request** | The HTTP Request object |
+**user** | [**User**](User.md)| Created user object |
+
+### Return type
+
+Nothing
+
+### Authorization
+
+[api_key](../README.md#api_key)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **create_users_with_array_input**
+> create_users_with_array_input(req::HTTP.Request, user::Vector{User};) -> Nothing
+
+Creates list of users with given input array
+
+
+
+### Required Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **req** | **HTTP.Request** | The HTTP Request object |
+**user** | [**Vector{User}**](User.md)| List of user object |
+
+### Return type
+
+Nothing
+
+### Authorization
+
+[api_key](../README.md#api_key)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **create_users_with_list_input**
+> create_users_with_list_input(req::HTTP.Request, user::Vector{User};) -> Nothing
+
+Creates list of users with given input array
+
+
+
+### Required Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **req** | **HTTP.Request** | The HTTP Request object |
+**user** | [**Vector{User}**](User.md)| List of user object |
+
+### Return type
+
+Nothing
+
+### Authorization
+
+[api_key](../README.md#api_key)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **delete_user**
+> delete_user(req::HTTP.Request, username::String;) -> Nothing
+
+Delete user
+
+This can only be done by the logged in user.
+
+### Required Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **req** | **HTTP.Request** | The HTTP Request object |
+**username** | **String**| The name that needs to be deleted | [default to nothing]
+
+### Return type
+
+Nothing
+
+### Authorization
+
+[api_key](../README.md#api_key)
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **get_user_by_name**
+> get_user_by_name(req::HTTP.Request, username::String;) -> User
+
+Get user by user name
+
+
+
+### Required Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **req** | **HTTP.Request** | The HTTP Request object |
+**username** | **String**| The name that needs to be fetched. Use user1 for testing. | [default to nothing]
+
+### Return type
+
+[**User**](User.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **login_user**
+> login_user(req::HTTP.Request, username::String, password::String;) -> String
+
+Logs user into the system
+
+
+
+### Required Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **req** | **HTTP.Request** | The HTTP Request object |
+**username** | **String**| The user name for login | [default to nothing]
+**password** | **String**| The password for login in clear text | [default to nothing]
+
+### Return type
+
+**String**
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **logout_user**
+> logout_user(req::HTTP.Request;) -> Nothing
+
+Logs out current logged in user session
+
+
+
+### Required Parameters
+This endpoint does not need any parameter.
+
+### Return type
+
+Nothing
+
+### Authorization
+
+[api_key](../README.md#api_key)
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **update_user**
+> update_user(req::HTTP.Request, username::String, user::User;) -> Nothing
+
+Updated user
+
+This can only be done by the logged in user.
+
+### Required Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **req** | **HTTP.Request** | The HTTP Request object |
+**username** | **String**| name that need to be deleted | [default to nothing]
+**user** | [**User**](User.md)| Updated user object |
+
+### Return type
+
+Nothing
+
+### Authorization
+
+[api_key](../README.md#api_key)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
diff --git a/test/server/openapigenerator_petstore_v3/petstore/src/OpenAPIGenPetStoreServer.jl b/test/server/openapigenerator_petstore_v3/petstore/src/OpenAPIGenPetStoreServer.jl
new file mode 100644
index 0000000..a68d7d9
--- /dev/null
+++ b/test/server/openapigenerator_petstore_v3/petstore/src/OpenAPIGenPetStoreServer.jl
@@ -0,0 +1,123 @@
+# This file was generated by the Julia OpenAPI Code Generator
+# Do not modify this file directly. Modify the OpenAPI specification instead.
+
+
+@doc raw"""
+Encapsulates generated server code for OpenAPIGenPetStoreServer
+
+The following server methods must be implemented:
+
+- **add_pet**
+ - *invocation:* POST /pet
+ - *signature:* add_pet(req::HTTP.Request, pet::Pet;) -> Pet
+- **delete_pet**
+ - *invocation:* DELETE /pet/{petId}
+ - *signature:* delete_pet(req::HTTP.Request, pet_id::Int64; api_key=nothing,) -> Nothing
+- **find_pets_by_status**
+ - *invocation:* GET /pet/findByStatus
+ - *signature:* find_pets_by_status(req::HTTP.Request, status::Vector{String};) -> Vector{Pet}
+- **find_pets_by_tags**
+ - *invocation:* GET /pet/findByTags
+ - *signature:* find_pets_by_tags(req::HTTP.Request, tags::Vector{String};) -> Vector{Pet}
+- **get_pet_by_id**
+ - *invocation:* GET /pet/{petId}
+ - *signature:* get_pet_by_id(req::HTTP.Request, pet_id::Int64;) -> Pet
+- **update_pet**
+ - *invocation:* PUT /pet
+ - *signature:* update_pet(req::HTTP.Request, pet::Pet;) -> Pet
+- **update_pet_with_form**
+ - *invocation:* POST /pet/{petId}
+ - *signature:* update_pet_with_form(req::HTTP.Request, pet_id::Int64; name=nothing, status=nothing,) -> Nothing
+- **upload_file**
+ - *invocation:* POST /pet/{petId}/uploadImage
+ - *signature:* upload_file(req::HTTP.Request, pet_id::Int64; file=nothing, additional_metadata=nothing,) -> ApiResponse
+- **delete_order**
+ - *invocation:* DELETE /store/order/{orderId}
+ - *signature:* delete_order(req::HTTP.Request, order_id::String;) -> Nothing
+- **get_inventory**
+ - *invocation:* GET /store/inventory
+ - *signature:* get_inventory(req::HTTP.Request;) -> Dict{String, Int64}
+- **get_order_by_id**
+ - *invocation:* GET /store/order/{orderId}
+ - *signature:* get_order_by_id(req::HTTP.Request, order_id::Int64;) -> Order
+- **place_order**
+ - *invocation:* POST /store/order
+ - *signature:* place_order(req::HTTP.Request, order::Order;) -> Order
+- **create_user**
+ - *invocation:* POST /user
+ - *signature:* create_user(req::HTTP.Request, user::User;) -> Nothing
+- **create_users_with_array_input**
+ - *invocation:* POST /user/createWithArray
+ - *signature:* create_users_with_array_input(req::HTTP.Request, user::Vector{User};) -> Nothing
+- **create_users_with_list_input**
+ - *invocation:* POST /user/createWithList
+ - *signature:* create_users_with_list_input(req::HTTP.Request, user::Vector{User};) -> Nothing
+- **delete_user**
+ - *invocation:* DELETE /user/{username}
+ - *signature:* delete_user(req::HTTP.Request, username::String;) -> Nothing
+- **get_user_by_name**
+ - *invocation:* GET /user/{username}
+ - *signature:* get_user_by_name(req::HTTP.Request, username::String;) -> User
+- **login_user**
+ - *invocation:* GET /user/login
+ - *signature:* login_user(req::HTTP.Request, username::String, password::String;) -> String
+- **logout_user**
+ - *invocation:* GET /user/logout
+ - *signature:* logout_user(req::HTTP.Request;) -> Nothing
+- **update_user**
+ - *invocation:* PUT /user/{username}
+ - *signature:* update_user(req::HTTP.Request, username::String, user::User;) -> Nothing
+"""
+module OpenAPIGenPetStoreServer
+
+using HTTP
+using URIs
+using Dates
+using TimeZones
+using OpenAPI
+using OpenAPI.Servers
+
+const API_VERSION = "1.0.0"
+
+include("modelincludes.jl")
+
+include("apis/api_PetApi.jl")
+include("apis/api_StoreApi.jl")
+include("apis/api_UserApi.jl")
+
+"""
+Register handlers for all APIs in this module in the supplied `Router` instance.
+
+Paramerets:
+- `router`: Router to register handlers in
+- `impl`: module that implements the server methods
+
+Optional parameters:
+- `path_prefix`: prefix to be applied to all paths
+- `optional_middlewares`: Register one or more optional middlewares to be applied to all requests.
+
+Optional middlewares can be one or more of:
+ - `init`: called before the request is processed
+ - `pre_validation`: called after the request is parsed but before validation
+ - `pre_invoke`: called after validation but before the handler is invoked
+ - `post_invoke`: called after the handler is invoked but before the response is sent
+
+The order in which middlewares are invoked are:
+`init |> read |> pre_validation |> validate |> pre_invoke |> invoke |> post_invoke`
+"""
+function register(router::HTTP.Router, impl; path_prefix::String="", optional_middlewares...)
+ registerPetApi(router, impl; path_prefix=path_prefix, optional_middlewares...)
+ registerStoreApi(router, impl; path_prefix=path_prefix, optional_middlewares...)
+ registerUserApi(router, impl; path_prefix=path_prefix, optional_middlewares...)
+ return router
+end
+
+# export models
+export ApiResponse
+export Category
+export Order
+export Pet
+export Tag
+export User
+
+end # module OpenAPIGenPetStoreServer
diff --git a/test/server/openapigenerator_petstore_v3/petstore/src/apis/api_PetApi.jl b/test/server/openapigenerator_petstore_v3/petstore/src/apis/api_PetApi.jl
new file mode 100644
index 0000000..9484444
--- /dev/null
+++ b/test/server/openapigenerator_petstore_v3/petstore/src/apis/api_PetApi.jl
@@ -0,0 +1,248 @@
+# This file was generated by the Julia OpenAPI Code Generator
+# Do not modify this file directly. Modify the OpenAPI specification instead.
+
+
+function add_pet_read(handler)
+ function add_pet_read_handler(req::HTTP.Request)
+ openapi_params = Dict{String,Any}()
+ openapi_params["Pet"] = OpenAPI.Servers.to_param_type(Pet, String(req.body))
+ req.context[:openapi_params] = openapi_params
+
+ return handler(req)
+ end
+end
+
+function add_pet_validate(handler)
+ function add_pet_validate_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+
+ return handler(req)
+ end
+end
+
+function add_pet_invoke(impl; post_invoke=nothing)
+ function add_pet_invoke_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+ ret = impl.add_pet(req::HTTP.Request, openapi_params["Pet"];)
+ resp = OpenAPI.Servers.server_response(ret)
+ return (post_invoke === nothing) ? resp : post_invoke(req, resp)
+ end
+end
+
+function delete_pet_read(handler)
+ function delete_pet_read_handler(req::HTTP.Request)
+ openapi_params = Dict{String,Any}()
+ path_params = HTTP.getparams(req)
+ openapi_params["petId"] = OpenAPI.Servers.to_param(Int64, path_params, "petId", required=true, )
+ headers = Dict{String,String}(HTTP.headers(req))
+ openapi_params["api_key"] = OpenAPI.Servers.to_param(String, headers, "api_key", )
+ req.context[:openapi_params] = openapi_params
+
+ return handler(req)
+ end
+end
+
+function delete_pet_validate(handler)
+ function delete_pet_validate_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+
+ return handler(req)
+ end
+end
+
+function delete_pet_invoke(impl; post_invoke=nothing)
+ function delete_pet_invoke_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+ ret = impl.delete_pet(req::HTTP.Request, openapi_params["petId"]; api_key=get(openapi_params, "api_key", nothing),)
+ resp = OpenAPI.Servers.server_response(ret)
+ return (post_invoke === nothing) ? resp : post_invoke(req, resp)
+ end
+end
+
+function find_pets_by_status_read(handler)
+ function find_pets_by_status_read_handler(req::HTTP.Request)
+ openapi_params = Dict{String,Any}()
+ query_params = HTTP.queryparams(URIs.URI(req.target))
+ openapi_params["status"] = OpenAPI.Servers.to_param(Vector{String}, query_params, "status", required=true, )
+ req.context[:openapi_params] = openapi_params
+
+ return handler(req)
+ end
+end
+
+function find_pets_by_status_validate(handler)
+ function find_pets_by_status_validate_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+
+ return handler(req)
+ end
+end
+
+function find_pets_by_status_invoke(impl; post_invoke=nothing)
+ function find_pets_by_status_invoke_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+ ret = impl.find_pets_by_status(req::HTTP.Request, openapi_params["status"];)
+ resp = OpenAPI.Servers.server_response(ret)
+ return (post_invoke === nothing) ? resp : post_invoke(req, resp)
+ end
+end
+
+function find_pets_by_tags_read(handler)
+ function find_pets_by_tags_read_handler(req::HTTP.Request)
+ openapi_params = Dict{String,Any}()
+ query_params = HTTP.queryparams(URIs.URI(req.target))
+ openapi_params["tags"] = OpenAPI.Servers.to_param(Vector{String}, query_params, "tags", required=true, )
+ req.context[:openapi_params] = openapi_params
+
+ return handler(req)
+ end
+end
+
+function find_pets_by_tags_validate(handler)
+ function find_pets_by_tags_validate_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+
+ return handler(req)
+ end
+end
+
+function find_pets_by_tags_invoke(impl; post_invoke=nothing)
+ function find_pets_by_tags_invoke_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+ ret = impl.find_pets_by_tags(req::HTTP.Request, openapi_params["tags"];)
+ resp = OpenAPI.Servers.server_response(ret)
+ return (post_invoke === nothing) ? resp : post_invoke(req, resp)
+ end
+end
+
+function get_pet_by_id_read(handler)
+ function get_pet_by_id_read_handler(req::HTTP.Request)
+ openapi_params = Dict{String,Any}()
+ path_params = HTTP.getparams(req)
+ openapi_params["petId"] = OpenAPI.Servers.to_param(Int64, path_params, "petId", required=true, )
+ req.context[:openapi_params] = openapi_params
+
+ return handler(req)
+ end
+end
+
+function get_pet_by_id_validate(handler)
+ function get_pet_by_id_validate_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+
+ return handler(req)
+ end
+end
+
+function get_pet_by_id_invoke(impl; post_invoke=nothing)
+ function get_pet_by_id_invoke_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+ ret = impl.get_pet_by_id(req::HTTP.Request, openapi_params["petId"];)
+ resp = OpenAPI.Servers.server_response(ret)
+ return (post_invoke === nothing) ? resp : post_invoke(req, resp)
+ end
+end
+
+function update_pet_read(handler)
+ function update_pet_read_handler(req::HTTP.Request)
+ openapi_params = Dict{String,Any}()
+ openapi_params["Pet"] = OpenAPI.Servers.to_param_type(Pet, String(req.body))
+ req.context[:openapi_params] = openapi_params
+
+ return handler(req)
+ end
+end
+
+function update_pet_validate(handler)
+ function update_pet_validate_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+
+ return handler(req)
+ end
+end
+
+function update_pet_invoke(impl; post_invoke=nothing)
+ function update_pet_invoke_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+ ret = impl.update_pet(req::HTTP.Request, openapi_params["Pet"];)
+ resp = OpenAPI.Servers.server_response(ret)
+ return (post_invoke === nothing) ? resp : post_invoke(req, resp)
+ end
+end
+
+function update_pet_with_form_read(handler)
+ function update_pet_with_form_read_handler(req::HTTP.Request)
+ openapi_params = Dict{String,Any}()
+ path_params = HTTP.getparams(req)
+ openapi_params["petId"] = OpenAPI.Servers.to_param(Int64, path_params, "petId", required=true, )
+ ismultipart = false
+ form_data = ismultipart ? HTTP.parse_multipart_form(req) : HTTP.queryparams(String(copy(req.body)))
+ openapi_params["name"] = OpenAPI.Servers.to_param(String, form_data, "name"; multipart=ismultipart, isfile=false, )
+ openapi_params["status"] = OpenAPI.Servers.to_param(String, form_data, "status"; multipart=ismultipart, isfile=false, )
+ req.context[:openapi_params] = openapi_params
+
+ return handler(req)
+ end
+end
+
+function update_pet_with_form_validate(handler)
+ function update_pet_with_form_validate_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+
+ return handler(req)
+ end
+end
+
+function update_pet_with_form_invoke(impl; post_invoke=nothing)
+ function update_pet_with_form_invoke_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+ ret = impl.update_pet_with_form(req::HTTP.Request, openapi_params["petId"]; name=get(openapi_params, "name", nothing), status=get(openapi_params, "status", nothing),)
+ resp = OpenAPI.Servers.server_response(ret)
+ return (post_invoke === nothing) ? resp : post_invoke(req, resp)
+ end
+end
+
+function upload_file_read(handler)
+ function upload_file_read_handler(req::HTTP.Request)
+ openapi_params = Dict{String,Any}()
+ path_params = HTTP.getparams(req)
+ openapi_params["petId"] = OpenAPI.Servers.to_param(Int64, path_params, "petId", required=true, )
+ ismultipart = true
+ form_data = ismultipart ? HTTP.parse_multipart_form(req) : HTTP.queryparams(String(copy(req.body)))
+ openapi_params["file"] = OpenAPI.Servers.to_param(Vector{UInt8}, form_data, "file"; multipart=ismultipart, isfile=true, )
+ openapi_params["additionalMetadata"] = OpenAPI.Servers.to_param(String, form_data, "additionalMetadata"; multipart=ismultipart, isfile=false, )
+ req.context[:openapi_params] = openapi_params
+
+ return handler(req)
+ end
+end
+
+function upload_file_validate(handler)
+ function upload_file_validate_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+
+ return handler(req)
+ end
+end
+
+function upload_file_invoke(impl; post_invoke=nothing)
+ function upload_file_invoke_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+ ret = impl.upload_file(req::HTTP.Request, openapi_params["petId"]; file=get(openapi_params, "file", nothing), additional_metadata=get(openapi_params, "additionalMetadata", nothing),)
+ resp = OpenAPI.Servers.server_response(ret)
+ return (post_invoke === nothing) ? resp : post_invoke(req, resp)
+ end
+end
+
+
+function registerPetApi(router::HTTP.Router, impl; path_prefix::String="", optional_middlewares...)
+ HTTP.register!(router, "POST", path_prefix * "/pet", OpenAPI.Servers.middleware(impl, add_pet_read, add_pet_validate, add_pet_invoke; optional_middlewares...))
+ HTTP.register!(router, "DELETE", path_prefix * "/pet/{petId}", OpenAPI.Servers.middleware(impl, delete_pet_read, delete_pet_validate, delete_pet_invoke; optional_middlewares...))
+ HTTP.register!(router, "GET", path_prefix * "/pet/findByStatus", OpenAPI.Servers.middleware(impl, find_pets_by_status_read, find_pets_by_status_validate, find_pets_by_status_invoke; optional_middlewares...))
+ HTTP.register!(router, "GET", path_prefix * "/pet/findByTags", OpenAPI.Servers.middleware(impl, find_pets_by_tags_read, find_pets_by_tags_validate, find_pets_by_tags_invoke; optional_middlewares...))
+ HTTP.register!(router, "GET", path_prefix * "/pet/{petId}", OpenAPI.Servers.middleware(impl, get_pet_by_id_read, get_pet_by_id_validate, get_pet_by_id_invoke; optional_middlewares...))
+ HTTP.register!(router, "PUT", path_prefix * "/pet", OpenAPI.Servers.middleware(impl, update_pet_read, update_pet_validate, update_pet_invoke; optional_middlewares...))
+ HTTP.register!(router, "POST", path_prefix * "/pet/{petId}", OpenAPI.Servers.middleware(impl, update_pet_with_form_read, update_pet_with_form_validate, update_pet_with_form_invoke; optional_middlewares...))
+ HTTP.register!(router, "POST", path_prefix * "/pet/{petId}/uploadImage", OpenAPI.Servers.middleware(impl, upload_file_read, upload_file_validate, upload_file_invoke; optional_middlewares...))
+ return router
+end
diff --git a/test/server/openapigenerator_petstore_v3/petstore/src/apis/api_StoreApi.jl b/test/server/openapigenerator_petstore_v3/petstore/src/apis/api_StoreApi.jl
new file mode 100644
index 0000000..b982905
--- /dev/null
+++ b/test/server/openapigenerator_petstore_v3/petstore/src/apis/api_StoreApi.jl
@@ -0,0 +1,124 @@
+# This file was generated by the Julia OpenAPI Code Generator
+# Do not modify this file directly. Modify the OpenAPI specification instead.
+
+
+function delete_order_read(handler)
+ function delete_order_read_handler(req::HTTP.Request)
+ openapi_params = Dict{String,Any}()
+ path_params = HTTP.getparams(req)
+ openapi_params["orderId"] = OpenAPI.Servers.to_param(String, path_params, "orderId", required=true, )
+ req.context[:openapi_params] = openapi_params
+
+ return handler(req)
+ end
+end
+
+function delete_order_validate(handler)
+ function delete_order_validate_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+
+ return handler(req)
+ end
+end
+
+function delete_order_invoke(impl; post_invoke=nothing)
+ function delete_order_invoke_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+ ret = impl.delete_order(req::HTTP.Request, openapi_params["orderId"];)
+ resp = OpenAPI.Servers.server_response(ret)
+ return (post_invoke === nothing) ? resp : post_invoke(req, resp)
+ end
+end
+
+function get_inventory_read(handler)
+ function get_inventory_read_handler(req::HTTP.Request)
+ openapi_params = Dict{String,Any}()
+ req.context[:openapi_params] = openapi_params
+
+ return handler(req)
+ end
+end
+
+function get_inventory_validate(handler)
+ function get_inventory_validate_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+
+ return handler(req)
+ end
+end
+
+function get_inventory_invoke(impl; post_invoke=nothing)
+ function get_inventory_invoke_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+ ret = impl.get_inventory(req::HTTP.Request;)
+ resp = OpenAPI.Servers.server_response(ret)
+ return (post_invoke === nothing) ? resp : post_invoke(req, resp)
+ end
+end
+
+function get_order_by_id_read(handler)
+ function get_order_by_id_read_handler(req::HTTP.Request)
+ openapi_params = Dict{String,Any}()
+ path_params = HTTP.getparams(req)
+ openapi_params["orderId"] = OpenAPI.Servers.to_param(Int64, path_params, "orderId", required=true, )
+ req.context[:openapi_params] = openapi_params
+
+ return handler(req)
+ end
+end
+
+function get_order_by_id_validate(handler)
+ function get_order_by_id_validate_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+
+ OpenAPI.validate_param("orderId", "get_order_by_id", :maximum, openapi_params["orderId"], 5, false)
+ OpenAPI.validate_param("orderId", "get_order_by_id", :minimum, openapi_params["orderId"], 1, false)
+
+ return handler(req)
+ end
+end
+
+function get_order_by_id_invoke(impl; post_invoke=nothing)
+ function get_order_by_id_invoke_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+ ret = impl.get_order_by_id(req::HTTP.Request, openapi_params["orderId"];)
+ resp = OpenAPI.Servers.server_response(ret)
+ return (post_invoke === nothing) ? resp : post_invoke(req, resp)
+ end
+end
+
+function place_order_read(handler)
+ function place_order_read_handler(req::HTTP.Request)
+ openapi_params = Dict{String,Any}()
+ openapi_params["Order"] = OpenAPI.Servers.to_param_type(Order, String(req.body))
+ req.context[:openapi_params] = openapi_params
+
+ return handler(req)
+ end
+end
+
+function place_order_validate(handler)
+ function place_order_validate_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+
+ return handler(req)
+ end
+end
+
+function place_order_invoke(impl; post_invoke=nothing)
+ function place_order_invoke_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+ ret = impl.place_order(req::HTTP.Request, openapi_params["Order"];)
+ resp = OpenAPI.Servers.server_response(ret)
+ return (post_invoke === nothing) ? resp : post_invoke(req, resp)
+ end
+end
+
+
+function registerStoreApi(router::HTTP.Router, impl; path_prefix::String="", optional_middlewares...)
+ HTTP.register!(router, "DELETE", path_prefix * "/store/order/{orderId}", OpenAPI.Servers.middleware(impl, delete_order_read, delete_order_validate, delete_order_invoke; optional_middlewares...))
+ HTTP.register!(router, "GET", path_prefix * "/store/inventory", OpenAPI.Servers.middleware(impl, get_inventory_read, get_inventory_validate, get_inventory_invoke; optional_middlewares...))
+ HTTP.register!(router, "GET", path_prefix * "/store/order/{orderId}", OpenAPI.Servers.middleware(impl, get_order_by_id_read, get_order_by_id_validate, get_order_by_id_invoke; optional_middlewares...))
+ HTTP.register!(router, "POST", path_prefix * "/store/order", OpenAPI.Servers.middleware(impl, place_order_read, place_order_validate, place_order_invoke; optional_middlewares...))
+ return router
+end
diff --git a/test/server/openapigenerator_petstore_v3/petstore/src/apis/api_UserApi.jl b/test/server/openapigenerator_petstore_v3/petstore/src/apis/api_UserApi.jl
new file mode 100644
index 0000000..f8033b3
--- /dev/null
+++ b/test/server/openapigenerator_petstore_v3/petstore/src/apis/api_UserApi.jl
@@ -0,0 +1,238 @@
+# This file was generated by the Julia OpenAPI Code Generator
+# Do not modify this file directly. Modify the OpenAPI specification instead.
+
+
+function create_user_read(handler)
+ function create_user_read_handler(req::HTTP.Request)
+ openapi_params = Dict{String,Any}()
+ openapi_params["User"] = OpenAPI.Servers.to_param_type(User, String(req.body))
+ req.context[:openapi_params] = openapi_params
+
+ return handler(req)
+ end
+end
+
+function create_user_validate(handler)
+ function create_user_validate_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+
+ return handler(req)
+ end
+end
+
+function create_user_invoke(impl; post_invoke=nothing)
+ function create_user_invoke_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+ ret = impl.create_user(req::HTTP.Request, openapi_params["User"];)
+ resp = OpenAPI.Servers.server_response(ret)
+ return (post_invoke === nothing) ? resp : post_invoke(req, resp)
+ end
+end
+
+function create_users_with_array_input_read(handler)
+ function create_users_with_array_input_read_handler(req::HTTP.Request)
+ openapi_params = Dict{String,Any}()
+ openapi_params["User"] = OpenAPI.Servers.to_param_type(Vector{User}, String(req.body))
+ req.context[:openapi_params] = openapi_params
+
+ return handler(req)
+ end
+end
+
+function create_users_with_array_input_validate(handler)
+ function create_users_with_array_input_validate_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+
+ return handler(req)
+ end
+end
+
+function create_users_with_array_input_invoke(impl; post_invoke=nothing)
+ function create_users_with_array_input_invoke_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+ ret = impl.create_users_with_array_input(req::HTTP.Request, openapi_params["User"];)
+ resp = OpenAPI.Servers.server_response(ret)
+ return (post_invoke === nothing) ? resp : post_invoke(req, resp)
+ end
+end
+
+function create_users_with_list_input_read(handler)
+ function create_users_with_list_input_read_handler(req::HTTP.Request)
+ openapi_params = Dict{String,Any}()
+ openapi_params["User"] = OpenAPI.Servers.to_param_type(Vector{User}, String(req.body))
+ req.context[:openapi_params] = openapi_params
+
+ return handler(req)
+ end
+end
+
+function create_users_with_list_input_validate(handler)
+ function create_users_with_list_input_validate_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+
+ return handler(req)
+ end
+end
+
+function create_users_with_list_input_invoke(impl; post_invoke=nothing)
+ function create_users_with_list_input_invoke_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+ ret = impl.create_users_with_list_input(req::HTTP.Request, openapi_params["User"];)
+ resp = OpenAPI.Servers.server_response(ret)
+ return (post_invoke === nothing) ? resp : post_invoke(req, resp)
+ end
+end
+
+function delete_user_read(handler)
+ function delete_user_read_handler(req::HTTP.Request)
+ openapi_params = Dict{String,Any}()
+ path_params = HTTP.getparams(req)
+ openapi_params["username"] = OpenAPI.Servers.to_param(String, path_params, "username", required=true, )
+ req.context[:openapi_params] = openapi_params
+
+ return handler(req)
+ end
+end
+
+function delete_user_validate(handler)
+ function delete_user_validate_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+
+ return handler(req)
+ end
+end
+
+function delete_user_invoke(impl; post_invoke=nothing)
+ function delete_user_invoke_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+ ret = impl.delete_user(req::HTTP.Request, openapi_params["username"];)
+ resp = OpenAPI.Servers.server_response(ret)
+ return (post_invoke === nothing) ? resp : post_invoke(req, resp)
+ end
+end
+
+function get_user_by_name_read(handler)
+ function get_user_by_name_read_handler(req::HTTP.Request)
+ openapi_params = Dict{String,Any}()
+ path_params = HTTP.getparams(req)
+ openapi_params["username"] = OpenAPI.Servers.to_param(String, path_params, "username", required=true, )
+ req.context[:openapi_params] = openapi_params
+
+ return handler(req)
+ end
+end
+
+function get_user_by_name_validate(handler)
+ function get_user_by_name_validate_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+
+ return handler(req)
+ end
+end
+
+function get_user_by_name_invoke(impl; post_invoke=nothing)
+ function get_user_by_name_invoke_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+ ret = impl.get_user_by_name(req::HTTP.Request, openapi_params["username"];)
+ resp = OpenAPI.Servers.server_response(ret)
+ return (post_invoke === nothing) ? resp : post_invoke(req, resp)
+ end
+end
+
+function login_user_read(handler)
+ function login_user_read_handler(req::HTTP.Request)
+ openapi_params = Dict{String,Any}()
+ query_params = HTTP.queryparams(URIs.URI(req.target))
+ openapi_params["username"] = OpenAPI.Servers.to_param(String, query_params, "username", required=true, )
+ openapi_params["password"] = OpenAPI.Servers.to_param(String, query_params, "password", required=true, )
+ req.context[:openapi_params] = openapi_params
+
+ return handler(req)
+ end
+end
+
+function login_user_validate(handler)
+ function login_user_validate_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+
+
+ return handler(req)
+ end
+end
+
+function login_user_invoke(impl; post_invoke=nothing)
+ function login_user_invoke_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+ ret = impl.login_user(req::HTTP.Request, openapi_params["username"], openapi_params["password"];)
+ resp = OpenAPI.Servers.server_response(ret)
+ return (post_invoke === nothing) ? resp : post_invoke(req, resp)
+ end
+end
+
+function logout_user_read(handler)
+ function logout_user_read_handler(req::HTTP.Request)
+ openapi_params = Dict{String,Any}()
+ req.context[:openapi_params] = openapi_params
+
+ return handler(req)
+ end
+end
+
+function logout_user_validate(handler)
+ function logout_user_validate_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+
+ return handler(req)
+ end
+end
+
+function logout_user_invoke(impl; post_invoke=nothing)
+ function logout_user_invoke_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+ ret = impl.logout_user(req::HTTP.Request;)
+ resp = OpenAPI.Servers.server_response(ret)
+ return (post_invoke === nothing) ? resp : post_invoke(req, resp)
+ end
+end
+
+function update_user_read(handler)
+ function update_user_read_handler(req::HTTP.Request)
+ openapi_params = Dict{String,Any}()
+ path_params = HTTP.getparams(req)
+ openapi_params["username"] = OpenAPI.Servers.to_param(String, path_params, "username", required=true, )
+ openapi_params["User"] = OpenAPI.Servers.to_param_type(User, String(req.body))
+ req.context[:openapi_params] = openapi_params
+
+ return handler(req)
+ end
+end
+
+function update_user_validate(handler)
+ function update_user_validate_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+
+ return handler(req)
+ end
+end
+
+function update_user_invoke(impl; post_invoke=nothing)
+ function update_user_invoke_handler(req::HTTP.Request)
+ openapi_params = req.context[:openapi_params]
+ ret = impl.update_user(req::HTTP.Request, openapi_params["username"], openapi_params["User"];)
+ resp = OpenAPI.Servers.server_response(ret)
+ return (post_invoke === nothing) ? resp : post_invoke(req, resp)
+ end
+end
+
+
+function registerUserApi(router::HTTP.Router, impl; path_prefix::String="", optional_middlewares...)
+ HTTP.register!(router, "POST", path_prefix * "/user", OpenAPI.Servers.middleware(impl, create_user_read, create_user_validate, create_user_invoke; optional_middlewares...))
+ HTTP.register!(router, "POST", path_prefix * "/user/createWithArray", OpenAPI.Servers.middleware(impl, create_users_with_array_input_read, create_users_with_array_input_validate, create_users_with_array_input_invoke; optional_middlewares...))
+ HTTP.register!(router, "POST", path_prefix * "/user/createWithList", OpenAPI.Servers.middleware(impl, create_users_with_list_input_read, create_users_with_list_input_validate, create_users_with_list_input_invoke; optional_middlewares...))
+ HTTP.register!(router, "DELETE", path_prefix * "/user/{username}", OpenAPI.Servers.middleware(impl, delete_user_read, delete_user_validate, delete_user_invoke; optional_middlewares...))
+ HTTP.register!(router, "GET", path_prefix * "/user/{username}", OpenAPI.Servers.middleware(impl, get_user_by_name_read, get_user_by_name_validate, get_user_by_name_invoke; optional_middlewares...))
+ HTTP.register!(router, "GET", path_prefix * "/user/login", OpenAPI.Servers.middleware(impl, login_user_read, login_user_validate, login_user_invoke; optional_middlewares...))
+ HTTP.register!(router, "GET", path_prefix * "/user/logout", OpenAPI.Servers.middleware(impl, logout_user_read, logout_user_validate, logout_user_invoke; optional_middlewares...))
+ HTTP.register!(router, "PUT", path_prefix * "/user/{username}", OpenAPI.Servers.middleware(impl, update_user_read, update_user_validate, update_user_invoke; optional_middlewares...))
+ return router
+end
diff --git a/test/server/openapigenerator_petstore_v3/petstore/src/modelincludes.jl b/test/server/openapigenerator_petstore_v3/petstore/src/modelincludes.jl
new file mode 100644
index 0000000..b3a3db8
--- /dev/null
+++ b/test/server/openapigenerator_petstore_v3/petstore/src/modelincludes.jl
@@ -0,0 +1,9 @@
+# This file was generated by the Julia OpenAPI Code Generator
+# Do not modify this file directly. Modify the OpenAPI specification instead.
+
+include("models/model_ApiResponse.jl")
+include("models/model_Category.jl")
+include("models/model_Order.jl")
+include("models/model_Pet.jl")
+include("models/model_Tag.jl")
+include("models/model_User.jl")
diff --git a/test/server/openapigenerator_petstore_v3/petstore/src/models/model_ApiResponse.jl b/test/server/openapigenerator_petstore_v3/petstore/src/models/model_ApiResponse.jl
new file mode 100644
index 0000000..e19464b
--- /dev/null
+++ b/test/server/openapigenerator_petstore_v3/petstore/src/models/model_ApiResponse.jl
@@ -0,0 +1,42 @@
+# This file was generated by the Julia OpenAPI Code Generator
+# Do not modify this file directly. Modify the OpenAPI specification instead.
+
+
+@doc raw"""ApiResponse
+Describes the result of uploading an image resource
+
+ ApiResponse(;
+ message=nothing,
+ code=nothing,
+ type=nothing,
+ )
+
+ - message::String
+ - code::Int64
+ - type::String
+"""
+Base.@kwdef mutable struct ApiResponse <: OpenAPI.APIModel
+ message::Union{Nothing, String} = nothing
+ code::Union{Nothing, Int64} = nothing
+ type::Union{Nothing, String} = nothing
+
+ function ApiResponse(message, code, type, )
+ OpenAPI.validate_property(ApiResponse, Symbol("message"), message)
+ OpenAPI.validate_property(ApiResponse, Symbol("code"), code)
+ OpenAPI.validate_property(ApiResponse, Symbol("type"), type)
+ return new(message, code, type, )
+ end
+end # type ApiResponse
+
+const _property_types_ApiResponse = Dict{Symbol,String}(Symbol("message")=>"String", Symbol("code")=>"Int64", Symbol("type")=>"String", )
+OpenAPI.property_type(::Type{ ApiResponse }, name::Symbol) = Union{Nothing,eval(Base.Meta.parse(_property_types_ApiResponse[name]))}
+
+function check_required(o::ApiResponse)
+ true
+end
+
+function OpenAPI.validate_property(::Type{ ApiResponse }, name::Symbol, val)
+ if name === Symbol("code")
+ OpenAPI.validate_param(name, "ApiResponse", :format, val, "int32")
+ end
+end
diff --git a/test/server/openapigenerator_petstore_v3/petstore/src/models/model_Category.jl b/test/server/openapigenerator_petstore_v3/petstore/src/models/model_Category.jl
new file mode 100644
index 0000000..5224efb
--- /dev/null
+++ b/test/server/openapigenerator_petstore_v3/petstore/src/models/model_Category.jl
@@ -0,0 +1,41 @@
+# This file was generated by the Julia OpenAPI Code Generator
+# Do not modify this file directly. Modify the OpenAPI specification instead.
+
+
+@doc raw"""Category
+A category for a pet
+
+ Category(;
+ name=nothing,
+ id=nothing,
+ )
+
+ - name::String
+ - id::Int64
+"""
+Base.@kwdef mutable struct Category <: OpenAPI.APIModel
+ name::Union{Nothing, String} = nothing
+ id::Union{Nothing, Int64} = nothing
+
+ function Category(name, id, )
+ OpenAPI.validate_property(Category, Symbol("name"), name)
+ OpenAPI.validate_property(Category, Symbol("id"), id)
+ return new(name, id, )
+ end
+end # type Category
+
+const _property_types_Category = Dict{Symbol,String}(Symbol("name")=>"String", Symbol("id")=>"Int64", )
+OpenAPI.property_type(::Type{ Category }, name::Symbol) = Union{Nothing,eval(Base.Meta.parse(_property_types_Category[name]))}
+
+function check_required(o::Category)
+ true
+end
+
+function OpenAPI.validate_property(::Type{ Category }, name::Symbol, val)
+ if name === Symbol("name")
+ OpenAPI.validate_param(name, "Category", :pattern, val, r"^[a-zA-Z0-9]+[a-zA-Z0-9\.\-_]*[a-zA-Z0-9]+$")
+ end
+ if name === Symbol("id")
+ OpenAPI.validate_param(name, "Category", :format, val, "int64")
+ end
+end
diff --git a/test/server/openapigenerator_petstore_v3/petstore/src/models/model_Order.jl b/test/server/openapigenerator_petstore_v3/petstore/src/models/model_Order.jl
new file mode 100644
index 0000000..da94163
--- /dev/null
+++ b/test/server/openapigenerator_petstore_v3/petstore/src/models/model_Order.jl
@@ -0,0 +1,66 @@
+# This file was generated by the Julia OpenAPI Code Generator
+# Do not modify this file directly. Modify the OpenAPI specification instead.
+
+
+@doc raw"""Order
+An order for a pets from the pet store
+
+ Order(;
+ petId=nothing,
+ shipDate=nothing,
+ status=nothing,
+ id=nothing,
+ complete=false,
+ quantity=nothing,
+ )
+
+ - petId::Int64
+ - shipDate::ZonedDateTime
+ - status::String : Order Status
+ - id::Int64
+ - complete::Bool
+ - quantity::Int64
+"""
+Base.@kwdef mutable struct Order <: OpenAPI.APIModel
+ petId::Union{Nothing, Int64} = nothing
+ shipDate::Union{Nothing, ZonedDateTime} = nothing
+ status::Union{Nothing, String} = nothing
+ id::Union{Nothing, Int64} = nothing
+ complete::Union{Nothing, Bool} = false
+ quantity::Union{Nothing, Int64} = nothing
+
+ function Order(petId, shipDate, status, id, complete, quantity, )
+ OpenAPI.validate_property(Order, Symbol("petId"), petId)
+ OpenAPI.validate_property(Order, Symbol("shipDate"), shipDate)
+ OpenAPI.validate_property(Order, Symbol("status"), status)
+ OpenAPI.validate_property(Order, Symbol("id"), id)
+ OpenAPI.validate_property(Order, Symbol("complete"), complete)
+ OpenAPI.validate_property(Order, Symbol("quantity"), quantity)
+ return new(petId, shipDate, status, id, complete, quantity, )
+ end
+end # type Order
+
+const _property_types_Order = Dict{Symbol,String}(Symbol("petId")=>"Int64", Symbol("shipDate")=>"ZonedDateTime", Symbol("status")=>"String", Symbol("id")=>"Int64", Symbol("complete")=>"Bool", Symbol("quantity")=>"Int64", )
+OpenAPI.property_type(::Type{ Order }, name::Symbol) = Union{Nothing,eval(Base.Meta.parse(_property_types_Order[name]))}
+
+function check_required(o::Order)
+ true
+end
+
+function OpenAPI.validate_property(::Type{ Order }, name::Symbol, val)
+ if name === Symbol("petId")
+ OpenAPI.validate_param(name, "Order", :format, val, "int64")
+ end
+ if name === Symbol("shipDate")
+ OpenAPI.validate_param(name, "Order", :format, val, "date-time")
+ end
+ if name === Symbol("status")
+ OpenAPI.validate_param(name, "Order", :enum, val, ["placed", "approved", "delivered"])
+ end
+ if name === Symbol("id")
+ OpenAPI.validate_param(name, "Order", :format, val, "int64")
+ end
+ if name === Symbol("quantity")
+ OpenAPI.validate_param(name, "Order", :format, val, "int32")
+ end
+end
diff --git a/test/server/openapigenerator_petstore_v3/petstore/src/models/model_Pet.jl b/test/server/openapigenerator_petstore_v3/petstore/src/models/model_Pet.jl
new file mode 100644
index 0000000..2b4069f
--- /dev/null
+++ b/test/server/openapigenerator_petstore_v3/petstore/src/models/model_Pet.jl
@@ -0,0 +1,59 @@
+# This file was generated by the Julia OpenAPI Code Generator
+# Do not modify this file directly. Modify the OpenAPI specification instead.
+
+
+@doc raw"""Pet
+A pet for sale in the pet store
+
+ Pet(;
+ name=nothing,
+ status=nothing,
+ id=nothing,
+ photoUrls=nothing,
+ tags=nothing,
+ category=nothing,
+ )
+
+ - name::String
+ - status::String : pet status in the store
+ - id::Int64
+ - photoUrls::Vector{String}
+ - tags::Vector{Tag}
+ - category::Category
+"""
+Base.@kwdef mutable struct Pet <: OpenAPI.APIModel
+ name::Union{Nothing, String} = nothing
+ status::Union{Nothing, String} = nothing
+ id::Union{Nothing, Int64} = nothing
+ photoUrls::Union{Nothing, Vector{String}} = nothing
+ tags::Union{Nothing, Vector} = nothing # spec type: Union{ Nothing, Vector{Tag} }
+ category = nothing # spec type: Union{ Nothing, Category }
+
+ function Pet(name, status, id, photoUrls, tags, category, )
+ OpenAPI.validate_property(Pet, Symbol("name"), name)
+ OpenAPI.validate_property(Pet, Symbol("status"), status)
+ OpenAPI.validate_property(Pet, Symbol("id"), id)
+ OpenAPI.validate_property(Pet, Symbol("photoUrls"), photoUrls)
+ OpenAPI.validate_property(Pet, Symbol("tags"), tags)
+ OpenAPI.validate_property(Pet, Symbol("category"), category)
+ return new(name, status, id, photoUrls, tags, category, )
+ end
+end # type Pet
+
+const _property_types_Pet = Dict{Symbol,String}(Symbol("name")=>"String", Symbol("status")=>"String", Symbol("id")=>"Int64", Symbol("photoUrls")=>"Vector{String}", Symbol("tags")=>"Vector{Tag}", Symbol("category")=>"Category", )
+OpenAPI.property_type(::Type{ Pet }, name::Symbol) = Union{Nothing,eval(Base.Meta.parse(_property_types_Pet[name]))}
+
+function check_required(o::Pet)
+ o.name === nothing && (return false)
+ o.photoUrls === nothing && (return false)
+ true
+end
+
+function OpenAPI.validate_property(::Type{ Pet }, name::Symbol, val)
+ if name === Symbol("status")
+ OpenAPI.validate_param(name, "Pet", :enum, val, ["available", "pending", "sold"])
+ end
+ if name === Symbol("id")
+ OpenAPI.validate_param(name, "Pet", :format, val, "int64")
+ end
+end
diff --git a/test/server/openapigenerator_petstore_v3/petstore/src/models/model_Tag.jl b/test/server/openapigenerator_petstore_v3/petstore/src/models/model_Tag.jl
new file mode 100644
index 0000000..f3410e8
--- /dev/null
+++ b/test/server/openapigenerator_petstore_v3/petstore/src/models/model_Tag.jl
@@ -0,0 +1,38 @@
+# This file was generated by the Julia OpenAPI Code Generator
+# Do not modify this file directly. Modify the OpenAPI specification instead.
+
+
+@doc raw"""Tag
+A tag for a pet
+
+ Tag(;
+ name=nothing,
+ id=nothing,
+ )
+
+ - name::String
+ - id::Int64
+"""
+Base.@kwdef mutable struct Tag <: OpenAPI.APIModel
+ name::Union{Nothing, String} = nothing
+ id::Union{Nothing, Int64} = nothing
+
+ function Tag(name, id, )
+ OpenAPI.validate_property(Tag, Symbol("name"), name)
+ OpenAPI.validate_property(Tag, Symbol("id"), id)
+ return new(name, id, )
+ end
+end # type Tag
+
+const _property_types_Tag = Dict{Symbol,String}(Symbol("name")=>"String", Symbol("id")=>"Int64", )
+OpenAPI.property_type(::Type{ Tag }, name::Symbol) = Union{Nothing,eval(Base.Meta.parse(_property_types_Tag[name]))}
+
+function check_required(o::Tag)
+ true
+end
+
+function OpenAPI.validate_property(::Type{ Tag }, name::Symbol, val)
+ if name === Symbol("id")
+ OpenAPI.validate_param(name, "Tag", :format, val, "int64")
+ end
+end
diff --git a/test/server/openapigenerator_petstore_v3/petstore/src/models/model_User.jl b/test/server/openapigenerator_petstore_v3/petstore/src/models/model_User.jl
new file mode 100644
index 0000000..0572483
--- /dev/null
+++ b/test/server/openapigenerator_petstore_v3/petstore/src/models/model_User.jl
@@ -0,0 +1,65 @@
+# This file was generated by the Julia OpenAPI Code Generator
+# Do not modify this file directly. Modify the OpenAPI specification instead.
+
+
+@doc raw"""User
+A User who is purchasing from the pet store
+
+ User(;
+ password=nothing,
+ id=nothing,
+ username=nothing,
+ firstName=nothing,
+ lastName=nothing,
+ phone=nothing,
+ userStatus=nothing,
+ email=nothing,
+ )
+
+ - password::String
+ - id::Int64
+ - username::String
+ - firstName::String
+ - lastName::String
+ - phone::String
+ - userStatus::Int64 : User Status
+ - email::String
+"""
+Base.@kwdef mutable struct User <: OpenAPI.APIModel
+ password::Union{Nothing, String} = nothing
+ id::Union{Nothing, Int64} = nothing
+ username::Union{Nothing, String} = nothing
+ firstName::Union{Nothing, String} = nothing
+ lastName::Union{Nothing, String} = nothing
+ phone::Union{Nothing, String} = nothing
+ userStatus::Union{Nothing, Int64} = nothing
+ email::Union{Nothing, String} = nothing
+
+ function User(password, id, username, firstName, lastName, phone, userStatus, email, )
+ OpenAPI.validate_property(User, Symbol("password"), password)
+ OpenAPI.validate_property(User, Symbol("id"), id)
+ OpenAPI.validate_property(User, Symbol("username"), username)
+ OpenAPI.validate_property(User, Symbol("firstName"), firstName)
+ OpenAPI.validate_property(User, Symbol("lastName"), lastName)
+ OpenAPI.validate_property(User, Symbol("phone"), phone)
+ OpenAPI.validate_property(User, Symbol("userStatus"), userStatus)
+ OpenAPI.validate_property(User, Symbol("email"), email)
+ return new(password, id, username, firstName, lastName, phone, userStatus, email, )
+ end
+end # type User
+
+const _property_types_User = Dict{Symbol,String}(Symbol("password")=>"String", Symbol("id")=>"Int64", Symbol("username")=>"String", Symbol("firstName")=>"String", Symbol("lastName")=>"String", Symbol("phone")=>"String", Symbol("userStatus")=>"Int64", Symbol("email")=>"String", )
+OpenAPI.property_type(::Type{ User }, name::Symbol) = Union{Nothing,eval(Base.Meta.parse(_property_types_User[name]))}
+
+function check_required(o::User)
+ true
+end
+
+function OpenAPI.validate_property(::Type{ User }, name::Symbol, val)
+ if name === Symbol("id")
+ OpenAPI.validate_param(name, "User", :format, val, "int64")
+ end
+ if name === Symbol("userStatus")
+ OpenAPI.validate_param(name, "User", :format, val, "int32")
+ end
+end
diff --git a/test/server/openapigenerator_petstore_v3/petstore_server.jl b/test/server/openapigenerator_petstore_v3/petstore_server.jl
new file mode 100644
index 0000000..3ee5ca7
--- /dev/null
+++ b/test/server/openapigenerator_petstore_v3/petstore_server.jl
@@ -0,0 +1,169 @@
+module OpenAPIGenPetStoreV3Server
+
+using HTTP
+
+include("petstore/src/OpenAPIGenPetStoreServer.jl")
+
+using .OpenAPIGenPetStoreServer
+
+const server = Ref{Any}(nothing)
+const pets = Vector{Pet}()
+const orders = Vector{Order}()
+const users = Vector{User}()
+const PRESET_TEST_USER = "user1"
+
+function add_pet(req::HTTP.Request, pet::Pet;)
+ push!(pets, pet)
+ return pet
+end
+
+function delete_pet(req::HTTP.Request, pet_id::Int64; api_key=nothing,)
+ filter!(x->x.id != pet_id, pets)
+ return nothing
+end
+
+function find_pets_by_status(req::HTTP.Request, status::Vector{String};)
+ return filter(x->x.status == status, pets)
+end
+
+function find_pets_by_tags(req::HTTP.Request, tags::Vector{String};)
+ return filter(x->!isempty(intersect(Set(x.tags), Set(tags))), pets)
+end
+
+function get_pet_by_id(req::HTTP.Request, pet_id::Int64;)
+ pet = findfirst(x->x.id == pet_id, pets)
+ if pet === nothing
+ return HTTP.Response(404, "Pet not found")
+ else
+ return pets[pet]
+ end
+end
+
+function update_pet(req::HTTP.Request, pet::Pet;)
+ filter!(x->x.id != pet.id, pets)
+ push!(pets, pet)
+ return pet
+end
+
+function update_pet_with_form(req::HTTP.Request, pet_id::Int64; name=nothing, status=nothing,)
+ for pet in pets
+ if pet.id == pet_id
+ if !isnothing(name)
+ pet.name = name
+ end
+ if !isnothing(status)
+ pet.status = status
+ end
+ end
+ end
+ return nothing
+end
+
+function upload_file(req::HTTP.Request, pet_id::Int64; additional_metadata=nothing, file=nothing,)
+ return ApiResponse(; code=1, type="pet", message="file uploaded", )
+end
+
+function delete_order(req::HTTP.Request, order_id::String;)
+ filter!(x->x.id != order_id, orders)
+ return nothing
+end
+
+function get_inventory(req::HTTP.Request;)
+ return Dict{String, Int64}(
+ "additionalProp1" => 0,
+ "additionalProp2" => 0,
+ "additionalProp3" => 0,
+ )
+end
+
+function get_order_by_id(req::HTTP.Request, order_id::Int64;)
+ order = findfirst(x->x.id == order_id, orders)
+ if order === nothing
+ return HTTP.Response(404, "Order not found")
+ else
+ return orders[order]
+ end
+end
+
+function place_order(req::HTTP.Request, order::Order;)
+ if isnothing(order.id)
+ max_OrderId = isempty(orders) ? 0 : maximum(x->x.id, orders)
+ order.id = max_OrderId + 1
+ end
+ push!(orders, order)
+ return order
+end
+
+function create_user(req::HTTP.Request, user::User;)
+ push!(users, user)
+ return nothing
+end
+
+function create_users_with_array_input(req::HTTP.Request, user::Vector{User};)
+ append!(users, user)
+ return nothing
+end
+
+function create_users_with_list_input(req::HTTP.Request, user::Vector{User};)
+ append!(users, user)
+ return nothing
+end
+
+function delete_user(req::HTTP.Request, username::String;)
+ filter!(x->x.username != username, users)
+ return nothing
+end
+
+function get_user_by_name(req::HTTP.Request, username::String;)
+ # user = findfirst(x->x.username == username, users)
+ # if user === nothing
+ # return HTTP.Response(404, "User not found")
+ # else
+ # return user
+ # end
+ if username == PRESET_TEST_USER
+ return User(; id=1, username=PRESET_TEST_USER, firstName="John", lastName="Doe", email="jondoe@test.com", phone="1234567890", userStatus=1, )
+ else
+ return HTTP.Response(404, "User not found")
+ end
+end
+
+function login_user(req::HTTP.Request, username::String, password::String;)
+ return "logged in user session: test"
+end
+
+function logout_user(req::HTTP.Request;)
+ return nothing
+end
+
+function update_user(req::HTTP.Request, username::String, user::User;)
+ filter!(x->x.username != username, users)
+ push!(users, user)
+ return nothing
+end
+
+function stop(::HTTP.Request)
+ HTTP.close(server[])
+ return HTTP.Response(200, "")
+end
+
+function ping(::HTTP.Request)
+ return HTTP.Response(200, "")
+end
+
+function run_server(port=8081)
+ try
+ router = HTTP.Router()
+ router = OpenAPIGenPetStoreServer.register(router, @__MODULE__; path_prefix="/v3")
+ HTTP.register!(router, "GET", "/stop", stop)
+ HTTP.register!(router, "GET", "/ping", ping)
+ server[] = HTTP.serve!(router, port)
+ wait(server[])
+ catch ex
+ @error("Server error", exception=(ex, catch_backtrace()))
+ end
+end
+
+end # module OpenAPIGenPetStoreV3Server
+
+OpenAPIGenPetStoreV3Server.run_server()
diff --git a/test/specs/openapigenerator_petstore_v3.json b/test/specs/openapigenerator_petstore_v3.json
new file mode 100644
index 0000000..4958171
--- /dev/null
+++ b/test/specs/openapigenerator_petstore_v3.json
@@ -0,0 +1,1132 @@
+{
+ "openapi": "3.0.0",
+ "servers": [
+ {
+ "url": "/v3"
+ }
+ ],
+ "externalDocs": {
+ "description": "Find out more about Swagger",
+ "url": "http://swagger.io"
+ },
+ "paths": {
+ "/user/logout": {
+ "get": {
+ "summary": "Logs out current logged in user session",
+ "responses": {
+ "default": {
+ "description": "successful operation"
+ }
+ },
+ "operationId": "logoutUser",
+ "tags": [
+ "user"
+ ],
+ "description": "",
+ "security": [
+ {
+ "api_key": []
+ }
+ ]
+ }
+ },
+ "/store/order/{orderId}": {
+ "delete": {
+ "summary": "Delete purchase order by ID",
+ "parameters": [
+ {
+ "name": "orderId",
+ "required": true,
+ "in": "path",
+ "description": "ID of the order that needs to be deleted",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "404": {
+ "description": "Order not found"
+ },
+ "400": {
+ "description": "Invalid ID supplied"
+ }
+ },
+ "operationId": "deleteOrder",
+ "tags": [
+ "store"
+ ],
+ "description": "For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors"
+ },
+ "get": {
+ "summary": "Find purchase order by ID",
+ "parameters": [
+ {
+ "name": "orderId",
+ "required": true,
+ "in": "path",
+ "description": "ID of pet that needs to be fetched",
+ "schema": {
+ "minimum": 1,
+ "format": "int64",
+ "type": "integer",
+ "maximum": 5
+ }
+ }
+ ],
+ "responses": {
+ "404": {
+ "description": "Order not found"
+ },
+ "400": {
+ "description": "Invalid ID supplied"
+ },
+ "200": {
+ "content": {
+ "application/xml": {
+ "schema": {
+ "$ref": "#/components/schemas/Order"
+ }
+ },
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Order"
+ }
+ }
+ },
+ "description": "successful operation"
+ }
+ },
+ "operationId": "getOrderById",
+ "tags": [
+ "store"
+ ],
+ "description": "For valid response try integer IDs with value <= 5 or > 10. Other values will generate exceptions"
+ }
+ },
+ "/user/{username}": {
+ "delete": {
+ "summary": "Delete user",
+ "parameters": [
+ {
+ "name": "username",
+ "required": true,
+ "in": "path",
+ "description": "The name that needs to be deleted",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "404": {
+ "description": "User not found"
+ },
+ "400": {
+ "description": "Invalid username supplied"
+ }
+ },
+ "operationId": "deleteUser",
+ "tags": [
+ "user"
+ ],
+ "description": "This can only be done by the logged in user.",
+ "security": [
+ {
+ "api_key": []
+ }
+ ]
+ },
+ "put": {
+ "summary": "Updated user",
+ "parameters": [
+ {
+ "name": "username",
+ "required": true,
+ "in": "path",
+ "description": "name that need to be deleted",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/User"
+ }
+ }
+ },
+ "required": true,
+ "description": "Updated user object"
+ },
+ "responses": {
+ "404": {
+ "description": "User not found"
+ },
+ "400": {
+ "description": "Invalid user supplied"
+ }
+ },
+ "operationId": "updateUser",
+ "tags": [
+ "user"
+ ],
+ "description": "This can only be done by the logged in user.",
+ "security": [
+ {
+ "api_key": []
+ }
+ ]
+ },
+ "get": {
+ "summary": "Get user by user name",
+ "parameters": [
+ {
+ "name": "username",
+ "required": true,
+ "in": "path",
+ "description": "The name that needs to be fetched. Use user1 for testing.",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "404": {
+ "description": "User not found"
+ },
+ "400": {
+ "description": "Invalid username supplied"
+ },
+ "200": {
+ "content": {
+ "application/xml": {
+ "schema": {
+ "$ref": "#/components/schemas/User"
+ }
+ },
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/User"
+ }
+ }
+ },
+ "description": "successful operation"
+ }
+ },
+ "operationId": "getUserByName",
+ "tags": [
+ "user"
+ ],
+ "description": ""
+ }
+ },
+ "/user/login": {
+ "get": {
+ "summary": "Logs user into the system",
+ "parameters": [
+ {
+ "name": "username",
+ "required": true,
+ "in": "query",
+ "description": "The user name for login",
+ "schema": {
+ "pattern": "^[a-zA-Z0-9]+[a-zA-Z0-9\\.\\-_]*[a-zA-Z0-9]+$",
+ "type": "string"
+ }
+ },
+ {
+ "name": "password",
+ "required": true,
+ "in": "query",
+ "description": "The password for login in clear text",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "400": {
+ "description": "Invalid username/password supplied"
+ },
+ "200": {
+ "headers": {
+ "Set-Cookie": {
+ "description": "Cookie authentication key for use with the `api_key` apiKey authentication.",
+ "schema": {
+ "example": "AUTH_KEY=abcde12345; Path=/; HttpOnly",
+ "type": "string"
+ }
+ },
+ "X-Rate-Limit": {
+ "description": "calls per hour allowed by the user",
+ "schema": {
+ "format": "int32",
+ "type": "integer"
+ }
+ },
+ "X-Expires-After": {
+ "description": "date in UTC when token expires",
+ "schema": {
+ "format": "date-time",
+ "type": "string"
+ }
+ }
+ },
+ "content": {
+ "application/xml": {
+ "schema": {
+ "type": "string"
+ }
+ },
+ "application/json": {
+ "schema": {
+ "type": "string"
+ }
+ }
+ },
+ "description": "successful operation"
+ }
+ },
+ "operationId": "loginUser",
+ "tags": [
+ "user"
+ ],
+ "description": ""
+ }
+ },
+ "/pet/{petId}/uploadImage": {
+ "post": {
+ "summary": "uploads an image",
+ "parameters": [
+ {
+ "name": "petId",
+ "required": true,
+ "in": "path",
+ "description": "ID of pet to update",
+ "schema": {
+ "format": "int64",
+ "type": "integer"
+ }
+ }
+ ],
+ "requestBody": {
+ "content": {
+ "multipart/form-data": {
+ "schema": {
+ "properties": {
+ "file": {
+ "format": "binary",
+ "description": "file to upload",
+ "type": "string"
+ },
+ "additionalMetadata": {
+ "description": "Additional data to pass to server",
+ "type": "string"
+ }
+ },
+ "type": "object"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ApiResponse"
+ }
+ }
+ },
+ "description": "successful operation"
+ }
+ },
+ "operationId": "uploadFile",
+ "tags": [
+ "pet"
+ ],
+ "description": "",
+ "security": [
+ {
+ "petstore_auth": [
+ "write:pets",
+ "read:pets"
+ ]
+ }
+ ]
+ }
+ },
+ "/store/inventory": {
+ "get": {
+ "summary": "Returns pet inventories by status",
+ "responses": {
+ "200": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "additionalProperties": {
+ "format": "int32",
+ "type": "integer"
+ },
+ "type": "object"
+ }
+ }
+ },
+ "description": "successful operation"
+ }
+ },
+ "operationId": "getInventory",
+ "tags": [
+ "store"
+ ],
+ "description": "Returns a map of status codes to quantities",
+ "security": [
+ {
+ "api_key": []
+ }
+ ]
+ }
+ },
+ "/pet": {
+ "put": {
+ "summary": "Update an existing pet",
+ "requestBody": {
+ "$ref": "#/components/requestBodies/Pet"
+ },
+ "externalDocs": {
+ "url": "http://petstore.swagger.io/v2/doc/updatePet",
+ "description": "API documentation for the updatePet operation"
+ },
+ "operationId": "updatePet",
+ "responses": {
+ "405": {
+ "description": "Validation exception"
+ },
+ "404": {
+ "description": "Pet not found"
+ },
+ "400": {
+ "description": "Invalid ID supplied"
+ },
+ "200": {
+ "content": {
+ "application/xml": {
+ "schema": {
+ "$ref": "#/components/schemas/Pet"
+ }
+ },
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Pet"
+ }
+ }
+ },
+ "description": "successful operation"
+ }
+ },
+ "tags": [
+ "pet"
+ ],
+ "description": "",
+ "security": [
+ {
+ "petstore_auth": [
+ "write:pets",
+ "read:pets"
+ ]
+ }
+ ]
+ },
+ "post": {
+ "summary": "Add a new pet to the store",
+ "requestBody": {
+ "$ref": "#/components/requestBodies/Pet"
+ },
+ "responses": {
+ "405": {
+ "description": "Invalid input"
+ },
+ "200": {
+ "content": {
+ "application/xml": {
+ "schema": {
+ "$ref": "#/components/schemas/Pet"
+ }
+ },
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Pet"
+ }
+ }
+ },
+ "description": "successful operation"
+ }
+ },
+ "operationId": "addPet",
+ "tags": [
+ "pet"
+ ],
+ "description": "",
+ "security": [
+ {
+ "petstore_auth": [
+ "write:pets",
+ "read:pets"
+ ]
+ }
+ ]
+ }
+ },
+ "/user": {
+ "post": {
+ "summary": "Create user",
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/User"
+ }
+ }
+ },
+ "required": true,
+ "description": "Created user object"
+ },
+ "responses": {
+ "default": {
+ "description": "successful operation"
+ }
+ },
+ "operationId": "createUser",
+ "tags": [
+ "user"
+ ],
+ "description": "This can only be done by the logged in user.",
+ "security": [
+ {
+ "api_key": []
+ }
+ ]
+ }
+ },
+ "/user/createWithArray": {
+ "post": {
+ "summary": "Creates list of users with given input array",
+ "requestBody": {
+ "$ref": "#/components/requestBodies/UserArray"
+ },
+ "responses": {
+ "default": {
+ "description": "successful operation"
+ }
+ },
+ "operationId": "createUsersWithArrayInput",
+ "tags": [
+ "user"
+ ],
+ "description": "",
+ "security": [
+ {
+ "api_key": []
+ }
+ ]
+ }
+ },
+ "/pet/findByStatus": {
+ "get": {
+ "summary": "Finds Pets by status",
+ "parameters": [
+ {
+ "schema": {
+ "items": {
+ "default": "available",
+ "type": "string",
+ "enum": [
+ "available",
+ "pending",
+ "sold"
+ ]
+ },
+ "type": "array"
+ },
+ "name": "status",
+ "required": true,
+ "style": "form",
+ "in": "query",
+ "description": "Status values that need to be considered for filter",
+ "explode": false,
+ "deprecated": true
+ }
+ ],
+ "responses": {
+ "400": {
+ "description": "Invalid status value"
+ },
+ "200": {
+ "content": {
+ "application/xml": {
+ "schema": {
+ "items": {
+ "$ref": "#/components/schemas/Pet"
+ },
+ "type": "array"
+ }
+ },
+ "application/json": {
+ "schema": {
+ "items": {
+ "$ref": "#/components/schemas/Pet"
+ },
+ "type": "array"
+ }
+ }
+ },
+ "description": "successful operation"
+ }
+ },
+ "operationId": "findPetsByStatus",
+ "tags": [
+ "pet"
+ ],
+ "description": "Multiple status values can be provided with comma separated strings",
+ "security": [
+ {
+ "petstore_auth": [
+ "read:pets"
+ ]
+ }
+ ]
+ }
+ },
+ "/user/createWithList": {
+ "post": {
+ "summary": "Creates list of users with given input array",
+ "requestBody": {
+ "$ref": "#/components/requestBodies/UserArray"
+ },
+ "responses": {
+ "default": {
+ "description": "successful operation"
+ }
+ },
+ "operationId": "createUsersWithListInput",
+ "tags": [
+ "user"
+ ],
+ "description": "",
+ "security": [
+ {
+ "api_key": []
+ }
+ ]
+ }
+ },
+ "/pet/{petId}": {
+ "delete": {
+ "summary": "Deletes a pet",
+ "parameters": [
+ {
+ "name": "api_key",
+ "required": false,
+ "in": "header",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "petId",
+ "required": true,
+ "in": "path",
+ "description": "Pet id to delete",
+ "schema": {
+ "format": "int64",
+ "type": "integer"
+ }
+ }
+ ],
+ "responses": {
+ "400": {
+ "description": "Invalid pet value"
+ }
+ },
+ "operationId": "deletePet",
+ "tags": [
+ "pet"
+ ],
+ "description": "",
+ "security": [
+ {
+ "petstore_auth": [
+ "write:pets",
+ "read:pets"
+ ]
+ }
+ ]
+ },
+ "post": {
+ "summary": "Updates a pet in the store with form data",
+ "parameters": [
+ {
+ "name": "petId",
+ "required": true,
+ "in": "path",
+ "description": "ID of pet that needs to be updated",
+ "schema": {
+ "format": "int64",
+ "type": "integer"
+ }
+ }
+ ],
+ "requestBody": {
+ "content": {
+ "application/x-www-form-urlencoded": {
+ "schema": {
+ "properties": {
+ "name": {
+ "description": "Updated name of the pet",
+ "type": "string"
+ },
+ "status": {
+ "description": "Updated status of the pet",
+ "type": "string"
+ }
+ },
+ "type": "object"
+ }
+ }
+ }
+ },
+ "responses": {
+ "405": {
+ "description": "Invalid input"
+ }
+ },
+ "operationId": "updatePetWithForm",
+ "tags": [
+ "pet"
+ ],
+ "description": "",
+ "security": [
+ {
+ "petstore_auth": [
+ "write:pets",
+ "read:pets"
+ ]
+ }
+ ]
+ },
+ "get": {
+ "summary": "Find pet by ID",
+ "parameters": [
+ {
+ "name": "petId",
+ "required": true,
+ "in": "path",
+ "description": "ID of pet to return",
+ "schema": {
+ "format": "int64",
+ "type": "integer"
+ }
+ }
+ ],
+ "responses": {
+ "404": {
+ "description": "Pet not found"
+ },
+ "400": {
+ "description": "Invalid ID supplied"
+ },
+ "200": {
+ "content": {
+ "application/xml": {
+ "schema": {
+ "$ref": "#/components/schemas/Pet"
+ }
+ },
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Pet"
+ }
+ }
+ },
+ "description": "successful operation"
+ }
+ },
+ "operationId": "getPetById",
+ "tags": [
+ "pet"
+ ],
+ "description": "Returns a single pet",
+ "security": [
+ {
+ "api_key": []
+ }
+ ]
+ }
+ },
+ "/pet/findByTags": {
+ "get": {
+ "summary": "Finds Pets by tags",
+ "parameters": [
+ {
+ "name": "tags",
+ "required": true,
+ "style": "form",
+ "in": "query",
+ "description": "Tags to filter by",
+ "explode": false,
+ "schema": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ }
+ }
+ ],
+ "responses": {
+ "400": {
+ "description": "Invalid tag value"
+ },
+ "200": {
+ "content": {
+ "application/xml": {
+ "schema": {
+ "items": {
+ "$ref": "#/components/schemas/Pet"
+ },
+ "type": "array"
+ }
+ },
+ "application/json": {
+ "schema": {
+ "items": {
+ "$ref": "#/components/schemas/Pet"
+ },
+ "type": "array"
+ }
+ }
+ },
+ "description": "successful operation"
+ }
+ },
+ "operationId": "findPetsByTags",
+ "tags": [
+ "pet"
+ ],
+ "deprecated": true,
+ "description": "Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.",
+ "security": [
+ {
+ "petstore_auth": [
+ "read:pets"
+ ]
+ }
+ ]
+ }
+ },
+ "/store/order": {
+ "post": {
+ "summary": "Place an order for a pet",
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Order"
+ }
+ }
+ },
+ "required": true,
+ "description": "order placed for purchasing the pet"
+ },
+ "responses": {
+ "400": {
+ "description": "Invalid Order"
+ },
+ "200": {
+ "content": {
+ "application/xml": {
+ "schema": {
+ "$ref": "#/components/schemas/Order"
+ }
+ },
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Order"
+ }
+ }
+ },
+ "description": "successful operation"
+ }
+ },
+ "operationId": "placeOrder",
+ "tags": [
+ "store"
+ ],
+ "description": ""
+ }
+ }
+ },
+ "tags": [
+ {
+ "name": "pet",
+ "description": "Everything about your Pets"
+ },
+ {
+ "name": "store",
+ "description": "Access to Petstore orders"
+ },
+ {
+ "name": "user",
+ "description": "Operations about user"
+ }
+ ],
+ "info": {
+ "title": "OpenAPI Petstore",
+ "license": {
+ "name": "Apache-2.0",
+ "url": "https://www.apache.org/licenses/LICENSE-2.0.html"
+ },
+ "description": "This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.",
+ "version": "1.0.0"
+ },
+ "components": {
+ "securitySchemes": {
+ "petstore_auth": {
+ "flows": {
+ "implicit": {
+ "authorizationUrl": "http://petstore.swagger.io/api/oauth/dialog",
+ "scopes": {
+ "read:pets": "read your pets",
+ "write:pets": "modify pets in your account"
+ }
+ }
+ },
+ "type": "oauth2"
+ },
+ "api_key": {
+ "name": "api_key",
+ "in": "header",
+ "type": "apiKey"
+ }
+ },
+ "requestBodies": {
+ "UserArray": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "items": {
+ "$ref": "#/components/schemas/User"
+ },
+ "type": "array"
+ }
+ }
+ },
+ "required": true,
+ "description": "List of user object"
+ },
+ "Pet": {
+ "content": {
+ "application/xml": {
+ "schema": {
+ "$ref": "#/components/schemas/Pet"
+ }
+ },
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Pet"
+ }
+ }
+ },
+ "required": true,
+ "description": "Pet object that needs to be added to the store"
+ }
+ },
+ "schemas": {
+ "User": {
+ "xml": {
+ "name": "User"
+ },
+ "properties": {
+ "password": {
+ "type": "string"
+ },
+ "id": {
+ "format": "int64",
+ "type": "integer"
+ },
+ "username": {
+ "type": "string"
+ },
+ "firstName": {
+ "type": "string"
+ },
+ "lastName": {
+ "type": "string"
+ },
+ "phone": {
+ "type": "string"
+ },
+ "userStatus": {
+ "format": "int32",
+ "type": "integer",
+ "description": "User Status"
+ },
+ "email": {
+ "type": "string"
+ }
+ },
+ "title": "a User",
+ "description": "A User who is purchasing from the pet store",
+ "type": "object"
+ },
+ "Order": {
+ "xml": {
+ "name": "Order"
+ },
+ "properties": {
+ "petId": {
+ "format": "int64",
+ "type": "integer"
+ },
+ "shipDate": {
+ "format": "date-time",
+ "type": "string"
+ },
+ "status": {
+ "type": "string",
+ "description": "Order Status",
+ "enum": [
+ "placed",
+ "approved",
+ "delivered"
+ ]
+ },
+ "id": {
+ "format": "int64",
+ "type": "integer"
+ },
+ "complete": {
+ "default": false,
+ "type": "boolean"
+ },
+ "quantity": {
+ "format": "int32",
+ "type": "integer"
+ }
+ },
+ "title": "Pet Order",
+ "description": "An order for a pets from the pet store",
+ "type": "object"
+ },
+ "Pet": {
+ "xml": {
+ "name": "Pet"
+ },
+ "required": [
+ "name",
+ "photoUrls"
+ ],
+ "properties": {
+ "name": {
+ "example": "doggie",
+ "type": "string"
+ },
+ "status": {
+ "deprecated": true,
+ "type": "string",
+ "description": "pet status in the store",
+ "enum": [
+ "available",
+ "pending",
+ "sold"
+ ]
+ },
+ "id": {
+ "format": "int64",
+ "type": "integer"
+ },
+ "photoUrls": {
+ "xml": {
+ "name": "photoUrl",
+ "wrapped": true
+ },
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "tags": {
+ "xml": {
+ "name": "tag",
+ "wrapped": true
+ },
+ "items": {
+ "$ref": "#/components/schemas/Tag"
+ },
+ "type": "array"
+ },
+ "category": {
+ "$ref": "#/components/schemas/Category"
+ }
+ },
+ "title": "a Pet",
+ "description": "A pet for sale in the pet store",
+ "type": "object"
+ },
+ "Category": {
+ "xml": {
+ "name": "Category"
+ },
+ "properties": {
+ "name": {
+ "pattern": "^[a-zA-Z0-9]+[a-zA-Z0-9\\.\\-_]*[a-zA-Z0-9]+$",
+ "type": "string"
+ },
+ "id": {
+ "format": "int64",
+ "type": "integer"
+ }
+ },
+ "title": "Pet category",
+ "description": "A category for a pet",
+ "type": "object"
+ },
+ "Tag": {
+ "xml": {
+ "name": "Tag"
+ },
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "id": {
+ "format": "int64",
+ "type": "integer"
+ }
+ },
+ "title": "Pet Tag",
+ "description": "A tag for a pet",
+ "type": "object"
+ },
+ "ApiResponse": {
+ "properties": {
+ "message": {
+ "type": "string"
+ },
+ "code": {
+ "format": "int32",
+ "type": "integer"
+ },
+ "type": {
+ "type": "string"
+ }
+ },
+ "title": "An uploaded response",
+ "description": "Describes the result of uploading an image resource",
+ "type": "object"
+ }
+ }
+ }
+}