← Назад к вопросам
Что такое сессия в Requests?
2.4 Senior🔥 151 комментариев
#DevOps и инфраструктура#REST API и HTTP
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Сессия в Requests
Session в Requests — это объект, который управляет состоянием HTTP-сессии, позволяя вам сохранять параметры между несколькими запросами (cookies, заголовки, аутентификация). Сессия повторно использует базовое TCP-соединение, что повышает производительность при множественных запросах к одному сервису.
Основное применение
Без сессии каждый запрос создаёт новое соединение:
import requests
# Без сессии — 3 отдельных соединения
requests.get('https://api.example.com/users')
requests.post('https://api.example.com/login', json={"user": "admin"})
requests.get('https://api.example.com/profile')
С сессией — одно переиспользуемое соединение:
import requests
session = requests.Session()
# Все запросы используют одно соединение
session.get('https://api.example.com/users')
session.post('https://api.example.com/login', json={"user": "admin"})
session.get('https://api.example.com/profile')
session.close() # Закрываем соединение
Управление Cookies
Сессия автоматически сохраняет и отправляет cookies:
import requests
session = requests.Session()
# Первый запрос (логин)
response = session.post(
'https://api.example.com/login',
json={"username": "admin", "password": "secret"}
)
# Сервер возвращает Set-Cookie в заголовке
# Session автоматически сохраняет этот cookie
print(session.cookies) # CookieJar со всеми cookies
print(session.cookies.get_dict()) # Словарь cookies
# Второй запрос — cookie отправляется автоматически
profile = session.get('https://api.example.com/profile')
print(profile.json()) # Сервер распознаёт, что мы авторизованы
Установка заголовков по умолчанию
import requests
session = requests.Session()
# Устанавливаем заголовки для всех запросов в сессии
session.headers.update({
'User-Agent': 'MyApp/1.0',
'Authorization': 'Bearer token_123abc',
'Accept': 'application/json'
})
# Все запросы будут содержать эти заголовки
response1 = session.get('https://api.example.com/users')
response2 = session.get('https://api.example.com/posts')
# Оба запроса включают Authorization заголовок
Базовая аутентификация
import requests
from requests.auth import HTTPBasicAuth, HTTPDigestAuth
session = requests.Session()
# Способ 1: HTTPBasicAuth
session.auth = HTTPBasicAuth('username', 'password')
response = session.get('https://api.example.com/protected')
# Способ 2: Сокращённый синтаксис
session.auth = ('username', 'password')
# Все запросы в сессии используют эту аутентификацию
for url in ['https://api.example.com/users', 'https://api.example.com/posts']:
response = session.get(url)
Практический пример: API клиент с сессией
import requests
from typing import Any, Dict
class APIClient:
"""Клиент для работы с API"""
def __init__(self, base_url: str, api_key: str):
self.base_url = base_url
self.session = requests.Session()
# Устанавливаем общие заголовки
self.session.headers.update({
'Authorization': f'Bearer {api_key}',
'Content-Type': 'application/json',
'User-Agent': 'APIClient/1.0'
})
def get(self, endpoint: str, params: Dict[str, Any] = None) -> Dict:
"""GET запрос"""
url = f"{self.base_url}/{endpoint}"
response = self.session.get(url, params=params)
response.raise_for_status()
return response.json()
def post(self, endpoint: str, data: Dict[str, Any] = None) -> Dict:
"""POST запрос"""
url = f"{self.base_url}/{endpoint}"
response = self.session.post(url, json=data)
response.raise_for_status()
return response.json()
def put(self, endpoint: str, data: Dict[str, Any] = None) -> Dict:
"""PUT запрос"""
url = f"{self.base_url}/{endpoint}"
response = self.session.put(url, json=data)
response.raise_for_status()
return response.json()
def delete(self, endpoint: str) -> bool:
"""DELETE запрос"""
url = f"{self.base_url}/{endpoint}"
response = self.session.delete(url)
response.raise_for_status()
return True
def close(self):
"""Закрыть сессию"""
self.session.close()
def __enter__(self):
return self
def __exit__(self, *args):
self.close()
# Использование
with APIClient('https://api.example.com', 'my_api_key') as client:
users = client.get('users')
new_user = client.post('users', {'name': 'Alice', 'email': 'alice@example.com'})
client.put('users/1', {'name': 'Bob'})
client.delete('users/2')
Контекстный менеджер (Context Manager)
import requests
# Правильно: сессия закроется автоматически
with requests.Session() as session:
response = session.get('https://api.example.com/users')
print(response.json())
# Соединение автоматически закрыто после выхода из блока with
Обработка ошибок в сессии
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry
def create_session_with_retries():
"""Создать сессию с автоматическими переповторами"""
session = requests.Session()
# Конфигурируем переповторы
retry_strategy = Retry(
total=3, # 3 попытки всего
backoff_factor=1, # Экспоненциальная задержка: 1s, 2s, 4s
status_forcelist=[429, 500, 502, 503, 504], # Статус-коды для переповтора
)
# Применяем стратегию к обоим HTTP и HTTPS
adapter = HTTPAdapter(max_retries=retry_strategy)
session.mount('http://', adapter)
session.mount('https://', adapter)
return session
# Использование
session = create_session_with_retries()
try:
response = session.get('https://api.example.com/data', timeout=10)
response.raise_for_status()
except requests.RequestException as e:
print(f"Ошибка запроса: {e}")
finally:
session.close()
Пулинг соединений
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.connection import create_connection
def patched_create_connection(address, *args, **kwargs):
"""Кастомная функция для создания соединения"""
host, port = address
print(f"Подключаемся к {host}:{port}")
return create_connection(address, *args, **kwargs)
session = requests.Session()
# Настраиваем пулинг соединений
adapter = HTTPAdapter(
pool_connections=10, # Максимум соединений в пуле
pool_maxsize=20, # Максимум переиспользуемых соединений
max_retries=3
)
session.mount('https://', adapter)
# Делаем несколько запросов (переиспользуя соединения)
for i in range(5):
response = session.get(f'https://api.example.com/item/{i}')
print(f"Статус: {response.status_code}")
Сравнение: Session vs requests.get()
import time
import requests
urls = ['https://httpbin.org/uuid'] * 10
# БЕЗ сессии — 10 новых соединений
start = time.time()
for url in urls:
requests.get(url)
time_without_session = time.time() - start
print(f"Без сессии: {time_without_session:.2f}s") # медленнее
# С СЕССИЕЙ — 1 переиспользуемое соединение
start = time.time()
with requests.Session() as session:
for url in urls:
session.get(url)
time_with_session = time.time() - start
print(f"С сессией: {time_with_session:.2f}s") # быстрее (в 2-3 раза)
Лучшие практики
- Используйте контекстный менеджер — гарантирует закрытие соединения
- Переиспользуйте одну сессию — для множественных запросов к одному сервису
- Устанавливайте timeout — избегайте зависаний
- Обрабатывайте исключения — используйте
raise_for_status() - Конфигурируйте переповторы — для устойчивости к сетевым ошибкам
Session — это критически важный инструмент для эффективной работы с HTTP-запросами в Python, обеспечивая производительность и управление состоянием.