In a previous blog post, we created a simple greeting API using FastAPI, entirely within a Jupyter Notebook. This follow-up post shows how to deploy it on SAP Business Technology Platform (SAP BTP), making it accessible from your SAP or non-SAP projects.
(I assume you already have access to an SAP BTP account with Cloud Foundry enabled.)
You’ll learn how to:
- Turn the Jupyter Notebook (my go-to tool for rapid prototyping) into a standalone Python file
- Capture your app’s dependencies in a
requirements.txt
file - Create a
manifest.yaml
file - Add a
Procfile
to instruct Cloud Foundry how to start the app. - Test your app locally in a virtual environment
- Deploy the FastAPI app to SAP BTP
In short, we’ll take the FastAPI greeting service from “it works on my machine” to “deployed on SAP BTP.” 🤓
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 theuvicorn.run(...)
call, as the server will be launched outsideapp.py
.
Creating requirements.txt
For our 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 moduleapp.py
. Since both arguments are the same, let’s change it for clarity. If you had writtengreeting_app = FastAPI()
inside a file calledapi_app.py
, you would runuvicorn api_app:greeting_app --reload
--reload
: Automatically restarts the server whenever you make code changes — useful during development.
Note for later: When deploying to SAP BTP, you’ll also need to add two files to your app folder:
manifest.yaml
andProcfile
. These are only needed for deployment and not required when testing locally.
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. This ensures you’re not relying on any globally installed Python packages from your system or IDE setup.
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
: Thevenv
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 on BTP.
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
Preparing for Deployment to SAP BTP
Before deploying our API to SAP BTP using Cloud Foundry, we need to complete a few preparation steps. First, we need to install the Cloud Foundry CLI (unless you want to deploy via the BTP UI which is also possible). Additionally, we need to create two configuration files: manifest.yaml
and Procfile
. These will define how the application is deployed and run on BTP.
Installing the Cloud Foundry CLI
To interact with Cloud Foundry, the preferred way is to use the cf
command-line interface. If you have not installed it yet, you can download and install it from the official Cloud Foundry CLI page.
On macOS, you can conveniently install the current version 8 using brew
:
brew install cloudfoundry/tap/cf-cli@8
Once installed, you should be able to run:
cf --version
You should see the version number of the CLI which confirms the CLI is available and ready to use.
Creating the manifest.yaml
The manifest.yaml
file defines how Cloud Foundry should deploy your app. It includes metadata such as the app name, memory allocation, number of instances, and route configuration. For a complete reference, please check out the Cloud Foundry Manifest Reference
Create a new file named manifest.yaml
in the same folder as your app.py
and add the following content:
---
applications:
- name: greeting-api
memory: 256M
instances: 1
buildpacks:
- python_buildpack
path: .
routes:
- route: greeting-api-test.cfapps.eu10-004.hana.ondemand.com
Let’s break down the content of the manifest.yaml
:
name
: The name of the app as it will appear in your BTP subaccount.memory
: The memory allocated per app instance. 256M is typically sufficient for small FastAPI services.instances
: Number of app instances to start (1 for now).buildpacks
: Sets the Python buildpack (if not set explicitly, BTP will try to detect it automatically).path
: The path to the application directory.routes
: The custom URL (host + domain) you want your app to use. You can find the correct domain (e.g.cfapps.eu10-004.hana.ondemand.com
) in your BTP subaccount under “Cloud Foundry → Overview → API Endpoint.”
Creating the Procfile
The purpose of a Procfile
is to define how your app should be started. While you can specify the start command manually during cf push
(this is the command which finally deploy the API on BTP), it’s good practice to include a Procfile
for clarity, consistency, and maintainability.
Create a plain text file named Procfile
(no extension) in your app’s root directory with the following content:
web: uvicorn app:app --host=0.0.0.0 --port=${PORT:-8080}
Let’s break it down:
web:
tells the platform that this process handles incoming HTTP requests.uvicorn app:app
loads your FastAPI app instance namedapp
from theapp.py
file.--host=0.0.0.0
makes Uvicorn listen on all network interfaces (required for deployment).--port=${PORT:-8080}
uses the port environment variable ($PORT
) provided by Cloud Foundry or falls back to port8080
when running locally.
Deploying the API on SAP BTP
After we’ve successfully tested our API locally and completed all the necessary preparations, it’s time to deploy it to SAP BTP using Cloud Foundry.
To keep things organized, I created a new folder called app-btp
and copied the following files into it:
app.py
– the main FastAPI applicationrequirements.txt
– the list of dependenciesProcfile
– the startup instructionmanifest.yaml
– the deployment descriptor
To start the deployment, open a terminal, cd
into the app-btp
directory, and log in to Cloud Foundry using the SAP BTP CLI:
cf login
You’ll be prompted to enter your API endpoint, email, password, org, and space. You can find the API endpoint in your BTP cockpit by navigating to your subaccount and checking the “Cloud Foundry Environment” section.
Once logged in, push your app to BTP:
cf push
Think of cf push
like pushing code to GitHub: It copies your application to the BTP environment, sets up the app using the manifest.yaml
, installs the dependencies from requirements.txt
, and starts the app using the Procfile
.
After deployment, your app will be assigned a public URL, as specified in your manifest.yaml
. For example:
https://greeting-api-test.cfapps.eu10-004.hana.ondemand.com
You can now test the API using the GET client notebook or the POST client notebook.
Alternative: Deploying via ZIP Upload in the SAP BTP Cockpit
If you prefer to deploy your app via the SAP BTP UI instead of using the CLI, you can also create a ZIP archive and upload it directly through the cockpit.
Simply create a ZIP archive of your app folder containing the following files:
app.py
requirements.txt
Procfile
Make sure there are no folders in the ZIP-file, the files should be in the root of the ZIP archive.
Keep the manifest.yaml
as a separate file.
To upload the file for deployment, follow these steps:
- Navigate to a space in your subaccount
- Click on “Deploy Application”
- Upload your
app-btp.zip
file and themanifest.yaml
file - Click on “Deploy”
After the deployment is complete, your app will be live under the route you defined in manifest.yaml
.
You can now test the API using the GET client notebook or the POST client notebook.
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. After creating manifest.yaml
and Procfile
files, we deployed the API to the cloud using the SAP BTP CLI or the SAP BTP Cockpit.
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.
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!