diff --git a/run/helloworld-fastapi/README.md b/run/helloworld-fastapi/README.md new file mode 100644 index 0000000000..4d86597fc8 --- /dev/null +++ b/run/helloworld-fastapi/README.md @@ -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 + +## Deploy + +```sh +# Ensure you have set your Google Cloud Project ID +gcloud config set project + +# 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) diff --git a/run/helloworld-fastapi/main.py b/run/helloworld-fastapi/main.py new file mode 100644 index 0000000000..9fd7ba6ca6 --- /dev/null +++ b/run/helloworld-fastapi/main.py @@ -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("/") +def hello(name: str = "World"): + """Return a friendly HTTP greeting.""" + return { + "message": f"Hello {name}!" + } +# [END cloudrun_helloworld_fastapi] diff --git a/run/helloworld-fastapi/main_test.py b/run/helloworld-fastapi/main_test.py new file mode 100644 index 0000000000..ae57ffe435 --- /dev/null +++ b/run/helloworld-fastapi/main_test.py @@ -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 diff --git a/run/helloworld-fastapi/requirements-test.txt b/run/helloworld-fastapi/requirements-test.txt new file mode 100644 index 0000000000..15d066af31 --- /dev/null +++ b/run/helloworld-fastapi/requirements-test.txt @@ -0,0 +1 @@ +pytest==8.2.0 diff --git a/run/helloworld-fastapi/requirements.txt b/run/helloworld-fastapi/requirements.txt new file mode 100644 index 0000000000..5c98637847 --- /dev/null +++ b/run/helloworld-fastapi/requirements.txt @@ -0,0 +1,2 @@ +fastapi[standard]==0.116.1 +uvicorn==0.35.0 diff --git a/run/helloworld-gradio/README.md b/run/helloworld-gradio/README.md new file mode 100644 index 0000000000..aa33c32010 --- /dev/null +++ b/run/helloworld-gradio/README.md @@ -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 + +# 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) diff --git a/run/helloworld-gradio/main.py b/run/helloworld-gradio/main.py new file mode 100644 index 0000000000..d1d5ed4ed2 --- /dev/null +++ b/run/helloworld-gradio/main.py @@ -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] diff --git a/run/helloworld-gradio/requirements.txt b/run/helloworld-gradio/requirements.txt new file mode 100644 index 0000000000..f4fb04bb92 --- /dev/null +++ b/run/helloworld-gradio/requirements.txt @@ -0,0 +1 @@ +gradio==5.39.0 diff --git a/run/helloworld-streamlit/README.md b/run/helloworld-streamlit/README.md new file mode 100644 index 0000000000..bd2b0446d3 --- /dev/null +++ b/run/helloworld-streamlit/README.md @@ -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 + +# 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) diff --git a/run/helloworld-streamlit/main.py b/run/helloworld-streamlit/main.py new file mode 100644 index 0000000000..7d7d55c446 --- /dev/null +++ b/run/helloworld-streamlit/main.py @@ -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] diff --git a/run/helloworld-streamlit/main_test.py b/run/helloworld-streamlit/main_test.py new file mode 100644 index 0000000000..f196dc471c --- /dev/null +++ b/run/helloworld-streamlit/main_test.py @@ -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! 👏" diff --git a/run/helloworld-streamlit/requirements-test.txt b/run/helloworld-streamlit/requirements-test.txt new file mode 100644 index 0000000000..15d066af31 --- /dev/null +++ b/run/helloworld-streamlit/requirements-test.txt @@ -0,0 +1 @@ +pytest==8.2.0 diff --git a/run/helloworld-streamlit/requirements.txt b/run/helloworld-streamlit/requirements.txt new file mode 100644 index 0000000000..56cf7132a1 --- /dev/null +++ b/run/helloworld-streamlit/requirements.txt @@ -0,0 +1 @@ +streamlit==1.47.1