Mastering FastAPI Third-Party API Calls In the world of web development, APIs (Application Programming Interfaces) play a crucial role in enabling applications to communicate with each other.
FastAPI Third-Party API
FastAPI, a modern web framework for building APIs with Python, has gained immense popularity due to its speed, ease of use, and automatic generation of OpenAPI documentation. One of the most common tasks when building an API is making calls to third-party APIs. In this blog post, we will explore how to effectively call third-party APIs using FastAPI, covering everything from setup to error handling.
Mastering FastAPI Third-Party API Calls
- Introduction to FastAPI
- Setting Up FastAPI
- Making Third-Party API Calls
- Handling Responses
- Error Handling
- Asynchronous API Calls
- Testing Your API
- Conclusion
Introduction to FastAPI
FastAPI is a Python web framework designed for building APIs quickly and efficiently. It is built on top of Starlette for the web parts and Pydantic for the data parts. FastAPI is known for its high performance, thanks to its asynchronous capabilities, and for its automatic generation of interactive API documentation using Swagger UI and ReDoc.
Key Features of FastAPI
- Fast: As the name suggests, FastAPI is designed for speed. It is one of the fastest Python frameworks available.
- Easy to Use: FastAPI is intuitive and easy to learn, making it accessible for both beginners and experienced developers.
- Automatic Documentation: FastAPI automatically generates interactive API documentation, which is a significant advantage for developers.
- Type Safety: FastAPI uses Python type hints to validate request and response data, reducing the chances of runtime errors.
Setting Up FastAPI
Before we dive into making third-party API calls, we need to set up a FastAPI project. Follow these steps to get started:
Step 1: Install FastAPI and Uvicorn
First, you need to install FastAPI and Uvicorn, an ASGI server that will run your FastAPI application. You can do this using pip:
pip install fastapi uvicorn
Step 2: Create a Basic FastAPI Application
Create a new Python file, main.py
, and add the following code to set up a basic FastAPI application:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
Step 3: Run the Application
You can run your FastAPI application using Uvicorn with the following command:
uvicorn main:app --reload
This command will start the server, and you can access your API at http://127.0.0.1:8000
. You can also view the automatically generated documentation at http://127.0.0.1:8000/docs
.
Making FastAPI Third-Party API Call
Now that we have our FastAPI application set up, let’s explore how to make calls to third-party APIs. For this example, we will use the JSONPlaceholder API, a free fake online REST API for testing and prototyping.
Step 1: Install the httpx
Library
To make HTTP requests in Python, we can use the httpx
library, which supports both synchronous and asynchronous requests. Install it using pip:
pip install httpx
Step 2: Create a Function to Call the FastAPI Third-Party API
In your main.py
file, create a new endpoint that will call the JSONPlaceholder API to fetch a list of posts:
import httpx
from fastapi import FastAPI
app = FastAPI()
@app.get("/posts")
async def get_posts():
async with httpx.AsyncClient() as client:
response = await client.get("https://jsonplaceholder.typicode.com/posts")
return response.json()
Step 3: Test the Endpoint
Run your FastAPI application again and navigate to http://127.0.0.1:8000/posts
. You should see a list of posts fetched from the JSONPlaceholder API.
Handling Responses FastAPI Third-Party API
When making API calls, it’s essential to handle the responses correctly. This includes checking the status code and processing the data accordingly.
Step 1: Check the Status Code
Modify the get_posts
function to check the status code of the response:
@app.get("/posts")
async def get_posts():
async with httpx.AsyncClient() as client:
response = await client.get("https://jsonplaceholder.typicode.com/posts")
if response.status_code == 200:
return response.json()
else:
return {"error": "Failed to fetch posts", "status_code": response.status_code}
Step 2: Return a Custom Response
You can also create a custom response model using Pydantic to ensure that the data returned from your API is structured correctly. First, define a Pydantic model for the post: FastAPI Third-Party API
from pydantic import BaseModel
from typing import List
class Post(BaseModel):
userId: int
id: int
title: str
body: str
class PostsResponse(BaseModel):
posts: List[Post]
Now, update the get_posts
function to return a structured response:
@app.get("/posts", response_model=PostsResponse)
async def get_posts():
async with httpx.AsyncClient() as client:
response = await client.get("https://jsonplaceholder.typicode.com/posts")
if response.status_code == 200:
return {"posts": response.json()}
else:
return {"error": "Failed to fetch posts", "status_code": response.status_code}
Error Handling
Error handling is a critical aspect of API development. You should anticipate potential issues when making third-party API calls and handle them gracefully.
Step 1: Handle Connection Errors
You can catch exceptions that may occur during the API call, such as connection errors. Update the get_posts
function to include error handling:
from httpx import HTTPStatusError, RequestError
@app.get("/posts", response_model=PostsResponse)
async def get_posts():
async with httpx.AsyncClient() as client:
try:
response = await client.get("https://jsonplaceholder.typicode.com/posts")
response.raise_for_status() # Raise an error for bad responses
return {"posts": response.json()}
except HTTPStatusError as e:
return {"error": "HTTP error occurred", "status_code": e.response.status_code}
except RequestError:
return {"error": "An error occurred while requesting the API"}
Step 2: Log Errors
For better debugging and monitoring, consider logging errors. You can use Python’s built-in logging module:
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
@app.get("/posts", response_model=PostsResponse)
async def get_posts():
async with httpx.AsyncClient() as client:
try:
response = await client.get("https://jsonplaceholder.typicode.com/posts")
response.raise_for_status()
return {"posts": response.json()}
except HTTPStatusError as e:
logger.error(f"HTTP error occurred: {e.response.status_code}")
return {"error": "HTTP error occurred", "status_code": e.response.status_code}
except RequestError as e:
logger.error(f"Request error occurred: {e}")
return {"error": "An error occurred while requesting the API"}
Asynchronous API Calls
One of the significant advantages of FastAPI is its support for asynchronous programming. This allows you to make non-blocking API calls, which can improve the performance of your application.
Step 1: Use AsyncClient for Non-Blocking Calls
As shown in the previous examples, using httpx.AsyncClient
allows you to make non-blocking calls. This is particularly useful when you need to call multiple APIs simultaneously.
Step 2: Making Multiple API Calls
You can create an endpoint that fetches data from multiple third-party APIs concurrently. For example, let’s say you want to fetch both posts and comments from JSONPlaceholder:
@app.get("/combined")
async def get_combined_data():
async with httpx.AsyncClient() as client:
posts_future = client.get("https://jsonplaceholder.typicode.com/posts")
comments_future = client.get("https://jsonplaceholder.typicode.com/comments")
posts_response, comments_response = await asyncio.gather(posts_future, comments_future)
return {
"posts": posts_response.json(),
"comments": comments_response.json()
}
Testing Your API
Testing is an essential part of API development. FastAPI provides built-in support for testing your application using the TestClient
.
Step 1: Install the Testing Dependencies
If you haven’t already, install pytest
and httpx
for testing:
pip install pytest httpx
Step 2: Write Tests for Your API
Create a new file called test_main.py
and write tests for your API endpoints:
from fastapi.testclient import TestClient
from main import app
client = TestClient(app)
def test_get_posts():
response = client.get("/posts")
assert response.status_code == 200
assert "posts" in response assert isinstance(response.json()["posts"], list)
def test_get_combined_data():
response = client.get("/combined")
assert response.status_code == 200
assert "posts" in response.json()
assert "comments" in response.json()
assert isinstance(response.json()["posts"], list)
assert isinstance(response.json()["comments"], list)
Step 3: Run Your Tests
You can run your tests using the following command:
pytest test_main.py
This will execute the tests and provide you with feedback on whether they passed or failed.
Fast API development with Swagger in Python
Conclusion
In this blog post, we explored how to make FastAPI Third-Party API Call. We covered the setup of a FastAPI application, making asynchronous API calls, handling responses and errors, and testing our API. FastAPI’s powerful features make it an excellent choice for building APIs that interact with other services. By leveraging its capabilities, you can create efficient and robust applications that can easily integrate with third-party APIs. As you continue to develop with FastAPI, you’ll find that its speed and ease of use will significantly enhance your development experience.