python-dependency-injector icon indicating copy to clipboard operation
python-dependency-injector copied to clipboard

Calling provided methods prior to inject doesn't update the provided object

Open rkr87 opened this issue 2 years ago • 0 comments
trafficstars

I have the below container for API consumers;

class Consumers(DeclarativeContainer):
    steam_web_credentials: Dependency[ConfigSteamCredentials] = Dependency(
        ConfigSteamCredentials)
    steam_web_consumer: Singleton[SteamWebConsumer] = Singleton(SteamWebConsumer,
                                                                steam_web_credentials)
    steam_web_auth = steam_web_consumer.provided.authenticated.call()
    steam_web_token = steam_web_consumer.provided.authenticated.token # USING FOR DEBUG

The provided method steam_web_auth looks like this;

    def authenticated(self) -> bool:
        if not self.client and not self.secret:
            self._authenticated = True
        else:
            if not self._authenticated:
                self._authenticated = self._authenticate()
            if self._authenticated:
                if self.token:
                    self._inject_auth()
                    print(f"injected token: {self.token}")
                else:
                    raise self.TokenUnassigned
        return self._authenticated

Where self_authenticate() will attempt to receive an oAuth token and self._inject_auth() will inject that token into all future web requests.

I also have this container that provides methods from a local config file;

class Config(DeclarativeContainer):
    local_service: Singleton[LocalService] = Singleton(LocalService)
    config_repo: Singleton[ConfigRepo] = Singleton(ConfigRepo, local_service)
    get_steam_credentials = config_repo.provided.get_steam_credentials.call()
    reset_steam_credentials = config_repo.provided.reset_steam_credentials.call()

In my DI App file I have below;

class Application(DeclarativeContainer):
    config: Container[Config] = Container(Config)

    consumers: Container[Consumers] = Container(
        Consumers,
        steam_web_credentials=config.get_steam_credentials,
        igdb_credentials=config.get_igdb_credentials)

    while not consumers.steam_web_auth():
        config.reset_steam_credentials()

    print(consumers.steam_web_token) ## USING FOR DEBUG == "value of oAuth token"

    wiring_config: WiringConfiguration = WiringConfiguration(
        modules=['data.test']
    )

Basically, before I inject the consumer into objects that need it, I want to authenticate it and inject the relevant headers/parameters etc. This appears to work fine, during initial launch, I can see that the DI calls the relevant methods and populates relevant variables.

EG the print(consumers.steam_web_token) ## USING FOR DEBUG line in the Application class prints the token. However, when I then provide the steam_web_consumer object to my app, it's like the steps were never performed, IE steam_web_consumer.token == None;

@final
class Test:
    @inject
    def __init__(self, 
                 steam_web: SteamWebConsumer = Provide['steam_web_consumer']) \
            -> None:
        self._steam_web: SteamWebConsumer = steam_web
        print(self._steam_web.token) ## USING FOR DEBUG == None

I have no doubt this is something I'm doing wrong or misunderstanding but I'm at a loss as to how to fix this.

Any help would be greatly appreciated.

rkr87 avatar Mar 19 '23 10:03 rkr87