An open API service indexing awesome lists of open source software.

https://github.com/unix4ever/python-sandbox

Sandbox
https://github.com/unix4ever/python-sandbox

Last synced: 11 months ago
JSON representation

Sandbox

Awesome Lists containing this project

README

          

## Первоначальная настройка для работы с Git

Перед тем как загружать к себе проект, необходимо сгенерировать себе пару ssh ключей (private, public ключи).

```bash
ssh-keygen -t rsa -b 4096 -C ""
```

Если задать все свойства по умолчанию. То есть пролистать все нажатием на enter, ключи должны будут
появиться в папке ~/.ssh/

```
~/.ssh/id_rsa
~/.ssh/id_rsa.pub
```

Содержимое файла `~/.ssh/id_rsa.pub` необходимо загрузить в свой профиль в github. Это и есть публичный ключ.

После этих действий должна начать работать команда:

```bash
git clone git@github.com:Unix4ever/python-sandbox.git
```

## Настройка Python окружения

Чтобы можно было работать с Python на linux, надо 3 пакета:

```bash
python-dev
python-pip
python-virtualenv
```

Установка пакетов:

```bash
sudo apt-get install ...
```

Чтобы создать копию окружения Python:

```bash
virtualenv env
env/bin/python
env/bin/pip install requests
```

Чтобы не вводить env/bin в 1 сессии терминала можно набрать команду:

```bash
source env/bin/activate
```

Потом вызов:

```bash
python будет вызывать python из env/bin
```

Далее есть файлик, в котором хранятся все зависимости.

`==` - Ссылается на определенную версию
`` - Ссылается на последнюю версию

Установка всех зависимостей из requirements:

```bash
env/bin/pip install -r requirements.txt
```

Пакеты можно искать тут:
https://pypi.python.org/pypi

### Задание

1. Сделать virtualenv.
2. Надо все сторонние зависимости записать в файл.
3. Добавить зависимость для HTTP сервера (wsgi).
4. Сделать Makefile, который будет сам запускать создание virtualenv и ставить пакеты.

## HTTP Server

Пример URL:
http://host:8080/path?query=133

Примеры URI:
POST /path/to/resource?query=123
GET /1234/

У HTTP есть разные виды запросов:
POST - это запрос с телом (JSON, Binary, XML), если объект существует
GET - в нем нет тела.

PUT - используется для создания объектов.
DELETE - удаление объекта.

HEAD - он для получения только заголовков. GET который не возвращает тело. Например, чтобы проверить, что объект существует.

OPTIONS

В качестве примера простейшего HTTP сервера, можно рассмотреть wsgiref https://docs.python.org/2/library/wsgiref.html.
wsgiref в коллбек возвращать будет все.
Сокет можно привязать к определенному IP.
Например 127.0.0.1.

А если задать 0.0.0.0, то сервер будет доступен на всех интерфейсах.

## Создание скрипта установки модуля:

Чтобы сделать возможным установку Python пакета в систему, необходимо создать
установочный скрипт.
Скрипт должен называться `setup.py` и располагаться в корне проекта:
Формат:

```python
from distutils.core import setup
import http_server

setup(
name='sandbox',
version='0.0.1',
py_modules=['http_server', 'start', 'server.http_handler'],
author='',
author_email='',
url='',
description='Python library for',
)
```
Внутри можно даже компилировать C++.

чтобы установить такой пакет есть 3 варианта:
1. Скачать его из репы, затем запустить `setup.py`:

```bash
python setup.py install
```

2. Скачать его через pip

```bash
pip install -e git+http://ruch-net.ru:10022/artem/python-sandbox.git#egg=sandbox
```

3. Положить его в архиве на FTP сервер, добавить этот FTP в конфиги PIP.
И тогда он скачается:

```bash
pip install sandbox
```

## Deployment

### Capistrano

Как работает деплой:

1. Заливается код на сервер:
1.1. Запаковать в архив и залить его через ssh.
1.2. Зайти на машину и сделать git clone кода(git pull, если он уже есть).

2. Устанавливаются зависимости.

3. Создаются папки, необходимые для работы сервиса:
3.1. /var/run/ (В ней обычно лежит pid -- файл, в который записывается ID потока сервиса,
чтобы его можно было остановить. Потому что ты его запускаешь, как демона. И по нему же скрипт запуска отслеживает,
что сервис уже запущен).
3.2. /var/log/
3.3. Создается папка с проектом, в нем меняются конфиги под эту конкретную машину.

4. Скрипт для запуска, который должен лежать в проекта, добавляется в папку /etc/init.d/
`/etc/init.d` -- это папка, в которой лежат все сервисы, которые можно запустить в системе.

5. Осуществляет запуск, или перезагрузку сервиса.

Также существует механизм отката версий. То есть Capistrano, в частности, хранит прямо на машине N предыдущих версий.

По сути, все эти действия -- это просто ssh команды.
Соответственно, Capistrano просто удаленно запускает по очереди все эти команды.

Структура папки с деплой скриптами Capistrano:

Вся эта структура создается командой:

```bash
cap install
```

Она создает папки config, deploy, lib. Файлы deploy.rb и конфиги production.rb, staging.rb.

