Esri / arcgis-python-api

Documentation and samples for ArcGIS API for Python
https://developers.arcgis.com/python/
Apache License 2.0
1.89k stars 1.1k forks source link

Expired tokens don't refresh for unfederated server connections #1558

Open spiskulaos opened 1 year ago

spiskulaos commented 1 year ago

Describe the bug I query an unfederated ArcGIS Server 11.1 logs for errors in a long running process every few minutes. I noticed that if the querying happens after 1 hour / 6 minutes, internally an error happens which is caused by the token expiring / not being refreshed

To Reproduce Steps to reproduce the behavior:

  gis_server = Server(url="https://someurl/server/admin", username="adminuser", password="adminpass")

  # some long running repeated logic
  # monitor logs for errors every few minutes

  logs = gis_server.logs.query(
      end_time=end_time,
      level='SEVERE',
      server="SERVER"
  )

error:

After manually editing / logging the payloads returned inside of 'query' method I saw the following coming back from ArcGIS Server 11.1. On the surface it threw just this: File "C:\Program Files\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\site-packages\arcgis\gis\server\admin\_logs.py", line 292, in query has_more = logs["hasMore"] KeyError: 'hasMore'

After manually fiddling with above I was able to confirm that what is returned from the log query request from server is actually this (after 1 hour if this running OK! )

{'status': 'error', 'messages': ['Token Expired.'], 'code': 498}

Expected behavior If a token expires, the internals of the module should handle refreshing it. In particular I guess ? the issue is in

class EsriGenTokenAuth(AuthBase, SupportMultiAuth):
...
...    
   @cached(cache=TTLCache(maxsize=255, ttl=60))
    def token(self, server_url=None) -> str:
        if self._token:
            if (_dt.datetime.now() - _dt.timedelta(minutes=5)) >= self.expiration: # wrong condition, should be '+' instead ?
                self._token = None   <---- HERE ?
            return self._token          <---- HERE ? Should it not run a refresh instead ?
        elif self.username and self.password:
            return self._init_token_auth_handshake()
        elif self._portal_auth:
            return self._init_token_auth_handshake(server_url)

        return None

in this method, which does nothing if token is about to expire ?

Platform (please complete the following information):

spiskulaos commented 1 year ago

This is also true for Python API Version 2.1.0.2