User Guides

How to use LaunchFlow with an Existing Application


Project Setup

Migrating an existing app to use LaunchFlow is easy and can be done incrementally. Let's walk through the process with a minimal FastAPI code sample on GCP.

main.py:

1
from fastapi import FastAPI
2
import uvicorn
3
4
app = FastAPI()
5
6
@app.get("/value")
7
def get_value():
8
return "Hello World"
9
10
if __name__ == "__main__":
11
uvicorn.run(app, host="0.0.0.0", port=8000)

Here, we have an app with one endpoint that returns a hard-coded string. It can be run by calling python main.py. Let's integrate LaunchFlow to use some some resources! To do so your project must contain a launchflow.yaml file. The simplest way to create one is by running lf init.

1
$ lf init

Running this command will prompt you to provide a project name and choose whether to use a local backend or LaunchFlow Cloud. Here we've chosen to use a local backend producing the following launchflow.yaml:

1
project: use-launchflow-with-existing
2
backend: file://.launchflow

That's it!

Add Resources

Now we can add resources and create them by running lf create. Let's add a Postgres database to our app.

1
from fastapi import FastAPI
2
import launchflow as lf
3
import uvicorn
4
5
app = FastAPI()
6
7
postgres = lf.gcp.ComputeEnginePostgres("vm-postgres")
8
9
@app.get("/value")
10
def get_value():
11
return postgres.query("SELECT 1")
12
13
if __name__ == "__main__":
14
uvicorn.run(app, host="0.0.0.0", port=8000)

We've added a Postgres database and are using it a trivial way in our endpoint. To create it, we can just run lf create. This command searches your codebase for LaunchFlow resources, checks to see if they've already been created (or were created with different arguments that now need updating), prompts for confirmation, then creates / updates resources in the cloud.

You'll also need to run your command using lf run:

1
$ lf run YOUR_ENVIRONMENT_NAME -- python main.py

This command can wrap any other, and is used to configure LaunchFlow to use the correct environment. Under the hood, it runs the command in a subprocess with the environment variable LAUNCHFLOW_ENVIRONMENT set to the requested environment name. If you run into any problems, check that your program is able to receive it -- for example, some build systems require you to declare the environment variables you want to allow through.

After it completes, you should be good to use the Postgres instance!

Deploy

Now that we have a working app, we can deploy it to our cloud account using LaunchFlow. The steps here are the same as for a new project:

  1. Create a Dockerfile that can build and run your application.
  2. Add a Cloud Run service to your code.
  3. Run lf deploy on the command line.

Here's a Dockerfile that will work for our example:

1
FROM python:3.11-slim
2
3
WORKDIR /code
4
5
RUN apt-get update && apt-get install -y --no-install-recommends gcc libpq-dev && apt-get clean && rm -rf /var/lib/apt/lists/*
6
7
RUN pip install --no-cache-dir -U pip setuptools wheel && pip install --no-cache-dir launchflow[gcp] fastapi uvicorn
8
9
COPY ./main.py /code/main.py
10
11
ENV PORT=8080
12
13
EXPOSE $PORT
14
15
CMD uvicorn main:app --host 0.0.0.0 --port $PORT

We'll add it next to our main.py file, and update our code to use it:

main.py:

1
from fastapi import FastAPI
2
import launchflow as lf
3
import uvicorn
4
5
app = FastAPI()
6
7
postgres = lf.gcp.ComputeEnginePostgres("vm-postgres")
8
cloud_run = lf.gcp.CloudRunService("my-cloud-run")
9
10
@app.get("/value")
11
def get_value():
12
return postgres.query("SELECT 1")
13
14
if __name__ == "__main__":
15
uvicorn.run(app, host="0.0.0.0", port=8000)

The cloud_run service will find the Dockerfile since it's right next to our launchflow.yaml file, but if you want to store yours elsewhere, you can pass a path to it when creating your CloudRun object. That's it! Running lf deploy will deploy your code to cloud run.

Previous
Dynamic Resource Names