PYTHON DEVELOPMENT

Deploying your First FastAPI Application in OpenShift

Should take you less than five minutes

Frank Ceballos

--

Weslaco, Texas

In this article we will show the reader how to deploy a FastAPI application in OpenShift. We will not cover any actual API development since FastAPI haves excellent documentation. It will be assumed that the reader is familiar with Python and GitHub. To build our application image, we will use the Source-To-Image (S2I) technique — a standalone OpenShift tool which is very useful when creating builder images.

Getting Started

  1. Fork the following GitHub repository:

2. Clone the forked repository locally and open it with your favorite code editor and set the repository visibility to public. This is done to facilitate the build process in OpenShift. Please be careful to not set the visibility to public on a private repository without knowing the consequences of this action. Since the forked FastAPI repository has no proprietary code its fine to do so.

3. Optional: Install MiniShift to build and deploy applications in a single node OpenShift cluster or provisioned your free OpenShift cluster.

OpenShift Specific Content

We will like to cover the OpenShift related content of the repository. This is to help the reader customize how the API starts up upon deployment. Here are the contents of the repository:

Repository tree structure.

The OpenShift related files can be found under the .s2i directory. Let’s go over the run file which is responsible for running the application.

Script 01: Contents of the run file. You can update this to meet your specifications.

Let’s go over the parameters:

  • uvicorn : Server used to server your application.
  • main:app : Upon startup, the server will serve the contents of the file main.py and is expecting to find the application instance to be saved under a variable called app .
  • --host 0.0.0.0 : Bind socket to this host. Use --host 0.0.0.0 to make the application available on the available Pod IP address. Every time a new Pod gets spin up, OpenShift assigns it a random IP address. Don’t change this unless you know what you are doing.
  • --port 8080 : In OpenShift applications are by default served in port 8080 when using S2I. You can change this if your route and service are configured to work with a different port.
  • --workers 8 : The number of workers the server should spin up. The default value is 1. As your server receives request from users, it will assign the request to an available worker. If all workers are busy at the time of the request, the request will put on a queue and will executed once a worker is freed up. In this case, this mean that the server is capable of executing eight different request in parallel. Feel free to change this number to match your business needs. Don’t forget that you will need increase the Pod resources in order to handle a larger amount of workers.
  • --header server:custom-server-name : With this parameter you specify that the response headers should contain the server name custom-sever-name . Here is an example of the response headers:
content-length: 25  
content-type: application/json
date: Wed,05 Jan 2022 23:59:52 GMT
server: custom-server-name

To learn more about what parameters you can passed to the server, visit the official documentation page for uvicorn.

FastAPI Related Content

We will briefly cover the FastAPI portion of the repository. Everything related to FastAPI can be found in the main.py file:

Script 02: Contents of the main.py

Important things to note:

  • In line 4 of main.py , the application instance is saved under a variable called app
  • There are two endpoints: / and /message
  • The host is set to 0.0.0.0 and the port to 8080

Running FastAPI Locally

Before we move on to OpenShift, let’s run our FastAPI application locally. This will allows us to add and test changes before pushing them to GitHub/OpenShift.

After cloning the forked repository, you will need to create a virtual environment. To create a virtual environment open a terminal, cd into the FastAPI repository, and run the following command:

python -m venv env

This will create a folder called env . To activate the virtual environment run:

source env/bin/activate

After you activate the virtual environment, you should see the virtual environment name appearing on the terminal as shown in the figure below:

The necessary packages to run our FastAPI application are saved in requirements.txt . To install them we will use pip:

pip install -r requirements.txt
Packages in requirement.txt being install via pip

Any other packages that you might want to use, add them to requirements.txt and run the pip install command.

To start up our FastAPI application run:

python main.py

Once the server is running, open a browser and visit the following address: localhost:8080

To access a different endpoint such as /message you will need to visit: localhost:8080/message — see the figure below:

Finally, to access the FastAPI documentation visit: localhost:8080/docs

localhost:8080/docs

Now you are free to use your favorite IDE to make changes to the repository and see them reflected locally.

Source-To-Image Overview

To build our application image, we will use the Source-To-Image (S2I) technique, a standalone tool which is very useful when creating builder images. In the most simplest form this is how S2I works:

  1. A base image is pulled from an image registry. In this case, we will be using a Python image. The Python base image will contain all the necessary tools for running your Python application + basic Linux tools.
  2. OpenShift clones the Git repository into the home directory of the base Python image.
  3. The packages specified in requirements.txt get installed using pip
  4. After the image is built with your custom code, packages, and configured based on the contents of .s2i folder, the image is stored in the internal image registry.
  5. Finally, a pod is spin up, a container with your image application is injected, and the run command gets executed which is found in .s2i/bin/run .

Building and Deploying in OpenShift

