Hello World in FastAPI

Video thumbnail

Finally, it's time to create the "Hello World" program with FastAPI; that is, to implement the minimum necessary to see something on the screen. We agreed that we've already created our virtual environment, installed dependencies, and set up the project in FastAPI.

So, we create a file within the project (the tasks folder):

api.py

With the following code:

api.py

from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def hello_world():
    return {"hello": "world"}

In this first example, the first thing we do is load a class that provides access to the FastAPI framework:

from fastapi import FastAPI

With this class, we create an instance of FastApi:

app = FastAPI ()

Which gives us access to multiple features of the framework, such as creating the application routes.

We define a GET request for the root and this is done through a decorator like the one we can see below:

@app.get("/")

Of course, we can access other types of requests such as POST, PUT, PATCH or DELETE indicating the corresponding method which has its direct equivalent with the name of the request to use; that is, to send a GET request, we use the function get(), to send a POST request, we use the post() function.

As with other web frameworks, each request is processed by a function, in the previous example, the GET request for the root is processed by a function called hello_world() which all it does is return a dictionary indicating the "hello world" message:

@app.get("/")
def hello_world():
    return {"hello": "world"}

With this, we have our first hello world example in FlastApi; but, in order to see this message on the screen, specifically any program that allows processing HTTP requests such as a browser, we have to open the server associated with the previous application and this is where we use the previously installed uvicorn server; to do this, from the terminal and root of the project, we use the following command:

$ uvicorn api: app --reload

With the previous command, we indicate the name of the file, which in this case is called api.py:

api:app

And that the server stays tuned for changes; that is, with the option of:

--reload

The server will be reloaded every time changes are made to the application.

When executing the previous command, we will see in the terminal:

INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     Started reloader process [15820] using StatReload
INFO:     Started server process [4024]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     127.0.0.1:58209 - "GET / HTTP/1.1" 200 OK
INFO:     127.0.0.1:58209 - "GET /favicon.ico HTTP/1.1" 404 Not Found
INFO:     127.0.0.1:58209 - "GET / HTTP/1.1" 200 OK
Video thumbnail

It tells us which is the route in which the application has been raised:

http://127.0.0.1:8000

And from this route, which we can execute in the browser, we will see the message of:

http://127.0.0.1:8000
{
  "hello": "world"
}

If necessary, you can also customize the port using the port option and indicate the port you want to use, in this example, port 8001:

$ uvicorn api:app --port 8001

With the reload option:

$ uvicorn api:app --port 8001 --reload

And in the output you will now see that the server is loading the application on port 8001

Uvicorn running on http://127.0.0.1:8001 (Press CTRL+C to quit)

Finally, the previous function can also indicate the return data type:

@app.get("/")
def hello_world() -> dict:
    return {"hello": "world"}

It is important to note that a GET type request is used, which is the typical type of request used to query data; and the only one that we can use directly from the browser without having to use a form.

Parameters in routes (path)

At the route level, you can also define parameters with which the end user interacts and they look like this:

@app.get("/posts/{id}")

As you can see, this route scheme allows the use of dynamic parameters and with this, being able to supply data to each of the API resources that we are building; in the previous example, it is indicated that for the route a parameter called id must be supplied, which is then supplied as an argument to the decorated function; that is to say:

@app.get("/posts/{id}")
def add(id: int):
    #TODO
    return {"POST ID": id}

In the previous example, a parameter called "id" must be indicated, which must be an integer type which can be used (for example) to search for the identifier of a post that you want to retrieve:

/post/123

Types of routes

There are different HTTP methods that we can use to make requests to the server; these methods are nothing more than a set of verbs that are used to perform different types of actions; the most common methods are GET, POST, PUT, PATCH, and DELETE:

  • GET: used to get information from a web server. The information is sent in the request URL.
  • POST: used to send information to a web server. The information is sent in the body of the request.
  • PUT: used to update information on a web server. The information is sent in the body of the request.
  • PATCH: used to partially update information on a web server. The information is sent in the body of the request.
  • DELETE: used to delete information from a web server. The information is sent in the request URL.

All of these methods have their equivalent in FastApi; at the moment we have used GET type methods to obtain data, but it is also possible to use others:

@app.get(<URI>)
@app.post(<URI>)
@app.put(<URI>)
@app.patch(<URI>)
@app.delete(<URI>)

As you can see, we have a decorator function for each type of method and it has a direct relationship with the HTTP request type; that is, we have a decorator method put() to send requests of type PUT, and so on for the rest.

FastApi core libraries

To end this introduction with FastAPI, it is important to note that FastAPI is based on two main Python libraries: Starlette, a low-level ASGI web framework (https://www.starlette.io/), and Pydantic, a validation library. (https://pydantic-docs.helpmanual.io/), of which this last library, we will use heavily in the following sections.

Both libraries can be seen if you do a:

$ pip freeze

About your project in FastApi.

The next step is to learn how to generate test data from the FastAPI documentation.

We will create the first function in FastAPI for the API and learn the basics of FastAPI, start the server, create our controller and see the Hello World on the screen.

I agree to receive announcements of interest about this Blog.

Andrés Cruz

ES En español