Various test tasks for creating client-server applications
Ваша цель - реализовать сервер WSGI с HTTP-оболочкой без использования каких-либо внешних зависимостей. Он должен прослушивать локальный порт 8888 и анализировать параметры GET из URL-адреса, для каждого типа credentials возвращая вам JSON в соответствии с таблицей:
Cyberman: John Lumic
Dalek: Davros
Judoon: Shadow Proclamation Convention 15 Enforcer
Human: Leonardo da Vinci
Ood: Klineman Halpen
Silence: Tasha Lem
Slitheen: Coca-Cola salesman
Sontaran: General Staal
Time Lord: Rassilon
Weeping Angel: The Division Representative
Zygon: Broton
Возвращаться должен HTTP-код 200, также обратите внимание на соответствующий заголовок Content-Type и кодировку URL-адреса. Пример использования cURL может выглядеть следующим образом:
~$ curl http://127.0.0.1:8888/?species=Time%20Lord
{"credentials": "Rassilon"}
Если он не знает переданный тип, он должен вернуть "{"credentials": "Unknown"}" вместе с кодом состояния HTTP 404.
Все приложение для этой задачи должно быть в виде одного файла credentials.py.
- Сервер реализован в
WSGI/credentials.py. - Для проверки сервера можно запустить скрипт
WSGI/test_credentials.sh - Работоспособность протестирована на Ubuntu и MacOS
Создать простое клиент-серверное приложение WSGI+HTTP для управления звуковыми файлами.
Во-первых, сервер. Он не должен использовать какую-либо базу данных, достаточно просто хранить файлы на диске. Веб-интерфейс должен работать через порт 8888. При открытии веб-страницы должен отображаться список уже загруженных звуковых файлов и кнопка для загрузки другого. Как пользователь, вы должны иметь возможность нажать на эту кнопку, загрузить файл на сервер, и он должен появиться в списке файлов, отображаемых на веб-странице.
Кроме того, сервер должен выполнить проверку MIME-типа, чтобы принимались только аудиофайлы (например, "mp3", ogg и wav). Если загружен незвуковой файл (например, "jpg", "exe" или "docx"), он должен быть отклонен, а на веб-странице должно появиться сообщение "Non-audio file detected". Также можете реализовать воспроизведение загруженных звуковых файлов непосредственно с веб-страницы.
Для этой задачи рекомендуется использовать фреймворк Flask или Django, хотя это и не является строгим требованием.
Во-вторых, клиент. Это должно быть приложение командной строки с двумя возможными действиями:
python screwdriver.py upload /path/to/file.mp3должен загрузить локальный аудиофайл/path/to/file.mp3на сервер.- `python screwdriver.py list" должен получить и распечатать имена всех файлов, которые в данный момент находятся на сервере.
Все общение между клиентом и сервером должен использовать HTTP. Рекомендуется (хотя и не обязательно) использовать либо requests или HTTPX для выполнения HTTP-запросов.
- Подробности установки зависимости, запуска и тестирования смотри в
Flask/README.md - Дизайн приложения мималистичен и прост, ибо не это главное.
- Дополнительно к заданию, реализован запрет на повторную загрузку файла с таким же именем.
- Можно было "по-взрослому" запустить через Gunicorn или uWSGI, но для такой задачи это излишнее.
- Работоспособность протестирована на Ubuntu и MacOS
Программа должна состоять из двух файлов - crawl.py и server.py. Рекомендуется использовать aiohttp или httpx для клиентской части и FastAPI для серверной части. Весь код ввода-вывода должен быть асинхронным.
Рабочий процесс выглядит следующим образом:
- Сервер запускается и прослушивает порт 8888.
- Клиент (
crawl.py) получает один или несколько URL-адресов, доступных для запроса, в качестве аргумента. - Клиент отправляет все URL-адреса через HTTP POST-запрос в виде списка JSON на конечную точку сервера
/api/v1/tasks/. - Сервер отвечает сообщением о создании HTTP 201 и объекта задачи (попробуйте использовать PyDantic).
- Объект задачи содержит статус "running" и идентификатор, который равен UUID4.
- Затем сервер начинает асинхронно (без использования потоков или многопроцессорной обработки) отправлять запросы HTTP GET на отправленные URL-адреса и собирать коды ответов HTTP, будь то 200, 404 или какие-либо другие - клиент продолжает периодически запрашивать конечную точку
/api/v1/tasks/{received_task_id}, пока сервер не завершит обработку всех URL-адресов. Затем статус задачи должен измениться на "ready", а поле "result" задачи должно содержать список кодов HTTP-ответа для отправленных URL-адресов. - Клиент печатает разделенный табуляцией код HTTP-ответа и соответствующий URL-адрес для каждой записи.
В синхронном мире люди часто реализуют это, используя модули, подобные Celery, но в этой задаче не требуется никаких внешних исполнителей, поэтому весь сервер должен быть в одном файле на Python, а весь код должен использовать парадигму async/await.
Кроме этого сервер должен реализовать кэширование. Если сервер недавно видел один из отправленных URL-адресов, он может просто принять кэшированное значение за HTTP-код.
Другим решением было бы собрать некоторые показатели для входных данных. Независимо от того, был ли URL-адрес кэширован или нет, давайте также подсчитаем на сервере, сколько запросов мы уже выполнили для определенного домена (например, для "https://www.google.com/search?q=there+is+no+spoon", домен был бы "www.google.com").
Вы должны использовать Redis как для счетчика кэша, так и для счетчика домена.
Включите в код корутину, которая очищает кэшированные записи по истечении настраиваемого времени ожидания.
- Подробности установки зависимости, запуска и тестирования смотри в
FastAPI/README.md - Время очиски кэша устанавливается в
.envпеременной TIMEOUT в секундах. - Для адресов не содержащих
httpилиhttpsавтоматически добавляетсяhttp://. - Работоспособность протестирована на Ubuntu и MacOS