All streams
Search
Write a publication
Pull to refresh
52
0
Pastukhov Nikita @Propan671

Python, Opensource enthusiast, FastStream creator

Send message

Неплохо, есть какие-либо планы по поддержки AsyncAPI?

Опа, в таком мы участвуем

Как в итоге ваши эксперименты с FastStream?)

Если ты под "доменными объектами" имеешь в виду модельки алхимии, то все так и есть, как ты описал.

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

Ну, я в принципе против того, чтобы у нас был глобальный объект `from app.settings import settings`, который можно импортнуть в любом месте кода - потом очень сложно следить, какое поле конфига где используется.

Запутанные конфиги с алиасами тоже как будто не упрошают восприятие кода. Если же юзать только один алиас для всего приложения целиком - то никакой проблемы не вижу

Например, вот тот же конфиг, но без лишних зависимостей

class ServiceSettings(BaseModel):
    service_name: str = "micro-service",
    service_description: str = "Micro service description"

    database_url: str = "your-database-url"
    database_read_timeout: int = 5

    redis_url: str = "your-redis-url"

    ...


settings = ServiceSettings(**os.environ)

У нас этот «паттерн» работает хорошо. Ты всегда знаешь, что в project_name лежит settings.py из которого ты достаешь глобальный объект с настройками, которые могут потребляться из любого окружения. Чем это хорошо:

— унифицировано

— наглядно

— просто

И вот эти все плюсы достижимы и без pydantic_settings, вот и все

Отлично, тогда снова возникает вопрос, какую пользу несет pydantic_settings[dotenv], если можно обойтись просто без этих двух зависимостей?

Не очень понял использование репозиториев AdvancedAlchemy

class PostRepository(SQLAlchemyAsyncRepository[Post]):
    """Repository for managing blog posts."""
    model_type = Post

    # уже реализовано в родительском классе репозитория
    async def add(...)
    async def add_many(...)
    async def list(...)
    async def update(...)
    async def delete(...)
    ...

Репозиторий должен возрващать доменные объекты приложения, полностью инкапсулируя модели алхимии внутри себя. Если я не путаю, AdvancedAlchemy репозиторий отдает в качестве ответов модели алхимии.

Если вы делаете свои надстройки над SQLAlchemyAsyncRepository, то тема с заворачиванием ее результата в доменные объекты не раскрыта. Опять же - там очень примитивная логика внутри. Если мы наследуемся от этих generic репозиториев, то какую пользу мы вообще получаем? Не проще реализовать репу с 0?

Пример с глобальным объектом settings, который еще и сам читает переменные окружения выглядит ну уж слишком сомнительно в вакууме

class ServiceSettings(pydantic_settings.BaseSettings):
    service_name: str = "micro-service",
    service_description: str = "Micro service description"

    database_url: str = "your-database-url"
    database_read_timeout: int = 5

    redis_url: str = "your-redis-url"

    ...

    # используется, чтобы загружать переменные из файла .env
    model_config = pydantic_settings.SettingsConfigDict(
        env_file=".env",
        env_file_encoding="utf-8",
        populate_by_name=True,
    )

settings = ServiceSettings()

Как вы в реальных проектах переключаете .env файлы под разные окружения? Как настраиваете окружение на проде, где .env файла просто нет (или у вас есть)?

Из моей практики pydantic_settings вообще никаких плюсов не дает - можно вполне обойтись pydantic.BaseModel, если нужна валидация конфига, либо обычным dataclass, если валидация не нужна

Какой-то треш... Автор не понимает ни концепции ООП, ни ФП, зато понимает TypeScript и ловко владеет всеми возможными способами прострелить себе колени

Нет, dishka inject - это декоратор под конкретный фреймворк и работает только в контроллере. Во всех остальных частях кода вам остается таскать контейнер явным образом и делать "container.get(T)" для получения зависимостей. Или писать свой inject-декоратор. Однако, это не рекомендуется делать, о чем я в статье вскольз предупреждаю.

Никто не планирует сроки поддержки библиотеки. Поэтому и нужно "сообщество" и круг мейнтейнеров, а не один человек. Bus factor никто не отменял. В жзни всякое может случиться и мейнтейнер может пропасть.
Яркие примеры - rocketry, faust. Но тот же Faust подхватило "сообщество", сделало форк и развивает дальше.
В этом у dishka тоже есть плюс, т.к. он входит в небольшую, но все-таки организацию энтузиастов, над проектом работает сразу несколько вовлеченных контрибуторов, и флаг есть кому подхватить

Согласен, тут имеет место быть небольшое смешение понятий. Для меня DI неразрывен от DIP, т.к. без него он приносит только половину пользы. Вторую половину я и хотел показать в статье.

Ну, то, что он мой - не значит, что он самый-самый). FastDepends - это буквально копия API FastAPI и он грешит теми же проблемами в качестве DI

Но он решает несколько другую проблему, нежели просто DI и нужен он мне именно в таком виде. Все-таки в качестве чистого IoC контейнера dishka значительно лучше.

Используйте запуск через uvicorn или любой другой ASGI сервер вместо FastAPI CLI

Ну ничего себе, действительно ожил. Однако, 1 коммит раз в месяц - это не прям "активное развитие". На самом деле, я не против Dependency Injector, просто он очень сильно перегружен, реализация на глобалах и вроде как не thread-safe

У меня уже глаз дергается от сочетания FastAPI + Celery, но тут он вполне уместен. Отличная работа! Btw, не пробовали сочетание FastAPI + FastStream - интересны ваши мысли на этот счет

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Date of birth
Registered
Activity