FastAPI – Quick Guide

FastAPI – Quick Guide ”; Previous Next FastAPI – Introduction FastAPI is a modern Python web framework, very efficient in building APIs. It is based on Python’s type hints feature that has been added since Python 3.6 onwards. It is one of the fastest web frameworks of Python. As it works on the functionality of Starlette and Pydantic libraries, its performance is amongst the best and on par with that of NodeJS and Go. In addition to offering high performance, FastAPI offers significant speed for development, reduces human-induced errors in the code, is easy to learn and is completely production-ready. FastAPI is fully compatible with well-known standards of APIs, namely OpenAPI and JSON schema. FastAPI has been developed by Sebastian Ramirez in Dec. 2018. FastAPI 0.68.0 is the currently available version. FastAPI – EnvironmentSetup To install FastAPI (preferably in a virtual environment), use pip installer. pip3 install fastapi FastAPI depends on Starlette and Pydantic libraries, hence they also get installed. Installing Uvicorn using PIP FastAPI doesn’t come with any built-in server application. To run FastAPI app, you need an ASGI server called uvicorn, so install the same too, using pip installer. It will also install uvicorn’s dependencies – asgiref, click, h11, and typing-extensions pip3 install uvicorn With these two libraries installed, we can check all the libraries installed so far. pip3 freeze asgiref==3.4.1 click==8.0.1 colorama==0.4.4 fastapi==0.68.0 h11==0.12.0 importlib-metadata==4.6.4 pydantic==1.8.2 starlette==0.14.2 typing-extensions==3.10.0.0 uvicorn==0.15.0 zipp==3.5.0 FastAPI – Hello World Getting Started The first step in creating a FastAPI app is to declare the application object of FastAPI class. from fastapi import FastAPI app = FastAPI() This app object is the main point of interaction of the application with the client browser. The uvicorn server uses this object to listen to client’s request. The next step is to create path operation. Path is a URL which when visited by the client invokes visits a mapped URL to one of the HTTP methods, an associated function is to be executed. We need to bind a view function to a URL and the corresponding HTTP method. For example, the index() function corresponds to ‘/’ path with ‘get’ operation. @app.get(“/”) async def root(): return {“message”: “Hello World”} The function returns a JSON response, however, it can return dict, list, str, int, etc. It can also return Pydantic models. Save the following code as main.py from fastapi import FastAPI app = FastAPI() @app.get(“/”) async def index(): return {“message”: “Hello World”} Start the uvicorn server by mentioning the file in which the FastAPI application object is instantiated. uvicorn main:app –reload INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) INFO: Started reloader process [28720] INFO: Started server process [28722] INFO: Waiting for application startup. INFO: Application startup complete. Open the browser and visit http://localhost:/8000. You will see the JSON response in the browser window. FastAPI – OpenAPI Enter the following URL in the browser to generate automatically the interactive documentation. http://127.0.0.1:8000/docs FastAPI uses Swagger UI to produce this documentation. The browser will display the following − Click the ”try it out” button and then ”Execute” button that appears afterward. You can see the Curl command internally executed, the request URL, the response headers, and the JSON format of the server’s response. FastAPI generates a schema using OpenAPI specifications. The specification determines how to define API paths, path parameters, etc. The API schema defined by the OpenAPI standard decides how the data is sent using JSON Schema. Visit http://127.0.0.1:8000/openapi.json from your browser. A neatly formatted JSON response as follows will be displayed − { “openapi”: “3.0.2”, “info”: { “title”: “FastAPI”, “version”: “0.1.0” }, “paths”: { “/”: { “get”: { “summary”: “Index”, “operationId”: “index__get”, “responses”: { “200”: { “description”: “Successful Response”, “content”: { “application/json”: { “schema”: {} } } } } } } } } FastAPI also supports another automatic documentation method provided by Redoc ( https://github.com/Redocly/redoc). Enter http://localhost:8000/redoc as URL in the browser’s address bar. FastAPI – Uvicorn Unlike the Flask framework, FastAPI doesn’t contain any built-in development server. Hence we need Uvicorn. It implements ASGI standards and is lightning fast. ASGI stands for Asynchronous Server Gateway Interface. The WSGI (Web Server Gateway Interface – the older standard) compliant web servers are not suitable for asyncio applications. Python web frameworks (such as FastAPI) implementing ASGI specifications provide high speed performance, comparable to web apps built with Node and Go. Uvicorn uses uvloop and httptools libraries. It also provides support for HTTP/2 and WebSockets, which cannot be handled by WSGI. uvloop id similar to the built-in asyncio event loop. httptools library handles the http protocols. The installation of Uvicorn as described earlier will install it with minimal dependencies. However, standard installation will also install cython based dependencies along with other additional libraries. pip3 install uvicorn(standard) With this, the WebSockets protocol will be supported. Also, PyYAML will be installed to allow you to provide a .yaml file. As mentioned earlier, the application is launched on the Uvicorn server with the following command − uvicorn main:app –reload The –reload option enables the debug mode so that any changes in app.pywill be automatically reflected and the display on the client browser will be automatically refreshed. In addition, the following command-line options may be used − Sr.No Command & Description 1 –host TEXT Bind socket to this host. [default 127.0.0.1] 2 –port INTEGER Bind socket to this port. [default 8000] 3 –uds TEXT Bind to a UNIX domain socket. 4 –fd INTEGER Bind to socket from this file descriptor. 5

