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

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.

  1. 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!!

10
Subscribe to my newsletter

Read articles from Oriazowan Emmanuel directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Oriazowan Emmanuel
Oriazowan Emmanuel