- How to Fix HTTPError in Python
- HTTPError Attributes
- What Causes HTTPError
- Python HTTPError Examples
- 404 Not Found
- 400 Bad Request
- 401 Unauthorized
- 500 Internal Server Error
- How to Fix HTTPError in Python
- Track, Analyze and Manage Errors With Rollbar
- Руководство по работе с HTTP в Python. Библиотека requests
- Что же умеет requests?
- Обработка исключений в requests
- Timeout
- ConnectionError
- HTTPError
- Полезные «плюшки»
- 💌 Присоединяйтесь к рассылке
- Интересные записи:
How to Fix HTTPError in Python
The urllib.error.HTTPError is a class in the Python urllib library that represents an HTTP error. An HTTPError is raised when an HTTP request returns a status code that represents an error, such as 4xx (client error) or 5xx (server error).
HTTPError Attributes
The urllib.error.HTTPError class has the following attributes:
- code : The HTTP status code of the error.
- reason : The human-readable reason phrase associated with the status code.
- headers : The HTTP response headers for the request that caused the HTTPError .
What Causes HTTPError
Here are some common reasons why an HTTPError might be raised:
- Invalid or malformed request URL.
- Invalid or malformed request parameters or body.
- Invalid or missing authentication credentials.
- Server internal error or malfunction.
- Server temporarily unavailable due to maintenance or overload.
Python HTTPError Examples
Here are a few examples of HTTP errors in Python:
404 Not Found
import urllib.request import urllib.error try: response = urllib.request.urlopen('http://httpbin.org/status/404') except urllib.error.HTTPError as err: print(f'A HTTPError was thrown: ')
In the above example, an invalid URL is attempted to be opened using the urllib.request.urlopen() function. Running the above code raises an HTTPError with code 404:
A HTTPError was thrown: 404 NOT FOUND
400 Bad Request
import urllib.request try: response = urllib.request.urlopen('http://httpbin.org/status/400') except urllib.error.HTTPError as err: if err.code == 400: print('Bad request!') else: print(f'An HTTP error occurred: ')
In the above example, a bad request is sent to the server. Running the above code raises a HTTPError with code 400:
401 Unauthorized
import urllib.request import urllib.error try: response = urllib.request.urlopen('http://httpbin.org/status/401') except urllib.error.HTTPError as err: if err.code == 401: print('Unauthorized!') else: print(f'An HTTP error occurred: ')
In the above example, a request is sent to the server with missing credentials. Running the above code raises a HTTPError with code 401:
500 Internal Server Error
import urllib.request import urllib.error try: response = urllib.request.urlopen('http://httpbin.org/status/500') except urllib.error.HTTPError as err: if err.code == 500: print('Internal server error!') else: print(f'An HTTP error occurred: ')
In the above example, the server experiences an error internally. Running the above code raises a HTTPError with code 500:
How to Fix HTTPError in Python
To fix HTTP errors in Python, the following steps can be taken:
- Check the network connection and ensure it is stable and working.
- Check the URL being accessed and make sure it is correct and properly formatted.
- Check the request parameters and body to ensure they are valid and correct.
- Check whether the request requires authentication credentials and make sure they are included in the request and are correct.
- If the request and URL are correct, check the HTTP status code and reason returned in the error message. This can give more information about the error.
- Try adding error handling code for the specific error. For example, the request can be attempted again or missing parameters can be added to the request.
Track, Analyze and Manage Errors With Rollbar
Managing errors and exceptions in your code is challenging. It can make deploying production code an unnerving experience. Being able to track, analyze, and manage errors in real-time can help you to proceed with more confidence. Rollbar automates error monitoring and triaging, making fixing Python errors easier than ever. Try it today!
Руководство по работе с HTTP в Python. Библиотека requests
Стандартная библиотека Python имеет ряд готовых модулей по работе с HTTP.
Если уж совсем хочется хардкора, то можно и сразу с socket поработать. Но у всех этих модулей есть один большой недостаток — неудобство работы.
Во-первых, большое обилие классов и функций. Во-вторых, код получается вовсе не pythonic. Многие программисты любят Python за его элегантность и простоту, поэтому и был создан модуль, призванный решать проблему существующих и имя ему requests или HTTP For Humans. На момент написания данной заметки, последняя версия библиотеки — 2.9.1. С момента выхода Python версии 3.5 я дал себе негласное обещание писать новый код только на Py >= 3.5. Пора бы уже полностью перебираться на 3-ю ветку змеюки, поэтому в моих примерах print отныне является функцией, а не оператором 🙂
Что же умеет requests?
Для начала хочется показать как выглядит код работы с http, используя модули из стандартной библиотеки Python и код при работе с requests. В качестве мишени для стрельбы http запросами будет использоваться очень удобный сервис httpbin.org
>>> import urllib.request >>> response = urllib.request.urlopen('https://httpbin.org/get') >>> print(response.read()) b', \n "headers": , \n "origin": "95.56.82.136", \n "url": "https://httpbin.org/get"\n>\n' >>> print(response.getheader('Server')) nginx >>> print(response.getcode()) 200 >>>
Кстати, urllib.request это надстройка над «низкоуровневой» библиотекой httplib о которой я писал выше.
>>> import requests >>> response = requests.get('https://httpbin.org/get') >>> print(response.content) b', \n "headers": , \n "origin": "95.56.82.136", \n "url": "https://httpbin.org/get"\n>\n' >>> response.json() , 'args': <>, 'origin': '95.56.82.136', 'url': 'https://httpbin.org/get'> >>> response.headers >>> response.headers.get('Server') 'nginx'
В простых методах запросов значительных отличий у них не имеется. Но давайте взглянем на работы с Basic Auth:
>>> import urllib.request >>> password_mgr = urllib.request.HTTPPasswordMgrWithDefaultRealm() >>> top_level_url = 'https://httpbin.org/basic-auth/user/passwd' >>> password_mgr.add_password(None, top_level_url, 'user', 'passwd') >>> handler = urllib.request.HTTPBasicAuthHandler(password_mgr) >>> opener = urllib.request.build_opener(handler) >>> response = opener.open(top_level_url) >>> response.getcode() 200 >>> response.read() b'\n'
>>> import requests >>> response = requests.get('https://httpbin.org/basic-auth/user/passwd', auth=('user', 'passwd')) >>> print(response.content) b'\n' >>> print(response.json())
А теперь чувствуется разница между pythonic и non-pythonic? Я думаю разница на лицо. И несмотря на тот факт, что requests ничто иное как обёртка над urllib3, а последняя является надстройкой над стандартными средствами Python, удобство написания кода в большинстве случаев является приоритетом номер один.
- Множество методов http аутентификации
- Сессии с куками
- Полноценная поддержка SSL
- Различные методы-плюшки вроде .json(), которые вернут данные в нужном формате
- Проксирование
- Грамотная и логичная работа с исключениями
О последнем пункте мне бы хотелось поговорить чуточку подробнее.
Обработка исключений в requests
При работе с внешними сервисами никогда не стоит полагаться на их отказоустойчивость. Всё упадёт рано или поздно, поэтому нам, программистам, необходимо быть всегда к этому готовыми, желательно заранее и в спокойной обстановке.
Итак, как у requests дела обстоят с различными факапами в момент сетевых соединений? Для начала определим ряд проблем, которые могут возникнуть:
- Хост недоступен. Обычно такого рода ошибка происходит из-за проблем конфигурирования DNS. (DNS lookup failure)
- «Вылет» соединения по таймауту
- Ошибки HTTP. Подробнее о HTTP кодах можно посмотреть здесь.
- Ошибки SSL соединений (обычно при наличии проблем с SSL сертификатом: просрочен, не является доверенным и т.д.)
Базовым классом-исключением в requests является RequestException. От него наследуются все остальные
И так далее. Полный список всех исключений можно посмотреть в requests.exceptions.
Timeout
В requests имеется 2 вида таймаут-исключений:
- ConnectTimeout — таймаут на соединения
- ReadTimeout — таймаут на чтение
>>> import requests >>> try: . response = requests.get('https://httpbin.org/user-agent', timeout=(0.00001, 10)) . except requests.exceptions.ConnectTimeout: . print('Oops. Connection timeout occured!') . Oops. Connection timeout occured! >>> try: . response = requests.get('https://httpbin.org/user-agent', timeout=(10, 0.0001)) . except requests.exceptions.ReadTimeout: . print('Oops. Read timeout occured') . except requests.exceptions.ConnectTimeout: . print('Oops. Connection timeout occured!') . Oops. Read timeout occured
ConnectionError
>>> import requests >>> try: . response = requests.get('http://urldoesnotexistforsure.bom') . except requests.exceptions.ConnectionError: . print('Seems like dns lookup failed..') . Seems like dns lookup failed..
HTTPError
>>> import requests >>> try: . response = requests.get('https://httpbin.org/status/500') . response.raise_for_status() . except requests.exceptions.HTTPError as err: . print('Oops. HTTP Error occured') . print('Response is: '.format(content=err.response.content)) . Oops. HTTP Error occured Response is: b''
Я перечислил основные виды исключений, которые покрывают, пожалуй, 90% всех проблем, возникающих при работе с http. Главное помнить, что если мы действительно намерены отловить что-то и обработать, то это необходимо явно запрограммировать, если же нам неважен тип конкретного исключения, то можно отлавливать общий базовый класс RequestException и действовать уже от конкретного случая, например, залоггировать исключение и выкинуть его дальше наверх. Кстати, о логгировании я напишу отдельный подробный пост.
У блога появился свой Telegram канал, где я стараюсь делиться интересными находками из сети на тему разработки программного обеспечения. Велком, как говорится 🙂
Полезные «плюшки»
- httpbin.org очень полезный сервис для тестирования http клиентов, в частности удобен для тестирования нестандартного поведения сервиса
- httpie консольный http клиент (замена curl) написанный на Python
- responses mock библиотека для работы с requests
- HTTPretty mock библиотека для работы с http модулями
💌 Присоединяйтесь к рассылке
Понравился контент? Пожалуйста, подпишись на рассылку.
Интересные записи:
- FastAPI, asyncio и multiprocessing
- Работа с MySQL в Python
- Введение в logging на Python
- Обзор Python 3.9
- Celery: начинаем правильно
- Pyenv: удобный менеджер версий python
- Django Channels: работа с WebSocket и не только
- Почему Python?
- Что нового появилось в Django Channels?
- Итоги первой встречи Python программистов в Алматы
- Python-RQ: очередь задач на базе Redis
- Авторизация через Telegram в Django и Python
- Как написать Telegram бота: практическое руководство
- Работа с PostgreSQL в Python
- Введение в pandas: анализ данных на Python
- Разворачиваем Django приложение в production на примере Telegram бота
- Участие в подкасте TalkPython
- Обзор Python 3.8
- Строим Data Pipeline на Python и Luigi
- Видео презентации ETL на Python