Return binary and parametric data from bottle web service

842 Views Asked by At

I am trying to write a web service that performs some data processing. The requests contain a data vector as a binary file, and meta-data and processing parameters as form data. An example using python with requests:

import numpy as np
import requests

url = 'http://localhost:8080/pp'
payload = {'param_a': 4, 'param_b': -2.1}
file = {'binary_data': ('file_name.bin', bytes(np.random.randn(1000))}

r = requests.post(url, data=payload, files=file)

Now on the service side, I have:

import bottle
import numpy as np

@bottle.post('/pp')
def pp():

    file_path = '/home/generic_user/howhaveyou.bin'
    return_file_path = '/home/generic_user/finethanks.bin'

    bin_file = bottle.request.files.get('binary_data')
    bin_file.save(file_path, overwrite=True)
    param_a = float(bottle.request.forms.get('param_a')
    param_b = float(bottle.request.forms.get('param_b')

    data_vector = np.fromfile(file_path)
    processed_data_vector = (data_vector-param_a)*param_b
    processed_data_mean = np.mean(processed_data_vector)
    processed_data_samples = len(processed_data_vector)

    return_metrics = {'mean': processed_data_mean, 
                      'n_of_samples': processed_data_samples}
    with open(return_file_path, 'wb') as return_file:
        return_file.write(bytes(processed_data_vector))

    return return_metrics, bottle.static_file(return_file_path, '/')

which doesn't quite work. Either of the returns work on their own, but together I get the following response:

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html>
    <head>
        <title>Error: 500 Internal Server Error</title>
        <style type="text/css">
          html {background-color: #eee; font-family: sans;}
          body {background-color: #fff; border: 1px solid #ddd;
                padding: 15px; margin: 15px;}
          pre {background-color: #eee; border: 1px solid #ddd; padding: 5px;}
        </style>
    </head>
    <body>
        <h1>Error: 500 Internal Server Error</h1>
        <p>Sorry, the requested URL <tt>&#039;http://localhost:8080/pp&#039;</tt>
           caused an error:</p>
        <pre>Unsupported response type: &lt;class &#039;dict&#039;&gt;</pre>
    </body>
</html>

I have a complete lack of experience with Web Services, so I don't even know if I'm on the right track at all. The point is I wish to return some binary data, along with a few (preferably named) metrics of said data. Is it possible to do this using bottle only? Is there a best practice (with respect to web services, python or both) that I should follow when it comes to this kind of thing?

Note that the client will not be written in python, that is just my test case.

Thanks for any guidance!

1

There are 1 best solutions below

0
On

The problem with the server-side code is that you cannot return a dictionary (return_metrics) and the contents of a file (return_file_path) with the same response. A solution is to encode the file contents in a string and include it in the returned dict (return_metrics). Then, the client will need to decode the content string to access the data.