Deploying a FastAPI App to the Cloud

fastapi
render
Author

Christian Wittmann

Published

July 9, 2025

In my previous blog post, we created a simple FastAPI-based greeting service with both GET and POST endpoints, an HTML frontend, and interactive documentation. In this follow-up blog post we’ll deploy it to the cloud so it can be accessed publicly using Render. I have no affiliation with them, but chose their platform because they offer a generous free tier.

You’ll learn how to:

In short, we’ll take the FastAPI greeting service from “it works on my machine” to “live on the internet.” 🤓

Creating a Local Deployment

Once you’re done developing your FastAPI app in a Jupyter Notebook, you can prepare it for local deployment by following these steps:

Creating app.py

To create the app.py file, follow these steps

  • Copy all the code from the final cell in the Jupyter Notebook and paste it into a new Python file named app.py.
  • Remove notebook-specific dependencies. Anything related to nest_asyncio is no longer needed, it is only necessary in Jupyter notebooks. Additionally, remove the uvicorn.run(...) call, as the server will be launched outside app.py.

Creating requirements.txt

For out simple project, you could easily create the requirements.txt file manually, but I am too lazy for that, so I am using the pipreqs package to generate it for me

If you don’t have the pipreqs package installed, you can simply install it using pip:

pip install pipreqs

Now you can generate the requirements.txt. Either cd into the directory where your app.py file is located and run

pipreqs .

Alternatively, you can specify the path to the app.py file

pipreqs path/to/app.py

Installing Dependencies

Once you have the requirements.txt file, you can install the dependencies using pip

pip install -r requirements.txt

When you are developing your own app, and you started in a Jupyter notebook, the installation of the dependencies is a self-fulfilling prophecy, but once we move to a virtual environment, you need to install the dependencies.

Running the App

Now you can run your app with Uvicorn from the terminal. From the directory where app.py is located, start the API server with:

uvicorn app:app --reload

Let’s break down the command:

  • uvicorn: The Uvicorn server.
  • app:app: This follows the format :: It tells Uvicorn to look for the FastAPI app instance named app inside the Python module app.py. Since both arguments are the same, let’s change it for clarity. If you had written greeting_app = FastAPI() inside a file called api_app.py, you would run uvicorn api_app:greeting_app --reload
  • --reload: Automatically restarts the server whenever you make code changes — useful during development.

Running the App in a Virtual Environment

So far, we have re-created the behavior of the Jupyter Notebook in a Python file. However, when we deploy the app in the cloud, we will have a different environment. To make sure that we defined the dependencies correctly and the app runs as expected, we should test it in a virtual environment.

Creating a Virtual Environment

To create a virtual environment, you can use the venv module that comes with Python. Open your terminal and navigate to the directory where your app.py file is located. Then, run the following command to create a virtual environment named venv:

python -m venv venv

Let’s break down the command:

  • python: The Python interpreter.
  • -m venv: The venv module, which is used to create virtual environments.
  • venv: The name of the virtual environment.

Activating the Virtual Environment

Once the virtual environment is created, you need to activate it. The activation command depends on your operating system:

  • Windows: venv\Scripts\activate
  • macOS/Linux: source venv/bin/activate

As a result, you should see the name of the virtual environment (venv) as a prefix in your terminal.

Installing Dependencies

Now that you have activated the virtual environment, you can install the dependencies using pip. From the directory where app.py is located, run:

pip install -r requirements.txt

Now the virtual environment has all the dependencies from requirements.txt installed, simulating the environment in which the app will be deployed in the cloud.

Running the App

Now you can run your app with Uvicorn from the terminal. From the directory where app.py is located, start the API server with:

uvicorn app:app --reload

Deactivating the Virtual Environment

When you are done testing, you can deactivate the virtual environment by running:

deactivate

Deploying the API in the Cloud

After we have successfully tested our API locally, it is time deploy it in the cloud. I will use Render to deploy my API, because they have a free tier that allows me to deploy the API for free.

To clearly separate the local development from the cloud deployment, I created a new folder called app-render and copied the app.py and the requirements.txt file into it.

After uploading everything to my GitHub repository, I created a new service in Render and linked it to my GitHub repository. During service creation, set the following parameters:

  • Service Type: Web Service
  • Language: Python 3
  • Branch: main
  • Root Directory: app-render
  • Build Command: pip install -r requirements.txt
  • Start Command: uvicorn app:app --host 0.0.0.0 --port $PORT
  • Instance Type: Free

After deployment, this is the URL of the API: https://fastapi-greeting-api.onrender.com

You can now call the API using the client notebooks for the POST method and the GET method

Conclusion

Taking the API from a Jupyter Notebook (my preferred environment for rapid prototyping) to a working cloud deployment took a few steps. First, we refactored the code into a standalone Python file (app.py). Then we created a requirements.txt file and tested everything locally in a clean virtual environment. Finally, we deployed the API to the cloud using Render. While the deployment step will vary across cloud providers, the general process is similar.

After building the greeting API in my previous blog post, we’ve now taken it all the way to the cloud. The goal here wasn’t to explore every FastAPI feature or every cloud deployment nuance, but to provide a reusable, step-by-step template for future projects and hackathons.

There’s lots more you could do, e.g. adding authentication, rate limiting, or monitoring, but we’ll leave that for another time. I Hope this was helpful, and happy coding!