Реальні скрипти для роботи з API зазнають збоїв. Сервер може повернути 404, мережа може відключитися, запит може перевищити час очікування. Явна обробка цих випадків робить скрипти надійними.
Є два типи збоїв:
1. **HTTP-помилки** -- сервер відповідає, але з кодом помилки (4xx або 5xx). За замовчуванням `requests` не кидає виняток -- він повертає відповідь, і виклик `.json()` може повернути payload помилки замість даних.
2. **Мережеві помилки** -- запит взагалі не доходить до сервера або сервер не відповідає. Ці помилки кидають винятки: ConnectionError, Timeout або базовий RequestException.
`raise_for_status()` усуває прогалину для HTTP-помилок -- кидає HTTPError при статусі 4xx або 5xx:
```python
import requests
response = requests.get('https://apilearn.tukas.dev/api/products/99999/')
response.raise_for_status() # кидає HTTPError при 404
data = response.json() # виконується тільки якщо статус 2xx
```
Для мережевих помилок використовуйте try/except:
```python
try:
response = requests.get(url, timeout=5)
response.raise_for_status()
data = response.json()
except requests.exceptions.Timeout:
print('Запит перевищив час очікування')
except requests.exceptions.ConnectionError:
print('Мережева помилка -- не вдалося зв'язатися з сервером')
except requests.exceptions.HTTPError as e:
print(f'HTTP помилка: {e.response.status_code}')
```
Параметр `timeout=` встановлює ліміт часу в секундах. Без нього зависаючий сервер може зупинити скрипт назавжди:
```python
# Кидає Timeout якщо немає відповіді протягом 5 секунд
response = requests.get(url, timeout=5)
# Окремі таймаути для підключення і читання
response = requests.get(url, timeout=(3, 10)) # (connect, read)
```
Ієрархія винятків requests (від конкретних до загальних):
```
RequestException Базовий клас для всіх винятків requests
ConnectionError Не вдалося зв'язатися з сервером
ProxyError Помилка підключення через проксі
Timeout Запит перевищив час очікування
ConnectTimeout Таймаут підключення
ReadTimeout Таймаут читання
HTTPError Статус 4xx або 5xx (raise_for_status)
TooManyRedirects Цикл перенаправлень
```
Перехоплення `RequestException` обробляє всі типи одразу -- корисно для простих скриптів, де різниця між типами помилок не важлива.
Зробіть GET до /api/products/99999/ (неіснуючий продукт). Без raise_for_status() виведіть код статусу. Потім додайте raise_for_status() і обробіть виняток HTTPError, вивівши повідомлення про помилку.
import requests
BASE_URL = 'https://apilearn.tukas.dev'
# Частина 1: без raise_for_status — перевірте код статусу
response = requests.get(f'{BASE_URL}/api/products/99999/')
print(response.status_code)
# Частина 2: з raise_for_status і обробкою HTTPError
Рішення
import requests
BASE_URL = 'https://apilearn.tukas.dev'
# Частина 1: без raise_for_status
response = requests.get(f'{BASE_URL}/api/products/99999/')
print(response.status_code) # 404
# Частина 2: з raise_for_status
try:
response = requests.get(f'{BASE_URL}/api/products/99999/')
response.raise_for_status()
except requests.exceptions.HTTPError as e:
print(f'HTTP помилка: {e.response.status_code}')
Спробуйте отримати /api/users/profile/ БЕЗ заголовка авторизації. Обробіть HTTPError і виведіть спеціальне повідомлення, якщо статус 401.
import requests
BASE_URL = 'https://apilearn.tukas.dev'
# GET профілю без авторизації — обробіть 401 окремо
try:
response = requests.get(f'{BASE_URL}/api/users/profile/')
response.raise_for_status()
except requests.exceptions.HTTPError as e:
# Виведіть різні повідомлення для 401 і інших кодів
pass
Зробіть GET до /api/products/ із timeout=5. Обробіть Timeout і ConnectionError окремо. Виведіть список продуктів при успіху або повідомлення про помилку.
import requests
BASE_URL = 'https://apilearn.tukas.dev'
# GET з timeout і обробкою мережевих помилок
Рішення
import requests
BASE_URL = 'https://apilearn.tukas.dev'
try:
response = requests.get(f'{BASE_URL}/api/products/', timeout=5)
response.raise_for_status()
products = response.json()['results']
print(f'Отримано {len(products)} продуктів')
except requests.exceptions.Timeout:
print('Помилка: запит перевищив час очікування')
except requests.exceptions.ConnectionError:
print('Помилка: не вдалося підключитися до API')
except requests.exceptions.HTTPError as e:
print(f'HTTP помилка: {e.response.status_code}')
Напишіть функцію safe_get(url, **kwargs), яка робить GET з timeout=5, викликає raise_for_status() і повертає JSON при успіху або None при будь-якій помилці (виводячи повідомлення). Протестуйте з валідним і неіснуючим URL.
import requests
BASE_URL = 'https://apilearn.tukas.dev'
def safe_get(url, **kwargs):
# Реалізуйте з timeout, raise_for_status і обробкою всіх помилок
pass
# Тест 1: валідний URL
result = safe_get(f'{BASE_URL}/api/products/')
if result:
print(f'Продуктів: {len(result["results"])}')
# Тест 2: неіснуючий ендпоінт
result = safe_get(f'{BASE_URL}/api/products/99999/')
print(result)
Рішення
import requests
BASE_URL = 'https://apilearn.tukas.dev'
def safe_get(url, **kwargs):
try:
response = requests.get(url, timeout=5, **kwargs)
response.raise_for_status()
return response.json()
except requests.exceptions.Timeout:
print(f'Помилка: timeout при запиті до {url}')
except requests.exceptions.ConnectionError:
print(f'Помилка: немає з'єднання з {url}')
except requests.exceptions.HTTPError as e:
print(f'HTTP {e.response.status_code} для {url}')
return None
result = safe_get(f'{BASE_URL}/api/products/')
if result:
print(f'Продуктів: {len(result["results"])}')
result = safe_get(f'{BASE_URL}/api/products/99999/')
print(result)
Напишіть функцію retry_get(url, retries=3), яка повторює запит при кодах 429 або 503, очікуючи 2**attempt секунд між спробами. При інших помилках — одразу кидати виняток. Виведіть повідомлення перед кожним очікуванням.
import requests
import time
BASE_URL = 'https://apilearn.tukas.dev'
def retry_get(url, retries=3, **kwargs):
# Повторюйте при 429/503, exponential backoff, кидайте при інших помилках
pass
# Тест із робочим ендпоінтом (не активує retry)
result = retry_get(f'{BASE_URL}/api/products/')
print(result['count'])
Рішення
import requests
import time
BASE_URL = 'https://apilearn.tukas.dev'
def retry_get(url, retries=3, **kwargs):
for attempt in range(retries):
try:
response = requests.get(url, timeout=5, **kwargs)
response.raise_for_status()
return response.json()
except requests.exceptions.HTTPError as e:
if e.response.status_code in (429, 503) and attempt < retries - 1:
wait = 2 ** attempt
print(f'Спроба {attempt + 1} невдала ({e.response.status_code}), чекаємо {wait}s...')
time.sleep(wait)
else:
raise
return None
result = retry_get(f'{BASE_URL}/api/products/')
print(result['count'])
No split tab
Налаштування cookies
Ми використовуємо необхідні cookies для роботи сайту. З вашого дозволу ми також можемо зберігати налаштування сайту та використовувати аналітичні й рекламні cookies, щоб розуміти використання сайту й підтримувати розвиток проєкту.
* Ви завжди можете змінити свій вибір у налаштуваннях сайту.
Оберіть категорії cookies
Налаштування аналітики
Можна вимкнути аналітику використання платформи. Також можна надіслати в Google Analytics запит на видалення даних про використання цього сайту, пов'язаних із цим браузером.
Навчальний workspace
Навчайтеся, читаючи, запускаючи код і розв'язуючи задачі.
Практикуйте програмування з поясненнями тем, вправами, інструментами browser IDE, перевіркою regex і тренуванням друку коду в одному workspace.
Відкривайте інструменти у вкладках.Вправи, IDE-інструменти й тренажери залишаються доступними як вкладки сайту.
Перемикайтеся без втрати контексту.Переходьте між поясненнями, кодом та утилітами, зберігаючи своє місце.
Використовуйте sidebar як карту.Ліві панелі містять навігацію, налаштування, файли, libraries та керування інструментами.
PythonJavaScriptSQLite
Одна IDE, три практичні режими
Python у браузері.Запускайте невеликі скрипти, пробуйте бібліотеки й тренуйте API-запити без встановлення.
JavaScript для швидких експериментів.Перевіряйте код для браузера й порівнюйте ідеї поруч із навчальними матеріалами.
SQLite для практики з даними.Відкривайте оглядач бази даних, переглядайте таблиці, пишіть запити й вивчайте SQL локально.
ТемаIDE
Працюйте поруч у split tabs
Тримайте інструкції перед очима.Відкрийте вправу або довідкову сторінку поруч з IDE, замість постійних перемикань.
Порівнюйте інструменти під час навчання.Розміщуйте перевірки regex, пояснення та експерименти з кодом поруч, коли це потрібно для задачі.
Закрийте split, коли завершите.Workspace повернеться до однієї сфокусованої вкладки, а відкриті вкладки сайту залишаться доступними.
Тренажер друку коду
Або звичайного тексту
Тренажер розрахований на фізичну клавіатуру.Відкрийте цей розділ на ноутбуці або комп'ютері з широким екраном. На телефоні тренування друку не працюватиме коректно.
Швидкість: 0 зн/хв
0 слів/хв
Найкраща швидкість (60с): 0 зн/хв
0 слів/хв
Помилки: 0
Загальний час: 0.0 с
Щоб тренувати сліпий друк, не підглядайте на фізичну клавіатуру.