Skip to content

Python and APIs: How to Use Python Requests for Building API-Driven Apps

Hi there! Are you looking to level up your Python skills and learn how to integrate powerful APIs into your applications? Then this guide is for you.

I‘m going to walk you through using the fantastic Python Requests library to interact with web APIs of all kinds. With some basic Python knowledge and Requests, you‘ll be able to:

  • Query data from any API endpoint
  • Build apps that integrate with popular services like Twitter, Stripe, Twilio etc.
  • Automate workflows by connecting APIs together
  • Unlock tons of useful data and functionality to enhance your Python apps

Sounds exciting right? Let‘s dive in!

Why Use APIs in Python?

Before we get into the code, let‘s first understand why connecting to APIs is so useful for developers.

APIs allow different software applications to communicate with each other. Companies and organizations expose APIs to let developers build apps with their services more easily.

Here are some of the top reasons to use APIs in your code:

  • Save time – Don‘t rebuild something from scratch that already exists as an API!
  • Leverage data – Access useful data sources like weather, stocks, social media, and more.
  • Extend functionality – Integrate maps, payments, notifications and more.
  • Automate workflows – Connect different systems together seamlessly.
  • Build apps faster – Focus on your app logic rather than the underlying infrastructure.

In short, well-designed APIs help you develop better applications, faster.

According to Postman‘s 2024 State of the API Report, public API adoption is growing rapidly:

  • 72% of organizations consume public APIs as part of their core business.
  • 58% have public APIs themselves.
  • API requests grew over 650% from 2020 to 2021 for responders.

With APIs becoming more ubiquitous across industries, it‘s a great time to level up your skills for connecting to them with Python.

Getting Started with Python Requests

Python has fantastic libraries that make working with APIs easy. The most popular one is Requests.

Requests allows you to call APIs with just a few lines of code:

import requests

