Domanda

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!

È stato utile?

Soluzione

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 TypeErrors 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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top