FastAPI – Discussion

Discuss – FastAPI ”; Previous Next FastAPI is a modern Python web framework, very efficient in building APIs. FastAPI has been developed by Sebastian Ramirez in Dec. 2018. FastAPI 0.68.0 is the currently available version. The latest version requires Python 3.6 or above. It is one of the fastest web frameworks of Python. Print Page Previous Next Advertisements ”;

FastAPI – Useful Resources

FastAPI – Useful Resources ”; Previous Next The following resources contain additional information on FastAPI. Please use them to get more in-depth knowledge on this. Useful Video Courses Python Flask and SQLAlchemy ORM 22 Lectures 1.5 hours Jack Chan More Detail Python and Elixir Programming Bundle Course 81 Lectures 9.5 hours Pranjal Srivastava More Detail TKinter Course – Build Python GUI Apps 49 Lectures 4 hours John Elder More Detail A Beginner”s Guide to Python and Data Science 81 Lectures 8.5 hours Datai Team Academy More Detail Deploy Face Recognition Project With Python, Django, And Machine Learning Best Seller 93 Lectures 6.5 hours Srikanth Guskra More Detail Professional Python Web Development with Flask 80 Lectures 12 hours Stone River ELearning More Detail Print Page Previous Next Advertisements ”;

FastAPI – Uploading Files

FastAPI – Uploading Files ”; Previous Next First of all, to send a file to the server you need to use the HTML form’s enctype as multipart/form-data, and use the input type as the file to render a button, which when clicked allows you to select a file from the file system. <html> <body> <form action=”http://localhost:8000/uploader” method=”POST” enctype=”multipart/form-data”> <input type=”file” name=”file” /> <input type=”submit”/> </form> </body> </html> Note that the form’s action parameter to the endpoint http://localhost:8000/uploader and the method is set to POST. This HTML form is rendered as a template with following code − from fastapi import FastAPI, File, UploadFile, Request import uvicorn import shutil from fastapi.responses import HTMLResponse from fastapi.templating import Jinja2Templates app = FastAPI() templates = Jinja2Templates(directory=”templates”) @app.get(“/upload/”, response_class=HTMLResponse) async def upload(request: Request): return templates.TemplateResponse(“uploadfile.html”, {“request”: request}) Visit http://localhost:8000/upload/. You should get the form with Choose File button. Click it to open the file to be uploaded. The upload operation is handled by UploadFile function in FastAPI from fastapi import FastAPI, File, UploadFile import shutil @app.post(“/uploader/”) async def create_upload_file(file: UploadFile = File(…)): with open(“destination.png”, “wb”) as buffer: shutil.copyfileobj(file.file, buffer) return {“filename”: file.filename} We shall use shutil library in Python to copy the received file in the server location by the name destination.png Print Page Previous Next Advertisements ”;

