FastAPI – Header Parameters ”; Previous Next In order to read the values of an HTTP header that is a part of the client request, import the Header object from the FastAPI library, and declare a parameter of Header type in the operation function definition. The name of the parameter should match with the HTTP header converted in camel_case. In the following example, the “accept-language” header is to be retrieved. Since Python doesn’t allow “-” (dash) in the name of identifier, it is replaced by “_” (underscore) from typing import Optional from fastapi import FastAPI, Header app = FastAPI() @app.get(“/headers/”) async def read_header(accept_language: Optional[str] = Header(None)): return {“Accept-Language”: accept_language} As the following Swagger documentation shows, the retrieved header is shown as the response body. You can push custom as well as predefined headers in the response object. The operation function should have a parameter of Response type. In order to set a custom header, its name should be prefixed with “X”. In the following case, a custom header called “X-Web-Framework” and a predefined header “Content-Language” is added along with the response of the operation function. from fastapi import FastAPI from fastapi.responses import JSONResponse app = FastAPI() @app.get(“/rspheader/”) def set_rsp_headers(): content = {“message”: “Hello World”} headers = {“X-Web-Framework”: “FastAPI”, “Content-Language”: “en-US”} return JSONResponse(content=content, headers=headers) The newly added headers will appear in the response header section of the documentation. Print Page Previous Next Advertisements ”;
Category: fastapi
FastAPI – Dependencies
FastAPI – Dependencies ”; Previous Next The built-in dependency injection system of FastAPI makes it possible to integrate components easier when building your API. In programming, Dependency injection refers to the mechanism where an object receives other objects that it depends on. The other objects are called dependencies. Dependency injection has the following advantages − reuse the same shared logic share database connections enforce authentication and security features Assuming that a FastAPI app has two operation functions both having the same query parameters id, name and age. from fastapi import FastAPI app = FastAPI() @app.get(“/user/”) async def user(id: str, name: str, age: int): return {“id”: id, “name”: name, “age”: age} @app.get(“/admin/”) async def admin(id: str, name: str, age: int): return {“id”: id, “name”: name, “age”: age} In case of any changes such as adding/removing query parameters, both the route decorators and functions need to be changed. FastAPI provides Depends class and its object is used as a common parameter in such cases. First import Depends from FastAPI and define a function to receive these parameters − async def dependency(id: str, name: str, age: int): return {“id”: id, “name”: name, “age”: age} Now we can use the return value of this function as a parameter in operation functions @app.get(“/user/”) async def user(dep: dict = Depends(dependency)): return dep For each new Request, FastAPI calls the dependency function using the corresponding parameters, returns the result, and assigns the result to your operation. You can use a class for managing dependencies instead of a function. Declare a class with id, name and age as attributes. class dependency: def __init__(self, id: str, name: str, age: int): self.id = id self.name = name self.age = age Use this class as the type of parameters. @app.get(“/user/”) async def user(dep: dependency = Depends(dependency)): return dep @app.get(“/admin/”) async def admin(dep: dependency = Depends(dependency)): return dep Here, we used the dependency injection in the operation function. It can also be used as operation decoration. For example, we want to check if the value of query parameter age is less than 21. If yes it should throw an exception. So, we write a function to check it and use it as a dependency. async def validate(dep: dependency = Depends(dependency)): if dep.age > 18: raise HTTPException(status_code=400, detail=”You are not eligible”) @app.get(“/user/”, dependencies=[Depends(validate)]) async def user(): return {“message”: “You are eligible”} In FastAPI dependency management, you can use yield instead of return to add some extra steps. For example, the following function uses database dependency with yield. async def get_db(): db = DBSession() try: yield db finally: db.close() Print Page Previous Next Advertisements ”;
FastAPI – HTML Form Templates ”; Previous Next Let us add another route “/login” to our application which renders a html template having a simple login form. The HTML code for login page is as follows − <html> <body> <form action=”/submit” method=”POST”> <h3>Enter User name</h3> <p><input type=”text” name=”nm”/></p> <h3>Enter Password</h3> <p><input type=”password” name=”pwd”/></p> <p><input type=”submit” value=”Login”/></p> </form> </body> </html> Note that the action parameter is set to “/submit” route and action set to POST. This will be significant for further discussion. Add login() function in the main.py file as under − @app.get(“/login/”, response_class=HTMLResponse) async def login(request: Request): return templates.TemplateResponse(“login.html”, {“request”: request}) The URL http://localhost:8000/login will render the login form as follows − Print Page Previous Next Advertisements ”;
FastAPI – CORS
FastAPI – CORS ”; Previous Next Cross-Origin Resource Sharing (CORS) is a situation when a frontend application that is running on one client browser tries to communicate with a backend through JavaScript code, and the backend is in a different “origin” than the frontend. The origin here is a combination of protocol, domain name, and port numbers. As a result, http://localhost and https://localhost have different origins. If the browser with a URL of one origin sends a request for the execution of JavaScript code from another origin, the browser sends an OPTIONS HTTP request. If the backend authorizes the communication from this different origin by sending the appropriate headers it will let the JavaScript in the frontend send its request to the backend. For that, the backend must have a list of “allowed origins”. To specify explicitly the allowed origins, import CORSMiddleware and add the list of origins to the app”s middleware. from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware app = FastAPI() origins = [ “http://192.168.211.:8000”, “http://localhost”, “http://localhost:8080”, ] app.add_middleware( CORSMiddleware, allow_origins=origins, allow_credentials=True, allow_methods=[“*”], allow_headers=[“*”], ) @app.get(“/”) async def main(): return {“message”: “Hello World”} Print Page Previous Next Advertisements ”;
FastAPI – Rest Architecture
FastAPI – REST Architecture ”; Previous Next RElational State Transfer (REST) is a software architectural style. REST defines how the architecture of a web application should behave. It is a resource based architecture where everything that the REST server hosts, (a file, an image, or a row in a table of a database), is a resource, having many representations. REST recommends certain architectural constraints. Uniform interface Statelessness Client-server Cacheability Layered system Code on demand REST constraints has the following advantages − Scalability Simplicity Modifiability Reliability Portability Visibility REST uses HTTP verbs or methods for the operation on the resources. The POST, GET, PUT and DELETE methods perform respectively CREATE, READ, UPDATE and DELETE operations respectively. Print Page Previous Next Advertisements ”;
FastAPI – Crud Operations
FastAPI – CRUD Operations ”; Previous Next The REST architecture uses HTTP verbs or methods for the operation on the resources. The POST, GET, PUT and DELETE methods perform respectively CREATE, READ, UPDATE and DELETE operations respectively. In the following example, we shall use a Python list as an in-memory database and perform the CRUD operations on it. First, let us set up a FastAPI app object and declare a Pydantic model called Book. from fastapi import FastAPI from pydantic import BaseModel app = FastAPI() data = [] class Book(BaseModel): id: int title: str author: str publisher: str An object of this model is populated using the @app.post() decorator and it is appended to the list of books (data is declared for the list of books) @app.post(“/book”) def add_book(book: Book): data.append(book.dict()) return data In the Swagger UI, execute this operation function a couple of times and add some data. The server’s JSON response shows the list of books added so far. To retrieve the list, define an operation function bound to the @app.get() decorator as follows − @app.get(“/list”) def get_books(): return data To retrieve a book with its id as a path parameter, define the get() operation decorator and get_book() function as below − @app.get(“/book/{id}”) def get_book(id: int): id = id – 1 return data[id] The /list route retrieves all the books. On the other hand, use “id” as the path parameter in the “/book/1” route. The book with “id=1” will be retrieved as can be seen in the server response of Swagger UI Next, define @app.put() decorator that modifies an object in the data list. This decorator too has a path parameter for the id field. @app.put(“/book/{id}”) def add_book(id: int, book: Book): data[id-1] = book return data Inspect this operation function in the swagger UI. Give id=1, and change value of publisher to BPB in the request body. When executed, the response shows the list with object with id=1 updated with the new values. Finally, we define the @app.delete() decorator to delete an object corresponding to the path parameter. @app.delete(“/book/{id}”) def delete_book(id: int): data.pop(id-1) return data Give id=1 as the path parameter and execute the function. Upon execution, the list now shows only two objects Print Page Previous Next Advertisements ”;
FastAPI – OpenAPI
FastAPI – OpenAPI ”; Previous Next 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. Print Page Previous Next Advertisements ”;
FastAPI – Path Parameters
FastAPI – Path Parameters ”; Previous Next Modern web frameworks use routes or endpoints as a part of URL instead of file-based URLs. This helps the user to remember the application URLs more effectively. In FastAPI, it is termed a path. A path or route is the part of the URL trailing after the first ‘/’. For example, in the following URL, http://localhost:8000/hello/TutorialsPoint the path or the route would be /hello/TutorialsPoint In FastAPI, such a path string is given as a parameter to the operation decorator. The operation here refers to the HTTP verb used by the browser to send the data. These operations include GET, PUT, etc. The operation decorator (for example, @app.get(“/”)) is immediately followed by a function that is executed when the specified URL is visited. In the below example − from fastapi import FastAPI app = FastAPI() @app.get(“/”) async def index(): return {“message”: “Hello World”} Here, (“/”) is the path, get is the operation, @app.get(“/”) is the path operation decorator, and the index() function just below it is termed as path operation function. Any of the following HTTP verbs can be used as operations. Sr.No. Method & Description 1 GET Sends data in unencrypted form to the server. Most common method. 2 HEAD Same as GET, but without the response body. 3 POST Used to send HTML form data to the server. Data received by the POST method is not cached by the server. 4 PUT Replaces all current representations of the target resource with the uploaded content. 5 DELETE Removes all current representations of the target resource given by a URL. The async keyword in the function’s definition tells FastAPI that it is to be run asynchronously i.e. without blocking the current thread of execution. However, a path operation function can be defined without the async prefix also. This decorated function returns a JSON response. Although it can return almost any of Python’s objects, it will be automatically converted to JSON. Further in this tutorial, we shall see how such a function returns Pydantic model objects. The URL’s endpoint or path can have one or more variable parameters. They can be accepted by using Python’s string formatting notation. In the above example URL http://localhost:8000/hello/TutorialsPoint, the last value may change in every client request. This variable parameter can be accepted in a variable as defined in the path and passed to the formal parameters defined in the function bound to the operation decorator. Example Add another path decorator with a variable parameter in the route, and bind hello() function to have name parameter. Modify the main.py as per the following. import uvicorn from fastapi import FastAPI app = FastAPI() @app.get(“/”) async def index(): return {“message”: “Hello World”} @app.get(“/hello/{name}”) async def hello(name): return {“name”: name} Start the Uvicorn server and visit http://localhost:8000/hello/Tutorialspoint URL. The browser shows the following JSON response. {“name”:”Tutorialspoint”} Change the variable path parameter to something else such as http://localhost:8000/hello/Python so that the browser shows − {“name”:”Python”} Check OpenAPI docs Now if we check the OpenAPI documentation by entering the URL as http://localhost:8000/docs, it will show two routes and their respective view functions. Click the try out button below /hello/{name} button and give Tutorialspoint as the value of the name parameter’s description and then click the Execute button. It will then show the Curl command, the request URL and the details of server’s response with response body and response headers. A route can have multiple parameters separated by “/” symbol. from fastapi import FastAPI app = FastAPI() @app.get(“/hello/{name}/{age}”) async def hello(name,age): return {“name”: name, “age”:age} In this case, /hello is the route, followed by two parameters put in curly brackets. If the URL given in the browser’s address bar is http://localhost:8000/hello/Ravi/20, The data of Ravi and 20 will be assigned to variables name and age respectively. The browser displays the following JSON response − {“name”:”Ravi”,”age”:”20″} Path Parameters with Types You can use Python’s type hints for the parameters of the function to be decorated. In this case, define name as str and age as int. @app.get(“/hello/{name}/{age}”) async def hello(name:str,age:int): return {“name”: name, “age”:age} This will result in the browser displaying an HTTP error message in the JSON response if the types don’t match. Try entering http://localhost:8000/hello/20/Ravi as the URL. The browser’s response will be as follows − { “detail”: [ { “loc”: [ “path”, “age” ], “msg”: “value is not a valid integer”, “type”: “type_error.integer” } ] } The reason is obvious as age being integer, can’t accept a string value. This will also be reflected in the Swagger UI (OpenAPI) documentation. Print Page Previous Next Advertisements ”;
FastAPI – IDE Support
FastAPI – IDE Support ”; Previous Next The Type Hinting feature of Python is most effectively used in almost all IDEs (Integrated Development Environments) such as PyCharm and VS Code to provide dynamic autocomplete features. Let us see how VS Code uses the type hints to provide autocomplete suggestions while writing a code. In the example below, a function named as sayhello with name as an argument has been defined. The function returns a string by concatenating “Hello” to the name parameter by adding a space in between. Additionally, it is required to ensure that the first letter of the name be in upper case. Python’s str class has a capitalize() method for the purpose, but if one doesn’t remember it while typing the code, one has to search for it elsewhere. If you give a dot after name, you expect the list of attributes but nothing is shown because Python doesn’t know what will be the runtime type of name variable. Here, type hint comes handy. Include str as the type of name in the function definition. Now when you press dot (.) after name, a drop down list of all string methods appears, from which the required method (in this case capitalize()) can be picked. It is also possible to use type hints with a user defined class. In the following example a rectangle class is defined with type hints for arguments to the __init__() constructor. class rectangle: def __init__(self, w:int, h:int) ->None: self.width=w self.height=h Following is a function that uses an object of above rectangle class as an argument. The type hint used in the declaration is the name of the class. def area(r:rectangle)->int: return r.width*r.height r1=rectangle(10,20) print (“area = “, area(r1)) In this case also, the IDE editor provides autocomplete support prompting list of the instance attributes. Following is a screenshot of PyCharm editor. FastAPI makes extensive use of the type hints. This feature is found everywhere, such as path parameters, query parameters, headers, bodies, dependencies, etc. as well as validating the data from the incoming request. The OpenAPI document generation also uses type hints. Print Page Previous Next Advertisements ”;
FastAPI – Introduction
FastAPI – Introduction ”; Previous Next 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 Print Page Previous Next Advertisements ”;