I am trying to create an object which is passed from form to form with some data got from the server modules.
This caches the data for a set ammount of time then requests the data again, reducing server calls.
However when running this code I get the following error
When calling
g = Groups(1,2)
g.groups
SuspensionError: Cannot call a function that blocks or suspends here
at property.py, line 20 column 8
This error does not happen if I remove the line calling the server.
And when the same line is run in the form init (Where g.groups
is) it runs fine
from time import time
import anvil.server
def merge_two_dicts(x, y):
x.update(y)
return x
def partial(fun, *part_args, **part_kwargs):
pk = part_kwargs
pa = part_args
def wrapper(*extra_args, **extra_kwargs):
args = list(pa)
args.extend(extra_args)
kwargs = merge_two_dicts(pk, extra_kwargs)
return fun(*args, **kwargs)
return wrapper
class APIException(Exception):
pass
class Data:
def getter(self, name):
if time() - self._last_update > Groups.update_time:
self._update()
self._last_update = time()
return getattr(self, "_" + name)
def setter(self, value, name):
self.set_multiple(**{name: value})
def set_multiple(self, **values):
if set(Groups.attributes) == values.keys():
self._last_update = time()
for k in values:
setattr(self, "_" + k, values[k])
def _update(self):
raise NotImplementedError("Must override _update")
def __init__(self, **kwargs):
self._last_update = 0
self.set_multiple(**kwargs)
class Groups(Data):
attributes = ["groups"]
update_time = 30
def _update(self):
resp = anvil.server.call("site_groups", method="GET", eventID=self.eventID, meal_date=self.date)
status = resp[0]
data = resp[1]
if status > 299:
raise APIException
self._groups = data
def __init__(self, eventID, date, **kwargs):
Data.__init__(self, **kwargs)
for a in Groups.attributes:
setattr(self, a, None)
self.eventID = eventID
self.date = date
for a in Groups.attributes:
setattr(Groups, a, property(partial(Groups.getter, name=a), partial(Groups.setter, name=a)))