FastAPI – Request Body

FastAPI – Request Body ”; Previous Next We shall now use the Pydantic model object as a request body of the client’s request. As mentioned earlier, we need to use POST operation decorator for the purpose. import uvicorn from fastapi import FastAPI from typing import List from pydantic import BaseModel, Field app = FastAPI() class Student(BaseModel): id: int name :str = Field(None, title=”name of student”, max_length=10) subjects: List[str] = [] @app.post(“/students/”) async def student_data(s1: Student): return s1 As it can be seen, the student_data() function is decorated by @app.post() decorator having the URL endpoint as “/students/”. It receives an object of Student class as Body parameter from the client’s request. To test this route, start the Uvicorn server and open the Swagger UI documentation in the browser by visiting http://localhost:8000/docs The documentation identifies that “/students/” route is attached with student_data() function with POST method. Under the schemas section the Student model will be listed. Expand the node in front of it to reveal the structure of the model Click the Try it out button to fill in the test values in the request body. Click the Execute button and get the server’s response values. While a Pydantic model automatically populates the request body, it is also possible to use singular values to add attributes to it. For that purpose, we need to use Body class objects as the parameters of the operation function to be decorated. First, we need to import Body class from fastapi. As shown in the following example, declare ”name” and ”marks” as the Body parameters in the definition of student_data() function below the @app.post() decorator. import uvicorn from fastapi import FastAPI, Body @app.post(“/students”) async def student_data(name:str=Body(…), marks:int=Body(…)): return {“name”:name,”marks”: marks} If we check the Swagger UI documentation, we should be able to find this POST method associated to student_data() function and having a request body with two parameters. It is also possible to declare an operation function to have path and/or query parameters along with request body. Let us modify the student_data() function to have a path parameter ”college’, ”age” as query parameter and a Student model object as body parameter. @app.post(“/students/{college}”) async def student_data(college:str, age:int, student:Student): retval={“college”:college, “age”:age, **student.dict()} return retval The function adds values of college and age parameters along with the dictionary representation of Student object and returns it as a response. We can check the API documentation as follows − As it can be seen, college is the path parameter, age is a query parameter, and the Student model is the request body. Print Page Previous Next Advertisements ”;

FastAPI – Cookie Parameters

FastAPI – Cookie Parameters ”; Previous Next A cookie is one of the HTTP headers. The web server sends a response to the client, in addition to the data requested, it also inserts one or more cookies. A cookie is a very small amount of data, that is stored in the client’s machine. On subsequent connection requests from the same client, this cookie data is also attached along with the HTTP requests. The cookies are useful for recording information about client’s browsing. Cookies are a reliable method of retrieving stateful information in otherwise stateless communication by HTTP protocol. In FastAPI, the cookie parameter is set on the response object with the help of set_cookie() method response.set_cookie(key, value) Example Here is an example of set_cookie() method. We have a JSON response object called content. Call the set_cookie() method on it to set a cookie as key=”usrname” and value=”admin” − from fastapi import FastAPI from fastapi.responses import JSONResponse app = FastAPI() @app.post(“/cookie/”) def create_cookie(): content = {“message”: “cookie set”} response = JSONResponse(content=content) response.set_cookie(key=”username”, value=”admin”) return response To read back the cookie on a subsequent visit, use the Cookie object in the FastAPI library. from fastapi import FastAPI, Cookie app = FastAPI() @app.get(“/readcookie/”) async def read_cookie(username: str = Cookie(None)): return {“username”: username} Inspect these two endpoints in the Swagger API. There are these two routes “/cookies” and “/readcookie”. Execute the create_cookie() function bound to “/cookies”. The response is just the content, although the cookie is set. When the read_cookie() function is executed, the cookie is read back and appears as the response. Also, not that the documentation identifies the user name as a cookie parameter. Print Page Previous Next Advertisements ”;

