FWIW Did a few tweaks … change code to return a dictionary and built a decorator to JSON encode any return values from a function.
Decorator
def jsonify(logger):
def decorator(fn):
@functools.wraps(fn)
def wrapper(*args, **kwargs):
try:
args_repr = [repr(a) for a in args]
kwargs_repr = ["{}={}".format(k, v) for k, v in kwargs.items()]
signature = ", ".join(args_repr + kwargs_repr)
logger.info('CALLING ' + fn.__name__ + ' ' + signature)
return json.dumps(fn(*args, **kwargs))
except Exception:
logger.exception('call failed')
raise
finally:
logger.info('EXITING ' + fn.__name__)
return wrapper
return decorator
Note, this decorator also add’s some logging, so every function call will get log statements similar to … for ENTRY / EXIT style logging.
2022-07-22 18:42:17,198 root INFO : CALLING boolean_test
2022-07-22 18:42:17,198 root INFO : EXITING boolean_test
New Test Code …
@anvil.server.http_endpoint("/boolean_test/", methods=["POST"])
@jsonify(logger)
def api_boolean_test(**args):
return boolean_test(**args)
@anvil.server.callable
def boolean_test(**args):
return {"test": True}
Function boolean_test
can be called from client code or uplink and return a dict
aligned to pythonic expectations.
But if you want to use that function in the API, I added a wrapper function to associate the API endpoint (/boolean_test/
) and used decorator to json.dumps()
the results.
No technical reason for the breaking the callable
and http_endpoint
into two different functions, but stylistically I am leaning that way.
From the sounds of it, @adorjana.arpad already did this (json encode his dictionarys to and returns str
) across the board for his app …
Anyhoo, seems like there is a bug with the JSON-Encoder in the guts of anvil.server.HttpResponse
…
From the text in the docs I would expect the simple dictionary {"test" : True}
to be encoded auto-magically.
oh and re-running the new test code from command line with curl
curl -X POST {{hostname}}/_/api/boolean_test/
{"test": true}%
so json.dumps
/ jsonify
the dict avoids this error.
@patricia @meredydd Maybe you can clarify. Should anvil.server.HttpResponse
body
attribute auto-magically json-encode a dict
?