Skip to main content

Meta Ads Library with FastAPI: A Developer's Deep Dive

 The Meta Graph API offers a programmatic gateway to a wealth of data and functionality within the Meta ecosystem. A standout feature is the Ads Library (formerly known as ads_archive), providing unprecedented transparency into advertising across Facebook, Instagram, and other platforms. For developers looking to harness this data, a robust and efficient API is crucial. This blog post explores how to build such an API using FastAPI, a modern, high-performance Python web framework. We'll delve into practical code examples, covering everything from setting up the API to handling authentication, querying the Ads Library, and managing potential errors.


Why FastAPI for Meta Ads Library Integration?

FastAPI is an excellent choice for building an API to access the Meta Ads Library due to its numerous advantages:

  • Speed and Performance: Built on top of Starlette and Pydantic, FastAPI offers impressive performance, crucial for handling large volumes of ad data.
  • Automatic Data Validation: Pydantic's data validation ensures that your API receives and processes data in the expected format, reducing errors.
  • Type Hints: Type hints enhance code readability and maintainability, making it easier to understand and debug.
  • Dependency Injection: FastAPI's dependency injection system simplifies code organization and testing.
  • Automatic API Documentation: FastAPI automatically generates interactive API documentation (using Swagger UI or ReDoc), making it easy for developers to understand and use your API.

Setting Up Your FastAPI Project

Before diving into the code, set up your FastAPI project:

Install Dependencies:


pip install fastapi uvicorn python-dotenv httpx

pip install "uvicorn[standard]"


Project Structure: 

A well-organized project structure is essential for maintainability:


/your_project ├── app/ │ ├── __init__.py │ ├── api/ │ │ ├── meta.py # Meta Ads Library API endpoints │ ├── schemas.py # Pydantic models for data validation │ ├── utils.py # Utility functions for interacting with Meta API │ ├── main.py # Main FastAPI application ├── .env # Environment variables (e.g., access token) ├── requirements.txt # Project dependencies ├── Dockerfile # Dockerfile for containerization


Code Examples: Building the API

Let's break down the code needed to create a FastAPI-based API for the Meta Ads Library.


.env File (Environment Variables):

Create a .env file to store sensitive information, such as your Meta Access Token.


META_ACCESS_TOKEN="YOUR_META_ACCESS_TOKEN"


app/schemas.py (Pydantic Models):

Define Pydantic models to validate the structure of incoming requests and outgoing responses.


from typing import Optional, List from pydantic import BaseModel from datetime import datetime class MetaAdsRequest(BaseModel): limit: Optional[int] = 10 after: Optional[str] = None ad_delivery_date_min: Optional[str] = None ad_delivery_date_max: Optional[str] = None search_terms: Optional[str] = None ad_reached_countries: str # Required media_type: Optional[str] = None ad_active_status: Optional[str] = None search_type: Optional[str] = None ad_type: Optional[str] = None languages: Optional[str] = None publisher_platforms: Optional[str] = None search_page_ids: Optional[str] = None unmask_removed_content: Optional[str] = None class AdData(BaseModel): # represents individual ad ad_creative_link_captions: Optional[List[str]] = None ad_creative_link_descriptions: Optional[List[str]] = None ad_snapshot_url: str page_id: str page_name: str publisher_platforms: List[str] ad_delivery_date: str class MetaAdsResponse(BaseModel): data: List[AdData] paging: Optional[dict] # Optional paging information


app/utils.py (Utility Functions):

Create utility functions to encapsulate the logic for interacting with the Meta Ads Library API.


