"""Objects representing api tokens."""## (C) Pywikibot team, 2008-2023## Distributed under the terms of the MIT license.#from__future__importannotationsfromcollections.abcimportContainerfromtypingimportTYPE_CHECKING,Anyfrompywikibot.toolsimportdeprecated,issue_deprecation_warningifTYPE_CHECKING:frompywikibot.siteimportAPISite
[docs]classTokenWallet(Container):"""Container for tokens. You should not use this container class directly; use :attr:`APISite.tokens<pywikibot.site._apisite.APISite.tokens>` instead which gives access to the site's TokenWallet instance. """def__init__(self,site:APISite)->None:"""Initializer."""self.site:APISite=siteself._tokens:dict[str,str]={}self._currentuser:str|None=site.user()# guess the needed token in update_tokensself._last_token_key:str|None=Nonedef__getitem__(self,key:str)->str:"""Get token value for the given key."""ifself.site.user()isNoneandkey!='login':self.site.login()ifself.site.user()!=self._currentuser:self._currentuser=self.site.user()self.clear()ifnotself._tokens:self._tokens=self.site.get_tokens([])# Redirect old tokens which were used by outdated MediaWiki versions# but show a FutureWarning for this usage:# https://www.mediawiki.org/wiki/MediaWiki_1.37/Deprecation_of_legacy_API_token_parametersifkeyin{'edit','delete','protect','move','block','unblock','email','import','options'}:issue_deprecation_warning(f'Token {key!r}',"'csrf'",since='8.0.0')key='csrf'try:token=self._tokens[key]exceptKeyError:raiseKeyError(f'Invalid token {key!r} for user {self._currentuser!r} on 'f'{self.site} wiki.')fromNoneself._last_token_key=keyreturntokendef__contains__(self,key)->bool:"""Return True if the token name is cached for the current user."""try:self[key]exceptKeyError:returnFalsereturnTruedef__str__(self)->str:"""Return a str representation of the internal tokens dictionary."""returnstr(self._tokens)def__repr__(self)->str:"""Return a representation of the TokenWallet. >>> import pywikibot >>> site = pywikibot.Site('wikipedia:test') >>> repr(site.tokens) "TokenWallet(pywikibot.Site('wikipedia:test'))" .. versionchanged:: 8.0 Provide a string which looks like a valid Python expression. """user=f', user={self._currentuser!r}'ifself._currentuserelse''return(f'{type(self).__name__}'f'(pywikibot.Site({self.site.sitename!r}{user}))')
[docs]defclear(self):"""Clear the self._tokens cache. Tokens are reloaded when needed. .. versionadded:: 8.0 """self._tokens.clear()
[docs]defupdate_tokens(self,tokens:list[str])->list[str]:"""Return a list of new tokens for a given list of tokens. This method can be used if a token is outdated and has to be renewed but the token type is unknown and we only have the old token. It first gets the token names from all given tokens, clears the cache and returns fresh new tokens of the found types. **Usage:** >>> import pywikibot >>> site = pywikibot.Site() >>> tokens = [site.tokens['csrf']] # doctest: +SKIP >>> new_tokens = site.tokens.update_tokens(tokens) # doctest: +SKIP .. code-block:: Python :caption: An example for replacing request token parameters r._params['token'] = r.site.tokens.update_tokens(r._params['token']) .. versionadded:: 8.0 """# find the token typestypes=[keyforkey,valueinself._tokens.items()fortokenintokensifvalue==token]or[self._last_token_key]self.clear()# clear the cachereturn[self[token_type]fortoken_typeintypes]
[docs]@deprecated('clear()',since='8.0.0')defload_tokens(self,*args:Any,**kwargs:Any)->None:"""Clear cache to lazy load tokens when needed. .. deprecated:: 8.0 Use :meth:`clear` instead. .. versionchanged:: 8.0 Clear the cache instead of loading tokens. All parameters are ignored. """self.clear()