Skip to content

Commit

Permalink
Add example of split API specifications with relative references (#2009)
Browse files Browse the repository at this point in the history
Store the API in one file, the schema definitions in another file

Co-authored-by: Christopher Lott <[email protected]>
  • Loading branch information
chrisinmtown and chrisinmtown authored Dec 4, 2024
1 parent 0a50bbb commit e5e20be
Show file tree
Hide file tree
Showing 6 changed files with 233 additions and 0 deletions.
34 changes: 34 additions & 0 deletions examples/splitspecs/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
===================
Split Specs Example
===================

This example demonstrates split specifications and relative references.
The OpenAPI specification and the Swagger specification are stored in
multiple files and use references that are resolved by Connexion.

Preparing
---------

Create a new virtual environment and install the required libraries
with these commands:

.. code-block:: bash
$ python -m venv my-venv
$ source my-venv/bin/activate
$ pip install 'connexion[flask,swagger-ui,uvicorn]>=3.1.0'
Running
-------

Launch the connexion server with this command:

Running:

.. code-block:: bash
$ python app.py
Now open your browser and view the Swagger UI for these specification files:

* http://localhost:8080/openapi/ui/ for the OpenAPI 3 spec
* http://localhost:8080/swagger/ui/ for the Swagger 2 spec
30 changes: 30 additions & 0 deletions examples/splitspecs/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from pathlib import Path

import connexion

pets = {
1: {"name": "Aldo", "registered": "2022-11-28T00:00:00Z"},
2: {"name": "Bailey", "registered": "2023-11-28T11:11:11Z"},
3: {"name": "Hugo", "registered": "2024-11-28T22:22:22Z"},
}


def get(petId):
id_ = int(petId)
if pets.get(id_) is None:
return connexion.NoContent, 404
return pets[id_]


def show():
# NOTE: we need to wrap it with list for Python 3 as dict_values is not JSON serializable
return list(pets.values())


app = connexion.FlaskApp(__name__, specification_dir="spec/")
app.add_api("openapi.yaml", arguments={"title": "Pet Store Rel Ref Example"})
app.add_api("swagger.yaml", arguments={"title": "Pet Store Rel Ref Example"})


if __name__ == "__main__":
app.run(f"{Path(__file__).stem}:app", port=8080)
34 changes: 34 additions & 0 deletions examples/splitspecs/spec/components.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
components:
schemas:
Pet:
required:
- name
properties:
id:
type: integer
format: int64
readOnly: true
example: 1
name:
type: string
example: fluffy
registered:
type: string
readOnly: true
example: 2019-01-16T23:52:54Z

Pets:
type: array
items:
$ref: "#/components/schemas/Pet"

Error:
properties:
code:
type: integer
format: int32
message:
type: string
required:
- code
- message
35 changes: 35 additions & 0 deletions examples/splitspecs/spec/definitions.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
definitions:
Pet:
type: object
required:
- name
properties:
id:
type: integer
format: int64
example: 1
name:
type: string
example: fluffy
registered:
type: string
format: date-time
example: 2019-01-16T23:52:54Z

Pets:
type: array
items:
$ref: "#/definitions/Pet"

Error:
type: object
properties:
code:
type: integer
format: int32
message:
type: string
required:
- code
- message

55 changes: 55 additions & 0 deletions examples/splitspecs/spec/openapi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
openapi: 3.0.0

info:
version: 1.0.0
title: Swagger Petstore
license:
name: MIT

servers:
- url: /openapi

paths:
/pets:
get:
summary: List all pets
operationId: app.show
responses:
'200':
description: A list of pets
content:
application/json:
schema:
$ref: "components.yaml#/components/schemas/Pets"
default:
description: Unexpected error
content:
application/json:
schema:
$ref: "components.yaml#/components/schemas/Error"

'/pets/{petId}':
get:
summary: Info for a specific pet
operationId: app.get
parameters:
- name: petId
in: path
description: Id of the pet to get.
required: true
schema:
type: integer
example: 1
responses:
'200':
description: Expected response to a valid request
content:
application/json:
schema:
$ref: "components.yaml#/components/schemas/Pet"
default:
description: Unexpected error
content:
application/json:
schema:
$ref: "components.yaml#/components/schemas/Error"
45 changes: 45 additions & 0 deletions examples/splitspecs/spec/swagger.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
swagger: "2.0"

info:
title: "{{title}}"
version: "1.0"

basePath: /swagger

paths:
/pets:
get:
summary: List all pets
operationId: app.show
responses:
'200':
description: List all pets
schema:
type: array
items:
$ref: 'definitions.yaml#/definitions/Pets'
default:
description: Unexpected Error
schema:
$ref: 'definitions.yaml#/definitions/Error'

'/pets/{petId}':
get:
summary: Info for a specific pet
operationId: app.get
parameters:
- name: petId
in: path
required: true
type: integer
minimum: 1
description: Parameter description in Markdown.
responses:
'200':
description: Expected response to a valid request
schema:
$ref: 'definitions.yaml#/definitions/Pet'
default:
description: Unexpected Error
schema:
$ref: 'definitions.yaml#/definitions/Error'

0 comments on commit e5e20be

Please sign in to comment.