import httpx from typing import Optional from fastapi import HTTPException from urllib.parse import urlencode import os from dotenv import load_dotenv load_dotenv() META_ACCESS_TOKEN = os.getenv("META_ACCESS_TOKEN") async def get_meta_ads( limit: int = 10, after: str | None = None, ad_delivery_date_min: str | None = None, ad_delivery_date_max: str | None = None, search_terms: str | None = None, ad_reached_countries: str | None = None, media_type: str | None = None, ad_active_status: str | None = None, search_type: str | None = None, ad_type: str | None = None, languages: str | None = None, publisher_platforms: str | None = None, search_page_ids: str | None = None, unmask_removed_content: str | None = None, ): """Fetches ads data from Meta Ad Library API.""" base_url = "https://graph.facebook.com/v21.0/ads_archive?fields=ad_creative_link_captions,ad_creative_link_descriptions,ad_snapshot_url,page_id,page_name,publisher_platforms,ad_delivery_date" params = { "access_token": META_ACCESS_TOKEN, "limit": limit, "ad_reached_countries": ad_reached_countries, } if after: params["after"] = after if ad_delivery_date_min: params["ad_delivery_date_min"] = ad_delivery_date_min if ad_delivery_date_max: params["ad_delivery_date_max"] = ad_delivery_date_max if search_terms: params["search_terms"] = search_terms if media_type: params["media_type"] = media_type if ad_active_status: params["ad_active_status"] = ad_active_status if search_type: params["search_type"] = search_type if ad_type: params["ad_type"] = ad_type if languages: params["languages"] = languages if publisher_platforms: params["publisher_platforms"] = publisher_platforms if search_page_ids: params["search_page_ids"] = search_page_ids if unmask_removed_content: params["unmask_removed_content"] = unmask_removed_content url = f"{base_url}&{urlencode(params)}" async with httpx.AsyncClient() as client: try: response = await client.get(url) response.raise_for_status() return response.json() # Return the JSON response except httpx.HTTPError as e: raise HTTPException(status_code=e.response.status_code, detail=str(e)) except Exception as e: raise HTTPException( status_code=500, detail=f"Failed to fetch Meta ads data: {e}" )


app/api/meta.py (API Endpoints):

Create the API endpoints using FastAPI's router.


from typing import Optional from fastapi import FastAPI, HTTPException, Depends, APIRouter from app.schemas import MetaAdsRequest, MetaAdsResponse from app.utils import get_meta_ads router = APIRouter() @router.post("/meta-ads", response_model=MetaAdsResponse) async def fetch_meta_ads_endpoint(request: MetaAdsRequest): """ Fetches ads data from the Meta Ad Library API. Requires at least 'ad_reached_countries' to be provided. """ try: if not request.ad_reached_countries: raise HTTPException( status_code=400, detail="ad_reached_countries is a required parameter.", ) # Call the utility function to fetch ads ads_data = await get_meta_ads( limit=request.limit, after=request.after, ad_delivery_date_min=request.ad_delivery_date_min, ad_delivery_date_max=request.ad_delivery_date_max, search_terms=request.search_terms, ad_reached_countries=request.ad_reached_countries, media_type=request.media_type, ad_active_status=request.ad_active_status, search_type=request.search_type, ad_type=request.ad_type, languages=request.languages, publisher_platforms=request.publisher_platforms, search_page_ids=request.search_page_ids, unmask_removed_content=request.unmask_removed_content, ) return ads_data except HTTPException as http_ex: # Re-raise HTTPExceptions to preserve status codes raise http_ex except Exception as e: # Handle other exceptions raise HTTPException( status_code=500, detail=f"An unexpected error occurred: {e}" )


app/main.py (FastAPI Application):

Create the main FastAPI application instance and include the router.


from fastapi import FastAPI from app.api import meta from fastapi.middleware.cors import CORSMiddleware app = FastAPI() # CORS (Cross-Origin Resource Sharing) settings origins = [ "http://localhost:3000", # Example origin for your frontend "https://your-frontend-domain.com", ] app.add_middleware( CORSMiddleware, allow_origins=origins, allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) app.include_router(meta.router, prefix="/api", tags=["Meta Ads"])


Running the Application

To run your FastAPI application:



fastapi dev


Best Practices

  • Environment Variables: Store sensitive information like access tokens in environment variables instead of hardcoding them into your code.
  • Error Handling: Implement robust error handling to catch potential exceptions and provide informative error messages to clients.
  • Data Validation: Use Pydantic models to validate the structure and content of incoming requests and outgoing responses.
  • Asynchronous Operations: Use async and await for I/O-bound operations (like API requests) to avoid blocking the event loop and improve performance.
  • Pagination: Implement pagination to handle large datasets efficiently. The Meta Ads Library API provides pagination through the after parameter.
  • Rate Limiting: Be aware of rate limits imposed by the Meta Graph API. Implement rate limiting in your API to avoid exceeding these limits.


Conclusion

This blog post has demonstrated how to build a robust and efficient API for accessing the Meta Ads Library using FastAPI. By leveraging FastAPI's features, you can create a well-structured, performant, and maintainable API to unlock the wealth of data available within the Meta ecosystem. Remember to always adhere to Meta's API terms of service and prioritize user privacy when working with advertising data.

Comments

Topics

Show more