Building a Sports API with Flask, Application Load Balancer and AWS ECS: A Full Guide

Table of contents
- Introduction
- Architecture
- Concepts covered:
- Project Steps
- Step 1.
- Step 2: 🐳 Containerizing the Flask Application with Docker
- Step 3: Create the .env File
- Step 4: Build the Docker Image
- Step 5: Tag and push the docker image
- Step 6: Create an ECS Task Definition
- Step 7: Create a Service
- Step 8: Test your API
- Step 9: Connect API Gateway to the Load Balancer
- Conclusion
- Areas for Further Development

Introduction
In this blog, I'll walk you through building a Sports API to fetch the NFL schedule using Flask, Docker, and AWS ECS (Elastic Container Service). This project helps you fetch sports data from an external API (SerpAPI), package the application into a Docker container, and deploy it on AWS ECS. Along the way, we'll address how to troubleshoot deployment issues and manage environment variables.
Let's get started!
Architecture
Concepts covered:
API management and routing using Amazon API Gateway
Exposes a REST API for querying real-time sports data
Containeriaztion with Amazon ECS with Fargate
Scalable and serverless architecture
Application Load Balancing
Project Steps
Step 1.
Clone the git repository from my github:
from flask import Flask, jsonify import requests import os import json from dotenv import load_dotenv load_dotenv()
app = Flask(__name__) # SerpAPI base URL and API key SERP_API_URL = "https://serpapi.com/search.json" SERP_API_KEY = os.getenv("SPORTS_API_KEY") @app.route('/sports', methods=['GET']) def get_nfl_schedule(): #Fetches the NFL schedule from SerpAPI and returns it as JSON try: # Query SerpAPI params = { "engine": "google", "q": "nfl schedule 2025", "api_key": SERP_API_KEY } response = requests.get(SERP_API_URL, params=params) response.raise_for_status() data = response.json() print(json.dumps(data, indent=2))
# Extract games from sports_results games = data.get("sports_results", {}).get("games", []) if not games: return jsonify({"message": "No NFL schedule available.", "games": []}), 200 # Format the schedule into JSON formatted_games = [] for game in games: teams = game.get("teams", []) if len(teams) == 2: away_team = teams[0].get("name", "Unknown") home_team = teams[1].get("name", "Unknown") else: away_team, home_team = "Unknown", "Unknown" game_info = { "away_team": away_team, "home_team": home_team, "venue": game.get("venue", "Unknown"), "date": game.get("date", "Unknown"), "time": f"{game.get('time', 'Unknown')} ET" if game.get("time", "Unknown") != "Unknown" else "Unknown" } formatted_games.append(game_info) return jsonify({"message": "NFL schedule fetched successfully.", "games": formatted_games}), 200 except Exception as e: return jsonify({"message": "An error occurred.", "error": str(e)}), 500 if __name__ == '__main__': app.run(host='0.0.0.0', port=8080)
Step 2: 🐳 Containerizing the Flask Application with Docker
Create a Dockerfile in the same directory as app.py:
# Use official Python runtime as base image FROM python:3.8-slim # Set the working directory in the container WORKDIR /app # Copy the current directory contents into the container COPY . . # Install required Python packages RUN pip install --no-cache-dir -r requirements.txt # Expose the port the app will run on EXPOSE 8080 # Set environment variables from .env COPY .env .env # Run the Flask app CMD ["python", "app.py"]
Step 3: Create the .env
File
Create a
.env
file to store your SerpAPI key securely:Don’t forget to add
.env
to.gitignore
to keep it secure.SPORTS_API_KEY=your_serpapi_key_here
Step 4: Build the Docker Image
docker build --platform linux/amd64 -t sports-api .
Step 5: Tag and push the docker image
docker tag sports-api:latest <AWS_ACCOUNT_ID>.dkr.ecr.us-east-1.amazonaws.com/sports-api:sports-api-latest docker push <AWS_ACCOUNT_ID>.dkr.ecr.us-east-1.amazonaws.com/sports-api:sports-api-latest
Once your Docker image is in ECR, you can deploy it to AWS ECS!
Step 6: Create an ECS Task Definition
Go to ECS and create a new task definition that points to your Docker image in ECR.
Choose Fargate as the launch type.
Add the necessary environment variables (like
SPORTS_API_KEY
).Set the container port to 8080 (or whatever port your Flask app uses).
Step 7: Create a Service
- Launch Type: Select Fargate (or EC2 if applicable).
Task Definition: Choose your latest revision.
Service Name: Name it something like
sports-api-service
.Number of Tasks: Start with 2, scale later if needed.
Select a VPC and subnets (public if no NAT gateway).
Allow incoming traffic on port 8080 in security groups.
Attach a Load Balancer for public access.
Click Create Service and wait for tasks to start.
Go to ECS > Cluster > Tasks to check their status.
Step 8: Test your API
Open your browser
Input the Load Balancer end point URL and test
http://your-load-balancer.amazonaws.com/sports
Expected Output in browser:
The list of nba sport schedules for 2025
Step 9: Connect API Gateway to the Load Balancer
To make your API publicly accessible via a fURL, connect API Gateway to your ALB.
Open API Gateway
Go to Amazon API Gateway > HTTP APIs.
Click Create API, choose REST API.
Integration type: Select "HTTP".
Endpoint: Use the DNS name of your ALB, e.g.:
http://your-load-balancer-name.us-east-1.elb.amazonaws.com
Leave default settings or add a route
/sports
.Add a GET route for
/sports
.
Click Next, give the API a name.
Click Create to deploy it.
You’ll get a public API Gateway URL, like:
https://abc123xyz.execute-api.us-east-1.amazonaws.com/sports
Now, when someone accesses this URL, API Gateway will forward the request to your load balancer, which routes it to your Flask app on ECS.
Expected output:
Conclusion
In this project, we built and deployed a containerized Flask-based Sports API that fetches the NFL schedule using SerpAPI. We went from a simple local Flask app to a fully deployed and scalable service running on AWS ECS, accessible through a public API Gateway endpoint.
Along the way, we:
Built the backend API using Flask and Python.
Containerized the app with Docker.
Pushed the image to Amazon ECR.
Deployed it using ECS Fargate.
Connected it to an Application Load Balancer.
Made it publicly available via API Gateway.
This setup is a solid foundation for running lightweight, containerized microservices in the cloud, and simulates a full end-to-end DevOps pipeline
Areas for Further Development
To improve and extend this project, consider diving into the following topics:
1. Security Enhancements
Add authentication to your API (API keys, JWT, OAuth2).
Use WAF (Web Application Firewall) on the load balancer.
Restrict traffic to your ALB using API Gateway private integrations.
2. CI/CD Integration
- Automate Docker builds and ECS deployments using GitHub Actions, CodePipeline, or Bitbucket Pipelines.
3. Testing & Quality
Add unit and integration tests for the Flask app.
Use pytest, Flask-Testing, or Postman/Newman to test endpoints.
Add health check endpoints beyond
/sports
.
Scaling & Optimization
Add autoscaling policies to ECS.
Use API caching to reduce calls to SerpAPI and improve response time.
Consider serverless deployment with AWS Lambda for low-traffic APIs.
TIll next time!!
Subscribe to my newsletter
Read articles from Oriazowan Emmanuel directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
