Skip to content

feat(run): add helloworld samples for FastAPI, Streamlit and Gradio #13525

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 11 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions run/helloworld-fastapi/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Cloud Run Hello World FastAPI Sample

This sample shows how to deploy a Hello World FastAPI application to Cloud Run.

[![Run in Google Cloud][run_img]][run_link]

[run_img]: https://storage.googleapis.com/cloudrun/button.svg
[run_link]: https://console.cloud.google.com/cloudshell/editor?shellonly=true&cloudshell_image=gcr.io/cloudrun/button&cloudshell_git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&cloudshell_working_dir=run/helloworld-fastapi
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either this needs to use just the Open in Cloud Shell URL (not specifying the cloudshell_image, and using the open_in_editor param in the query string (example), or use the redirector service URL (deploy.cloud.run). This will pick up the github repo, branch, and directory from the referer header, without having to specify anything (example).

(Note: cloud run button may not support the newer version of buildpacks, I'm investigating)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


## Deploy

```sh
# Ensure you have set your Google Cloud Project ID
gcloud config set project <PROJECT_ID>

# Deploy to Cloud Run
gcloud run deploy helloworld-fastapi --source .
```

For more details on how to work with this sample, read the [Python Cloud Run Samples README](https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/run)
27 changes: 27 additions & 0 deletions run/helloworld-fastapi/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# [START cloudrun_helloworld_fastapi]
from fastapi import FastAPI

app = FastAPI()


@app.get("/")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this deployment doesn't yet work. Turning this PR to draft until the functionality is ready, and this PR has system tests.

def hello(name: str = "World"):
"""Return a friendly HTTP greeting."""
return {
"message": f"Hello {name}!"
}
# [END cloudrun_helloworld_fastapi]
37 changes: 37 additions & 0 deletions run/helloworld-fastapi/main_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from fastapi.testclient import TestClient
import pytest

import main


@pytest.fixture
def client():
return TestClient(main.app)


def test_handler_no_param(client):
r = client.get("/")

assert r.json() == {"message": "Hello World!"}
assert r.status_code == 200


def test_handler_with_param(client):
r = client.get("/", params={"name": "Foo"})

assert r.json() == {"message": "Hello Foo!"}
assert r.status_code == 200
1 change: 1 addition & 0 deletions run/helloworld-fastapi/requirements-test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pytest==8.2.0
2 changes: 2 additions & 0 deletions run/helloworld-fastapi/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fastapi[standard]==0.116.1
uvicorn==0.35.0
20 changes: 20 additions & 0 deletions run/helloworld-gradio/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Cloud Run Hello World Gradio Sample

This sample shows how to deploy a Hello World Gradio application to Cloud Run.

[![Run in Google Cloud][run_img]][run_link]

[run_img]: https://storage.googleapis.com/cloudrun/button.svg
[run_link]: https://console.cloud.google.com/cloudshell/editor?shellonly=true&cloudshell_image=gcr.io/cloudrun/button&cloudshell_git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&cloudshell_working_dir=run/helloworld-gradio

## Deploy

```sh
# Ensure you have set your Google Cloud Project ID
gcloud config set project <PROJECT_ID>

# Deploy to Cloud Run
gcloud run deploy helloworld-gradio --source .
```

For more details on how to work with this sample, read the [Python Cloud Run Samples README](https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/run)
36 changes: 36 additions & 0 deletions run/helloworld-gradio/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# [START cloudrun_helloworld_gradio]
import gradio as gr


def hello(name, intensity):
"""Return a friendly greeting."""
return "Hello " + name + "!" * int(intensity)


demo = gr.Interface(
fn=hello,
inputs=["text", "slider"],
outputs=["text"],
title="Hello World 👋🌎",
description=("Type your name below and hit 'Submit', and try the slider to "
"make the greeting louder!"),
theme="soft",
flagging_mode="never",
)

demo.launch()
# [END cloudrun_helloworld_gradio]
1 change: 1 addition & 0 deletions run/helloworld-gradio/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
gradio==5.39.0
20 changes: 20 additions & 0 deletions run/helloworld-streamlit/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Cloud Run Hello World Streamlit Sample

This sample shows how to deploy a Hello World Streamlit application to Cloud Run.

[![Run in Google Cloud][run_img]][run_link]

[run_img]: https://storage.googleapis.com/cloudrun/button.svg
[run_link]: https://console.cloud.google.com/cloudshell/editor?shellonly=true&cloudshell_image=gcr.io/cloudrun/button&cloudshell_git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&cloudshell_working_dir=run/helloworld-streamlit

## Deploy

```sh
# Ensure you have set your Google Cloud Project ID
gcloud config set project <PROJECT_ID>

# Deploy to Cloud Run
gcloud run deploy helloworld-streamlit --source .
```

For more details on how to work with this sample, read the [Python Cloud Run Samples README](https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/run)
43 changes: 43 additions & 0 deletions run/helloworld-streamlit/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# [START cloudrun_helloworld_streamlit]
import streamlit as st

st.title("Hello World! 👋🌎")
st.markdown(
"""
This is a demo Streamlit app.

Enter your name in the text box below and press a button to see some fun features in Streamlit.
"""
)

name = st.text_input("Enter your name:")

# Use columns to create buttons side by side
col1, col2 = st.columns(2)

with col1:
if st.button("Send balloons! 🎈"):
st.balloons()
st.write(f"Time to celebrate {name}! 🥳")
st.write("You deployed a Streamlit app! 👏")

with col2:
if st.button("Send snow! ❄️"):
st.snow()
st.write(f"Let it snow {name}! 🌨️")
st.write("You deployed a Streamlit app! 👏")
# [END cloudrun_helloworld_streamlit]
40 changes: 40 additions & 0 deletions run/helloworld-streamlit/main_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import pytest
from streamlit.testing.v1 import AppTest


@pytest.fixture
def app_test() -> AppTest:
"""Fixture for creating a test app instance and setting a name."""
at = AppTest.from_file("main.py").run()
at.text_input[0].set_value("Foo").run()
return at


def test_balloons(app_test: AppTest):
"""A user presses the balloons button"""
app_test.button[0].click().run()
assert app_test.markdown.values[0] == "This is a demo Streamlit app.\n\nEnter your name in the text box below and press a button to see some fun features in Streamlit."
assert app_test.markdown.values[1] == "Time to celebrate Foo! 🥳"
assert app_test.markdown.values[2] == "You deployed a Streamlit app! 👏"


def test_snow(app_test: AppTest):
"""A user presses the snow button"""
app_test.button[1].click().run()
assert app_test.markdown.values[0] == "This is a demo Streamlit app.\n\nEnter your name in the text box below and press a button to see some fun features in Streamlit."
assert app_test.markdown.values[1] == "Let it snow Foo! 🌨️"
assert app_test.markdown.values[2] == "You deployed a Streamlit app! 👏"
1 change: 1 addition & 0 deletions run/helloworld-streamlit/requirements-test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pytest==8.2.0
1 change: 1 addition & 0 deletions run/helloworld-streamlit/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
streamlit==1.47.1