Fastapi: How to use swagger 2 in FastAPI

Created on 2 Jul 2020  路  4Comments  路  Source: tiangolo/fastapi

We need to use swagger2 in the FastAPI project, can we use Swagger 2 to replace the original OpenAPI

answered question

Most helpful comment

First i make the app fill the api data and create an endpoint which just returns a json of the schema

from fastapi import FastAPI
from fastapi.encoders import jsonable_encoder
from fastapi.openapi.utils import get_openapi

app = FastAPI()

openapi_schema = get_openapi(
    version='1.0',
    title='Title',
    description='Api',
    openapi_prefix='',
    routes=app.routes,
)

app.openapi_schema = openapi_schema

@app.get('/openapi')
async def openapi_export():
    openapi = app.openapi_schema
    return jsonable_encoder(openapi)

Then i have a function that goes to that url takes the schema and writes to a yaml file (json is also possible i believe)

def build():
    import requests

    spec = requests.get('http://WHATEVER_URL_U_HAVE/openapi').json()
    dest = ROOT / 'openapi_3.yaml'
    dest.write_yaml(spec)

Then i call the spec-converter as a CLI (requires a node env with npm install api-spec-converter)

def convert():
    subprocess.check_call('api-spec-converter --from=openapi_3 --to=swagger_2 --syntax=yaml /path/to/openapi_3.yaml > /path/to/openapi.yaml', shell=True)
# yes i know that shell=True is not a good practice

After which you should have a version 2 swagger in the openapi.yaml :)
The conversion while good wasn't completely perfect for me
For that i do a manual update by just loading the yaml file and changing whatever fields i want

def manual_update():
    openapi_yaml = yaml.load(open(str(ROOT.joinpath(openapi_location))))
    openapi_yaml['host'] = 'some_very_nice_fake_host'

All 4 comments

I've had the same issue and i fixed it by using https://github.com/LucyBot-Inc/api-spec-converter
You can make an endpoint which gets swagger3 and writes to file after which you run the spec converter cli

I did have to do some manual changes after that (some security stuff and empty body that gcp doesn't like) but that will be different for everyone

I can give a more concrete example later if you wish

Can you provide an example

First i make the app fill the api data and create an endpoint which just returns a json of the schema

from fastapi import FastAPI
from fastapi.encoders import jsonable_encoder
from fastapi.openapi.utils import get_openapi

app = FastAPI()

openapi_schema = get_openapi(
    version='1.0',
    title='Title',
    description='Api',
    openapi_prefix='',
    routes=app.routes,
)

app.openapi_schema = openapi_schema

@app.get('/openapi')
async def openapi_export():
    openapi = app.openapi_schema
    return jsonable_encoder(openapi)

Then i have a function that goes to that url takes the schema and writes to a yaml file (json is also possible i believe)

def build():
    import requests

    spec = requests.get('http://WHATEVER_URL_U_HAVE/openapi').json()
    dest = ROOT / 'openapi_3.yaml'
    dest.write_yaml(spec)

Then i call the spec-converter as a CLI (requires a node env with npm install api-spec-converter)

def convert():
    subprocess.check_call('api-spec-converter --from=openapi_3 --to=swagger_2 --syntax=yaml /path/to/openapi_3.yaml > /path/to/openapi.yaml', shell=True)
# yes i know that shell=True is not a good practice

After which you should have a version 2 swagger in the openapi.yaml :)
The conversion while good wasn't completely perfect for me
For that i do a manual update by just loading the yaml file and changing whatever fields i want

def manual_update():
    openapi_yaml = yaml.load(open(str(ROOT.joinpath(openapi_location))))
    openapi_yaml['host'] = 'some_very_nice_fake_host'

Thanks for the help here @ArcLightSlavik ! :clap: :bow:

If that solves the original problem, then you can close this issue @somta :heavy_check_mark:

Was this page helpful?
0 / 5 - 0 ratings