{}const=>[]async()letfn</>var
DevelopmentPython

Working with the API in Python: a complete guide to the requests library

Learn how to work with the API in Python using the requests library. The article contains practical examples of GET and POST requests, error handling, working with headers and authentication, and file uploading. A complete guide from basics to advanced techniques for developers.

К

Kodik

Author

4 min read

Why requests?

Python includes a built-in urllib module for working with HTTP, but its syntax is cumbersome and unintuitive. The requests library solves this problem by providing an elegant and intuitive interface. No wonder its slogan is "HTTP for Humans".

🔥 100,000+ students already with us

Tired of reading theory?
Time to code!

Kodik — an app where you learn to code through practice. AI mentor, interactive lessons, real projects.

🤖 AI 24/7
🎓 Certificates
💰 Free
🚀 Start learning
Joined today

Installation

Setting up requests is easy:

pip install requests

Basics: GET requests

Let's start with the most common type of request — GET. Let's imagine that we need to get data about a GitHub user:

import requests

response = requests.get('https://api.github.com/users/octocat')

# Checking the status of the response
print(response.status_code)  # 200

# Getting JSON
data = response.json()
print(data['name'])  # The Octocat
print(data['public_repos'])  # Number of public repositories

The response object contains all the information about the server response: status code, headers, response body, and much more.

Request parameters

APIs often require passing parameters in the URL. The requests library allows you to do this elegantly:

# Search for repositories on GitHub
params = {
    'q': 'python requests',
    'sort': 'stars',
    'order': 'desc'
}

response = requests.get('https://api.github.com/search/repositories', params=params)
repos = response.json()

for repo in repos['items'][:5]:
    print(f"{repo['name']}: {repo['stargazers_count']} stars")

The library automatically generates the correct URL with parameters, escaping special characters.

POST requests and sending data

POST requests are used to create resources or send forms. Let's consider an example with sending JSON:

# Creating a new resource
data = {
    'title': 'I'm studying requests',
    'body': 'This is a very convenient library!',
    'userId': 1
}

response = requests.post('https://jsonplaceholder.typicode.com/posts', json=data)

if response.status_code == 201:
    print('Resource created!')
    print(response.json())

Pay attention to the json parameter — requests automatically serializes the dictionary in JSON and sets the correct Content-Type header.

Working with headings

Many APIs require authentication through headers. Here's how it's done:

headers = {
    'Authorization': 'Bearer YOUR_TOKEN_HERE',
    'User-Agent': 'MyApp/1.0'
}

response = requests.get('https://api.example.com/data', headers=headers)

Some APIs use API keys:

headers = {'X-API-Key': 'your_api_key'}
response = requests.get('https://api.example.com/protected', headers=headers)

Error handling

Professional work with the API is impossible without proper error handling:

try:
    response = requests.get('https://api.example.com/data', timeout=5)
    response.raise_for_status()  # Throws an exception for 4xx and 5xx codes
    
    data = response.json()
    
except requests.exceptions.HTTPError as http_err:
    print(f'HTTP error: {http_err}')
except requests.exceptions.ConnectionError:
    print('Connection error')
except requests.exceptions.Timeout:
    print('Timeout')
except requests.exceptions.RequestException as err:
    print(f'An error occurred: {err}')

The raise_for_status() method automatically throws an exception if the server returned an error code.

Sessions for multiple requests

If you need to make multiple requests to the same API, use sessions. They save cookies and the connection, which significantly speeds up the work:

session = requests.Session()
session.headers.update({'Authorization': 'Bearer TOKEN'})

# All requests within the session will use common headers
response1 = session.get('https://api.example.com/users')
response2 = session.get('https://api.example.com/posts')
response3 = session.post('https://api.example.com/comments', json={'text': 'Hello'})

session.close()

It is even better to use the context manager:

with requests.Session() as session:
    session.headers.update({'Authorization': 'Bearer TOKEN'})
    response = session.get('https://api.example.com/data')

File management

Uploading files via the API is also easy:

# File upload
files = {'file': open('document.pdf', 'rb')}
response = requests.post('https://api.example.com/upload', files=files)

# Downloading file
response = requests.get('https://example.com/image.jpg', stream=True)
with open('image.jpg', 'wb') as file:
    for chunk in response.iter_content(chunk_size=8192):
        file.write(chunk)

The stream=True parameter allows you to load large files in batches without loading them completely into memory.

Practical example: working with the weather API

Let's create a full-fledged weather app:

import requests

def get_weather(city, api_key):
    """Gets the current weather for the specified city"""
    base_url = "http://api.openweathermap.org/data/2.5/weather"
    
    params = {
        'q': city,
        'appid': api_key,
        'units': 'metric',
        'lang': 'ru'
    }
    
    try:
        response = requests.get(base_url, params=params, timeout=10)
        response.raise_for_status()
        
        data = response.json()
        
        weather_info = {
            'city': data['name'],
            'temperature': data['main']['temp'],
            'feels': data['main']['feels_like'],
            'description': data['weather'][0]['description'],
            'Humidity': data['main']['humidity'],
            'Wind': data['wind']['speed']
        }
        
        return weather_info
        
    except requests.exceptions.RequestException as e:
        print(f"Error retrieving data: {e}")
        return None

# Use
weather = get_weather('Moscow', 'YOUR_API_KEY')
if weather:
    print(f"Weather in the city {weather['city']}:"
    print(f"Temperature: {weather['temperature']}°C")
    print(f"Feels like: {weather['ощущается']}°C"  print(f"Description: {weather['description']}"]}")

Advanced options

Retry mechanism using adapters:

from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry

session = requests.Session()
retry = Retry(
    total=3,
    backoff_factor=1,
    status_forcelist=[500, 502, 503, 504]
)
adapter = HTTPAdapter(max_retries=retry)
session.mount('http://', adapter)
session.mount('https://', adapter)

response = session.get('https://api.example.com/data')

Working with authentication:

# Basic Auth
response = requests.get('https://api.example.com/data', 
                       auth=('username', 'password'))

# OAuth 2.0 usually via headers
headers = {'Authorization': f'Bearer {access_token}'}
response = requests.get('https://api.example.com/data', headers=headers)

Conclusion

The requests library makes working with the API in Python a pleasure. Simple and intuitive syntax, powerful features, and excellent documentation make it the de facto standard for HTTP requests in Python. By mastering requests, you will be able to integrate thousands of different services into your projects and create truly powerful applications.

Appendix Code offers structured courses in Python, JavaScript, API, and more. Interactive lessons, practical tasks and step-by-step learning will help you become a developer.

Join our Telegram channel, where you will find support from experienced developers, useful materials and answers to any questions about programming. Learn at a comfortable pace with a community of like-minded people!

🎯Stop procrastinating

Liked the article?
Time to practice!

In Kodik, you don't just read — you write code immediately. Theory + practice = real skills.

Instant practice
🧠AI explains code
🏆Certificate

No registration • No card