Google QPX Express API with Python - api

Here is the code I write for getting the flight price information by using Google QPX Express API from Python:
import urllib2
import json
url = "https://www.googleapis.com/qpxExpress/v1/trips/search?key=AIzaSyBH_S3LDUQWmQtbXyExUShtUSI8MmxObfY"
code = {
"request": {
"passengers": {
"kind": "qpxexpress#passengerCounts",
"adultCount": 1,
},
"slice": [
{
"kind": "qpxexpress#sliceInput",
"origin": "DCA",
"destination": "NYC",
"date": 2014-11-20,
}
],
"refundable": False,
"solutions": 5
}
}
jsonreq = json.dumps(code, encoding = 'utf-8')
req = urllib2.Request(url, jsonreq, {'Content-Type': 'application/json'})
flight = urllib2.urlopen(req)
response = flight.read()
flight.close()
print(flight)
It always give me the error of urllib2.HTTPError: HTTP Error 400: Bad Request. I really can't figure out what to do.
Related: QPX Express API from Python

You're almost there! Just a few minor errors:
The date needs to be quoted
False is written in lowercase in json: false, so you'll need to quote it in Python
No commas before close-bracket (OK in Python, but better to follow json conventions)
print(response), not print(flight)
also, it's generally a bad idea to publish your API key in a forum!
This gives:
import urllib2
import json
url = "https://www.googleapis.com/qpxExpress/v1/trips/search?key=XXX"
code = {
"request": {
"passengers": {
"kind": "qpxexpress#passengerCounts",
"adultCount": 1,
},
"slice": [
{
"kind": "qpxexpress#sliceInput",
"origin": "DCA",
"destination": "NYC",
"date": "2015-11-20",
}
],
"refundable": "false",
"solutions": 5
}
}
jsonreq = json.dumps(code, encoding = 'utf-8')
req = urllib2.Request(url, jsonreq, {'Content-Type': 'application/json'})
flight = urllib2.urlopen(req)
response = flight.read()
flight.close()
print(response)
By the way, to get the best responses, you should probably ask for more than 5 solutions. QPX Express tries to return a variety of answers (e.g., different times, different airlines, etc.) so if you want to have your own selection of the best trade-off of qualities, you probably want to examine more solutions.

Related

Trying to run Automation Anywhere import API through Power Automate Cloud Flow

Have anyone tried to run Automation Anywhere A360 import API with HTTP Post action with Power Automate Flow?
The flow runs smoothly and I'm receiving the requestId in response. However, the whole action fails at the Automation Anywhere Control Room side with no imported bot at the end. I'm receiving the following error: net.lingala.zip4j.exception.ZipException: Zip headers not found. Probably not a zip file?
Power Automate HTTP Post - Body
I added below code to the Http Post Body:
{
"$content-type": "multipart/form-data",
"$multipart": [
{
"headers": {
"Content-Type": "application/x-zip-compressed",
"Content-Disposition": "form-data; name=\"upload\"; filename=\"#{variables('fullPath')}\""
},
"body": "#{variables('contentString')}"
},
{
"headers": {
"Content-Disposition": "form-data; name=\"actionIfExisting\""
},
"body": "OVERWRITE"
},
{
"headers": {
"Content-Disposition": "form-data; name=\"publicWorkspace\""
},
"body": "true"
},
{
"headers": {
"Content-Disposition": "form-data; name=\"upload\""
},
"body": "#{variables('fullPath')}"
}
]
}
The contentString variable is: #{body('Get_file_content_using_path')?['$content']}
What am I doing wrong?

How can I pass the Session ID in API Request via Apps Script?

