I have a flask api that is expecting a post request in Avro. The problem is I'm not sure how to send Avro requests to test it. The api reads the data using the fastavro.reader(io.BytesIO(request.data))
I have tried using postman: In the header defining Content-Type as "avro/binary" However looks like its not possible https://github.com/postmanlabs/postman-app-support/issues/4435
I also tried curl:
curl -X POST -H "Content-Type: avro/binary" --data "{"city": "ALA",
"number_of_points": 42, "transport": "CAR", "subtype": "PURCHASE"}"
"http://localhost:8080/invocations"
However fastavro returns the following error:
File "fastavro/_read.pyx", line 725, in fastavro._read.file_reader.init
ValueError: cannot read header - is it an avro file?
Resources:
Okay, so I am assuming you have a valid .avro
file, as per the example on the fastavro docs.
This then becomes a simple case of handling this as a standard file upload to Flask. So rather than taking the data from request.data
you could so something like:
from fastavro import reader
from flask import Flask, request
app = Flask(__name__)
# This is really basic and could use some validation
@app.route('/invocations', methods=['POST'])
def upload():
if request.method == 'POST':
file = request.files['file']
for record in reader(file):
print (record)
return 'uploaded'
You could then submit your file to the endpoint with curl:
curl -i -X POST -F '[email protected]' "http://localhost:5000/invocations" -H 'ContentType: multipart/form-data'
This should result in something on the server console like:
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
{'station': '011990-99999', 'time': 1433269388, 'temp': 0}
{'station': '011990-99999', 'time': 1433270389, 'temp': 22}
If you wish to submit using the requests library, you can do something like this:
import requests
def upload(filename):
headers={'ContentType': 'multipart/form-data'}
with open(filename,'rb') as f:
files = {'file': f}
url='http://localhost:5000/invocations'
r = requests.post(url, files=files)
print (r.content, r.status_code)
upload('out.avro')