How to send http post request with an Avro file? - rest

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:
https://github.com/fastavro/fastavro
https://avro.apache.org/

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 'file=#out.avro' "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')

Related

Jenkins http plugin to upload file using rest

I am trying to upload a file to a rest server from jenkins using http plugin. I have a jenkins pipelie where a step involves loading a file(type formData)
to a server using rest.
the server side method uses two parameters:
(#FormDataParam("file") InputStream file, #FormDataParam("fileName") String fileName)
I am using the below method
def filename = "${WORKSPACE}/Test.txt"
data="""{ \"fileName\" : \"Test.txt\" }"""
resp3 = httpRequest consoleLogResponseBody: true,url: "http://<url>",contentType:'APPLICATION_OCTETSTREAM',customHeaders:[[name:'Authorization', value:"Basic ${auth}"]],httpMode: 'POST',multipartName: 'Test.txt',uploadFile: "${filename}",requestBody:data,validResponseCodes: '200'
but when I run the status code is 400 and in the server logs the message is that no filestream and no filename is received i.e not able to get both the arguments.
Please let me know where it is getting wrong
Regards
You can try using curl instead of built-in Jenkins methods:
curl -XPOST http://<url> -H 'Content-Type: application/octet-stream' -H 'Authorization: Basic ${auth}' --data-binary '{\"fileName\" : \"Test.txt\" }'
You can debug it first from within shell. Once it's working, wrap it in sh directive:
sh "curl ..."
Since I was running on windows so bat + curl worked for me .With this workaround I was able to transfer files using jenkins and rest
However using httpRequest from jenkins inbuild library is still not working.

Push a pdf file on wiremock

I'm using a wiremock standlaone service to mock several json Object.
Actually I want to mock a pdf file: it works fine on my local by just adding my pdf to the __files folder
However I'm trying to use a POSTMAN (or curl) to push the pdf on the server and this doesnt work :
Here is my curl :
curl -X PUT https://wiremock-mock.myserver.com/__admin/files/Hello_World.pdf
-H 'Accept: */*'-H 'content-type: multipart/form-data'
-F pdf=#///usr/Perso/Downloads/Hello_World.pdf
I'm getting this error:
HTTP ERROR 500
Problem accessing /api/test/fichiers/111111. Reason:
Server Error
Caused by:
wiremock.com.github.jknack.handlebars.HandlebarsException: inline#7adccef6:30:88: found: '?'
#???8FV?c?M8?+?J-P??????????GY???(|?6M:#????w]t???2?P?o?si????2??u?yD]F??$p?
?a????{{z???Z????q????5D&????j}??
??i?s??????{*?r?)5??ee???gzZ?-??kh?'??``Av?2?????(?????Q[????>yYn??iy???vj?f2O?u???gK_???#?7!?c??WF?Y??3$?u ?tT?k)???>??YE???0eX|?V?>?n?-????=?>??j?vB??;?????}2??e?mS?c?D?az??,^?ahV???^??G??R?????\??2?oTjD???G???3??|??9????vnz???&????????M??~?b???????????0???i[v?]?e?"????_????H1m??I?~à;?=???K?.????Ws???? c[?zW9?????]?E:,???????[?^?:????=?????9??V?DF??8?C??+"g$????J??\?nJ?
?Q??n?/?y?????NY?|??????L??3{??c??`C??????N??l??e?????-A??r?4??%???~i?-?????????9ZT!K?i?6)5R???1.????4??6????? B?k2Z????P?6!$??????GFQ????ur?(??(??G?z???d??(????*???J??U??
?R"?b??I?Q?#?? mt??2d??= ????\?6??kO
^
at wiremock.com.github.jknack.handlebars.internal.HbsErrorReporter.syntaxError(HbsErrorReporter.java:93)
at wiremock.org.antlr.v4.runtime.ProxyErrorListener.syntaxError(ProxyErrorListener.java:41)
at wiremock.com.github.jknack.handlebars.internal.HbsParserFactory$2.notifyListeners(HbsParserFactory.java:148)
at wiremock.org.antlr.v4.runtime.Lexer.nextToken(Lexer.java:144)
at wiremock.org.antlr.v4.runtime.BufferedTokenStream.fetch(BufferedTokenStream.java:169)
at wiremock.org.antlr.v4.runtime.BufferedTokenStream.sync(BufferedTokenStream.java:152)
at wiremock.org.antlr.v4.runtime.BufferedTokenStream.consume(BufferedTokenStream.java:136)
at wiremock.org.antlr.v4.runtime.Parser.consume(Parser.java:571)
at wiremock.org.antlr.v4.runtime.Parser.match(Parser.java:203)
at wiremock.com.github.jknack.handlebars.internal.HbsParser.sexpr(HbsParser.java:887)
at wiremock.com.github.jknack.handlebars.internal.HbsParser.var(HbsParser.java:1381)
at wiremock.com.github.jknack.handlebars.internal.HbsParser.statement(HbsParser.java:344)
at wiremock.com.github.jknack.handlebars.internal.HbsParser.body(HbsParser.java:222)
at wiremock.com.github.jknack.handlebars.internal.HbsParser.template(HbsParser.java:165)
at wiremock.com.github.jknack.handlebars.internal.HbsParserFactory$1.parse(HbsParserFactory.java:84)
at wiremock.com.github.jknack.handlebars.cache.NullTemplateCache.get(NullTemplateCache.java:54)
at wiremock.com.github.jknack.handlebars.Handlebars.compile(Handlebars.java:475)
at wiremock.com.github.jknack.handlebars.Handlebars.compileInline(Handlebars.java:435)
at wiremock.com.github.jknack.handlebars.Handlebars.compileInline(Handlebars.java:415)
at com.github.tomakehurst.wiremock.extension.responsetemplating.ResponseTemplateTransformer.uncheckedCompileTemplate(ResponseTemplateTransformer.java:168)
at com.github.tomakehurst.wiremock.extension.responsetemplating.ResponseTemplateTransformer.transform(ResponseTemplateTransformer.java:122)
at com.github.tomakehurst.wiremock.stubbing.InMemoryStubMappings.applyTransformations(InMemoryStubMappings.java:91)
at com.github.tomakehurst.wiremock.stubbing.InMemoryStubMappings.serveFor(InMemoryStubMappings.java:72)
at com.github.tomakehurst.wiremock.core.WireMockApp.serveStubFor(WireMockApp.java:167)
at com.github.tomakehurst.wiremock.http.StubRequestHandler.handleRequest(StubRequestHandler.java:50)
at com.github.tomakehurst.wiremock.http.AbstractRequestHandler.handle(AbstractRequestHandler.java:47)
at com.github.tomakehurst.wiremock.servlet.WireMockHandlerDispatchingServlet.service(WireMockHandlerDispatchingServlet.java:108)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at wiremock.org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:812)
at wiremock.org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:587)
at wiremock.org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127)
at wiremock.org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)
at wiremock.org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061)
at wiremock.org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at wiremock.org.eclipse.jetty.servlets.gzip.GzipHandler.handle(GzipHandler.java:479)
at wiremock.org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:110)
at wiremock.org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
at wiremock.org.eclipse.jetty.server.Server.handle(Server.java:499)
at wiremock.org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311)
at wiremock.org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:258)
at wiremock.org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544)
at wiremock.org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
at wiremock.org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
at java.lang.Thread.run(Thread.java:748)
How may I push a pdf file on the wiremock server ?

How to get form-data from PUT request using Flask-restplus

One of the endpoints of my API handles PUT request with multipart/form-data. While an audio file is uploaded, some other data is sent from client in form-data. I am able to receive the file using the following code, but am having trouble getting the form-data.
#api.route('/upload')
class AudioUpload(Resource):
def put(self):
now = datetime.now()
filename = now.strftime("%Y%m%d_%H%M%S") + ".mp3"
cwd = os.getcwd()
filepath = os.path.join(cwd, filename)
name = request.form['name']
print('name: ', name, file=sys.stdout)
with open(filepath, 'wb') as f:
f.write(request.stream.read())
return filepath
The curl command I tested with is:
curl -X PUT \
http://localhost:5000/api/upload \
-H 'content-type: multipart/form-data \
-F file=#Audio-3791_244-Feb_04_2018-13_30_04.wav \
-F name=xyz
I got 400 with error The browser (or proxy) sent a request that this server could not understand.
What is the correct way getting form-data in PUT request?
EDIT
Just tried the same code with post. It does not work for getting the form-data either with same error.

How to use Alamofire to make a MailGun API call?

I have been trying to make a MailGun API call to send an email from within my project: MailGun message sending API documentation
However, to no avail I don't seem to be able to make it work. I did successfully send an email through the terminal with the curl command, but when it comes to Alamofire I am stuck.
I need help translating this terminal code snippet:
curl -s --user 'api:YOUR_API_KEY' \
https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages \
-F from='Excited User <mailgun#YOUR_DOMAIN_NAME>' \
-F to=YOU#YOUR_DOMAIN_NAME \
-F to=bar#example.com \
-F subject='Hello' \
-F text='Testing some Mailgun awesomness!'
To a request using Alamofire.
My current faulty Swift code is:
let basicAuthentication = Request.authorizationHeader(user: "api", password: "mySecretApiKey")
let headers: HTTPHeaders = [(basicAuthentication?.key)!: (basicAuthentication?.value)!]
let parameters: Parameters? = ["from": "mailgun#YOUR_DOMAIN_NAME",
"to": "destination#email.com",
"subject": "Hello There!",
"text": "This is sent from within a Swift project!"]
Alamofire.request("https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages", method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: headers).responseJSON{ response in
print(response)
}
Any help will be much appreciated!
I haven't tried your code but at least your encoding is wrong. You're encoding your body as JSON and the curl code is using a form. URLEncoding.default should be the right value for the encoding parameter. After that, if it's still breaking, debug the response. I suggest you download Charles proxy to see if the requests curl and the iOS app send are any different and how.

How to parse Mitmdump/Mitmproxy content

I am using mitmdump -dd > outfile to parse content,which gives me the complete request and response "headers and its body content"(which also removes the junk part of the traffic i.e no certificate's and no compressed data).
But this is making my file really large.How can I just get only the request part of the traffic....
Any advice or link how can this be done??
Thanks
The way i handled not exact but similar case is using -s flag of mitmdump and get the flow.request.content in my script and log it to some log file that will be pretty neat and clean
Here below code might be of some help ( save as t.py and run mitmdump -s t.py )
from mitmproxy import http
import time,re
import logging
def response(flow: http.HTTPFlow) -> None:
flow.response.headers["newheader"] = "foo"
def request(flow: http.HTTPFlow) -> None:
print(flow.request.content)
request_content = flow.request.content
# here u get the request content and then log it and use it