I am trying to access the API of our CRM Documentation through Google Sheets / Apps Script.
When accessing the API through Postman I have no issues and get the desired results using the following setup:
POST: https://api.sharpspring.com/pubapi/v1.2/?accountID={{accountID}}&secretKey={{secretKey}}
BODY:
{
"id":"12345678912345678999",
"method": "getOpportunities",
"params": {
"where": {},
"limit":"500",
"offset": "0"
}
}
Now, when I try to replicate the same in Apps Script I get the following result:
{ result: null,
error: { code: 102, message: 'Header missing request ID', data: [] },
id: null }
The function that I am running is as below:
function myFunction() {
var URL = "https://api.sharpspring.com/pubapi/v1.2/?accountID={{accountID}}&secretKey={{secretKey}}"
var body = {
"method": "POST",
"body": raw,
"headers": {"Content-Type": "application/json"},
"redirect": "follow"
}
var raw = {
"method": "getOpportunities",
"id": "12345678912345678999",
"params": {
"where": {},
"limit":"500",
"offset": "0"
}
}
var results = UrlFetchApp.fetch(URL, body).getContentText();
var data = JSON.parse(results);
console.log(data);
}
In both I am passing a random session ID "12345678912345678999". I tried finding a session ID in the cookie but that didn't work and I assume that I am on the wrong path there. Passing the id in the header directly didn't work either.
Any ideas? Thanks a lot in advance!

Log data from dataPower to splunk

The question might be looking easy but I am quite struck on this.
I have a requirement whereby I have to store data regarding Timestamp,latency,serviceName etc in a variable and then log that into splunk.
However I am unable to call splunk through datapower xslt.
How can we call splunk through datapower using XSLT
Thanks
Splunk has several interfaces, but XSLT is not one of them. Lucky for you, there's already a Splunk app that can collect data from Datapower and index it. See https://splunkbase.splunk.com/app/3517/.
I would consider using the Splunk HTTP Event Collector.
You can use XSLT ou Gatewayscript, in conjunction with the Datapower urlopen function (available in both language), to make a simple http call to the collector.
I found here (Code under Apache license) that the call is as simple as a call to https://SPLUNK_SVR:8088/services/collector/event/1.0 with the following body:
{
"source": "chicken coop",
"sourcetype": "httpevent",
"index": "main",
"host": "farm.local",
"event": {
"message": {
"chickenCount": 500
"msg": "Chicken coup looks stable.",
"name": "my logger",
"put": 98884,
"temperature": "70F",
"v": 0
},
"severity": "info"
}
}
I think it would work better on the datapower by using gateway script, an example of such a call can be found here. Look for the first example. You will find similar code, in which I modified the "Data" section:
//Could be added to a library
var urlopen = require('urlopen');
var jsonData = '{
"source": "Datapower",
"sourcetype": "SOMETHING DYNAMIC",
"index": "main",
"host": "GET_THIS_FROM_DP_VARIABLES",
"event": {
"message": {
"SOMECOUNTER": 500
"msg": "SOME INTERESTING INFORMATION.",
"name": "GET_THIS_FROM_DP_VARIABLES",
"put": 3333,
"yadayada": "foo",
"bar": 0
},
"severity": "info"
}
}';
var options = {
target: 'https://SPLUNK_SVR:8088/services/collector/event/1.0',
method: 'POST',
headers: { },
contentType: 'text/plain',
timeout: 60,
sslClientProfile: 'AN_EXISTING_SSL_PROFILE_ON_DATAPOWER',
data: jsonData};
urlopen.open(options, function(error, response) {
if (error) {
// an error occurred during the request sending or response header parsing
console.error("Splunk Logging - urlopen error: "+JSON.stringify(error));
} else {
// get the response status code
var responseStatusCode = response.statusCode;
var responseReasonPhrase = response.reasonPhrase;
console.log("Splunk Logging - status code: " + responseStatusCode);
console.log("Splunk Logging - reason phrase: " + responseReasonPhrase);
// no need to read response data - This is just logging
}
});

How do you get all the email body parts? And how do you know how many parts exist?

