python-dependency-injector
python-dependency-injector copied to clipboard
Unable to initialize instance that are picklable in the container
trafficstars
Getting the following error while initializing the container that contains instances that cannot be pickled. Is there a requirement that all the instances created within the container should be picklable?
Version used: 4.41.0
class DependencyContainer(containers.DeclarativeContainer):
metric_flow_client = providers.Singleton(
MetricFlowClient,
sql_client=SnowflakeSqlClient.from_config(mf_snowflake_config)
)
if __name__ == "__main__":
container = DependencyContainer(). <---- Fails here
container.init_resources()
container.wire(modules=[__name__])
Error log:
Traceback (most recent call last):
File "/Users/arunkumar/Projects/unified-metrics-platform/consumption_grpc/grpc_server.py", line 79, in <module>
container = DependencyContainer()
File "src/dependency_injector/containers.pyx", line 730, in dependency_injector.containers.DeclarativeContainer.__new__
File "src/dependency_injector/providers.pyx", line 4913, in dependency_injector.providers.deepcopy
File "src/dependency_injector/providers.pyx", line 4920, in dependency_injector.providers.deepcopy
File "/Users/arunkumar/.pyenv/versions/3.9.10/lib/python3.9/copy.py", line 146, in deepcopy
y = copier(x, memo)
File "/Users/arunkumar/.pyenv/versions/3.9.10/lib/python3.9/copy.py", line 230, in _deepcopy_dict
y[deepcopy(key, memo)] = deepcopy(value, memo)
File "/Users/arunkumar/.pyenv/versions/3.9.10/lib/python3.9/copy.py", line 153, in deepcopy
y = copier(memo)
File "src/dependency_injector/providers.pyx", line 2835, in dependency_injector.providers.BaseSingleton.__deepcopy__
File "src/dependency_injector/providers.pyx", line 4920, in dependency_injector.providers.deepcopy
File "/Users/arunkumar/.pyenv/versions/3.9.10/lib/python3.9/copy.py", line 146, in deepcopy
y = copier(x, memo)
File "/Users/arunkumar/.pyenv/versions/3.9.10/lib/python3.9/copy.py", line 230, in _deepcopy_dict
y[deepcopy(key, memo)] = deepcopy(value, memo)
File "/Users/arunkumar/.pyenv/versions/3.9.10/lib/python3.9/copy.py", line 172, in deepcopy
y = _reconstruct(x, memo, *rv)
File "/Users/arunkumar/.pyenv/versions/3.9.10/lib/python3.9/copy.py", line 270, in _reconstruct
state = deepcopy(state, memo)
File "/Users/arunkumar/.pyenv/versions/3.9.10/lib/python3.9/copy.py", line 146, in deepcopy
y = copier(x, memo)
File "/Users/arunkumar/.pyenv/versions/3.9.10/lib/python3.9/copy.py", line 230, in _deepcopy_dict
y[deepcopy(key, memo)] = deepcopy(value, memo)
File "/Users/arunkumar/.pyenv/versions/3.9.10/lib/python3.9/copy.py", line 161, in deepcopy
rv = reductor(4)
TypeError: cannot pickle '_thread.lock' object
Thanks for the help!
I've had the same problem, but with pymongo's Collection class. Ended up using providers.Callable and wrapping the object creation in a function, as they are picklable:
from dependency_injector import containers, providers
from pymongo.collection import Collection
MONGO_DATABASE = ...
COLLECTION_NAME = ...
class FooRepository:
pass
def _create_collection():
return Collection(
database=MONGO_DATABASE,
name=COLLECTION_NAME,
)
class FooContainer(containers.DeclarativeContainer):
foo_repository = providers.Factory(
FooRepository,
collection=providers.Callable(_create_collection),
)
It's not an ideal solution, but I hope it helps!