-
Notifications
You must be signed in to change notification settings - Fork 0
Description
The functions case
Simply put, we want to be able, given a list funcs of callables, be able to
w_funcs = http2py(py2http(funcs))
assert w_funcs == funcs get another list w_funcs of callables that are equivalent to the original funcs list.
The difference being that the functions of func_ are actually calling a web-service that itself calls the original functions of funcs.
Equivalent in what sense?
Well, to be defined, and possibly configured. But ideally we'd like to get as close to possible to a state where a user of the functions difference between using funcs or w_funcs (besides perhaps speed). This means of course, same inputs for the same outputs, but also same signature and input/output types.
So of course the "simply put" code above is just for illustration. In reality,
The first line will look more like:
web_service = py2http.mk_web_service(funcs, **ws_configs)
specs = web_service.openapi_specs
w_funcs = mk_request_funcs.from_openapi_specs(specs, **py_configs)
# equivalence tests ############################################
inputs_for_func = ... # a map from functions of func to an [(args, kwargs),...] list of valid inputs
with run_server(web_service, wait_before_entering=2):
for f, ff in zip(funcs, w_funcs):
assert signature(f) == signature(ff)
for args, kwargs in inputs_for_func[f]:
f_output = f(*args, **kwargs)
ff_output = ff(*args, **kwargs)
assert f_output == ff_outputThe general case
Now let's look at the general case. That is;
w_obj= http2py(py2http(obj))
assert w_obj == obj It's the same as above except we have obj instead of funcs. obj can be any python object.
Again, what needs to be defined here is what the equivalence (not "equality") == means?
What it means will depend on what we need it to mean.
We have more than that though: We know that what ever it means, the only thing that really matters, pragmatically, is behavior, and the behavior of a python object is completely defined by its methods (yes -- even data only shares its contents via methods (think of __iter__, __getitem__, etc.).
So we're back to needing equivalence over functions, which is why we started with that.
Still, let's make our general case test a bit more fleshed out.
w_obj= http2py(
py2http(obj, py2http_configs),
http2py_configs
)
assert are_equivalent(w_obj, obj)Here, py2http_configs could contain information like what methods of the object we actually want to expose (and how, under what name, etc.), http2py_configs could contain particulars of how we need to wrap the py2http "http service" object to get a python object. Finally, are_equivalent can be defined structurally, or simply running some methods on some data, and checking if the datas returned by the methods are equal (or, really... equivalent in some sense, yet again).
One problem that needs to be kept in mind is the fact that during the py -> http -> py loop we have a py_data -> json_data -> py_data loop, so codecs will need to be defined. See py2json.
Also strongly related to this is the Mapping python collections builtin methods to REST API patterns discussion.