FastAPI – FastAPI Event Handlers

FastAPI – FastAPI Event Handlers ”; Previous Next Event handlers are the functions to be executed when a certain identified event occurs. In FastAPI, two such events are identified − startup and shutdown. FastAPI’s application object has on_event() decorator that uses one of these events as an argument. The function registered with this decorator is fired when the corresponding event occurs. The startup event occurs before the development server starts and the registered function is typically used to perform certain initialization tasks, establishing connection with the database etc. The event handler of shutdown event is called just before the application shutdown. Example Here is a simple example of startup and shutdown event handlers. As the app starts, the starting time is echoed in the console log. Similarly, when the server is stopped by pressing ctrl+c, the shutdown time is also displayed. main.py from fastapi import FastAPI import datetime app = FastAPI() @app.on_event(“startup”) async def startup_event(): print(”Server started :”, datetime.datetime.now()) @app.on_event(“shutdown”) async def shutdown_event(): print(”server Shutdown :”, datetime.datetime.now()) Output It will produce the following output − uvicorn main:app –reload INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) INFO: Started reloader process [28720] INFO: Started server process [28722] INFO: Waiting for application startup. Server started: 2021-11-23 23:51:45.907691 INFO: Application startup complete. INFO: Shutting down INFO: Waiting for application server Shutdown: 2021-11-23 23:51:50.82955 INFO: Application shutdown com INFO: Finished server process Print Page Previous Next Advertisements ”;

FastAPI – Using GraphQL

FastAPI – Using GraphQL ”; Previous Next Facebook developed GraphQL in 2012, a new API standard with the intention of optimizing RESTful API Calls. GraphQL is the data query and manipulation language for the API. GraphQL is more flexible, efficient, and accurate as compared to REST. A GraphQL server provides only a single endpoint and responds with the precise data required by the client. As GraphQL is compatible with ASGI, it can be easily integrated with a FastAPI application. There are many Python libraries for GraphQL. Some of them are listed below − Strawberry Ariadne Tartiflette Graphene FastAPI’s official documentation recommends using Strawberry library as its design is also based on type annotations (as in the case of FastAPI itself). In order to integrate GraphQL with a FastAPI app, first decorate a Python class as Strawberry type. @strawberry.type class Book: title: str author: str price: int Next, declare a Query class containing a function that returns a Book object. @strawberry.type class Query: @strawberry.field def book(self) -> Book: return Book(title=”Computer Fundamentals”, author=”Sinha”, price=300) Use this Query class as the parameter to obtain Strawberry.Schema object schema = strawberry.Schema(query=Query) Then declare the objects of both GraphQL class and FastAPI application class. graphql_app = GraphQL(schema) app = FastAPI() Finally, add routes to the FastAPI object and run the server. app.add_route(“/book”, graphql_app) app.add_websocket_route(“/book”, graphql_app) Visit http://localhost:8000/book in the browser. An in-browser GraphQL IDE opens up. Below the commented section, enter the following query using the Explorer bar of the Graphiql IDE. Run the query to display the result in the output pane. Print Page Previous Next Advertisements ”;

FastAPI – Mounting Flast App

