• Не удается отправить файл на ftp сервер, в чем может быть причина?

    neatsoft
    @neatsoft
    501 ошибка указывает на неправильную настройку файрвола - не отслеживаются и не открываются порты для корректной работы пассивного режима:
    https://interface31.ru/tech_it/2013/10/osobennosti...
  • Не удается отправить файл на ftp сервер, в чем может быть причина?

    neatsoft
    @neatsoft
    Дмитрий, да, учитывая что это винда, при открытии файла нужно указывать режим:
    f = open(filename, 'rb')

    А про бинарный режим сохранения писал в изначальном сообщении - вместо storlines нужно использовать storbinary:
    ftp.storbinary(f'STOR {filename}', f)
  • Не удается отправить файл на ftp сервер, в чем может быть причина?

    neatsoft
    @neatsoft
    Что выводит print(ftp.nlst()), если вставить этот вызов вместо ftp.storlines?
    Какие-нибудь файлы в этом каталоге уже есть?
  • Как разместить vue-ssr или nuxt приложение и laravel api на одном vps сервере/домене?

    neatsoft
    @neatsoft
    Nginx в режиме reverse proxy - отличный, проверенный временем инструмент, но он неприменим для роутинга запросов в Docker.

    Использование традиционных способов масштабирования приложений по ядрам (запуск нескольких экземпляров с помощью uwsgi, supervisor, php-fpm, и т.д.) противоречит одному из основополагающих принципов использования докера - "one process per container". Теперь это достигается изменением количества контейнеров.

    Предположим, приложение запускается на восьмиядерном процессоре, и нам нужно шестнадцать процессов, чтобы оптимально его загрузить. Значит docker-compose up нужно вызывать с параметром --scale my_app=16. В результате будет создано шестнадцать контейнеров, каждый из которых имеет уникальный IP адрес, причем назначаются эти адреса произвольно - пытаться вручную прописывать их в конфиге Nginx неразумно. Сам docker-compose балансировать запросы не умеет, соответственно параметр ports: HOST:CONTAINER использовать тоже не получится.

    Выходом из этой ситуации является reverse proxy с поддержкой service discovery, например, Traefik. В docker-compose.yml прописываются правила роутинга для каждого сервиса (домен или путь), и Traefik автоматически их подхватывает, обеспечивая роутинг и load balancing. При этом настраивается он ещё проще чем Nginx: вся конфигурация - буквально несколько строк.
  • Панель администратора?

    neatsoft
    @neatsoft
    И не стоит нарушать PEP 8: один отступ - это 4 пробела, а не 2
  • Как реализовать на сайте таблицу мер продуктов?

    neatsoft
    @neatsoft
    an543, уже писал про это выше:
    Есть ещё одна вещь, которую можно реализовать по разному - базовая единица измерения. В приведенной выше реализации поле foodstuff_unit в модели DishIngredient опционально: если единица измерения не выбрана (foodstuff_unit==null), то подразумеваются граммы. Вместо этого для каждого продукта при создании можно автоматически добавлять базовую единицу измерения в FoodstuffUnit и убрать поле foodstuff из DishIngredient, но оба решения имеют свои плюсы и минусы.
  • Как реализовать на сайте таблицу мер продуктов?

    neatsoft
    @neatsoft
    Ещё один довод в пользу отдельных единиц измерения для каждого продукта - никто не измеряет молоко чайными ложками, соль литрами, а сахар штуками. Отображать все возможные единицы - веселить пользователей, отвлекая от работы. Разделять продукты на классы и фильтровать список единиц измерения в зависимости от типа продукта - вносить дополнительную сложность без веской причины.
  • Как реализовать на сайте таблицу мер продуктов?

    neatsoft
    @neatsoft
    an543, Столовая ложка бывает с горкой (если продукт сыпучий) и без (если жидкий), как в этом случае сопоставить граммы, литры, и ложки? При этом многие компоненты измеряются штуками, для которых вообще не существует предопределённых способов конвертации в объём или вес. Некоторые продукты имеют вес брутто и нетто, например, бананы или грецкие орехи. Структура данных это всегда компромисс между идеалом и здравым смыслом. Даже незначительное переусложнение структуры данных может очень сильно увеличить сроки реализации проекта или сделать готовый продукт непонятным для конечного пользователя.
    В данном случае, если потребуется упрощение ввода данных, более разумным, с моей точки зрения, будет написать скрипт для начального заполнения таблиц, либо для автоматического добавления определенных единиц измерения при создании нового продукта, чем пытаться реализовать общие типы единиц измерения с автоматической конвертацией. Возможен и второй вариант: в Foodstuff можно добавить плотность продукта, сделать общие и специальные единицы измерения, но это будет работать не во всех случаях, следовательно будет неуниверсальным решением.
    Концепции, которые хорошо ложатся на структуры данных, стоит реализовывать в данных. Для всех остальных случаев есть код.
  • Как преобразовать datetime в django?

    neatsoft
    @neatsoft
    Артем Викторович, yw

    >>> hours, minutes, seconds = 4, 32, 1
    >>> f'{hours}:{minutes}:{seconds}'
    '4:32:1'
    >>> f'{hours:02}:{minutes:02}:{seconds:02}'
    '04:32:01'
  • Как реализовать на сайте таблицу мер продуктов?

    neatsoft
    @neatsoft
    an543, Таблица Unit не имеет смысла в отрыве от Foodstuff: один банан среднего размера весит 200 грамм (за вычетом кожуры - 150), киви - 80 грамм, а десяток яиц без скорлупы - от 320 до 680 в зависимости от категории (С0, С1, С2, С3). Единственный возможный плюс - такая таблица может немного облегчить интернационализацию, в остальном она будет только мешать.
  • Как реализовать на сайте таблицу мер продуктов?

    neatsoft
    @neatsoft
    an543, отдельную таблицу с названиями единиц измерения создать можно, но в таком решении есть два существенных минуса: 1. справочные таблицы делают ввод и редактирование данных менее удобным, 2. эта таблица довольно быстро перестанет выглядеть опрятно, т.к. помимо литров и стаканов в ней появятся "1 шт (~200 гр)", "ч.л. с горкой", и т.п. Если присмотреться внимательнее, между единицами измерения разных продуктов не так много общего.

    Есть ещё одна вещь, которую можно реализовать по разному - базовая единица измерения. В приведенной выше реализации поле foodstuff_unit в модели DishIngredient опционально: если единица измерения не выбрана (foodstuff_unit==null), то подразумеваются граммы. Вместо этого для каждого продукта при создании можно автоматически добавлять базовую единицу измерения в FoodstuffUnit и убрать поле foodstuff из DishIngredient, но оба решения имеют свои плюсы и минусы.
  • Как прочитать словарь из текстового файла?

    neatsoft
    @neatsoft
    blackbb, вместо print(repr(data)) можно делать с этими данными всё что заблагорассудится, в том числе сохранять в базу:

    country, __ = Country.objects.get_or_create(
        name=data['country'],
    )
    
    city, __ = City.objects.get_or_create(
        country_id=country.id,
        name=data['city'],
    )
  • Обладает ли преимуществами RAML перед SWAGGER (Open Api) в 2018 году?

    neatsoft
    @neatsoft
    Станислав Макаров, Это работает с примитивной кодогенерацией, но в реальной жизни встречаются существенно более сложные случаи, когда кодогенератор - это отдельный проект, зачастую написанный на другом языке, который формирует не только интерфейсы, но и сами методы. С помощью одной лишь документации такое сделать не получится.

    Waterfall, со всеми присущими ему подходами и инструментами, до сих пор активно используется в некоторых сферах, и там альтернатив ему нет. Но в массовом сегменте это прямой путь к коммерческому провалу из-за отсутствия гибкости и недостаточной динамичности.
  • Обладает ли преимуществами RAML перед SWAGGER (Open Api) в 2018 году?

    neatsoft
    @neatsoft
    Станислав Макаров, Есть, но зачем возить мебель в седане или людей в грузовике, если для каждой из этих задач есть свои инструменты? OpenAPI - это не только Swagger, это ещё и большое количество инструментов, которые значительно упрощают работу с ним. Большинство из них рассчитаны именно на bottom-up.

    RAML в 2018 - довольно рискованная инвестиция времени (т.к. непонятно жив ли он), а это главное что должно интересовать разработчика, который ответственно относится к своей жизни. По этой причине, например, многие отказываются от Trio в пользу asyncio, или выбирают Go вместо Rust.
  • Обладает ли преимуществами RAML перед SWAGGER (Open Api) в 2018 году?

    neatsoft
    @neatsoft
    Иван Шумов, Зависит от проекта и от квалификации.

    Документация обычно и так есть - спецификация проекта. И на начальном этапе лучше побольше времени уделить описанию бизнес задач и граничных условий, чтобы не обнаружить через несколько месяцев (или даже лет) что в текущем виде ни апи, ни документация больше никому не нужны, т.к. систему нужно полностью переделывать из-за какой-то маленькой, но очень важной детали (несколько реальных случаев из жизни - приходилось разгребать результаты "труда" других архитекторов и разработчиков).

    Спроектировать начисто - сложно, многие аспекты становятся очевидны лишь в процессе. Есть уникумы, которые уже успели зафейлить не один десяток проектов, и поэтому хорошо знают где "подстелить соломки", но это не относится к массовому рынку, т.к. сейчас колоссальный дефицит кадров.

    В реальной жизни на поддержание документации в актуальном состоянии всегда забивают, т.к. сделать это может только грамотный разработчик, что выливается немалые дополнительные расходы и снижение мотивации в коллективе. Код писать гораздо интереснее чем доки, т.к. постоянно узнаёшь что-то новое, не прикладывая к этому больших усилий. Поэтому от документирования все отлынивают.

    Что касается автоматизации, из описания код можно сгенерировать только один раз, а документацию из кода - хоть каждый день, и для этого не нужно прикладывать никаких усилий.

    При top-down подходе излишняя формализация создаёт дополнительную бюрократию, и увеличивает затраты времени на согласования. При bottom-up стабильность документации обеспечивается стабилизацией самого АПИ - ключевая функциональность покрывается тестами, и никакие изменения не могут попасть в прод, если они эту функциональность ломают.

    Единственное место для "наоборот" - это команды с очень опытным архитектором, который при проектировании АПИ заранее может предусмотреть все подводные камни, и очень неопытными бэкендерами, которые не в состоянии самостоятельно вникать в бизнес задачи и нести ответственность за свои решения.
  • Обладает ли преимуществами RAML перед SWAGGER (Open Api) в 2018 году?

    neatsoft
    @neatsoft
    btw, Апишки не обязательно писать, их можно генерировать. И уже на их основе создавать OpenAPI спецификации, которые фронты будут видеть в Swagger UI. Если Software Architect не брезгует написанием кода, то такой подход не только сэкономит время, но и очень сильно упростит сопровождение проекта, т.к. в нём будет меньше мест для типичных программерских ошибок. Некоторые эндпоинты всё-таки придётся создать вручную, но со значительной частью апи можно будет начать работать практически сразу, причём не с фейковыми данными, а с реальной бд.
  • Обладает ли преимуществами RAML перед SWAGGER (Open Api) в 2018 году?

    neatsoft
    @neatsoft
    Иван Николаевич, Согласен, top-down тоже имеет право на жизнь. Но в тех проектах, где он действительно нужен, обычно есть опытный Software Architect / API Designer, который и так прекрасно знает разницу между RAML и Swagger.

    Проектирование хороших API, которые потом не приходится переделывать для повышения производительности или обеспечения согласованности, это выдающийся навык, которым обладают единицы. Поэтому в большинстве случаев bottom-up это более жизнеспособная концепция.
  • Обладает ли преимуществами RAML перед SWAGGER (Open Api) в 2018 году?

    neatsoft
    @neatsoft
    spaceatmoon, Нужно не API на основе документации создавать, а автоматически генерировать документацию на основе кода. Именно для этого swagger и создан.