How to use Alamofire to make a MailGun API call? - swift

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.

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.

How to send http post request with an Avro file?

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')

POST URL with REST API token in vbs without password

I'm launching build jobs on a local Jenkins with:
curl -X POST "http://UID:TOKEN#server:port/job/DevGate/build?delay=0sec&json=%7B%22parameter%22%3A+%7B%22name%22%3A+%22DEVGATE_PACKAGELIST%22%2C+%22value%22%3A+%2212345678%3A9%22%7D%2C+%22statusCode%22%3A+%22303%22%2C+%22redirectTo%22%3A+%22.%22%7D&Submit=Build"
which translates into
curl -X POST "http://UID:TOKEN#server:port/job/DevGate/build?delay=0sec&json={"parameter": {"name": "DEVGATE_PACKAGELIST", "value": "12345678:9"}, "statusCode": "303", "redirectTo": "."}&Submit=Build"
UID being userID. TOKEN being API Token given by Jenkins/REST API. And it works. Now, this command is launched inside of a VBScript that mainly gathers data for creation of aforementioned URL. No password needed, and I'd like to keep it that way. The problem: I'd like to avoid using curl and use just native VBScript functionality.
What I've tried so far:
Dim http: Set http = CreateObject("Microsoft.XMLHTTP")
Dim url: url = "http://server:port/job/DevGate/build"
Dim data: data = "delay=0sec&json=%7B%22parameter%22:+%7B%22name%22:+%22DEVGATE_PACKAGELIST%22,+%22value%22:+%22" + the rest of data
'string2try = Base64EncodeString("UID:TOKEN")
'string2try = Base64EncodeString("UID:PASSWORD")
With http
.Open "POST", url, False
Call .SetRequestHeader("Content-Type", "application/x-www-form-urlencoded")
Call .SetRequestHeader("oAuth", token)
.Send data
'Call .SetRequestHeader("X-Api-Key", token)
'Call .SetRequestHeader("Authorization", "Bearer " & token)
'Call .SetRequestHeader("X-Auth-Token", token or string2try)
'Call .SetRequestHeader("X-Parse-REST-API-Key", token)
End With
Every permutation of that code fails authentication. How to pass my token + uid properly in VBScript without using curl?

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.

Github REST API full example

I would like to create a new file in the my github repository by using github REST API. I've found following link, but honestly I don't understand it((
As I understand, I could do POST
url: https://api.github.com/repos/MyUserName/MyRepositoryName
headers:
Accept: application/vnd.github.v3+json
body:
{
"message": "my commit message",
"committer": {
"name": "My name",
"email": "my email"
},
"content": "base64encoded"
}
But it doesn't work. Could you please, write
1) which url should I call
2) which headers this request should contains
3) what body should be
You were close:) Lets assume, that
1) your login: YourUsername
2) your access token: 123a321
3) repository to be updated: YourRepo
4) file to be created: file.txt
5) folder that will contains new file: f1/f2
According to those assumptions your request should be following:
type : PUT
url : https://api.github.com/repos/YourUsername/YourRepo/contents/f1/f2/file.txt
headers :
{
"Content-Type" : "application/vnd.github.v3+json",
"Authorization" : "token 123a321"
}
body :
{
"message": "my commit message",
"committer": {
"name": "My name",
"email": "my email"
},
"content": "base64encoded"
}
UPD
If you write in java, you can use GitHubFileAPI library, that I recently pushed to the maven central repository.
Solution: In order to perform action on github api you can use curl
according to Github doc:
first make sure you have specific privileges and authentication token generated to your account in order to interact with Github api:
profile Settings -> Developer Settings -> Personal access tokens -> Generate new token
the command should be in http PUT method on path /repos/:owner/:repo/contents/:path
The required params for editing or adding new files (according to api)
message (String), Content (String) and sha(String), additional params are branch(String) commiter(String) and author(String)
Lets perform some curl message in order to perform your action, the simple formula for this case would be:
curl --user <userName>:<token>
--data '{"key":"value"}'
--header <HeaderType>
--request <HTTPMethod>
<fullURL>
for demonstration lets fill some details:
curl --user johnDoe:abc123!##
--data '{"message":"my message","content":"my content","sha":"abcjfhtenf736gd843ji43903"}'
--header Content-Type:application/json
--request PUT
https://api.github.com/repos/MyOrganization/MyCoolApp/contents/app/models
Verify on Github the content has been inserted correctly to your branch