ets-labs / python-dependency-injector

Dependency injection framework for Python
https://python-dependency-injector.ets-labs.org/
BSD 3-Clause "New" or "Revised" License
3.89k stars 304 forks source link

Compatibility Issue with Pydantic 2 #726

Open Pentusha opened 1 year ago

Pentusha commented 1 year ago

The major version of Pydantic was recently released and lost backward compatibility. In particular, the .from_pydantic method stopped working for providers.Configuration due to the fact that the BaseSettings class now needs to be imported from a new package called pydantic-settings.

[tool.poetry.dependencies]
python = "^3.11"
pydantic = "^2.0.3"
pydantic-settings = "^2.0.2"
Traceback (most recent call last):
  File "<frozen runpy>", line 189, in _run_module_as_main
  File "<frozen runpy>", line 112, in _get_module_details
  File "/home/pentusha/projects/kyt.service-template/app/__init__.py", line 4, in <module>
    from app.core.containers import app_container
  File "/home/pentusha/projects/kyt.service-template/app/core/containers.py", line 80, in <module>
    app_container = AppContainer()
                    ^^^^^^^^^^^^^^
  File "src/dependency_injector/containers.pyx", line 742, in dependency_injector.containers.DeclarativeContainer.__new__
  File "src/dependency_injector/containers.pyx", line 393, in dependency_injector.containers.DynamicContainer.load_config
  File "src/dependency_injector/providers.pyx", line 2106, in dependency_injector.providers.Configuration.load
  File "src/dependency_injector/providers.pyx", line 2381, in dependency_injector.providers.Configuration.from_pydantic
  File "/home/pentusha/.cache/pypoetry/virtualenvs/kyt-service-template-cl7ERtKI-py3.11/lib/python3.11/site-packages/pydantic/__init__.py", line 207, in __getattr__
    return _getattr_migration(attr_name)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/pentusha/.cache/pypoetry/virtualenvs/kyt-service-template-cl7ERtKI-py3.11/lib/python3.11/site-packages/pydantic/_migration.py", line 288, in wrapper
    raise PydanticImportError(
pydantic.errors.PydanticImportError: `BaseSettings` has been moved to the `pydantic-settings` package. See https://docs.pydantic.dev/2.0.3/migration/#basesettings-has-moved-to-pydantic-settings for more details.
Pentusha commented 1 year ago

If anyone is interested in a workaround with monkeypatch:

import pydantic
from pydantic_settings import BaseSettings

pydantic.BaseSettings = BaseSettings

class AppContainer(containers.DeclarativeContainer):
    config = providers.Configuration(strict=True)
    env = providers.Configuration(strict=True, pydantic_settings=[env_secrets])
    ...
ZipFile commented 1 year ago

You do not really need to monkeypatch anything:

-container.config.from_pydantic(settings)
+container.config.from_dict(settings.model_dump())

from_pydantic did essentially the same:

https://github.com/ets-labs/python-dependency-injector/blob/cc2304e46e054ae08dc12995428759fbfb51af10/src/dependency_injector/providers.pyx#L1818

akalex commented 1 year ago

Hey @rmk135, Any chance that this issue will be considered soon? Many thanks for considering this request.

abdalazizrashid commented 8 months ago

Is this package maintained?

Pentusha commented 8 months ago

@abdalazizrashid seems like no. You can switch to my fork, but only python3.12 compatibility was introduces compared to original repo.