```
/config -- в ней лежит все, что относится к нашему деплою
/deploy -- здесь лежат все конфиги, и все скрипты
/shared -- здесь лежат темплейты в формате erb (это ruby формат шаблонов)
start.sh.erb
application.conf.erb
...
production.rb -- набор конфигов специфичных для хостов
staging.rb
qa.rb
dev.rb
...

deploy.rb -- файл со всеми задачами для деплоя
/lib/capistrano/tasks/ -- папка с кастомными задачами для деплоя. Например их можно скачивать при деплое и они
могут быть общими для нескольких проектов.

Например, туда можно добавить задачу для создания virtualenv и использовать эту задачу без изменений во всех проектах.
```

После того, как скрипт готов, можно осуществлять deploy:

```bash
cap deploy
```

Чтобы запустить только какой шаг, команда должна будет выглядеть так:

```bash
cap deploy:
```

Потом, после установки нашего сервиса, его можно будет запустить командой:

```bash
/etc/init.d/sandbox start
```

Или:

```bash
service sandbox start
```

### Docker

Docker можно так же использовать для деплоя серверных приложений.

Docker позволяет создавать для приложений отдельные контейнеры.
Контейнер -- это своего рода виртуальная машина, которая полностью отведена под
1 сервис.

Для того, чтобы описать, как нужно сконфигурировать контейнер, предназначен Dockerfile файл.
В нем записываются все команды для создания папок, файлов конфигурации, команды для установки
зависимостей сервиса.

А так же контейнеры можно наследовать.
В нашем случае, в качестве базового контейнера, можно использовать `busybox:ubuntu-14.04`.

Рассмотрим функции Dockerfile:
`ADD` - добавляет файлы/папки в контейнер.
`EXPOSE ` - если у сервиса есть порт, который должен быть доступен извне, необходимо сделать `EXPOSE 1234`
Затем, при старте можно будет указать `-p '1234:1234'`. Только тогда, к этому порту можно будет получить
доступ.
При чем доступ можно будет получить по тому номеру порта, который указан до двоеточия.
Так же можно указать и интерфесы `-p '127.0.0.1:1234:1234'`.

RUN - выполнить bash скрипт.
ENTRYPOINT - команда, которая должна будет выполниться после запуска контейнера (init скрипт сервиса например).

Но так же можно использовать контейнеры, в которых уже установлены все зависимости для Python приложений.
Структура:

```
/
service/__init__.py
service/server.py
Dockerfile
```

Для сборки такого контейнера используется команда:

```bash
docker -t sandbox build .
```

Где `-t` - это тег образа.
Затем это имя тега можно использовать, для того чтобы запустить собранный контейнер:

```bash
docker run sandbox
```

Остановка контейнера:

```bash
docker stop sandbox
```

Удаление:

```bash
docker rm -f sandbox
```

Чтобы посмотреть все контейнеры:

```bash
docker ps -a
```

Чтобы посмотреть логи:

```bash
docker logs sandbox
```

Чтобы узнать подробную информацию о контейнере:
```bash
docker inspect sandox
```

Когда контейнер собран, он загружается в registry:

```bash
docker push registry.domain/sandbox
```

Потом, чтобы его загрузить достачно просто выполнить команду:

```bash
docker run registry.domain/sandbox
```

Если мы хотим запустить сервис, у которого есть в зависимостях другие контейнеры, мы производим
линковку контейнеров:

```bash
docker run -t redis redis
```

```bash
docker run --link redis sandbox
```

При таком запуске, у контейнеров получается общая сеть. То есть у тебя sandbox, сможет попасть на
порты редиса, даже если они не EXPOSE. То есть как-будто это одна машина.
И при этом, docker сам прописывает в /etc/hosts <адрес redis контейнера> redis (то есть то, что указывается в -t)

Видно, что чтобы запустить все контейнеры, нужно вызвать кучу команд.
Чтобы это упростить, появилась библиотека, которая позволяет записать все эти команды в формате одного файла.

Эта библиотека называется docker-compose.
Она использует docker-compose.yml файлы. yml -- язык сериализации.

```yaml
redis: # имя контейнера -t
image: redis # образ контейнера
ports:
- 6379 # -p "6379"

sandbox:
image: sandbox
ports:
- 8000:8000
links:
- redis
```

```python
import RedisClient()
r = RedisClient(address="redis:6379") # это имя будет резолвиться через /etc/hosts на контейнер с redis сервером
```

### Задание

#### Часть 1 HTTP сервер

1. Настроить сервис, так, чтобы он загружал в себя flask библиотеку.
(flask -- это библиотека для работы с http запросами: muxer, socket server, обработчики).

2. Сделать на flask контроллер, который принимает GET, POST запросы:
2.1 POST должен создавать задачу и сохранить ее в redis. Как должна выглядеть эта задача:
Это класс, в котором есть уникальный UID(hash md5, sha), есть время старта, время выполнения,
время завершения и текстовый идентификатор типа задачи.

Собственно, эта задача должна создаваться из тела POST запроса.
UID должен генериться на сервере, как и поля старта, завершения.
Клиент должен передавать только тип задачи.

При создании задачи, нужно вернуть тело, как в GET.
Нужно проставить все заголовки в запросе правильно. Например:
`Content-Type: application/json`

Сохранять в Redis нужно с ключом UID, и значением задачи в JSON
2.2 GET должен возвращать тело в JSON формате.
Должен принимать query параметры:
?task_id=