Skip to content
Justin Digs Data
Justin Digs Data
  • Home
  • Nerd Library
Justin Digs Data
Google API Gateway Logo

API Key Authentication with Google Cloud API Gateway and Cloud Run

Posted on February 10, 2024February 15, 2024 By Justin

Table of Contents

Toggle
  • Introduction
      • WARNING
  • Basic Steps
  • Prerequisites
  • Google Cloud Setup
    • Enable Needed Google Cloud Services
      • Console Method
      • Command Line Method
    • Create a Google Cloud Service Account
      • Console Method
      • Command Line Method
  • Backend API Creation
    • Create a simple Python-based API
      • main.py
      • requirements.txt
      • Dockerfile
      • start.sh
    • Deploy Code as a Docker Container to Cloud Run
    • Testing
    • Reenable Authentication
    • Grant Service Account Permissions
  • API Gateway Setup
    • Create API Gateway API
    • Testing Your API
      • Cloud Run URL
      • API Gateway URL
      • GET Tests
      • POST Tests
  • Conclusion

Backend API Creation

Create a simple Python-based API

If you want to jump straight to the code, you can clone this Github repo: https://github.com/JustinDigsData/api_gateway_demo

But the project itself is pretty simple, containing just three files:

  • main.py — Our actual Python code that defines our two API endpoints.
  • requirements.txt — Text file that includes the list of Python libraries we need to install.
  • Dockerfile — The text file that describes how to build the Docker container we’ll push to Cloud Run.
    • If you’re new to Docker, you can read more about it over in their docs: https://docs.docker.com/engine/reference/builder/
  • start.sh — Simple shell script that starts the uvicorn webserver.

main.py

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class NumAdd(BaseModel):
    num1: int | float
    num2: int | float


@app.get('/get/helloworld')
async def get_helloworld():
    return {'message': 'Hello, world!'}


@app.post('/post/add')
async def post_add_numbers(nums: NumAdd):
    return {'num1': nums.num1, 
            'num2': nums.num2,
            'sum': nums.num1 + nums.num2
            }

Our actual Python code is pretty straightforward:

  1. We import the FastAPI and BaseModel classes from fastapi and pydantic, respectively.
  2. We create an instance of the FastAPI class that we name “app” (could be called anything you like, but “app” is generally used by convention).
  3. We define a custom class called NumAdd that inherits from BaseModel, creating two attributes (num1 and num2) that should be either an int or a float
    • This class defines what type of input we’re expecting the requestor to send to our POST endpoint
  4. We define a GET endpoint that listens for calls to /get/helloworld without any parameters and returns the message {'message': 'Hello, world!'}
  5. We define a POST endpoint that listens for calls to /post/add and expects to receive two variables (num1 and num2). The endpoint then returns a message that contains the numbers received and their sum (e.g. {'num1': 10, 'num2': 20, 'sum': 30} )

requirements.txt

The requirements.txt file just lists out the different third-party Python libraries we need to install in order for this application to work correctly. As this is a pretty simple example, we only need three:

fastapi==0.109.0
pydantic==2.6.0
uvicorn==0.27.0.post1
  • FastAPI is the framework we’ll use to create our actual API.
  • pydantic is a validation library (the most commonly used one, according to their page).
  • uvicorn is the web server we’ll use to actually expose this endpoint to the world.

Dockerfile

The Dockerfile spells out how to create the Docker image we’ll use to create the Docker container. If none of that makes sense, that’s OK. It’s not really that important for this tutorial, and Docker itself is one of those things that’s pretty easy to learn but can be difficult to master.

FROM python:3.12.1-slim

WORKDIR /app/

RUN apt-get update && apt-get upgrade -y
RUN python -m pip install --upgrade pip

COPY ./ /app
RUN cd /app

RUN pip install -r requirements.txt

RUN chmod +x start.sh

ENV PATH=$PATH:/app

EXPOSE 8080
RUN export PORT=8080

CMD ["start.sh"]

Without getting too much into the weeds on Docker, this basically says:

  1. Fetch the python:3.12.1-slim image and use it as the base for the one we’re going to create.
  2. Create a directory inside that image called /app/
  3. Run two shell commands inside the container (the first updates operating system packages, the second updates pip)
    • apt-get update && apt-get upgrade -y
    • python -m pip install --upgrade pip
  4. Copy the files from our local directory (i.e. our workstation) into the /app/ directory inside the image.
  5. Inside the image, use pip to install the third-party libraries listed in our requirements.txt file.
  6. Change permissions on our start.sh file so it’s executable.
  7. Append our /app directory to the operating system’s PATH environmental variable.
  8. Tell Docker to have containers built from this image listen on port 8080
  9. Create an environment variable called PORT with the value 8080
  10. Run our start.sh script

start.sh

This file just starts the uvicorn webserver for us inside the Docker container

#! /usr/bin/env sh
set -e
exec uvicorn --host 0.0.0.0 --port 8080 main:app

The meat of the script is that last line. We’re just telling it to start up the uvicorn webserver, listening on 0.0.0.0 and port 8080, and to run the FastAPI app instance that’s inside our main.py file.

Pages: 1 2 3 4 5 6 7 8 9 10 11 12
Backend Stuff APICloud RunGCPPythonTutorial

Post navigation

Next post

Categories

  • AI
  • Backend Stuff

Recent Posts

  • An LLM’s Blog Post about Why You Shouldn’t Use LLMs to Write Blog Posts
  • API Key Authentication with Google Cloud API Gateway and Cloud Run

Archives

  • February 2024
©2025 Justin Digs Data | WordPress Theme by SuperbThemes