FastAPI podstawy

Introduction

FastApi is a framework which is used to build as a communication point from backend level.


This framework have some good points which are listed bellow:

  • adding types of the expected arguments- reduce time of the validation
  • validating argument type
  • autodocumentation
  • swagger

 

How to prepare environment

How to prepare environment to run first API. First of all if we have prepared python
environment we need to install fastapi and unicorn. Commands are presented bellow:

<pre style=”background-color: rgb(88, 86, 86) ; border: 1px solid #999; display: block; padding: 10px; color: white;”>

pip install unicorn
pip install fastapi

</pre>

Prepare first script

Than if we have installed those frameworks we need to create python file and create ours fastapi object. This file will be executable by unicorn but right now we work only in the fastapi object to create endpoints. So first step will be to create object and add new endpoints to the one object

 

<pre style=”background-color: rgb(88, 86, 86) ; border: 1px solid #999; display: block; padding: 20px; color: white;”>

# 1. Create api.file

# 2. import FastApi obj from fastapi lib

from fastapi import FastAPI

# 3. create fastapi object

example_api = FastAPI()

# 4. create first endpoint

@example_api.get(’/’)
def index():
     return {’example_obj”: 1}

</pre>

How to run script?

If we have already done those steps than we can run ours API using unicorn

–> template command

<pre style=”background-color: rgb(88, 86, 86) ; border: 1px solid #999; display: block; padding: 20px; color: white;”>

unicorn file_name:api_obj

–> in this case will be
unicorn api:example_api

</pre>

Flags:
— reload keep api in a active state

 

If we have not defined url than we can open ours first API in web
http://127.0.0.1:8000

Documentation


This framework have a very good documentation interface which have implemented
swagger lib. To run this documentation we need add to ours app url prefix docs

http://127.0.0.1:8000/docs

This feature is very usefull and have some additionall options:

  • informations how many enpoints we have in ours API
  • abiliy to test ours API using swagger
  • check API behaviours if something will be not planned 

 

Types of endpoints

To keep API standard in fastapi exists four types of endpoints;

  • POST
  • GET
  • PUT
  • DELETE

When we need to get get some informations from the server about specyfic item from db or take many elements without additionall arguments than user should used GET method.

If we need add some element or group of elements than POST method is a mandatory. Naturaly python language allows to that by another method but this is antipattern to the people who create API.

Next method will be PUT which is used to update some elements in the db. In another frameworks this method could be named UPDATE but in this case we are using PUT method.

To remove some elements from the db user should use DELETE method.

Example of the fast-api methods?

<pre style=”background-color: rgb(88, 86, 86) ; border: 1px solid #999; display: block; padding: 20px; color: white;”>

from fastapi import FastAPI


@app.post(’/’)
def get_index_page():
return {’arg’: 'this is a argument’}


@app.delete(’/’)
def get_index_page():
return {’arg’: 'this is a argument’}


@app.put(’/’)
def get_index_page():
return {’arg’: 'this is a argument’}

</pre>


Getting element from test pool

<pre style=”background-color: rgb(88, 86, 86) ; border: 1px solid #999; display: block; padding: 20px; color: white;”>


TEST_POOL = {
0: {’test0′: 3321},
1: {’test’: 32},
2: {’test2′: 321}
}


@app.get(’/getitem/{item_id}/{name}’)
def get_item_element(item_id: int, name: str=None):
return TEST_POOL[item_id]

</pre>

adding path to describe input parameter

<pre style=”background-color: rgb(88, 86, 86) ; border: 1px solid #999; display: block; padding: 20px; color: white;”>


@app.get(’/getitem/2/{item_id}/{name}/{param_value}’)
def get_item_element_2(
item_id: int,
name: str=Path(None, description=”This is a name of the parameter”),
param_value: int=Path(None, description=”This is a value of the name parameter”)):
try:
return TEST_POOL[item_id]
except KeyError as e:
return TEST_POOL + {item_id:{name:param_value}}

</pre>

# POINT: Query url
Description:

<pre style=”background-color: rgb(88, 86, 86) ; border: 1px solid #999; display: block; padding: 20px; color: white;”>

@app.get(’/get/query’)
def get_by_query(name: str):
if name:
return {’Data’: 'This is work’}
else:
return {’Data’: 'query is empty’}

</pre>


POINT: Optional
Based on this argument, user can define specyfic parameter as optionall. This class is definned in the
typing lib

<pre style=”background-color: rgb(88, 86, 86) ; border: 1px solid #999; display: block; padding: 20px; color: white;”>

from typing import Optionall


@app.get(’/get/element’)
def get_element(name: Optional[str]=None):
if name:
return {’Data’: 'This is work’}
else:
return {’Data’: 'query is empty’}


@app.get(’/get/element/by’)
def get_element_by(*, name: Optional[str]=None):
if name:
return {’Data’: name}
else:
return {’Data’: 'query is empty’}

</pre>


If we have some more parameters and we don’t want to add parameters in the query
we can use body request in post method. Bellow is presented how we can do this

add BaseModel obj from pydantic

from pydantic import BaseModel

create new Model based on the BaseModel

<pre style=”background-color: rgb(88, 86, 86) ; border: 1px solid #999; display: block; padding: 20px; color: white;”>

class Item(BaseModel):
name: str
price: float
brand: Optional[str] = None

item_list = {}

@app.post(„/create/item/{item_id}”)
def create_new_item(item_id: int, item: Item):
if item_id in item_list:
return {’Data’: 'This item is already in list’}

item_list[item_id] = item
return item_list

</pre>


To not use by default returning the dictionary with error
message in FastApi exist mechanism to raise specyfic exceptions.
To do that user need to import HTTPException and status obj

<pre style=”background-color: rgb(88, 86, 86) ; border: 1px solid #999; display: block; padding: 20px; color: white;”>

from fastapi import HTTPException, status
@app.post(„/get/item/{item_id}”)
def get_item(item_id: int, item: Item):
if item_id in item_list:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
„””
or another way will be to use statuscode number and add detail
raise HTTPException(status_code=404, detail=”Item name not found”)

OUTPUT:
{
’detail’: 'Item name not found’
}
„””
item_list[item_id] = item
return item_list

</pre>

Popular Posts
Categories
Tags

agile_pl

Translate »