Writing
Cloud Run: Dataset Summaries via HTTP Request
6 June 2019Updated 14 October 20266 min read
This project deploys a Flask application to Cloud Run that returns summary statistics for a CSV dataset. The application reads the CSV file from a URL passed in an HTTP request and builds the report with ydata-profiling.
Google Cloud Run is a managed platform for running stateless containers. Google manages the compute infrastructure. Cloud Run scales the number of containers up and down with user traffic. A Cloud Run service receives web traffic through HTTP requests or through asynchronous events, such as a Pub/Sub message.
This project uses Cloud Run to run a stateless container that displays the summary statistics of a structured CSV dataset. The summary comes from the ydata-profiling package, which was called pandas-profiling when this project was first written. We pass the location of the CSV file to the container in an HTTP request.
To begin, open Cloud Shell from the Google Cloud console and clone the repository:
bashgit clone https://github.com/dvdbisong/google-cloud-run.git
The repository holds the 2019 version of the code. Replace app.py and Dockerfile in the pandas-profile folder with the versions below. Then add the requirements.txt file.
The Application Code
The file app.py contains a Flask web application. Requests to the path /profile carry the URL of a well-formed CSV file in the parameter data. The application reads the file with pandas, builds the summary report with ydata-profiling and returns the report as a web page. The code is in the pandas-profile folder. You can open it in the Cloud Shell Editor.
pythonimport os import pandas as pd from flask import Flask, render_template, request from ydata_profiling import ProfileReport app = Flask(__name__) @app.route("/") def home(): return render_template("index.html") @app.route("/profile") def profile(): # read the CSV file from the URL passed in the `data` parameter df = pd.read_csv(request.args.get("data")) report = ProfileReport(df, title="Dataset Summary") # return the report as an HTML page return report.to_html() if __name__ == "__main__": app.run(debug=True, host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))
The file requirements.txt lists the Python packages for the container. ydata-profiling still imports pkg_resources, which setuptools removed in version 82. For that reason, we keep setuptools below version 82.
textFlask==3.1.3 gunicorn==26.2.0 ydata-profiling==4.18.4 # ydata-profiling imports pkg_resources, which setuptools 82 removed setuptools<82
Create the Container Image
A Dockerfile is the recipe for a container image. For this project, we build the image from the official Python image. The Dockerfile installs the packages in requirements.txt when the image is built and starts the application with the gunicorn web server. Cloud Run tells the container which port to listen on through the PORT environment variable.
dockerfile# Use the official lightweight Python image. FROM python:3.12-slim # Send Python output straight to the logs. ENV PYTHONUNBUFFERED=1 # Copy local code to the container image. WORKDIR /app COPY . . # Install production dependencies. RUN pip install --no-cache-dir -r requirements.txt # Run the web service on container startup with gunicorn. # Cloud Run sets the PORT environment variable. CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 app:app
The table below summarizes the Dockerfile instructions used here.
| Instruction | Description |
|---|---|
FROM |
Sets the base image for the new image. |
ENV |
Sets an environment variable as a key-value pair. The variable is available in the container after the build. |
WORKDIR |
Sets the working directory of the container. |
COPY |
Copies files from the local machine into the container file system. |
RUN |
Runs a command on top of the current image and saves the result as a new layer. |
CMD |
Sets the command to run when the container starts. A command given at runtime overrides it. |
Deploy the Container to Cloud Run
In 2019, we built the image with Cloud Build, pushed it to Container Registry and then deployed it with gcloud beta run deploy. Container Registry shut down on March 18, 2025. Artifact Registry now stores container images on Google Cloud.
Cloud Run can also build and deploy in one step from the source folder. When the folder contains a Dockerfile, Cloud Build uses it to build the image. Without a Dockerfile, Cloud Build uses Google Cloud's buildpacks to detect the language and build the image. The built image is stored in an Artifact Registry repository named cloud-run-source-deploy.
First, set your project and enable the Cloud Run Admin API and the Cloud Build API. Replace PROJECT_ID with your Google Cloud project ID.
bashgcloud config set project PROJECT_ID gcloud services enable run.googleapis.com cloudbuild.googleapis.com
Cloud Build uses the Compute Engine default service account to build source code. Grant that account the Cloud Run Builder role. Replace PROJECT_NUMBER with your project number.
bashgcloud projects add-iam-policy-binding PROJECT_ID \ --member=serviceAccount:PROJECT_NUMBER-compute@developer.gserviceaccount.com \ --role=roles/run.builder
From the pandas-profile folder, deploy the service. Building the profile report uses a lot of memory, so we raise the memory limit to 2 GiB. The --allow-unauthenticated flag lets anyone on the internet call the service.
bashgcloud run deploy dataset-profile \ --source . \ --region us-central1 \ --memory 2Gi \ --allow-unauthenticated
If the command asks to enable the Artifact Registry API or to create a repository, answer y. When the deployment finishes, the command prints the service URL. Open the URL in a browser to see the home page of the application.
To list the images that the source deploy stored in Artifact Registry, run:
bashgcloud artifacts docker images list us-central1-docker.pkg.dev/PROJECT_ID/cloud-run-source-deploy
Make the Dataset Public on Cloud Storage
The application reads the CSV file from a public URL. For this project, we store the dataset in a Cloud Storage bucket and make the objects in the bucket readable by everyone. The grant applies to every object in the bucket. Use a bucket that holds only data you are happy to share.
We use a 10,000-row sample of a cryptocurrency markets dataset from the code repository of the book Building Machine Learning and Deep Learning Models on Google Cloud Platform. Replace BUCKET_NAME with a globally unique bucket name.
bash# download the dataset and keep the header plus the first 10,000 rows curl -sL https://raw.githubusercontent.com/Apress/building-ml-and-dl-models-on-gcp/master/code/Chapter_38/crypto-markets.csv \ | head -n 10001 > crypto-markets-sample.csv # create a bucket and upload the file gcloud storage buckets create gs://BUCKET_NAME --location=us-central1 gcloud storage cp crypto-markets-sample.csv gs://BUCKET_NAME/ # make the objects in the bucket publicly readable gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME \ --member=allUsers --role=roles/storage.objectViewer
You cannot share an object publicly when its bucket is subject to public access prevention. If the last command fails, check whether your organization enforces public access prevention. The Cloud Storage guide to making data public explains the options.
The public URL of the file is https://storage.googleapis.com/BUCKET_NAME/crypto-markets-sample.csv.
Retrieve the Dataset Summary
To get the dataset summary, pass the public URL of the dataset to the path /profile in the parameter data. Replace SERVICE_URL with the URL that the deploy command printed.
textSERVICE_URL/profile?data=https://storage.googleapis.com/BUCKET_NAME/crypto-markets-sample.csv
Open this URL in a browser. The page shows an overview of the dataset, statistics for each variable, correlations and missing values.
Clean Up
When you no longer need the service, delete it along with the stored images and the bucket.
bashgcloud run services delete dataset-profile --region us-central1 gcloud artifacts repositories delete cloud-run-source-deploy --location=us-central1 gcloud storage rm --recursive gs://BUCKET_NAME/
Conclusion
This article walked through building and deploying a stateless containerized application on Cloud Run. The application produces an exploratory data analysis report for a structured CSV dataset with the Python package ydata-profiling. An application like this gives you a quick overview of a dataset with little effort.

Ekaba Bisong is a Ph.D. researcher at the University of Victoria and the founder of SiliconBlast. More about me