Автор оригинала: Guest Contributor.
Обслуживание файлов с помощью модуля SimpleHTTPServer Python
Вступление
Серверы-это компьютерное программное или аппаратное обеспечение, которое обрабатывает запросы и доставляет данные клиенту по сети. Существуют различные типы серверов, наиболее распространенными из которых являются веб-серверы, серверы баз данных, серверы приложений и серверы транзакций.
Широко используемые веб-серверы, такие как Apache , Monkey и Jigsaw , довольно трудоемки в настройке при тестировании простых проектов, и внимание разработчика смещается с создания логики приложения на настройку сервера.
Модуль Python SimpleHTTPServer
-это полезный и простой инструмент, который разработчики могут использовать для нескольких вариантов использования, главным из которых является быстрый способ обслуживания файлов из каталога.
Это избавляет от трудоемкого процесса, связанного с установкой и внедрением доступных кросс-платформенных веб-серверов.
Примечание : Хотя SimpleHTTPServer
– отличный способ легко обслуживать файлы из каталога, его не следует использовать в производственной среде. Согласно официальным документам Python, он “реализует только базовые проверки безопасности.”
Что такое HTTP-сервер
HTTP расшифровывается как Протокол передачи гипертекста . Давайте представим себе протокол как разговорный язык, подобный английскому. Английский язык имеет набор правил и словарный запас. Таким образом, если мы оба понимаем правила и словарь, определяющие английский язык, то мы можем эффективно общаться на этом языке.
Точно так же, как люди, электронные устройства общаются друг с другом. Поэтому им нужен “набор правил и словарный запас”, чтобы активно передавать и получать информацию друг от друга.
Протокол-это стандартный набор правил, который облегчает успешную коммуникацию между электронными устройствами. Эти наборы взаимно принятых и реализованных правил включают команды, используемые для инициирования отправки и приема данных, типы данных, передаваемых между устройствами, способы обнаружения ошибок в данных, способы подтверждения успешной передачи данных и многое другое.
Например, при выполнении простого поиска с помощью браузера были задействованы две основные системы – HttpClient и HTTP Server .
Клиент, обычно называемый browser , может быть сложной программой, такой как Google Chrome или Firefox, но он также может быть таким же простым, как приложение CLI. Клиент отправляет ваш запрос на сервер, который обрабатывает HTTP-запросы и предоставляет ответ клиенту. В случае браузеров ответ обычно представляет собой HTML-страницу.
Модуль SimpleHTTPServer Python
Когда вам нужен быстрый запуск веб-сервера, настройка сервера производственного уровня-это огромный перебор.
Модуль Python SimpleHTTPServer
-это экономящий труд инструмент, который вы можете использовать для превращения любого каталога в вашей системе в несложный веб-сервер. Он поставляется в комплекте с простым HTTP-сервером, который предоставляет стандартные обработчики запросов GET
и HEAD
.
Со встроенным HTTP-сервером вам не нужно ничего устанавливать или настраивать, чтобы ваш веб-сервер работал и работал.
Примечание : Модуль Python SimpleHTTPServer
был объединен с модулем http.server
в Python 3. На протяжении всей этой статьи мы будем использовать версию Python 3, но если вы используете Python 2, вы можете заменить http.server
на SimpleHTTPServer
, и это должно работать в большинстве случаев.
Использование командной строки
Самый простой способ запустить веб-сервер, обслуживающий каталог, в котором выполняется команда, – это просто перейти в каталог вашего проекта с помощью терминала и запустить:
Python 2
$ python -m SimpleHTTPServer 8000
Python 3
$ python3 -m http.server 8000
Выполнив эту команду, вы сможете получить доступ к файлам в вашем каталоге через браузер по адресу localhost:8000
:
Как вы можете видеть, сервер предоставляет простой пользовательский интерфейс каталога, в котором вы можете получить доступ к любому из файлов. Это самый простой способ напрямую обслуживать файлы локально по протоколу HTTP.
Использование Python по умолчанию
По той или иной причине запуск этого сервера через командную строку может не подойти нашему варианту использования. В такие моменты мы можем вместо этого использовать сервер непосредственно в нашем коде, используя объект SimpleHTTPRequestHandler
. Но сначала нам нужно настроить его с помощью сокет-сервера.
Под протоколом HTTP находятся UDP (User Datagram Protocol) или TCP (Transmission Control Protocol), которые являются транспортными протоколами, обрабатывающими транспортировку данных из одного сетевого местоположения в другое. Поскольку мы запускаем HTTP-сервер, наше приложение будет использовать протокол TCP через адрес сокета TCP , который содержит IP-адрес и номер порта. Это можно настроить с помощью Python socketserver.TCPServer , который мы реализовали ниже:
import http.server import socketserver PORT = 8000 handler = http.server.SimpleHTTPRequestHandler with socketserver.TCPServer(("", PORT), handler) as httpd: print("Server started at localhost:" + str(PORT)) httpd.serve_forever()
Примечание : Код завершится ошибкой AttributeError: __exit__
для версий Python < 3.6. Это связано с тем, что в предыдущих версиях socketserver.TCPServer
не поддерживает использование с контекстными менеджерами (ключевое слово with
). В этих случаях вам нужно вызвать server_close ()
, чтобы остановить сервер.
По умолчанию SimpleHTTPRequestHandler
обслуживает файлы из текущего каталога и связанных с ним подкаталогов. Как следует из названия, это простой обработчик HTTP-запросов. Будучи простым сервером, он позволяет вам только извлекать данные, а не отправлять их на сервер. И из-за этого он реализует только методы HTTP GET
и HEAD
через do_GET()
и do_HEAD()
.
Параметры, передаваемые в TCPServer
, представляют собой IP-адрес и номер порта. Оставив IP – адрес пустым, сервер прослушивает все доступные IP-адреса, в то время как мы установили порт на 8000
. Это означает, что тогда он будет доступен на localhost:8000
.
Наконец, httpd.server_forever()
запускает сервер, прослушивает и отвечает на входящие запросы от клиента a.
Сервер может быть запущен простым выполнением файла:
$ python3 simple-server.py
И точно так же, как при использовании командной строки, теперь мы можем получить доступ к каталогу через наш веб-браузер:
Настройка Путей
Другой подход, который мы можем использовать, – это создать пользовательский класс, который расширяет SimpleHTTPRequestHandler
и обрабатывает наши запросы с помощью некоторых пользовательских функций. Для этого мы реализуем нашу собственную функцию do_GET ()
.
Но прежде чем мы перейдем к этому, предположим, что у нас есть HTML-файл, который мы хотим обслуживать, mywebpage.html
:
Using Python's SimpleHTTPServer Module Rectangle served by SimpleHTTPServer
Для того чтобы обслуживать этот HTML-код с пути, который не является /mywebpage.html
, мы можем использовать наш пользовательский обработчик, чтобы обслуживать его на любом пути, который мы хотим. В этом примере мы просто подадим его на корневой путь, /
:
import http.server import socketserver class MyHttpRequestHandler(http.server.SimpleHTTPRequestHandler): def do_GET(self): if self.path == '/': self.path = 'mywebpage.html' return http.server.SimpleHTTPRequestHandler.do_GET(self) # Create an object of the above class handler_object = MyHttpRequestHandler PORT = 8000 my_server = socketserver.TCPServer(("", PORT), handler_object) # Star the server my_server.serve_forever()
Опять же, запуск этого скрипта позволит нам получить доступ к нему через браузер:
Однако есть гораздо больше настроек, которые мы можем сделать с ответом через ссылку self
, которую мы увидим в следующем разделе.
Возврат динамического HTML
Обычно веб – серверы используются для обслуживания динамически генерируемого HTML-кода. Хотя это всего лишь очень простой сервер, он также может выполнять эту задачу. В дополнение к отправке динамического HTML-кода мы также можем устанавливать различные коды состояния, заголовки и т. Д. В следующем примере мы устанавливаем некоторые заголовки и возвращаем динамический HTML, который генерируется с помощью параметра запроса name
:
import http.server import socketserver from urllib.parse import urlparse from urllib.parse import parse_qs class MyHttpRequestHandler(http.server.SimpleHTTPRequestHandler): def do_GET(self): # Sending an '200 OK' response self.send_response(200) # Setting the header self.send_header("Content-type", "text/html") # Whenever using 'send_header', you also have to call 'end_headers' self.end_headers() # Extract query param name = 'World' query_components = parse_qs(urlparse(self.path).query) if 'name' in query_components: name = query_components["name"][0] # Some custom HTML code, possibly generated by another function html = f"Hello {name}!
" # Writing the HTML contents with UTF-8 self.wfile.write(bytes(html, "utf8")) return # Create an object of the above class handler_object = MyHttpRequestHandler PORT = 8000 my_server = socketserver.TCPServer(("", PORT), handler_object) # Star the server my_server.serve_forever()
И запускаем этот код с URL-адресом http://localhost:8000?name=Billy
уступит:
Любое значение, которое вы зададите для параметра name
query, появится на экране! Вы даже можете опустить параметр name
query и посмотреть, что произойдет.
Как вы можете видеть, создание пользовательского обработчика запросов позволяет нам манипулировать ответами столько, сколько мы хотели бы, изменяя реализацию метода do_GET
, и у нас нет такого контроля над нашими ответами с реализацией по умолчанию.
То же самое можно сделать с помощью метода HTTP HEAD (через функцию do_HEAD ()
), но поскольку он очень похож на метод GET, мы оставим это упражнение для читателя.
Вывод
Python предоставляет нам модуль SimpleHTTPServer
(или http.server
в Python 3), который можно использовать для быстрого и легкого обслуживания файлов из локального каталога через HTTP. Это может быть использовано для многих разработок или других внутренних задач, но не предназначено для производства.
Это отличное решение для локального использования, поскольку веб-серверы , такие как Apache , Monkey и Jigsaw , гораздо сложнее настроить и часто являются излишними для разработки.