Let’s get our hand dirty. Start by visiting the OpenShift web console, change to the Developer Mode View ,and click on +Add (see Figure 1).

Figure 1 — Developer Mode view

Next, we will need to determine how do we want to build our application. OpenShift allows you to build applications directly from a Git repository using the S2I tool. Click on Import from Git as shown in Figure 2.

Figure 2 — Determining our build strategy for our FastAPI application in OpenShift.

Clicking on Import from Git will takes us to the build configuration section of our application — see Figure 3.

Figure 3 — Build configuration section.

In this screen we will:

  1. Add the Git Repo URL. Automatically, OpenShift will determine the builder image based on the contents of the repository. In this case, it will select the Python 3.9 (UBI 8). If you want a different image, click on Edit Import Strategy and select it from the Builder Image Version dropdown.
  2. Click on Show advanced Git options to provide the name of the branch and Git credentials.
  3. The Git credentials are only required if the repository view is set to private. However, in our case we will leave the Source Secret section blank since our repository view is set to public. If you have a private repository, I recommend that you use the SSH protocol as shown here to build your application from a private GitHub repository.
  4. In the General section, feel free to change the application name.

We are almost ready to build the application. We will now move to securing the route — as shown in Figure 4.

Figure 4 — Securing the route for our application.

5–7. Check the Secure Route checkbox, for TLS termination select Edge, and redirect insecure traffic by selecting Redirect under the Insecure traffic dropdown. This options will ensure that data exchange between two endpoints is secure and confidential. Additionally, insecure traffic will be force to use the HTTPS secure protocol.

Note: To fully secure your API, you will still need to lock-down/limit the access to your API endpoints. This is beyond the scope of this article and won’t be discussed.

8. To kick off the build hit on Create — see Figure 4.

This will take you back to Topology section where you will see a visual representation of your application — as seen in Figure 5.

Figure 5 — Topology of your an application in OpenShift.

From the Topology, you can access the build & deployment section, access the container via terminal, check the build and deployment logs, and open the route to visit your application. For example, if you click on Open URL you will taken to your FastAPI application — see Figure 5.

Suppose that your base URL looks something like this:

https://openshift-fastapi-git-some-openshift-environment.apps.sandbox-m2.ll9k.p1.openshiftapps.com

which should return the following JSON when you send a GET request:

{“data”:”Hello FastAPI!”}`

To access an API resource such as the/message endpoint, you will have to use:

https://openshift-fastapi-git-some-openshift-environment.apps.sandbox-m2.ll9k.p1.openshiftapps.com/message

To access the documentation:

https://openshift-fastapi-git-some-openshift-environment.apps.sandbox-m2.ll9k.p1.openshiftapps.com/docs

Rebuild Your Application with new Changes

Suppose you pushed some new changes to your GitHub repository. Unless you set up a hook, you will need to manually trigger a new build. To do so click on Builds and then on your FastAPI build configuration — see Figure 6.

Figure 6 — Build section for your namespace showing your fastapi build.

The build configuration section allows you to inspect and change everything regarding the build process. In our case we simply want to trigger a build so that any new changes from our repository are added to our application — see Figure 7.

Figure 7 — Triggering a new build from the build configuration section. Feel free to explore the build configuration by clicking on following tabs: Details, YAML, Builds, Environment, Logs, and Events.

After the build is complete, a new pod will be deployed using the new image — see Figure 8. The old pod is only scaled to zero when the new pod is up and successfully running.

Figure 8 — A new pod being deployed after a new build is complete.

FastAPI Logs

For sake of completeness, let’s verify that we have eight workers running. To do so, you will need to go into the FastAPI pod — see Figure 9.

Figure 9 — Steps to access the FastAPI pod.

Once you are in the pod click on the Logs tab to see the logs being returned the uvicorn server — see Figure 10.

Figure 10 — Inside the FastAPI pod. In here you can see the logs that were printed out during the deployment, the uvicorn server logs, and open a terminal to directly explore the container file system.

In Figure 10, you should see that eight workers were started up just like we specify in our run script. Additionally, you can open a terminal inside the container by clicking the Terminal tab. This will allow you to explore the file system of the container.

Clean Up

Finally, to clean up you can use the following command via OpenShift CLI:

oc delete all,is,dc,secrets,cm,pvc -l app=openshift-fastapi

This will delete the all the OpenShift objects that are tied to your FastAPI application.

Closing Remarks

You have learnt how to build and deploy a FastAPI application in OpenShift. You can now make any additional changes to repository such as:

  • Changing the run command to remove or add more workers
  • Adding environmental variables
  • Create to new endpoints
  • Develop additional tools to increase the functionality of your API

Once you have pushed your changes into GitHub rebuild your application to see them implemented.

Find me at LinkedIn. Until next time! Take care and code everyday!

--

--