FastAPI and Streamlit: The Python Duo You Must Know About | by Paul Iusztin | Jun, 2023

FastAPI Backend

FastAPI backend overview [Video by the Author].

As a reminder, the FastAPI code can be found under app-api/api.

Step 1: Create the FastAPI application, where we configured the docs, the CORS middleware and the endpoints root API router.

Step 2: Define the Settings class. The scope of this class is to hold all the constants and configurations you need across your API code, such as:

  • generic configurations: the port, log level or version,
  • GCP credentials: bucket name or path to the JSON service account keys.

You will use the Settings object across the project using the get_settings() function.

Also, inside the Config class, we programmed FastAPI to look for a .env file in the current directory and load all the variables prefixed with APP_API_.

As you can see in the .env.default file, all the variables start with APP_API_.

A screenshot of the .env.default file [Image by the Author].

Step 3: Define the schemas of the API data using Pydantic. These schemas encode or decode data from JSON to a Python object or vice versa. Also, they validate the type and structure of your JSON object based on your defined data model.

When defining a Pydantic BaseModel, it is essential to add a type to every variable, which will be used at the validation step.

Step 4: Define your endpoints, in web lingo, known as views. Usually, a view has access to some data storage and based on a query, it returns a subset of the data source to the requester.

Thus, a standard flow for retrieving (aka GET request) data looks like this:

“client → request data → endpoint → access data storage → encode to a Pydantic schema → decode to JSON → respond with requested data”

Let’s see how we defined an endpoint to GET all the consumer types:

We used “gcsfs.GCSFileSystem” to access the GCS bucket as a standard filesystem.

We attached the endpoint to the api_router.

Using the api_router.get() Python decorator, we attached a basic function to the /consumer_type_values endpoint.

In the example above, when calling “https://<some_ip>:8001/api/v1/consumer_type_values” the consumer_type_values() function will be triggered, and the response of the endpoint will be strictly based on what the function return.

Another important thing is to highlight that by defining the response_model (aka the schema) in the Python decorator, you don’t have to create the Pydantic schema explicitly.

If you return a dictionary that is 1:1, respecting the schema structure, FastAPI will automatically create the Pydantic object for you.

That’s it. Now we will repeat the same logic to define the rest of the endpoints. FastAPI makes everything so easy and intuitive for you.

Now, let’s take a look at the whole file, where we defined endpoints for the following:

  • /health → health check
  • /consumer_type_values → GET all possible consumer types
  • /area_values → GET all possible area types
  • /predictions/{area}/{consumer_type} → GET the predictions for a given area and consumer type. Note that using the {<some_variable>} syntax, you can add parameters to your endpoint — FastAPI docs [2].
  • /monitoring/metrics → GET the aggregated monitoring metrics
  • /monitoring/values/{area}/{consumer_type} → GET the monitoring values for a given area and consumer type

I want to highlight again that the FastAPI backend only reads the GCS bucket’s predictions. The inference step is done solely in the batch prediction pipeline.

You can also go to “http://<your-ip>:8001/api/v1/docs to access the Swagger docs of the API, where you can easily see and test all your endpoints:

Screenshot of the Swapper API docs [Image by the Author].

Thats it! Now you know how to build a FastAPI backend. Things might get more complicated when adding a database layer and user sessions, but you learned all the main concepts that will get you started!

Source link

Leave a Comment