Запуск веб-сервера на Python: от простого до продвинутого
Основные методы запуска локального HTTP сервера на Python
Как быстро раздать статические файлы без установки дополнительных библиотек?
Python предоставляет встроенный модуль http.server (для Python 3) или SimpleHTTPServer (для Python 2). Этот сервер однострочной командой запускает HTTP сервер, который отдаёт содержимое текущей директории. Это удобно для тестирования HTML, CSS, JavaScript.
python -m http.server 8000Python local server py (создание локального сервера на python)
После запуска в консоли появится сообщение "Serving HTTP on 0.0.0.0 port 8000". Откройте браузер по адресу http://localhost:8000. Остановить сервер можно клавишами Ctrl+C.
Возможные проблемы:
- Ошибка "Address already in use" - порт занят. Укажите другой порт, например, 8080.
- Файлы не отображаются - проверьте, что терминал находится в нужной папке.
- На Windows может быть блокировка брандмауэром - разрешите доступ.
Как создать сервер с произвольными маршрутами для разработки веб-приложений?
Микрофреймворк Flask позволяет легко определять маршруты и обрабатывать запросы. Это отличный выбор для создания API или простого динамического сайта.
from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
return 'Привет, мир!'
if __name__ == '__main__':
app.run(port=5000, debug=True)
Установите Flask: pip install flask. Запустите скрипт. Сервер будет доступен на http://localhost:5000.
Типичные ошибки:
- Ошибка импорта - убедитесь, что Flask установлен и используется правильное окружение Python.
- Порт занят - измените номер порта в вызове
app.run().
Как реализовать асинхронный сервер для прототипирования высоконагруженных систем?
Библиотека aiohttp построена на asyncio и позволяет создавать асинхронные веб-серверы с высокой производительностью.
from aiohttp import web
async def handle(request):
return web.Response(text='Привет от aiohttp!')
app = web.Application()
app.router.add_get('/', handle)
if __name__ == '__main__':
web.run_app(app, port=8080)
Установка: pip install aiohttp. Запуск выполняется аналогично.
Проблемы:
- Ошибки asyncio - требуется Python 3.5 или новее.
- Не устанавливается aiohttp - проверьте совместимость версий.
Как написать собственный TCP сервер с помощью модуля socketserver?
Модуль socketserver даёт базовые классы для создания сетевых серверов. Ниже пример эхо-сервера, который возвращает полученные данные.
import socketserver
class MyTCPHandler(socketserver.BaseRequestHandler):
def handle(self):
self.data = self.request.recv(1024).strip()
print('Получено:', self.data)
self.request.sendall(self.data)
if __name__ == '__main__':
with socketserver.TCPServer(('localhost', 9999), MyTCPHandler) as server:
server.serve_forever()
Подключитесь через telnet: telnet localhost 9999. Сервер выведет полученные данные и отправит их обратно.
Ошибки:
- Порт занят - выберите другой.
- Если telnet недоступен, используйте ncat или Python скрипт.
Как поднять сервер для производственного окружения с помощью Gunicorn?
Gunicorn - это WSGI сервер, часто используемый для деплоя Flask/Django приложений. Локально его также можно запустить.
gunicorn -w 4 -b 0.0.0.0:8000 myapp:app
Предполагается, что в файле myapp.py есть объект app (например, Flask приложение). Установка: pip install gunicorn.
Проблемы:
- Gunicorn не работает на Windows (рекомендуется использовать Waitress).
- Ошибка импорта модуля - проверьте, что приложение корректно импортируется.
Расширенные примеры и нестандартные конфигурации
HTTP сервер с кастомным обработчиком для выдачи JSON (http.server)
Можно наследовать BaseHTTPRequestHandler и переопределить методы. В примере сервер отвечает JSON на все GET запросы.
from http.server import HTTPServer, BaseHTTPRequestHandler
import json
class JSONHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('Content-type', 'application/json')
self.end_headers()
data = {'message': 'Hello', 'path': self.path}
self.wfile.write(json.dumps(data).encode('utf-8'))
if __name__ == '__main__':
server = HTTPServer(('localhost', 8080), JSONHandler)
print('Serving on http://localhost:8080')
server.serve_forever()
Результат при обращении к http://localhost:8080/test:
{"message": "Hello", "path": "/test"}
Проблемы: такой сервер не отдаёт статические файлы, только JSON.
Flask сервер с обработкой POST запросов и возвратом JSON
Пример демонстрирует приём данных в формате JSON и ответ с подтверждением.
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/api', methods=['POST'])
def api():
data = request.get_json()
if not data:
return jsonify({'error': 'No JSON'}), 400
return jsonify({'received': data}), 200
if __name__ == '__main__':
app.run(port=5000, debug=True)
Тестирование с curl:
curl -X POST -H "Content-Type: application/json" -d '{"name": "Python"}' http://localhost:5000/api
Ответ:
{"received": {"name": "Python"}}
Асинхронный сервер с WebSocket эхо (aiohttp)
WebSocket позволяет двустороннюю связь. Ниже эхо-сервер, возвращающий полученное сообщение.
from aiohttp import web
def index(request):
return web.Response(text='<!DOCTYPE html><html><body><script>var ws=new WebSocket("ws://localhost:8080/ws");ws.onmessage=function(e){console.log(e.data)};</script></body></html>', content_type='text/html')
async def websocket_handler(request):
ws = web.WebSocketResponse()
await ws.prepare(request)
async for msg in ws:
if msg.type == web.WSMsgType.TEXT:
await ws.send_str('Эхо: ' + msg.data)
elif msg.type == web.WSMsgType.ERROR:
break
return ws
app = web.Application()
app.router.add_get('/', index)
app.router.add_get('/ws', websocket_handler)
web.run_app(app, port=8080)
Откройте http://localhost:8080 и используйте консоль браузера для отправки сообщений через WebSocket. Сервер вернёт их с префиксом "Эхо:".
Сервер на сокетах с ручным разбором HTTP запроса
Можно написать минимальный HTTP сервер, используя только модуль socket. Это помогает понять протокол HTTP.
import socket
HOST, PORT = 'localhost', 8888
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
s.listen()
print('Сервер слушает на', PORT)
conn, addr = s.accept()
with conn:
data = conn.recv(1024).decode('utf-8')
print('Запрос:')
print(data)
response = b'HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\nHello from raw socket!'
conn.sendall(response)
После запуска откройте браузер на http://localhost:8888. В консоли появится сырой HTTP запрос, браузер получит ответ.
Проблемы: обрабатывается только одно соединение; для множества запросов нужен цикл.
Запуск HTTPS сервера на основе http.server с самоподписанным сертификатом
Для тестирования защищённого соединения можно создать самоподписанный сертификат и обернуть сокет в SSL.
Сначала создайте сертификат (одна строка):
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes -subj '/CN=localhost' && cat key.pem cert.pem > server.pem
Затем запустите сервер:
import http.server
import ssl
server_address = ('localhost', 4443)
httpd = http.server.HTTPServer(server_address, http.server.SimpleHTTPRequestHandler)
httpd.socket = ssl.wrap_socket(httpd.socket, certfile='server.pem', server_side=True)
print('Serving on https://localhost:4443')
httpd.serve_forever()
Перейдите по https://localhost:4443. Браузер предупредит о недоверенном сертификате, но соединение будет установлено.