I'm trying to read emails responded by the Gmail API.
I have trouble accessing all the "parts". And don't have great ways to traverse through the response. I'm also lost as to how many parts can exist so that I can make sure I read the different email responses properly. I've shortened the response below...
{ "payload": { "mimeType": "multipart/mixed", "filename": "",
], "body": { "size": 0 }, "parts": [ {
"body": {
"size": 0
},
"parts": [
{
"partId": "0.0",
"mimeType": "text/plain",
"filename": "",
"headers": [
{
"name": "Content-Type",
"value": "text/plain; charset=\"us-ascii\""
},
{
"name": "Content-Transfer-Encoding",
"value": "quoted-printable"
}
],
"body": {
"size": 2317,
"data": "RGVhciBNSVQgQ2x1YiBWb2x1bnRlZXJzIGluIEFzaWEsDQoNCkJ5IG5vdyBlYWNoIG9mIHlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBpbnZpdGF0aW9ucyB0byB0aGUgcmVjZXB0aW9ucyBpbiBib3RoIFNpbmdhcG9yZSBhbmQgSG9uZyBLb25nIHdpdGggUHJlc2lkZW50IFJlaWYgb24gTm92ZW1iZXIgNyBhbmQgTm92ZW1iZXIg"
}
},
{
"partId": "0.1",
"mimeType": "text/html",
"filename": "",
"headers": [
{
"name": "Content-Type",
"value": "text/html; charset=\"us-ascii\""
},
{
"name": "Content-Transfer-Encoding",
"value": "quoted-printable"
}
],
"body": {
"size": 9116,
"data": "PGh0bWwgeG1sbnM6dj0idXJuOnNjaGVtYXMtbWljcm9zb2Z0LWNvbTp2bWwiIHhtbG5zOm89InVybjpzY2hlbWFzLW1pY3Jvc29mdC1jb206b2ZmaWNlOm9mZmljZSIgeG1sbnM6dz0idXJuOnNjaGVtYXMtbWljcm9zb2Z0LWNvbTpvZmZpY2U6d29yZCIgeG1sbnM6bT0iaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS9vZmZpY2UvMjA"
}
}
] }, {
"partId": "1",
"mimeType": "text/plain",
"filename": "",
"body": {
"size": 411,
"data": "X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18NClRoYW5rIHlvdSBmb3IgYWxsb3dpbmcgdXMgdG8gcmVhY2ggeW91IGJ5IGVtYWlsLCB0aGUgbW9zdCBpbW1lZGlhdGUgbWVhbnMgZm9yIHNoYXJpbmcgaW5mb3JtYXRpb24gd2l0aCBNSVQgYWx1bW5pLiANCklmIHlvdSB3b3VsZCBsaWtlIHRvIHVuc3Vic2NyaWJlIGZyb20gdGhpcyBtYWlsaW5nIGxpc3Qgc2VuZCBhIGJsYW5rIGVtYWlsIHRvIGxpc3RfdW5zdWJzY3JpYmVAYWx1bS5taXQuZWR1IGFuZCBwdXQgdGhlIGxpc3QgbmFtZSBpbiB0aGUgc3ViamVjdCBsaW5lLg0KRm9yIGV4YW1wbGU6DQpUbzogbGlzdF91bnN1YnNjcmliZUBhbHVtLm1pdC5lZHUNCkNjOg0KU3ViamVjdDogYXNpYW9mZg0K"
} } ] } }
Is there something I'm missing?
A MIME message is not just an array it's a full blown tree structure. So you'll have to traverse it to correctly handle it. Luckily JSON parsers are plentiful and the problem can easily be handled with recursion. In many languages there exist very useful email parsing libraries that can make accessing traditional parts (e.g. the text/plain or text/html displayable part, or attachments) not too laborious.
You'll have to set up walker functions to traverse through the json and pick out the bits you are after. Here is a part of what I wrote. This may help you jumpstart your code. NOTE: this is used inside of wordpress...hence the special jQuery call. Not needed if you do not need to use jquery inside wordpress.
function makeApiCall() {
gapi.client.load('gmail', 'v1', function() {
//console.log('inside call: '+myquery);
var request = gapi.client.gmail.users.messages.list({
'userId': 'me',
'q': myquery
});
request.execute(function(resp) {
jQuery(document).ready(function($) {
//console.log(resp);
//$('.ASAP-emailhouse').height(300);
$.each(resp.messages, function(index, value){
messageId = value.id;
var messagerequest = gapi.client.gmail.users.messages.get({
'userId': 'me',
'id': messageId
});//end var message request
messagerequest.execute(function(messageresp) {
//console.log(messageresp);
$.each(messageresp, responsewalker);
function responsewalker(key, response){
messagedeets={};
$.each(messageresp.payload.headers, headerwalker);
function headerwalker(headerkey, header){
if(header.name =='Date'){
d = new Date(header.value);
var curr_date = d.getDate();
var curr_month = d.getMonth() + 1; //Months are zero based
var curr_year = d.getFullYear();
var formatteddate = curr_month+'/'+curr_date+'/'+curr_year;
messagedeets['date']=formatteddate;
//$('.ASAP-emailhouse').append('<p>'+header.value+'</p>');
}
if(header.name =='Subject'){
//console.log(header.value);
messagedeets.subject=header.value;
}
}
messagedeets.body = {};
$.each(messageresp.payload.parts, walker);
function walker(partskey, value) {
//console.log(value.body);
if (value.body.data !== "undefined") {
//console.log(value.body);
var messagebody = atob(value.body.data);
messagedeets.body.partskey = messagebody;
}
console.log(messagedeets);
$('.ASAP-emailhouse').append('<div class="messagedeets"><p class="message-date">'+messagedeets.date+': <span class="message-subject">'+messagedeets.subject+'</span></p><p>'+messagedeets.body.partskey+'</p></div>');
}//end responsewalker
//$('.ASAP-emailhouse').append('</li>');
}
//$('.ASAP-emailhouse').append('</ul>');
});//end message request
});//end each message id
});//end jquery wrapper for wordpress
});//end request execute list messages
});//end gapi client load gmail
}
The MIME parts you are looking for are in an array. JSON does not tell you up front how many items are in an array. Even MIME itself does not provide a way of knowing how many parts are present without looking at the entire message. You will just have to traverse the entire array to know how many parts are in it, and process each part as you encounter it.
To know how much parts exists, you can just use the Length property.
Example :
json.payload.parts.length
For your example, this property is 2 because there are 2 parts.

