pythonhttpcurlgetspyne

Spyne - GET with multiple paths instead of parameters for the query


I'm trying to create a service to stream some files to clients from the server. However, instead of a URL like this:

$ curl http://localhost:8000/get_file?path=file_name

the client requests the file like this:

$ curl http://localhost:8000/get_file/file_name

Is this possible in Spyne?

Looking at file_soap_http, I wrote the server as such:

# server.py
from spyne import (
    Service, rpc, Application,
    String,
    ByteArray,
)
from spyne.protocol.http import HttpRpc
from spyne.protocol.soap import Soap11
from spyne.server.wsgi import WsgiApplication
from wsgiref.simple_server import make_server

class FileService(Service):
    @rpc(String, _returns=ByteArray)
    def get_file(ctx, file_name):
        print(file_name)


application = Application(
    [FileService],
    'FileService',
    in_protocol=HttpRpc(),
    out_protocol=Soap11(),
)

wsgi_application = WsgiApplication(application)

if __name__ == '__main__':
    server = make_server('0.0.0.0', 8000, wsgi_application)
    server.serve_forever()

This works well with URLs like /get_file?path=file_name, but for URLs like /get_file/file_name, it gives Requested resource not found error:

<soap11env:Envelope xmlns:soap11env="http://schemas.xmlsoap.org/soap/envelope/">
  <soap11env:Body>
    <soap11env:Fault>
      <faultcode>soap11env:Client.ResourceNotFound</faultcode>
      <faultstring>Requested resource '{FileService}file_name' not found</faultstring>
      <faultactor></faultactor>
    </soap11env:Fault>
  </soap11env:Body>
</soap11env:Envelope>

I cannot change the fact that the client requests like this. How can I achieve this?


Solution

  • This is doable with HttpPattern.

    First have a look at this:

    https://github.com/arskom/spyne/blob/35fa93f1ac34f868b9d86c639b6e7687c1842115/examples/multiple_protocols/server.py

    Once you run the daemon, go to:

    Or:

    etc.

    In similar vein, here's how your code should look:

    class FileService(Service):
        @rpc(String, _returns=ByteArray,
            _patterns=[HttpPattern('/get_file/<file_name>')])
        def get_file(ctx, file_name):
            print(file_name)