Как стать автором
Обновить

Комментарии 24

И сразу же по установке пакетов для Python. Почему apt-get, а не православный pip? Не самый очевидный выбор, на мой взгляд.
Потому что на production сервере не должно стоять dev-пакетов.
Иными словами, нужно стремиться к тому чтобы все файлы на сервере обладали принадлежностью к каким-либо пакетам.

Неорганизованный pip/pear/gem приводит к бардаку в системе и поломкам в самых неожиданных местах.
virtualenv? Вполне нормальный способ, и там нифига не «dev-пакеты»
Ну да, почему бы и нет.
Можно использовать docker, virtualenv, катить бинари каким-нибудь chef'ом.

Но, позволю себе заметить, что правильная настройка всего этого — тема для отдельной статьи.
Deb пакеты — это инфраструктура с минимальными трудозатратами из коробки.
Именно то, что нужно для маленького, наколеночного сервиса.
Да господи. Поставьте Вы в virtualenv всё, что нужно, и до кучи pyinstaller. Соберите им хоть в один файл, его в deb пакет и разносите по серверам. И уже будет не столь важно, debian 7 или 8 на сервере: всё будет работать, и ничего лишнего на сервере.
И тогда мы вычеркиваем половину статьи (она и так получилась слишком объемной), потому что начинаем рассуждать про сборку пакетов и virtualenv.

virtualenv на самом деле лучшая практика.
Это вопрос еще. Если вы собираете venv на серверах с одной ОС а используете на других, с другим окружением — вы огребаете)

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

Другой разговор — если говорить про venv в контексте докероподобного образа (ну или, может, вы чрут захотите использовать). Но тогда и окружение вам при деплое все нужно будет собирать, а не только venv.

Иными словами, venv должен как то быть привязан к версии ОС.
если вы используете на dev, build и live разные ОС, разные версии, вообще разные окружения то огребаете в любом случае :)

никто не раскатывает venv без фиксированных зависимостей, а кто так делает, либо понимает, что он делает, либо сам себе злобный буратино.

и не надо мешать в одну кучу системные зависимости(те же deb, rpm, ...) и программные (pip, npm, ...), которые опираются на системные, у них разный жизненный цикл, цели и задачи.

ну а вообще не очень понятен контекст: мы говорим про небольшие наколеночные сервисы, в которых можно делать любые допущения, главное чтобы хоть как-то работало или же про более-менее нормальный продакшен, где множество заинтересованных сторон с своими хотелками, требованиями и ограничениями.

PS: за себя могу сказать, что я согласен с тем, что для python «virtualenv на самом деле лучшая практика», однако сейчас использую его в редких случаях, из-за его избыточности в текущих задачах.
А теперь представьте, что весь многокомпонентный сервис вам как-то нужно раскатывать на сервера. Как вы себе представляете деплой при помощи pip'a?
А debain-пакетах все сильно проще. Делайте свой пакет, указываете в Depends все необходимое — получаете сервис по кнопке.
не спорю, что deb-пакеты самый простой и быстрый способ, но в последнее время весь деплой на ansible, времени на написание плейбуков и ролей не сильно больше тратится
Я у себя вместо очереднего велосипеда просто поставил Whooey github.com/wooey/wooey и написал скриптов :)
Но, кажется, написать свой микросервис на Питоне занимает ровно столько времени, сколько нужно чтобы скачать чужой и запустить его :)
Каждый админ пишет свой веб сервис.
Я свой писал с flask, redirs, celery и angular.

Идея, кажется, витает в воздухе ;)
Ну парадигма называется — микросервисы (вот, например, пруф: www.infoq.com/articles/boot-microservices ).
Кажется сейчас очередной виток её развития.
gist.github.com/oxpa/1afb40770cafc0af0c38 просто оставлю это здесь, раз уж мы начали про flask.
Ещё есть пара интересных штук, но они написаны под воркеров и angular
Году в 2002 писал такое на perl без этих ваших jquery.
А это 2015 год и в наше время динозавры уже вымерли, а для того, чтобы не умереть с голоду, не обязательно охотится на мамонтов.
В итоге получился бэкдор, самый натуральный (ну или шелл, кому как больше нравится). Как-то вопросы безопасности решены?
Ну первая часть — она про знакомство с технологиями, вообще и в принципе.
Но спасибо за идею.
Может быть в следующих частях статьи я изображу какой-нибудь авторизующий декоратор на методы.

В принципе — ничто не мешает проставить пару кук в сервисе, поднять oauth, разместить сервис за nginx с basic http authorization/auth_request через какой-нибудь скрипт в xinetd.

Давайте выведем аргументы которые мы посылаем серверу — в ответе (кстати, с помощью функции print удобно выводить их прямо в консоль) этого самого сервера.


Не нужно так делать. Используйте logging.

import logging
log = logging.getLogger('modulename')

def main():
    log.debug('Hey! Main function started.')
    try:
        # do some stuff
        raise RuntimeError('Test')
    except (Exception) as e:
        log.error('Uncaught error occupied', exc_info=e)
        raise

if __name__ == '__main__':
    logging.basicConfig(level=logging.DEBUG)
    main()


Учитывая, что тесты Вы не пишите, в будущем, если вдруг внезапно что-то перестанет работать, будет легче найти ошибку.
Вы исходите из ложной в данном случае предпослыки что код написанный выше надо улучшить усложняя.
В данном случае — вы не правы.
Я, правда, знаю про logging. Я также знаю что код не идеален. Но, предположим, что код рассчитан на школьников и студентов, вообще не имеющих представления об веб разработке.

Предложите, пожалуйста, вариант без включения дополнительных модулей. Предложите упрощение кода без усложнения?
Не знаю, что может быть легче трех строк кода:

import logging
log = logging.getLogger('modulename')
logging.basicConfig(level=logging.DEBUG)


Дальше вместо print, использовать log:

log.debug("Message")


Пример выше всего лишь более подробный, и logging — находится в стандартной библиотеке python. Дополнительно устанавливать ничего не нужно.
Я считаю, что написать «log.debug('message')» не сложнее, чем написать print('message'), и этому нужно учить сразу в том числе школьников, и новичков. Вредные привычки, приобретенные во время обучения искореняются с большим трудом.

import flask
import logging
app_test = flask.Flask(__name__)
log = logging.getLogger(__name__)

@app_test.route("/ping")
def ping():
   return "pong"

@app_test.route("/add")
def add():
   log.debug(flask.request.args.to_dict())
   return str(flask.request.args)

@app_test.route("/remove")
def remove():
   log.debug(flask.request.args.to_dict())
   return str(flask.request.args)

if __name__ == "__main__":
   logging.basicConfig(level=logging.DEBUG)
   app_test.run(host='0.0.0.0')


Это существенное усложнение?
Теперь давайте еще поговорим что все в питоне это объект, а вот тут мы инициализируем класс :)
Это существенное усложнение?

Я думал поговорить про это во второй части.

Вы все говорите правильно, и предлагаете правильный код, спасибо.
Надеюсь что тот, кто доберётся до вашего комментария возмёт его на вооружение.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории