I'm tyring to use Mandrill on Google App Engine, with Python, and for that I'm using the urlfetch module, provided by Google.
The adaptation of the code I'm using for it is the following:
#The jMessage below was split with the formatting below to make it easier to follow
#the real code doesn't have such indentation issues
jMessage =
{
"key": mailchimp_key,
"message":
{
"track_clicks": False,
"track_opens": True,
"tags": [],
"google_analytics_domains": [],
"html": message_html,
"subject": "Reset your password",
"from_name": None,
"merge_var_map": {},
"auto_text": False,
"from_email": from_email,
"headers": {},
"google_analytics_campaign": [],
"merge_vars": [],
"text": None,
"global_merge_vars": [],
"url_strip_qs":False,
"to":
[
{
"email": to_email,
"name": None
}
]
}
}
headers = {'content-type': 'application/json'}
result = urlfetch.fetch(url='https://mandrillapp.com/api/1.0/messages/send.json',\
headers=headers, payload=json.dumps(jMessage), method=urlfetch.POST)
print result.content
The output for that is the following:
{"status":"error","code":-2,"name":"ValidationError","message":"Validation error{\"message\":\"Please enter an array\"}"}
What exactly is that array it wants? I was unsure on what to do, so I wrapped the "message" key, from the jMessagewith [], making it a list. Indeed, it stopped complaining about the array, however the output was simply [], and I didn't receive any email.
Related
According to the Microsoft Translator 3.0 documentation the JSON Response body for the Detect endpoint should contain the following property:
alternatives: An array of other possible languages. Each element of the array is another object with the same properties listed above: language, score, isTranslationSupported and isTransliterationSupported.
Here is an example of a Request body from the Translator Quickstart web page:
[
{ "Text": "Ich würde wirklich gern Ihr Auto um den Block fahren ein paar Mal." }
]
And here is an expected Response body:
[
{
"alternatives": [
{
"isTranslationSupported": true,
"isTransliterationSupported": false,
"language": "nl",
"score": 0.92
},
{
"isTranslationSupported": true,
"isTransliterationSupported": false,
"language": "sk",
"score": 0.77
}
],
"isTranslationSupported": true,
"isTransliterationSupported": false,
"language": "de",
"score": 1.0
}
]
However, when I use the same Request body in my language detection endpoint, I only get one language with the score of 1.0:
import requests, uuid, json
# Add your subscription key and endpoint
subscription_key = "XXXXXXXXXXXXXXXXXX"
endpoint = "https://api.cognitive.microsofttranslator.com"
# Add your location, also known as region. The default is global.
# This is required if using a Cognitive Services resource.
location = "global"
path = '/detect'
constructed_url = endpoint + path
params = {
'api-version': '3.0'
}
constructed_url = endpoint + path
headers = {
'Ocp-Apim-Subscription-Key': subscription_key,
'Ocp-Apim-Subscription-Region': location,
'Content-type': 'application/json',
'X-ClientTraceId': str(uuid.uuid4())
}
# You can pass more than one object in body.
body = [{
'text': 'Ich würde wirklich gern Ihr Auto um den Block fahren ein paar Mal.'
}]
request = requests.post(constructed_url, params=params, headers=headers, json=body)
response = request.json()
print(json.dumps(response, sort_keys=True, ensure_ascii=False, indent=4, separators=(',', ': ')))
[
{
"isTranslationSupported": true,
"isTransliterationSupported": false,
"language": "de",
"score": 1.0
}
]
Does anyone have an idea what I am missing here?
After tested, I have try to use nodejs, offical restapi, and C# language to test. Get same result. And I can debug it, find Alternatives is always null.
So I am sure offical document is not lastest.
Now the response you got is right. You can submit feedback in this page.
I have been doing a lot of reading on this website regarding post requests from Python to an API. But despite all the recommendations to using the json library within Python, I still cant quite get my head around it.
My current predicament is that I need to make an API call, grab certain fields and post them to another API.
An example of the information i receive from my initial API request:
{
"metadata": {
"configurationVersions": [
3
],
"clusterVersion": "1.174.168.20190814-173650"
},
"id": "5c1547a6-61ca-4dc3-8971-ec8d2f542592",
"name": "Registration",
"enabled": false,
"dataType": "STRING",
"dataSources": [
{
"enabled": true,
"source": "POST_PARAMETER",
"valueProcessing": {
"splitAt": "",
"trim": false
},
"parameterName": "f=register",
"scope": {
"tagOfProcessGroup": "Production"
}
}
],
"normalization": "ORIGINAL",
"aggregation": "FIRST",
"confidential": true,
"skipPersonalDataMasking": true
}
After this call, I extract the data in the following way:
def ReqOutput(output):
x=""
out = ()
inReq = ["name","enabled","dataType","dataSources","normalization","aggregation","confidential","skipPersonalDataMasking"]
for i in output.items():
for item in inReq:
if item in i:
x = x + str(i)
out=out + i
return json.dumps(out)
As recommended in other threads, I used to json.dumps method to convert my python tuple to JSON. However, I feel like it is not working as intended
Pre json.dumps output:
'name', 'Registration', 'enabled', False, 'dataType', 'STRING', 'dataSources', [{'enabled': True, 'source': 'POST_PARAMETER', 'valueProcessing': {'splitAt': '', 'trim': False}, 'parameterName': 'f=register', 'scope': {'tagOfProcessGroup': 'Production'}}], 'normalization', 'ORIGINAL', 'aggregation', 'FIRST', 'confidential', True, 'skipPersonalDataMasking', True)
Post json.dumps output:
["name", "Registration", "enabled", false, "dataType", "STRING", "dataSources", [{"enabled": true, "source": "POST_PARAMETER", "valueProcessing": {"splitAt": "", "trim": false}, "parameterName": "f=register", "scope": {"tagOfProcessGroup": "Production"}}], "normalization", "ORIGINAL", "aggregation", "FIRST", "confidential", true, "skipPersonalDataMasking", true]
I then try and POST this to another API using:
def PostRequest (data):
postURL = "XXXX"
headers = {'Content-type': 'application/json'}
r = requests.post(postURL,data = data,headers = headers)
print(r.text)
Where I am finally met with the error:
{"error":{"code":400,"message":"Could not map JSON at '' near line 1 column 1"}}
Try getting rid of the for loops in favor of a dict comprehension:
def ReqOutput(output):
inReq = ["name","enabled","dataType","dataSources","normalization","aggregation","confidential","skipPersonalDataMasking"]
out = {output: val for output, val in output.items() if output in inReq}
return json.dumps(out)
This is more readable and will always give you a dict with attributes from output that are in inReq. The reason your JSON looks like that is because serializing a tuple will give you an Array-like structure. If what you want is an Object structure, you should serialize a dict-like object.
I'm trying to hit my geocoding server's REST API:
[https://locator.stanford.edu/arcgis/rest/services/geocode/USA_StreetAddress/GeocodeServer] (ArcGIS Server 10.6.1)
...using the POST method (which, BTW, could use an example or two, there only seems to be this VERY brief "note" on WHEN to use POST, not HOW: https://developers.arcgis.com/rest/geocode/api-reference/geocoding-geocode-addresses.htm#ESRI_SECTION1_351DE4FD98FE44958C8194EC5A7BEF7D).
I'm trying to use requests.post(), and I think I've managed to get the token accepted, etc..., but I keep getting a 400 error.
Based upon previous experience, this means something about the formatting of the data is bad, but I've cut-&-pasted directly from the Esri support site, this test pair.
# import the requests library
import requests
# Multiple address records
addresses={
"records": [
{
"attributes": {
"OBJECTID": 1,
"Street": "380 New York St.",
"City": "Redlands",
"Region": "CA",
"ZIP": "92373"
}
},
{
"attributes": {
"OBJECTID": 2,
"Street": "1 World Way",
"City": "Los Angeles",
"Region": "CA",
"ZIP": "90045"
}
}
]
}
# Parameters
# Geocoder endpoint
URL = 'https://locator.stanford.edu/arcgis/rest/services/geocode/USA_StreetAddress/GeocodeServer/geocodeAddresses?'
# token from locator.stanford.edu/arcgis/tokens
mytoken = <GeneratedToken>
# output spatial reference id
outsrid = 4326
# output format
format = 'pjson'
# params data to be sent to api
params ={'outSR':outsrid,'f':format,'token':mytoken}
# Use POST to batch geocode
r = requests.post(url=URL, data=addresses, params=params)
print(r.json())
print(r.text)
Here's what I consistently get:
{'error': {'code': 400, 'message': 'Unable to complete operation.', 'details': []}}
I had to play around with this for longer than I'd like to admit, but the trick (I guess) is to use the correct request header and convert the raw addresses to a JSON string using json.dumps().
import requests
import json
url = 'http://sampleserver6.arcgisonline.com/arcgis/rest/services/Locators/SanDiego/GeocodeServer/geocodeAddresses'
headers = { 'Content-Type': 'application/x-www-form-urlencoded' }
addresses = json.dumps({ 'records': [{ 'attributes': { 'OBJECTID': 1, 'SingleLine': '2920 Zoo Dr' }}] })
r = requests.post(url, headers = headers, data = { 'addresses': addresses, 'f':'json'})
print(r.text)
I'm trying to do a basic Bitly shortening URL call. However, I cannot seem to either push the json correctly, or deal with the json response correctly... I omitted some obvious variables for brevity and obfuscated some real values for security purposes.
import requests
import json
bitly_header = {'Authorization':'Bearer
some_long_secret_character_string_here', 'Content-Type':'application/json'}
bitly_data = {
"long_url": ""+long_url+"",
"group_guid": ""+bitly_guid+""
}
short_link_resp =requests.post(bitly_endpoint,data=bitly_data,headers=bitly_header)
short_link_json = short_link_resp.json()
short_link = short_link_json["link"]
Errors is "Key error: 'link'
The json I get from Postman is:
{
"created_at": "1970-01-01T00:00:00+0000",
"id": "bit.ly/2MjdrrG",
"link": "bit.ly/2MjdrrG",
"custom_bitlinks": [],
"long_url": "google.com/",
"archived": false,
"tags": [],
"deeplinks": [],
"references": {
"group": "https://api-ssl.bitly.com/v4/groups/Bi7i8IbM1x9"
}
}
try replace data with json:
short_link_resp =requests.post(bitly_endpoint, json=bitly_data, headers=bitly_header)
see the doc ref.
I'm trying to send a json in POST method using REST, but i got error:
"Could not parse JSON data: Expecting value: line 1 column 1
(char 0)", "status": 500, "type": "ValueError",
"request": {"client_addr": "127.0.0.1",
"user_agent": "python-requests/2.3.0 CPython/3.4.2 Linux/3.16.0-41-generic",
"method": "POST", "path": "/api/adley/doc"}}
)
I'm trying to fix, use a json.dumps or json.loads, but nothing seems to work.
I need to send one key and two values. Here is the base:
{
metadata: {
idx_exp: false,
idx_exp_time: 0,
file_ext: false,
password: "",
description: "base de teste",
idx_exp_url: "",
model: {
item: "Text"
},
dt_base: "29/06/2015 14:47:10",
name: "adley",
id_base: 5,
file_ext_time: 0,
},
content: [
{
field: {
required: false,
multivalued: false,
alias: "Texto",
datatype: "Text",
name: "item",
indices: [
"Ordenado"
],
description: "placeholder"
}
}
]
}
My to send a post script:
import requests, json
url = "http://127.0.0.1/api/adley/doc"
json_data = {'value':{'item':'test'}}
response = requests.post(url, params=json_data)
print(response.text)
I can't see what's wrong with my script
try passing the data parameter instead of the params parameter to the post method. requests wants to url encode params where you want the json data. So something like this:
requests.post(url, data=json.dumps(json_data))