Build a REST API With FAST API
In this post I will show you how to build quickly a REST API using the package FAST API
The endpoints for each will be as shown
First create a virtual environment and install fast api and uvicorn
python3 -m venv env
source env/bin/activate
pip install fastapi, uvicorn
Instead of putting all the endpoints in one file we will use a modular approach and use one file for the routers and one for the switches. The file for routers routers_view.py
from fastapi import APIRouter, Path
from pydantic import BaseModel
from typing import List
import json
router_view = APIRouter()
with open('app/views/routers.json') as f:
router_list = json.load(f)['routers']
class Router(BaseModel):
rtr_id:int
model:str
category:str
IOS:str
IOS_Image:str
@router_view.get("/")
async def get_routers():
return {"routers": router_list }
@router_view.get("/{rtr_id}")
async def get_router(rtr_id:int):
return { "router" : router for router in router_list if router['rtr_id']==rtr_id }
@router_view.post("/")
async def create_router(rtr:Router):
router_list.append(rtr)
return { "router":rtr }
@router_view.put("/")
async def update_router(rtr:Router):
for router in router_list:
if router['rtr_id']==rtr.rtr_id:
router.update(rtr)
return { "router":rtr }
@router_view.delete("/{rtr_id}")
async def delete_router(rtr_id: int):
global router_list
router_list = [router for router in router_list if router['rtr_id']!=rtr_id]
return { f"router{rtr_id}": " deleted" }
For backend we will use a json file which we will load to memory. Please note this is only for demonstration purposes. Having a global variable is not thread safe and it does not make sense if you spawn multiple processes. In reality your backend will be a database.
The json file is
{
"routers": [
{
"rtr_id": 100,
"model": "isr4321",
"category": "branch",
"IOS":"IOS-XE",
"IOS_Image":"15.5.3"
},
{
"rtr_id": 101,
"model": "ASR-1001-x",
"category": "WAN_Agg",
"IOS":"IOS-XE",
"IOS_Image":"Amsterdam-17.3.2"
},
{
"rtr_id": 102,
"model": "isr4321",
"category": "branch",
"IOS":"IOS-XE",
"IOS_Image":"15.5.1"
},
{
"rtr_id": 103,
"model": "ASR-1001-x",
"category": "WAN_Agg",
"IOS":"IOS-XE",
"IOS_Image":"Everest-16.6.2"
}
]
}
For switches switches_view.py
from fastapi import APIRouter, Path
from pydantic import BaseModel
from typing import List
import json
switch_view = APIRouter()
with open('app/views/switches.json') as f:
switch_list = json.load(f)['switches']
class Switch(BaseModel):
rtr_id:int
model:str
category:str
IOS:str
IOS_Image:str
@switch_view.get("/")
async def get_switches():
return {"switches": switch_list }
@switch_view.get("/{sw_id}")
async def get_switch(sw_id:int):
return { "switch" : switch for switch in switch_list if switch['sw_id']==sw_id }
@switch_view.post("/")
async def create_switch(sw:Switch):
switch_list.append(sw)
return { "switch":sw }
@switch_view.put("/")
async def update_switch(sw:Switch):
for switch in switch_list:
if switch['sw_id']==sw.sw_id:
switch.update(sw)
return { "switch":sw }
@switch_view.delete("/{sw_id}")
async def delete_switch(sw_id: int):
global switch_list
switch_list = [switch for switch in switch_list if switch['sw_id']!=sw_id]
return { f"switch {sw_id}": " deleted" }
and switches.json
{
"switches": [
{
"sw_id": 100,
"model": "3750",
"category": "branch",
"IOS":"IOS",
"IOS_Image":"15.5.3"
},
{
"sw_id": 101,
"model": "3650",
"category": "branch",
"IOS":"IOS",
"IOS_Image":"15.5.2"
},
{
"sw_id": 102,
"model": "nexus3000",
"category": "branch",
"IOS":"IOS-XE",
"IOS_Image":"15.5.1"
},
{
"sw_id": 103,
"model": "nexus3000",
"category": "branch",
"IOS":"IOS-XE",
"IOS_Image":"Everest-16.6.2"
}
]
}
our main.py file
from fastapi import FastAPI
from .views.routers_view import router_view
from .views.switches_view import switch_view
app = FastAPI()
app.include_router(router_view,prefix="/routers",tags=["routers"])
app.include_router(switch_view,prefix="/switches",tags=["switches"])
so we have a folder app where are main.py is and a folder views where our routers_view.py and switches_view.py reside. to run it, you write uvicorn app.main:app
$uvicorn app.main:app
INFO: Started server process [17800]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: 127.0.0.1:54514 - "GET /docs HTTP/1.1" 200 OK
INFO: 127.0.0.1:54514 - "GET /openapi.json HTTP/1.1" 200 OK
if you then get to http://127.0.0.1:8000/docs you will get the first picture. this provides documentation and allows you to run all rest call from there.
if you go to http://127.0.0.1:8000/routers/100 you will get
{
"router": {
"rtr_id": 100,
"model": "isr4321",
"category": "branch",
"IOS": "IOS-XE",
"IOS_Image": "15.5.3"
}
}
In a later example I will show you how to connect to an sql database and read the values from there