I am trying to build a REST web service using spyne. So far I have been able to use ComplexModel to represent my resources. Something very basic, like this (borrowed from the examples):
class Meta(ComplexModel):
version = Unicode
description = Unicode
class ExampleService(ServiceBase):
@srpc(_returns=Meta)
def get_meta():
m = Meta()
m.version="2.0"
m.description="Meta complex class example"
return m
application = Application([ExampleService],
tns='sur.factory.webservices',
in_protocol=HttpRpc(validator='soft'),
out_protocol=JsonDocument()
)
if __name__ == '__main__':
wsgi_app = WsgiApplication(application)
server = make_server('0.0.0.0', 8000, wsgi_app)
server.serve_forever()
To run I use curl -v "http://example.com:8000/get_meta" and I get what I expect.
But what if I would like to access some hierarchy of resources like http://example.com:8000/resourceA/get_meta ??
Thanks for your time!
Two options: Static and dynamic. Here's the static one:
from spyne.util.wsgi_wrapper import WsgiMounter
app1 = Application([SomeService, ...
app2 = Application([SomeOtherService, ...
wsgi_app = WsgiMounter({
'resourceA': app1,
'resourceB': app2,
})
This works today. Note that you can stack WsgiMounter
's.
As for the dynamic one, you should use HttpPattern(). I consider this still experimental as I don't like the implementation, but this works with 2.10.x, werkzeug, pyparsing<2 and WsgiApplication:
class ExampleService(ServiceBase):
@rpc(Unicode, _returns=Meta, _patterns=[HttpPattern("/<resource>/get_meta")])
def get_meta(ctx, resource):
m = Meta()
m.version = "2.0"
m.description="Meta complex class example with resource %s" % resource
return m
Don't forget to turn on validation and put some restrictions on the resource
type to prevent DoS attacks and throwing TypeError
s and whatnot. I'd do:
ResourceType = Unicode(24, min_len=3, nullable=False,
pattern="[a-zA-Z0-9]+", type_name="ResourceType")
Note that you can also match http verbs with HttpPattern. e.g.
HttpPattern("/<resource>/get_meta", verb='GET')
or
HttpPattern("/<resource>/get_meta", verb='(PUT|PATCH)')
Don't use host matching, as of 2.10, it's broken.
Also, as this bit of Spyne is marked as experimental, its api can change any time.
I hope this helps