response = requests.get(‘https://api.data.gov/education‘)

Compared to lower-level alternatives like Python‘s built-in urllib module, Requests saves you a ton of time and headaches.

Some key features of Requests:

  • Simple, elegant API
  • Makes HTTP requests extremely easy
  • Built-in JSON support
  • Handling of headers, parameters, authentication
  • Automatic retries on network errors
  • Wide range of advanced features

To install Requests, simply run:

pip install requests

Then import requests in your code and you‘re ready to begin making API calls!

Let‘s walk through some simple examples.

Making a GET Request

The most common API call is a GET request to retrieve data from an endpoint.

Here‘s how to make a GET request with Requests:

import requests 

response = requests.get(‘https://api.github.com/repos/requests/requests‘)

This will send a GET request to the GitHub API endpoint to retrieve data on the Requests repository.

We get back a Response object containing the status code, response headers, and data.

To print the response status code:

print(response.status_code)

>>> 200

A status code of 200 indicates our request succeeded. Many other status codes exist indicating errors or failures – we‘ll cover how to handle those later.

To access the response data, simply call .json():

data = response.json()

print(data[‘stargazers_count‘])

>>> 64245

The data is parsed as JSON automatically. This makes working with JSON APIs very straightforward.

Passing Parameters

For many APIs, you need to pass parameters to filter data, paginate results, and more.

Pass the parameters as a dictionary to the params argument:

params = {‘type‘: ‘owner‘, ‘sort‘: ‘updated‘}
response = requests.get(‘https://api.github.com/repos/kennethreitz/requests‘, 
                        params=params)

Requests encodes the parameters and adds them to the URL for you.

You can also pass parameters directly in the URL:

response = requests.get(‘https://api.github.com/repos/kennethreitz/requests?type=owner&sort=updated‘)

Either way works but passing a dictionary is considered cleaner.

POST Requests

To create resources on the server, you would use a POST request.

Pass the data to post as a dictionary to the json parameter:

data = {‘name‘: ‘John Smith‘, ‘email‘: ‘[email protected]‘}
response = requests.post(‘https://api.example.com/users‘, json=data)

This encodes the data as JSON and sends a POST to the API to create a new user resource.

For POSTs you should also validate the status code returned:

if response.status_code == 201:
  print(‘User created!‘)

201 status means the resource was successfully created on the server.

PUT, PATCH, DELETE

Aside from GET and POST, the other common HTTP methods are:

  • PUT – Update an existing resource
  • PATCH – Partial update of a resource
  • DELETE – Delete a resource

These work similarly, just call the corresponding method on requests:

# PUT - Update user
requests.put(‘https://api.example.com/users/123‘, json=updated_data) 

# PATCH - Partial update  
requests.patch(‘https://api.example.com/users/123‘, json=partial_data)

# DELETE - Delete user
requests.delete(‘https://api.example.com/users/123‘)

Now you know how to make API calls using all the common HTTP methods!

Handling API Responses

When working with APIs, you need to handle the response data based on the status code returned by the server.

APIs use standard HTTP status codes to indicate success, errors or failures. Some common ones include:

  • 200 – OK – The request succeeded
  • 201 – Created – The resource was successfully created
  • 400 – Bad Request – The request was malformed or missing data
  • 401 – Unauthorized – Authentication is required
  • 403 – Forbidden – You don‘t have access to this resource
  • 404 – Not Found – The resource does not exist
  • 500 – Server Error – The server encountered an unexpected error

You check the status code on the Response object:

response = requests.get(‘https://api.example.com/items/123‘)

if response.status_code == 200:
  # Success!
elif response.status_code == 404:
  # Notify user item does not exist

For succinctness, I recommend wrapping all your Requests calls in a helper function like:

def make_api_request(endpoint):
  response = requests.get(endpoint)

  response.raise_for_status()

  return response.json()

This makes the code cleaner, as well as centralizing error handling in one place.

raise_for_status() will raise an exception if there is an HTTP error code like 500 or 404, saving you from checking manually each time.

Authenticating with APIs

Many APIs require authentication to restrict access. Some common forms of API authentication include:

  • API keys – Pass a unique API key via a request header or parameter
  • Basic auth – Pass a username and password with the request
  • Bearer tokens – Send an OAuth 2.0 bearer token from the auth provider
  • Digest auth – Similar to basic auth but credentials are encrypted

Requests makes handling authentication simple.

To use an API key, pass it as a header:

headers = {‘Authorization‘: ‘Bearer YOUR_API_KEY‘}
response = requests.get(‘https://api.example.com‘, headers=headers)

For basic auth, provide the username and password as a tuple:

requests.get(‘https://api.example.com‘, 
            auth=(‘username‘, ‘password‘))

Requests will handle encoding your credentials correctly.

For bearer tokens from OAuth providers like Facebook, Twitter, Google etc:

params = {‘access_token‘: ‘OAUTH_TOKEN‘}
requests.get(‘https://api.example.com‘, params=params)  

Pass the access token as a parameter and Requests will handle the rest.

Proper authentication is critical for securely accessing APIs in your Python apps and workflows.

Best Practices for Working with APIs

Now that you know how to call APIs with Python, let‘s discuss some best practices for working effectively with them:

Handle Errors Gracefully

APIs can fail in unexpected ways – servers go down, networks drop, providers make changes.

When making API requests:

  • Use try/except blocks to catch errors
  • Handle common exceptions like ConnectionErrors
  • Check status codes and handle non-200 responses
  • Use an exponential backoff strategy to retry failed requests

This ensures your application degrades gracefully when APIs fail.

Respect Rate Limits

To prevent abuse, APIs enforce rate limits on requests per hour/day.

Exceeding these limits will block your access, possibly permanently.

To avoid this:

  • Review rate limit documentation and understand your quota
  • Limit requests – only make calls when necessary
  • Implement a backoff timer if you hit the limit to pause before retrying
  • Never spam or abuse the API! This will lead to blocks.

Rate limits protect APIs so they work for all users. Respect them in your usage.

Cache Responses

APIs can be slow depending on connectivity. For performance, consider caching responses, especially if the data doesn‘t change frequently.

Popular Python caching libraries include Redis, Memcached, and SQLAlchemy.

Caching avoids unnecessary network calls for repeated requests.

Python API Examples & Uses

Now let‘s look at some real-world examples of popular APIs and how you can access them in Python.

Twitter API

The Twitter API allows querying tweets, users, hashtags, and analytics. You need to apply for a Twitter developer account to get API credentials.

Install the tweepy library for a friendlier Twitter API interface:

pip install tweepy

Example fetching tweets for a hashtag:

import tweepy

client = tweepy.Client(bearer_token=TWITTER_TOKEN)

tweets = client.search_recent_tweets(query="#python")

for tweet in tweets.data:
   print(tweet.text)

See the tweepy docs for more details.

GitHub API

The GitHub API enables programmatic access to GitHub repositories, code, users, and more without authentication.

Example fetching a user‘s repositories:

import requests

response = requests.get(‘https://api.github.com/users/kennethreitz/repos‘)

for repo in response.json():
  print(repo[‘name‘]) 

See the GitHub API docs for more use cases.

Stripe API

The Stripe API allows building payments into apps and websites.

Install the stripe library and import:

pip install stripe

import stripe

Example creating a charge:

stripe.api_key = ‘STRIPE_SECRET_KEY‘ 

charge = stripe.Charge.create(
  amount=1000,
  currency=‘usd‘,
  source=‘tok_visa‘ # Token from Stripe.js
)

Stripe handles the heavy lifting of payments for you.

See Stripe‘s API docs for the full API reference.

There are tons of other great APIs out there like Slack, Twilio, Google Maps, AWS, and more! The key is finding the right data source for your application and leveraging the power of APIs.

Conclusion

I hope this guide provided a helpful overview of making API requests in Python using the Requests library. Here are some key takeaways:

  • Requests makes calling APIs simple – install it using pip
  • Use common HTTP methods like GET, POST, PUT, DELETE for CRUD operations
  • Pass parameters, authentication, headers, and data easily
  • Handle status codes and errors properly
  • Implement best practices like rate limiting and caching
  • Integrate cool APIs like Twitter, GitHub, Stripe and more!

APIs help you build better apps faster by letting you leverage existing data and services. Python and Requests provide a great way to unlock the power of APIs in your code.

For next steps, I recommend browsing the official Requests docs, reading the API docs of any services you want to integrate, and reviewing some repositories using Python APIs like this one.

I hope you found this guide helpful! Let me know if you have any other questions on using Python and APIs. Happy coding!

Join the conversation

Your email address will not be published. Required fields are marked *