FastAPI – Mounting Flask App ”; Previous Next A WSGI application written in Flask or Django framework can be wrapped in WSGIMiddleware and mounted it on a FastAPI app to make it ASGI compliant. First install the Flask package in the current FastAPI environment. pip3 install flask The following code is a minimal Flask application − from flask import Flask flask_app = Flask(__name__) @flask_app.route(“/”) def index_flask(): return “Hello World from Flask!” Then declare app as a FastAPI application object and define an operation function for rendering Hello World message. from fastapi import FastAPI app = FastAPI() @app.get(“/”) def index(): return {“message”: “Hello World from FastAPI!”} Next, mount the flask application as a sub application of FastAPI main app using mount() method. from fastapi.middleware.wsgi import WSGIMiddleware app.mount(“/flask”, WSGIMiddleware(flask_app)) Run the Uvicorn development server. uvicorn flaskapp:app –reload The main FastAPI application is available at the URL http://localhost:8000/ route. {“message”:”Hello World from FastAPI!”} The Flask sub application is mounted at the URL http://localhost:8000/flask. Hello World from Flask! Print Page Previous Next Advertisements ”;

FastAPI – Using MongoDB

FastAPI – Using MongoDB ”; Previous Next FastAPI can also use NoSQL databases such as MongoDB, Cassandra, CouchDB, etc. as the backend for the CRUD operations of a REST app. In this topic, we shall see how to use MongoDB in a FastAPI application. MongoDB is a document oriented database, in which the semi-structured documents are stored in formats like JSON. Documents can contain many different key-value pairs, or key-array pairs, or even nested documents. It is a collection of key-value pairs, similar to Python dictionary object. One or more such documents are stored in a Collection. A Collection in MongoDB is equivalent to a table in relational database. However, MongoDB (as do all the NoSQL databases) doesn”t have a predefined schema. A Document is similar to single row in a table of SQL based relational database. Each document may be of variable number of key-value pairs. Thus MongoDB is a schema-less database. To use MongoDB with FastAPI, MongoDB server must be installed on the machine. We also need to install PyMongo, an official Python driver for MongoDB. pip3 install pymongo Before interacting with MongoDB database through Python and FastAPI code, ensure that MongoDB is running by issuing following command (assuming that MongoDB server is installed in e:mongodb folder). E:mongodbbin>mongod .. waiting for connections on port 27017 An object of MongoClient class in the PyMongo module is the handle using which Python interacts with MongoDB server. from pymongo import MongoClient client=MongoClient() We define Book as the BaseModel class to populate the request body (same as the one used in the SQLite example) from pydantic import BaseModel from typing import List class Book(BaseModel): bookID: int title: str author:str publisher: str Set up the FastAPI application object − from fastapi import FastAPI, status app = FastAPI() The POST operation decorator has “/add_new” as URL route and executes add_book() function. It parses the Book BaseModel object into a dictionary and adds a document in the BOOK_COLLECTION of test database. @app.post(“/add_new”, status_code=status.HTTP_201_CREATED) def add_book(b1: Book): “””Post a new message to the specified channel.””” with MongoClient() as client: book_collection = client[DB][BOOK_COLLECTION] result = book_collection.insert_one(b1.dict()) ack = result.acknowledged return {“insertion”: ack} Add a few documents using the web interface of Swagger UI by visiting http://localhost:8000/docs. You can verify the collection in the Compass GUI front end for MongoDB. To retrieve the list of all books, let us include the following get operation function − get_books(). It will be executed when “/books” URL route is visited. @app.get(“/books”, response_model=List[str]) def get_books(): “””Get all books in list form.””” with MongoClient() as client: book_collection = client[DB][BOOK_COLLECTION] booklist = book_collection.distinct(“title”) return booklist In this case, the server response will be the list of all titles in the books collection. [ “Computer Fundamentals”, “Python Cookbook”, “Let Us Python” ] This following GET decorator retrieves a book document corresponding to given ID as path parameter − @app.get(“/books/{id}”, response_model=Book) def get_book(id: int): “””Get all messages for the specified channel.””” with MongoClient() as client: book_collection = client[DB][BOOK_COLLECTION] b1 = book_collection.find_one({“bookID”: id}) return b1 Swagger UI documentation page shows the following interface − The server’s JSON response, when the above function is executed, is as follows − Print Page Previous Next Advertisements ”;