{"id":16769006,"url":"https://github.com/unix4ever/python-sandbox","last_synced_at":"2025-03-16T13:43:42.576Z","repository":{"id":88314806,"uuid":"45853315","full_name":"Unix4ever/python-sandbox","owner":"Unix4ever","description":"Sandbox","archived":false,"fork":false,"pushed_at":"2015-11-13T18:20:40.000Z","size":0,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-01-23T01:28:38.006Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Unix4ever.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-11-09T17:07:39.000Z","updated_at":"2015-11-09T18:16:12.000Z","dependencies_parsed_at":"2023-03-13T18:25:18.184Z","dependency_job_id":null,"html_url":"https://github.com/Unix4ever/python-sandbox","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Unix4ever%2Fpython-sandbox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Unix4ever%2Fpython-sandbox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Unix4ever%2Fpython-sandbox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Unix4ever%2Fpython-sandbox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Unix4ever","download_url":"https://codeload.github.com/Unix4ever/python-sandbox/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243878437,"owners_count":20362432,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-13T06:13:06.042Z","updated_at":"2025-03-16T13:43:42.554Z","avatar_url":"https://github.com/Unix4ever.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Первоначальная настройка для работы с Git\n\nПеред тем как загружать к себе проект, необходимо сгенерировать себе пару ssh ключей (private, public ключи).\n\n```bash\nssh-keygen -t rsa -b 4096 -C \"\u003cauthor_email\u003e\"\n```\n\nЕсли задать все свойства по умолчанию. То есть пролистать все нажатием на enter, ключи должны будут \nпоявиться в папке ~/.ssh/\n\n```\n~/.ssh/id_rsa\n~/.ssh/id_rsa.pub\n```\n\nСодержимое файла `~/.ssh/id_rsa.pub` необходимо загрузить в свой профиль в github. Это и есть публичный ключ.\n\nПосле этих действий должна начать работать команда:\n\n```bash\ngit clone git@github.com:Unix4ever/python-sandbox.git\n```\n\n## Настройка Python окружения\n\nЧтобы можно было работать с Python на linux, надо 3 пакета:\n\n```bash\npython-dev\npython-pip\npython-virtualenv\n```\n\nУстановка пакетов:\n\n```bash\nsudo apt-get install ...\n```\n\nЧтобы создать копию окружения Python:\n\n```bash\nvirtualenv env\nenv/bin/python\nenv/bin/pip install requests\n```\n\nЧтобы не вводить env/bin в 1 сессии терминала можно набрать команду:\n\n```bash\nsource env/bin/activate\n```\n\nПотом вызов:\n\n```bash\npython будет вызывать python из env/bin\n```\n\nДалее есть файлик, в котором хранятся все зависимости.\n\n`\u003cpackage\u003e==\u003cversion\u003e` - Ссылается на определенную версию\n`\u003cpackage\u003e` - Ссылается на последнюю версию\n\nУстановка всех зависимостей из requirements:\n\n```bash\nenv/bin/pip install -r requirements.txt\n```\n\nПакеты можно искать тут:\nhttps://pypi.python.org/pypi\n\n### Задание\n\n1. Сделать virtualenv.\n2. Надо все сторонние зависимости записать в файл.\n3. Добавить зависимость для HTTP сервера (wsgi).\n4. Сделать Makefile, который будет сам запускать создание virtualenv и ставить пакеты.\n\n## HTTP Server\n\nПример URL:\nhttp://host:8080/path?query=133\n\nПримеры URI:\nPOST /path/to/resource?query=123\nGET /1234/\n\nУ HTTP есть разные виды запросов:\nPOST - это запрос с телом (JSON, Binary, XML), если объект существует\nGET - в нем нет тела.\n\nPUT - используется для создания объектов.\nDELETE - удаление объекта.\n\nHEAD - он для получения только заголовков. GET который не возвращает тело. Например, чтобы проверить, что объект существует.\n\nOPTIONS\n\nВ качестве примера простейшего HTTP сервера, можно рассмотреть wsgiref https://docs.python.org/2/library/wsgiref.html.\nwsgiref в коллбек возвращать будет все.\nСокет можно привязать к определенному IP.\nНапример 127.0.0.1.\n\nА если задать 0.0.0.0, то сервер будет доступен на всех интерфейсах.\n\n## Создание скрипта установки модуля:\n\nЧтобы сделать возможным установку Python пакета в систему, необходимо создать \nустановочный скрипт.\nСкрипт должен называться `setup.py` и располагаться в корне проекта:\nФормат:\n\n```python\nfrom distutils.core import setup\nimport http_server\n\nsetup(\n    name='sandbox',\n    version='0.0.1',\n    py_modules=['http_server', 'start', 'server.http_handler'],\n    author='',\n    author_email='',\n    url='',\n    description='Python library for',\n)\n```\nВнутри можно даже компилировать C++.\n\nчтобы установить такой пакет есть 3 варианта:\n1. Скачать его из репы, затем запустить `setup.py`:\n\n```bash\npython setup.py install\n```\n\n2. Скачать его через pip\n\n```bash\npip install -e git+http://ruch-net.ru:10022/artem/python-sandbox.git#egg=sandbox\n```\n\n3. Положить его в архиве на FTP сервер, добавить этот FTP в конфиги PIP.\nИ тогда он скачается:\n\n```bash\npip install sandbox\n```\n\n## Deployment\n\n### Capistrano\n\nКак работает деплой:\n\n1. Заливается код на сервер:\n  1.1. Запаковать в архив и залить его через ssh.\n  1.2. Зайти на машину и сделать git clone кода(git pull, если он уже есть).\n\n2. Устанавливаются зависимости.\n\n3. Создаются папки, необходимые для работы сервиса:\n  3.1. /var/run/\u003cservice\u003e (В ней обычно лежит pid -- файл, в который записывается ID потока сервиса,\n  чтобы его можно было остановить. Потому что ты его запускаешь, как демона. И по нему же скрипт запуска отслеживает, \n  что сервис уже запущен).\n  3.2. /var/log/\u003cservice\u003e\n  3.3. Создается папка с проектом, в нем меняются конфиги под эту конкретную машину.\n\n4. Скрипт для запуска, который должен лежать в проекта, добавляется в папку /etc/init.d/\n`/etc/init.d` -- это папка, в которой лежат все сервисы, которые можно запустить в системе.\n\n5. Осуществляет запуск, или перезагрузку сервиса.\n\nТакже существует механизм отката версий. То есть Capistrano, в частности, хранит прямо на машине N предыдущих версий.\n\nПо сути, все эти действия -- это просто ssh команды.\nСоответственно, Capistrano просто удаленно запускает по очереди все эти команды.\n\nСтруктура папки с деплой скриптами Capistrano:\n\nВся эта структура создается командой:\n\n```bash\n\tcap install\n```\n\nОна создает папки config, deploy, lib. Файлы deploy.rb и конфиги production.rb, staging.rb.\n\n```\n/config -- в ней лежит все, что относится к нашему деплою\n\t/deploy -- здесь лежат все конфиги, и все скрипты\n\t\t/shared -- здесь лежат темплейты в формате erb (это ruby формат шаблонов)\n\t\t\tstart.sh.erb\n\t\t\tapplication.conf.erb\n\t\t\t...\n\t\tproduction.rb -- набор конфигов специфичных для хостов\n\t\tstaging.rb \n\t\tqa.rb\n\t\tdev.rb\n\t\t...\n\n\tdeploy.rb -- файл со всеми задачами для деплоя\n/lib/capistrano/tasks/ -- папка с кастомными задачами для деплоя. Например их можно скачивать при деплое и они\nмогут быть общими для нескольких проектов.\n\nНапример, туда можно добавить задачу для создания virtualenv и использовать эту задачу без изменений во всех проектах.\n```\n\nПосле того, как скрипт готов, можно осуществлять deploy:\n\n```bash\n\tcap \u003cconfiguration\u003e deploy\n```\n\nЧтобы запустить только какой шаг, команда должна будет выглядеть так:\n\n```bash\n\tcap \u003cconfiguration\u003e deploy:\u003cname\u003e\n```\n\nПотом, после установки нашего сервиса, его можно будет запустить командой:\n\n```bash\n\t/etc/init.d/sandbox start\n```\n\nИли:\n\n```bash\n\tservice sandbox start\n```\n\n\n### Docker\n\nDocker можно так же использовать для деплоя серверных приложений.\n\nDocker позволяет создавать для приложений отдельные контейнеры. \nКонтейнер -- это своего рода виртуальная машина, которая полностью отведена под\n1 сервис. \n\nДля того, чтобы описать, как нужно сконфигурировать контейнер, предназначен Dockerfile файл.\nВ нем записываются все команды для создания папок, файлов конфигурации, команды для установки \nзависимостей сервиса.\n\nА так же контейнеры можно наследовать. \nВ нашем случае, в качестве базового контейнера, можно использовать `busybox:ubuntu-14.04`.\n\nРассмотрим функции Dockerfile:\n`ADD` - добавляет файлы/папки в контейнер.\n`EXPOSE \u003cPORT\u003e` - если у сервиса есть порт, который должен быть доступен извне, необходимо сделать `EXPOSE 1234`\nЗатем, при старте можно будет указать `-p '1234:1234'`. Только тогда, к этому порту можно будет получить\nдоступ.\nПри чем доступ можно будет получить по тому номеру порта, который указан до двоеточия.\nТак же можно указать и интерфесы `-p '127.0.0.1:1234:1234'`.\n\nRUN - выполнить bash скрипт.\nENTRYPOINT - команда, которая должна будет выполниться после запуска контейнера (init скрипт сервиса например).\n\nНо так же можно использовать контейнеры, в которых уже установлены все зависимости для Python приложений.\nСтруктура:\n\n```\n/\n\tservice/__init__.py\n\tservice/server.py\n\tDockerfile\t\n```\n\nДля сборки такого контейнера используется команда:\n\n```bash\n\tdocker -t sandbox build .\n```\n\nГде `-t` - это тег образа.\nЗатем это имя тега можно использовать, для того чтобы запустить собранный контейнер:\n\n```bash\n\tdocker run sandbox\n```\n\nОстановка контейнера:\n\n```bash\n\tdocker stop sandbox\n```\n\nУдаление:\n\n```bash\n\tdocker rm -f sandbox\n```\n\nЧтобы посмотреть все контейнеры:\n\n```bash\n\tdocker ps -a\n```\n\nЧтобы посмотреть логи:\n\n```bash\n\tdocker logs sandbox\n```\n\nЧтобы узнать подробную информацию о контейнере:\n```bash\n\tdocker inspect sandox\n```\n\nКогда контейнер собран, он загружается в registry:\n\n```bash\n\tdocker push registry.domain/sandbox\n```\n\n\nПотом, чтобы его загрузить достачно просто выполнить команду:\n\n```bash\n\tdocker run registry.domain/sandbox\n```\n\nЕсли мы хотим запустить сервис, у которого есть в зависимостях другие контейнеры, мы производим\nлинковку контейнеров:\n\n```bash\n\tdocker run -t redis redis\n```\n\n```bash\n\tdocker run --link redis sandbox\n```\n\nПри таком запуске, у контейнеров получается общая сеть. То есть у тебя sandbox, сможет попасть на \nпорты редиса, даже если они не EXPOSE. То есть как-будто это одна машина.\nИ при этом, docker сам прописывает в /etc/hosts \u003cадрес redis контейнера\u003e redis (то есть то, что указывается в -t)\n\nВидно, что чтобы запустить все контейнеры, нужно вызвать кучу команд.\nЧтобы это упростить, появилась библиотека, которая позволяет записать все эти команды в формате одного файла.\n\nЭта библиотека называется docker-compose.\nОна использует docker-compose.yml файлы. yml -- язык сериализации.\n\n```yaml\nredis:  # имя контейнера -t\n  image: redis # образ контейнера\n  ports:\n    - 6379 #  -p \"6379\"\n\nsandbox:\n  image: sandbox\n  ports:\n    - 8000:8000\n  links:\n  \t- redis\n```\n\n```python\n\timport RedisClient()\n\tr = RedisClient(address=\"redis:6379\") # это имя будет резолвиться через /etc/hosts на контейнер с redis сервером\n```\n\n### Задание\n\n#### Часть 1 HTTP сервер\n\n1. Настроить сервис, так, чтобы он загружал в себя flask библиотеку.\n(flask -- это библиотека для работы с http запросами: muxer, socket server, обработчики).\n\n2. Сделать на flask контроллер, который принимает GET, POST запросы:\n\t2.1 POST должен создавать задачу и сохранить ее в redis. Как должна выглядеть эта задача:\n\t\tЭто класс, в котором есть уникальный UID(hash md5, sha), есть время старта, время выполнения,\n\t\tвремя завершения и текстовый идентификатор типа задачи.\n\n\t\tСобственно, эта задача должна создаваться из тела POST запроса.\n\t\tUID должен генериться на сервере, как и поля старта, завершения. \n\t\tКлиент должен передавать только тип задачи.\n\n\t\tПри создании задачи, нужно вернуть тело, как в GET.\n\t\tНужно проставить все заголовки в запросе правильно. Например:\n\t\t`Content-Type: application/json`\n\n\t\tСохранять в Redis нужно с ключом UID, и значением задачи в JSON\n\t2.2 GET должен возвращать тело в JSON формате.\n\t\tДолжен принимать query параметры:\n\t\t?task_id=\u003cuid\u003e","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funix4ever%2Fpython-sandbox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Funix4ever%2Fpython-sandbox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funix4ever%2Fpython-sandbox/lists"}