How to make ember work with Django REST gis

I am currently trying to setup ember to interact with Django's REST Framework using the ember-django-adapter.
This works flawless. But since I started using djangorestframework-gis, ember is not able to process the responses anymore.
I have not found anyone building geoJSON with ember except for: https://gist.github.com/cspanring/5114078 But that does not seem to be the right approach because I do not want to change the data model?
This is the api-response:
{
"type": "FeatureCollection",
"features": [
{
"id": 1,
"type": "Feature",
"geometry": {
"coordinates": [
9.84375,
53.665466308594
],
"type": "Point"
},
"properties": {
"date_created": "2014-10-05T20:08:43.565Z",
"body": "Hi",
"author": 1,
"expired": false,
"anonymous": false,
"input_device": 1,
"image": "",
"lat": 0.0,
"lng": 0.0
}
}
]
}
While ember expects something like:
[{"id":1,
"date_created":"2014-10-05T20:08:43.565Z",
"body":"Hi",
"author":1,
"expired":false,
"anonymous":false,
"input_device":1,
"image":"",
"lat":0,
"lng":0
}
]
My take on this was to write my own Serializer:
import Ember from "ember";
import DS from "ember-data";
export default DS.DjangoRESTSerializer.extend({
extractArray: function(store, type, payload) {
console.log(payload);
//console.log(JSON.stringify(payload));
var features = payload["features"];
var nPayload = [];
for (var i = features.length - 1; i >= 0; i--) {
var message = features[i];
var nmessage = {"id": message.id};
for(var entry in message.properties){
var props = message.properties;
if (message.properties.hasOwnProperty(entry)) {
var obj = {}
nmessage[entry]=props[entry];
}
}
nPayload.push(nmessage);
};
console.log(nPayload); //prints in the format above
this._super(store, type, nPayload);
},
})
But I receive the following error:
The response from a findAll must be an Array, not undefined
What am I missing here? Or is this the wrong approach? Has anyone ever tried to get this to work?
An alternative would be to handle this on the serverside and simply output a regular restframework response and set lat and long in the backend.
This is not a valid answer for the question above. I wanted to share my solution anyways,
just in case anyone ever gets into the same situation:
I now do not return a valid geoJSON, but custom lat, lng values. The following is backend code for django-rest-framework:
Model:
#models/message.py
class Message(models.Model):
def lat(self):
return self.location.coords[1]
def lng(self):
return self.location.coords[0]
And in the serializer:
#message/serializer.py
class MessageSerializer(serializers.ModelSerializer):
lat = serializers.Field(source="lat")
lng = serializers.Field(source="lng")
Ember can easily handle the format.