So a bit of setup. In web2py you can simply decorate a controller function to expose it as a json service, like so:
def call():
return service()
@service.json
def do_something():
return "blah"
Then you can call it (like in an ajax request) like "call/json/do_something" and you will get "blah", formatted in json.
You can do this in a class in a module, like so:
from gluon.tools import Service
service = Service()
class SomeClass(object):
@staticmethod
@service.json
def do_something():
return "blah"
So in your controller you can do this:
import mymodule
def m_call():
return mymodule.service()
def call():
return service()
@service.json
def do_another_thing():
return "blee"
And then in a view, I can call either service, such as "m_call/json/do_something" or "call/json/do_another_thing". This works, BUT I have multiple ways to call json services now. There is an upside to this, that the module services are scoped differently, but at least in certain circumstances I want to be able to do something like this in my controller:
import mymodule
def call():
# This obviously does NOT work, but shows what I WANT to do
service.merge_with(mymodule.service)
return service()
The result is that ALL of my services (or whichever ones I want) are exposed in a single service object, and can be called with the same syntax, regardless where the function is location in my application. Is there a way to do this?
The decorator simply adds the function to a dictionary, which is stored in an attribute of the Service
object. So, in theory you should just be able to merge the dictionary of the module's service object with the dictionary of the service object defined in the model file. I haven't tried it, but something like this might work:
import mymodule
def call():
service.json_procedures.update(mymodule.service.json_procedures)
return service()
You could write a function that takes a set of service objects and merges them all.
Note, the attribute name json_procedures
is an internal implementation detail, not part of the public API, so this isn't guaranteed to remain backward compatible.
A similar approach should work with the other types of services (via service.xml_procedures
, etc.).