FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Cache result objects... · python-webuntis/python-webuntis@4e40d14 · GitHub

Repository navigation

Commit 4e40d14

Browse files
committed
Cache result objects...
...instead of plain JSONRPC requests. I used to do this at the beginning. I probably had a reason why i reverted it. Whatever.
1 parent 98d424e commit 4e40d14

2 files changed

Lines changed: 48 additions & 44 deletions

File tree

‎webuntis/session.py‎

Lines changed: 45 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -155,9 +155,6 @@ class JSONRPCSession(object):
155155
:py:class:`webuntis.utils.option_utils` for more information.
156156
'''
157157

158-
_cache = None
159-
'''Contains the caching dictionary for requests.'''
160-
161158
def __init__(self, **kwargs):
162159
# The OptionStore is an extended dictionary, associating validators
163160
# and other helper methods with each key
@@ -169,16 +166,9 @@ def __init__(self, **kwargs):
169166
'username': None,
170167
'password': None,
171168
'jsessionid': None,
172-
'cachelen': 20, # Not implemented in LruDict
173169
'login_repeat': 0
174170
}
175171
options.update(kwargs)
176-
177-
if options['cachelen'] > 0:
178-
self._cache = utils.LruDict(maxlen=options['cachelen'])
179-
180-
del options['cachelen']
181-
182172
self.options.update(options)
183173

184174
def __enter__(self):
@@ -205,7 +195,7 @@ def throw_errors():
205195

206196
try:
207197
# Send a JSON-RPC 'logout' method without parameters to log out
208-
self._make_request('logout')
198+
self._request('logout')
209199
except errors.NotLoggedInError:
210200
throw_errors()
211201

@@ -237,7 +227,7 @@ def login(self):
237227
self.options['username'] +
238228
' Password: ' +
239229
self.options['password'])
240-
res = self._make_request('authenticate', {
230+
res = self._request('authenticate', {
241231
'user': self.options['username'],
242232
'password': self.options['password'],
243233
'client': self.options['useragent']
@@ -255,30 +245,7 @@ def login(self):
255245

256246
return self
257247

258-
def _make_cache_key(self, method, params):
259-
'''A helper method for _request that generates a hashable object out of
260-
a string and a dictionary.
261-
262-
It doesn't use ``hash()`` or similar methods because it's neat that the
263-
keys are human-readable and enable us to trace back the origin of the
264-
key. Python does that anyway under the hood when using it as a
265-
dictionary key.
266-
'''
267-
268-
return (method, frozenset((params or {}).items()))
269-
270-
def _request(self, method, params=None):
271-
'''A wrapper for :py:class:`JSONRPCRequest` using the LRU Cache'''
272-
273-
if self._cache is None:
274-
return self._make_request(method, params)
275-
else:
276-
key = self._make_cache_key(method, params)
277-
if key not in self._cache:
278-
self._cache[key] = self._make_request(method, params, use_login_repeat=True)
279-
return self._cache[key]
280-
281-
def _make_request(self, method, params=None, use_login_repeat=None):
248+
def _request(self, method, params=None, use_login_repeat=None):
282249
if use_login_repeat is None:
283250
use_login_repeat = (method not in ('logout', 'authenticate'))
284251
attempts_left = self.options['login_repeat'] if use_login_repeat else 0
@@ -305,16 +272,53 @@ class Session(JSONRPCSession):
305272
'''The origin of everything you want to do with the WebUntis API. Can be
306273
used as a context-handler.'''
307274

275+
_cache = None
276+
'''Contains the caching dictionary for requests.'''
277+
278+
def __init__(self, **options):
279+
try:
280+
cachelen = options['cachelen']
281+
del options['cachelen']
282+
except KeyError:
283+
cachelen = 20
284+
285+
if cachelen > 0:
286+
self._cache = utils.LruDict(maxlen=cachelen)
287+
288+
JSONRPCSession.__init__(self, **options)
289+
290+
291+
def _make_cache_key(self, method, kwargs):
292+
'''A helper method that generates a hashable object out of a string and
293+
a dictionary.
294+
295+
It doesn't use ``hash()`` or similar methods because it's neat that the
296+
keys are human-readable and enable us to trace back the origin of the
297+
key. Python does that anyway under the hood when using it as a
298+
dictionary key.
299+
'''
300+
301+
return (method, frozenset((kwargs or {}).items()))
302+
308303
def __getattr__(self, name):
309304
'''Returns a callable which creates an instance (or reuses an old one)
310305
of the appropriate object-list class
311306
'''
312-
def get_result_object(**kwargs):
313-
obj = objects.result_objects[name](session=self, kwargs=kwargs)
314-
obj.store_data()
315-
return obj
307+
def result_object_wrapper(**kwargs):
308+
key = self._make_cache_key(name, kwargs)
309+
def get_result_object():
310+
obj = objects.result_objects[name](session=self, kwargs=kwargs)
311+
obj.store_data()
312+
return obj
313+
314+
if self._cache is None:
315+
return get_result_object()
316+
317+
if key not in self._cache:
318+
self._cache[key] = get_result_object()
319+
return self._cache[key]
316320

317321
if name in objects.result_objects:
318-
return get_result_object
322+
return result_object_wrapper
319323
else:
320324
raise AttributeError(name)

‎webuntis/tests/offline.py‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -349,18 +349,18 @@ def test_requestcaching(self):
349349
open(self.data_path + '/getklassen_mock.json')
350350
)
351351

352-
def result_mock(s, method, params, use_login_repeat):
352+
def result_mock(s, method, params=None, use_login_repeat=None):
353353
self.assertEqual(method, 'getKlassen')
354354
return jsonstr
355355

356356
with mock.patch(
357-
'webuntis.session.Session._make_request',
357+
'webuntis.session.Session._request',
358358
new=result_mock
359359
):
360360
self.session.klassen()
361361

362362
with mock.patch(
363-
'webuntis.session.Session._make_request',
363+
'webuntis.session.Session._request',
364364
side_effect=Exception('CHUCK TESTA')
365365
):
366366
self.session.klassen()

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL