I am trying to submit a POST request with data in json format to create a user using the Crowd API.
Here is the code snippet:
url = 'http://crowdserver/crowd/rest/usermanagement/1/user'
payload = '{"name": "sampleuser", "password": {"value": "secret"}, "active": true, "first-name": "Sample", "last-name": "User","display-name": "Sample User", "email": "sample#user.cool"}'
req = urllib2.Request(url, payload)
req.add_header('Content-type','application/json')
req.add_header("Accept", "application/json")
res = urllib2.urlopen(req)
output = resp.read()
print output
print resp.code
I get the following output:
Bad Request
Error code returned is 400
I thought this might perhaps be an encoding issue so replaced payload with:
payload = json.dumps({"name": "sampleuser", "password": {"value": "secret"}, "active": true, "first-name": "Sample", "last-name": "User","display-name": "Sample User", "email": "sample#user.cool"})
Which returns:
NameError: name 'true' is not defined
So it looks like "active": true is not in an acceptable format.
If I add double quotes such as "active":"true" I get a TypeError; TypeError: not a valid non-string sequence or mapping object
Update
So the type error was indeed solved by setting the active attribute value to True but it turns out the 400 error was returned due to invalid user data, for example missing password or the user already exists read as the user already exists - I find it odd that the error for invalid input and an existing user share the same error code.
In this line:
payload = '{"name": "sampleuser", "password": {"value": "secret"}, "active": true, "first-name": "Sample", "last-name": "User","display-name": "Sample User", "email": "sample#user.cool"}'
Change ..., "active": true, ... to ..., "active": True, ...
Python's True/False are case-sensitive.
Related
I'm trying to make decoder, data-->json. You paste raw data, and it decodes it into json. Here are 2 scenarios:
FIRST input is a correct data, it then correctly decodes it into json.
FIRST input is random string, like "abcd" - code then says that data is invalid.
After second scenario, even when you try to put VALID data, it will say "invalid data" forever. How can make it work, so when you first write "abcd", and then paste valid data, it will just decode it?! I tried loops, breaks, continues... Nothing works, and typing invalid input ruins whole code - you have to restart program and paste VALID data.
import requests
import json
while True:
try:
raw = input('Please paste raw data: '+"\n")
url = 'https://platform.lobaro.com/api/mbus?raw={}'.format(raw)
print("\n")
get = requests.get(url)
json_body = get.json()
parsed = json.dumps(json_body)
parsed2 = json.loads(parsed)
formatted = json.dumps(json.loads(parsed), indent=2)
print(formatted+"\n")
print("INFORMATIONS:")
name = parsed2["MFieldLongString"]
print(f'Producer: {name}')
l1 = parsed2["Length"]
print(f'Lenght: {l1}'+'\n')
print('============================================================================')
except requests.exceptions.JSONDecodeError:
print('Invalid data! Could not parse to JSON.'+"\n")
continue
The site uses other API URL to decode wmbus messages:
import json
import requests
api_url = "https://platform.lobaro.com/gqlgen/query"
payload = {
"operationName": None,
"query": "query ($raw: String!, $key: String) {\n wmbus: parseWmbus(raw: $raw, key: $key) {\n data\n parseError\n __typename\n }\n}\n",
"variables": {
"key": "0102030405060708090A0B0C0D0E0F11", # <-- change this field
"raw": "2e44931578563412330333637a2a0020055923c95aaa26d1b2e7493b2a8b013ec4a6f6d3529b520edff0ea6defc955b29d6d69ebf3ec8a", # <-- change this field
},
}
data = requests.post(api_url, json=payload).json()
if data['data']['wmbus']['parseError'] == "":
data = json.loads(data["data"]["wmbus"]["data"])
print(data)
Prints:
{
"Raw": "0x2e4493157856341233037a2a0020055923c95aaa26d1b2e7493b013ec4a6f6d3529b520edff0ea6defc99d6d69ebf3",
"RawWithCrc": "0x2e44931578563412330333637a2a0020055923c95aaa26d1b2e7493b2a8b013ec4a6f6d3529b520edff0ea6defc955b29d6d69ebf3ec8a",
"FrameFormat": "A",
"Length": 46,
"CField": "0x44",
"CFieldString": "0x44 (SND_NR)",
"MField": "0x9315",
"MFieldCodeString": "ELS",
"MFieldLongString": "Elster GmbH, Germany, Europe",
"Id": 305419896,
"IdString": "12345678",
"Version": 51,
"Device": "0x03",
"DeviceString": "Gas",
"CiField": "0x7a",
"HeaderKnown": True,
"PayloadKnown": True,
"CrcValid": True,
"HasCrc": True,
"SourceType": "WMBUS",
"IsCompactFrame": False,
"FormatSignature": 61330,
"FormatFrame": "0x0c14046d02fd17",
"Header": {
"Serial": 0,
"IdString": "",
"ManufacturerCode": 0,
"MFieldCodeString": "",
"MFieldLongString": "",
"Version": 0,
"DeviceType": "0x00",
"DeviceString": "",
"EncryptionMode": 5,
"EncryptionModeString": "AES with CBC",
"EncryptedBlocks": 2,
"HopCount": 0,
"IsAccessible": True,
"IsBidirectionalMode": False,
"IsSynchronous": False,
"ReservedBit": False,
"TelegramType": 0,
"AccessNumber": 42,
"StatusByte": 0,
"ConfigField": [32, 5],
...and so on.
This is because the response could have been cached. One way to disable the caching is to pass the appropriate headers in the request. Something like
get = requests.get(url, headers={
'Cache-Control': 'no-cache',
'Pragma': 'no-cache',
'Expires': '0' })
See 'Pedro Lobitos' answer to this question here for a good explanation here How do I clear cache with Python Requests?. (Good explanation and very good discussion/comments too)
You could try to restart a method after the Exception, so you delete all local variables temporarily and restart from scratch:
import gc
def myMethod():
gc.collect(generation=2)
while True:
try:
raw = input('Please paste raw data: '+"\n")
url = 'https://platform.lobaro.com/api/mbus?raw={}'.format(raw)
print("\n")
get = requests.get(url)
json_body = get.json()
parsed = json.dumps(json_body)
parsed2 = json.loads(parsed)
formatted = json.dumps(json.loads(parsed), indent=2)
print(formatted+"\n")
print("INFORMATIONS:")
name = parsed2["MFieldLongString"]
print(f'Producer: {name}')
l1 = parsed2["Length"]
print(f'Lenght: {l1}'+'\n')
print('=====')
except requests.exceptions.JSONDecodeError:
print('Invalid data! Could not parse to JSON.'+"\n")
break
myMethod()
So everytime it raises an Exception, the "old execution" is killed and a new one starts. The gc is there for automatically garbage-collect the leftovers from the old execution.
Here's the code of my test:
#pytest.mark.run(order=18)
def test_post(client):
"""
Test whether the test client has been added or not.
"""
print(f"\n\n {'>>>'*6} TESTING CLIENT POST {'<<<'*6} \n\n")
access_token = cognito_auth.get_access_token({
"username": os.environ["TEST_USER_EMAIL"],
"password": os.environ["TEST_USER_PASSWORD"]
})
data = {
"client_code": "999999.9.9",
"name": "AUTOMATED TEST CLIENT",
"short_name": "AUTOMATED TEST CLIENT",
"br_cnpj": "123809128312",
"br_im": "213798238974324",
"br_ie": "7893248932794324",
"address_id": 7665,
"is_inserted": False,
"skin_id": 1,
"plan_id": 1,
"organization": "CFR-100000",
"is_api_connected": False
}
response = client.post('http://localhost:5000/dev/api/client', json=data, headers={
"Authorization": f"Bearer {access_token}"
})
print("THE RESPONSE")
print(response.json)
According to this doc, everything should be fine, but instead, I get the following postgres error:
{'error': {'code': 500, 'type': '/errors/internal-server-error', 'message': '(psycopg2.errors.InvalidTextRepresentation) invalid input syntax for type integer: ""\nLINE 1: ... plan_id, organization, is_api_connected) VALUES (\'\', \'99999...\n ^\n\n[SQL: INSERT INTO tb_client (client_id, client_code, name, short_name, br_cnpj, br_im, br_ie, address_id, is_inserted, skin_id, plan_id, organization, is_api_connected) VALUES (%(client_id)s, %(client_code)s, %(name)s, %(short_name)s, %(br_cnpj)s, %(br_im)s, %(br_ie)s, %(address_id)s, %(is_inserted)s, %(skin_id)s, %(plan_id)s, %(organization)s, %(is_api_connected)s) ON CONFLICT ON CONSTRAINT tb_client_client_code_key DO NOTHING]\n[parameters: {\'client_id\': \'\', \'client_code\': \'999999.9.9\', \'name\': \'AUTOMATED TEST CLIENT\', \'short_name\': \'AUTOMATED TEST CLIENT\', \'br_cnpj\': \'123809128312\', \'br_im\': \'213798238974324\', \'br_ie\': \'7893248932794324\', \'address_id\': 7665, \'is_inserted\': False, \'skin_id\': 1, \'plan_id\': 1, \'organization\': \'CFR-100000\', \'is_api_connected\': False}]\n(Background on this error at: http://sqlalche.me/e/13/9h9h)'}}
Is the client post function seriously only expecting strings for json? It seems that the problem goes away when I use only strings, but I'm not expecting that on the API.
Even if I include "'Content-Type': 'application/json'" on the headers, I get the same error. What could be happening?
I make a request to a backend API and get the data back in json format
The response looks something like this. Kindly note that the body key values will be different and there are over 100's of them. The data1.json looks like this
[
{
"body": "[{\"task_ids\":[],\"accounts\":[],\"entity_ids\":[12814],\"guid\":\"2DFEB337-5F5D-4DF5-84CF-E951D237D448\",\"id\":\"0034030fb97251b3\",\"subject\":\"Uploaded Application\"}]",
code": 200,
"headers": {
"Content-Type": "application/json"
},
"msg": "OK",
"name": "0"
},
{
"body": "[{\"task_ids\":[],\"accounts\":[],\"entity_ids\":[12814],\"guid\":\"2DFEB337-5F5D-4DF5-84CF-E951D237D448\",\"id\":\"0034030fb97251b3\",\"subject\":\"Uploaded Application\",\}]",
code": 200,
"headers": {
"Content-Type": "application/json"
},
"msg": "OK",
"name": "0"
},
...
]
I need to get rid of the
"\" in all of the body key in the json response
Concatenate the key[body'] into one array
ideally it should look something like this.
[
{"body":"[{"task_ids":[],"accounts":[],"entity_ids":[12814],"guid":"2DFEB337-5F5D-4DF5-84CF-E951D237D448","id":"0034030fb97251b3","subject":"Uploaded Application",]","[{"task_ids":[],"accounts":[],"entity_ids":[12814],"guid":"2DFEB337-5F5D-4DF5-84CF-E951D237D448","id":"0034030fb97251b3","subject":"Uploaded Application",]",..}
]
I have tried replace and a lot of methods but none of them are replacing the \ so I cannot even go to step 2. What I did find out was if I save it to a text file the backslashes are replaced but then I cannot again send the response back as a json object. The code to get the data1.json file so far looks like this.
data = json.loads(r.text)
with open('data1.json', 'w') as outfile:
json.dump(data, outfile, sort_keys = True, indent = 4,
ensure_ascii = False)
Any suggestions on how to achieve the first points as in my desired output? Thanks.
(For starters, what you gave is invalid JSON, and json will either fail to parse it completely or produce something bogus. You need to make sure you extract the response correctly, and if this is really what the response is, have the sending party fix it.)
Now, about the question as asked:
You don't need to do anything special. That's just how JSON represents values that themselves contain JSON's special characters ("escapes" them with a backslash).
If you load the data via a proper JSON parser (e.g. json.loads()), it will undo that escaping, and in e.g. data[0]['body'], you will see proper data.
Of course, since that string is JSON itself, you will need to further parse it with json, too, if you need to split it into its meaningful parts...
The JSON data is incorrectly formatted and invalid JSON (missing quotes in "key" strings (e.g. code": 200,), invalid syntax in second dictionary body object, as mentioned in comment (e.g. "Uploaded Application\",\}]")).
However, after fixing these, a simple str.replace() statement can be used to get the expected JSON format. Then, simply parse the JSON content and build the desired list:
import json
data = '''[
{
"body": "[{\"task_ids\":[],\"accounts\":[],\"entity_ids\":[12814],\"guid\":\"2DFEB337-5F5D-4DF5-84CF-E951D237D448\",\"id\":\"0034030fb97251b3\",\"subject\":\"Uploaded Application\"}]",
"code": 200,
"headers": {
"Content-Type": "application/json"
},
"msg": "OK",
"name": "0"
},
{
"body": "[{\"task_ids\":[],\"accounts\":[],\"entity_ids\":[12814],\"guid\":\"2DFEB337-5F5D-4DF5-84CF-E951D237D448\",\"id\":\"0034030fb97251b3\",\"subject\":\"Uploaded Application\"}]",
"code": 200,
"headers": {
"Content-Type": "application/json"
},
"msg": "OK",
"name": "0"
}
]'''
r = json.loads(data.replace('\\', '').replace('"[', "[").replace("]\"", "]"))
l = []
for d in r:
l.append(d)
Now inspect the contents of l:
>>> l
[{u'body': [{u'entity_ids': [12814], u'accounts': [], u'task_ids': [], u'guid': u'2DFEB337-5F5D-4DF5-84CF-E951D237D448', u'id': u'0034030fb97251b3', u'subject': u'Uploaded Application'}], u'headers': {u'Content-Type': u'application/json'}, u'code': 200, u'name': u'0', u'msg': u'OK'},
{u'body': [{u'entity_ids': [12814], u'accounts': [], u'task_ids': [], u'guid': u'2DFEB337-5F5D-4DF5-84CF-E951D237D448', u'id': u'0034030fb97251b3', u'subject': u'Uploaded Application'}], u'headers': {u'Content-Type': u'application/json'}, u'code': 200, u'name': u'0', u'msg': u'OK'}]
I am using python requests to validate mailgun email addresses.
def validateemail(emailaddress):
return requests.get(
"https://api.mailgun.net/v3/address/validate",
auth=("api", EMAILPUBLICVALIDATIONKEY ),
params={'address': emailaddress}
)
validation = validateemail(email)
validationtext = validation.json
validationtext contains the following response:
["{"address": "sdfhdd#assfuck.com", "did_you_mean": …: false, "is_role_address": false, "is_valid": tr", "ue, "mailbox_verification": "unknown", "parts": {"…: "assfuck.com", "local_part": "sdfhdd"}, "reason", "": null}"]
0: "{"address": "sdfhdd#assfuck.com", "did_you_mean": null, "is_disposable_address": false, "is_role_address": false, "is_valid": tr"
1: "ue, "mailbox_verification": "unknown", "parts": {"display_name": null, "domain": "assfuck.com", "local_part": "sdfhdd"}, "reason"
2: "": null}"
in array position 0 there is a is_validproperty. I want to see if its true or not and do some action.
everything I have tried keeps giving me errors
print(validationtext[0].is_valid)
TypeError: 'instancemethod' object has no attribute '__getitem__'
what gives?
validation.json is a function, not an attribute. If you want to get the result, you have to call the function by putting parentheses on the end, as in validationtext = validation.json().
You didn't call the validate.json function correctly. You're missing the parenthesis: validate.json()
Just a minor oversight on your end! Happens to the best of us.
I am using python requests for posting data in dpd api. If I post the data:
{
"job_id": null,
"collectionOnDelivery": false,
"invoice": null,
"collectionDate": "2012-05-01T09:00:00",
"consolidate": null,
"consignment": []
}
using requests, I am getting the response 200, with error as
{"errorCode":"1008","errorType":"Validation","errorMessage":"Invalid boolean value","obj":"collectionOnDelivery"}
I modified the value of collectionOnDelivery as 0 and tried, but got the same error message. Can anyone help in this?
I guess "null" and "false" aren't a variable or a type you created. In python it is "None" instead of "null", also you need to capitalize first letter of "false" So try this:
{
"job_id": None,
"collectionOnDelivery": False,
"invoice": None,
"collectionDate": "2012-05-01T09:00:00",
"consolidate": None,
"consignment": []
}