Request body has invalid json format - Python - python

I'm trying to post JSON data (RESTful API) using python.
null = none
payload = {
"priority": 1,
"hello_id": 207,
"bye_id": 207,
"s1": 1,
"s2": 2,
"sub": "CHECK 123",
"t1": "Leave",
"product_id": null,
"due": "2001-01-01T06:11:54.884Z",
"tags": [
"HelloTag"
]
}
headers = {'content-type': 'application/json'}
r = requests.post(myurl, data=json.dumps(payload), headers=headers)
(OR)
r = requests.post(myurl, json = json.dumps(payload_post), headers=headers)
(OR)
r = requests.post(myurl, data = payload_post, headers=headers, auth=(username_accadmin, password_accadmin))
(OR)
r = requests.post(myurl, json=payload, headers=headers)
None of the above 3 lines seems to yield the expected response (or) the response that I get in Postman.
In the response I get :
"Validation failed","errors":[{"field":"priority","message":"Unexpected/invalid field in request","code":"invalid_field"}]
(FOR ALL FIELDS IN THE JSON DATA)
Why is the data wrong even when I convert the dict() to JSON using dumps() method?
NOTE : If all the fields in the payload were string, the data is posted as expected.

data should be a dict or list, not a string (which the dumps) returns.
r = requests.post(myurl, json=payload, headers=headers)
See the documentation. Also, you should use None instead of null in your payload.

Related

String indicies must be integers in Python

I'm trying to get url value from the api, but have an issue saying TypeError: string indices must be integers
Here is the array that I get from api:
[
{
"created_utc": 1643524062,
"title": "title",
"url": "https://i.redd.it/tmd5shz9rre81.gif",
},
{
"created_utc": 1643530657,
"title": "title",
"url": "https://i.redd.it/qqjykysxase81.gif",
}
]
And here is the code I use to get the url:
url = "https://reddit-meme.p.rapidapi.com/memes/trending"
headers = {
"X-RapidAPI-Key": "83df5aba87msh4580fa40781b33cp12157bjsnb4b412cb57da",
"X-RapidAPI-Host": "reddit-meme.p.rapidapi.com"
}
response = requests.request("GET", url, headers=headers)
print(response.text[0]["url"])
What am I doing wrong?
response.text is a string, you have to parse it first, with the json librarie, like this:
import requests
import json
url = "https://reddit-meme.p.rapidapi.com/memes/trending"
headers = {
"X-RapidAPI-Key": "83df5aba87msh4580fa40781b33cp12157bjsnb4b412cb57da",
"X-RapidAPI-Host": "reddit-meme.p.rapidapi.com"
}
response = requests.request("GET", url, headers=headers)
data = json.loads(response.text)
print(data[0]["url"])

python dynamic value in api payload

Hey i have an api request and i need the value in payload to by dynamic, i tried with f'' but it wont make it dynamic
will appreciate your help.
import requests
url = "https://www.stie.com/api/conversations/KJQ-CZHNR-985/fields"
valuetarget = "123"
payload = {'apikey': 'zbyc88srdi333d3dpq5lye48pgg1tfo1pnjvj65ld',
'customfields': '[{"code": "orderno", "value":"valuetarget"}]'}
files = [
]
headers = {}
response = requests.request("POST", url, headers=headers, data=payload, files=files)
print(response.text)
You just need to load json and dump it to string and send it.
import json
valuetarget = "123"
payload = {
'apikey': 'zbyc88srdi333d3dpq5lye48pgg1tfo1pnjvj65ld',
'customfields':
json.dumps([{"code": "orderno", "value":valuetarget}])
}
You should escape the curly braces in the formatted string, like so:
f'[{{"code": "orderno", "value":"{valuetarget}"}}]'
But why not let requests format the string for you?
import requests
url = "https://www.stie.com/api/conversations/KJQ-CZHNR-985/fields"
valuetarget = "123"
# 'customfields' is now a list of dictionaries
payload = {'apikey': 'zbyc88srdi333d3dpq5lye48pgg1tfo1pnjvj65ld',
'customfields': [{"code": "orderno", "value": valuetarget}]}
files = [
]
headers = {}
response = requests.request("POST", url, headers=headers, data=payload, files=files)
print(response.text)

Python Requests Post within a nested Json - retrieve data with a specific value

I already look in stackoverflow and I could not find an answer to my problem.
I'm accessing an API from the German Government that has a output limit of 10.000 entries. I want all data from a specific city, and since there is more than 10.000 entries in the original database, I need to "do the query" while doing the requests.post.
Here is one entry of Json result, when I simply do request.post to this API:
{
"results":[
{
"_id":"CXPTYYFY807",
"CREATED_AT":"2019-12-17T14:48:17.130Z",
"UPDATED_AT":"2019-12-17T14:48:17.130Z",
"result":{
"id":"CXPTYYFY807",
"title":"Bundesstadt Bonn, SGB-315114, Ortsteilzentrum Brüser Berg, Fliesenarbeiten",
"description":["SGB-315114","Ortsteilzentrum Brüser Berg, Fliesenarbeiten"],
"procedure_type":"Ex ante Veröffentlichung (§ 19 Abs. 5)",
"order_type":"VOB",
"publication_date":"",
"cpv_codes":["45431000-7","45431100-8"],
"buyer":{
"name":"Bundesstadt Bonn, Referat Vergabedienste",
"address":"Berliner Platz 2",
"town":"Bonn",
"postal_code":"53111"},
"seller":{
"name":"",
"town":"",
"country":""
},
"geo":{
"lon":7.0944,
"lat":50.73657
},
"value":"",
"CREATED_AT":"2019-12-17T14:48:17.130Z",
"UPDATED_AT":"2019-12-17T14:48:17.130Z"}
}
],
"aggregations":{},
"pagination":{
"total":47389,
"start":0,
"end":0 }}
What I want is all the data which was bought in "town" : "Bonn"
What I already tryed:
import requests
url = 'https://daten.vergabe.nrw.de/rest/evergabe/aggregation_search'
headers = {'Accept': 'application/json', 'Content-Type': 'application/json'}
data = {"results": [{"result": {"buyer": {"town":"Bonn"}}}]}
#need to put the size limit, otherwise he delivers me less:
params = {'size': 10000}
req = requests.post(url, params=params, headers=headers, json=data)
This returns me the post, but not "filtered" by city.
I also tryed req = requests.post(url, params=params, headers=headers, data=data) , which returns me ERROR 400 .
Another way is to grab all the data with the pagination parameters on the end of the json code within a loop, but again I'm not being able to writwe down the json path to the pagination, for example : start: 0 , end:500
Can anyone help me solving it?
Try:
url = 'https://daten.vergabe.nrw.de/rest/evergabe/aggregation_search'
headers = {'Accept': 'application/json', 'Content-Type': 'application/json'}
query1 = {
"query": {
"match": {
"buyer.town": "Bonn"
}
}
}
req = requests.post(url, headers=headers, json=query1)
# Check the output
req.text
Edit:
This won't work if the filter matches with more than 10.000 results, but it may be a quick workaround to the problem you are facing.
import json
import requests
import math
url = "https://daten.vergabe.nrw.de/rest/vmp_rheinland"
size = 5000
payload = '{"sort":[{"_id":"asc"}],"query":{"match_all":{}},"size":'+str(size)+'}'
headers = {
'accept': "application/json",
'content-type': "application/json"
'cache-control': "no-cache"
}
response = requests.request("POST", url, data=payload, headers=headers)
tenders_array = []
query_data = json.loads(response.text)
tenders_array.extend(query_data['results'])
total_hits = query_data['pagination']['total']
result_size = len(query_data['results'])
last_id = query_data['results'][-1]["_id"]
number_of_loops = ((total_hits - size) // size )
last_loop_size = ((total_hits - size) % size)
for i in range(number_of_loops+1):
if i == number_of_loops:
size=last_loop_size
payload = '{"sort":[{"_id":"asc"}],"query":{"match_all":{}},"size":'+str(size)+',"search_after":["'+last_id+'"]}'
response = requests.request("POST", url, data=payload, headers=headers)
query_data = json.loads(response.text)
result_size = len(query_data['results'])
if result_size > 0:
tenders_array.extend(query_data['results'])
last_id = query_data['results'][-1]["_id"]
else:
break
https://gist.github.com/thiagoalencar/34401e204358499ea3b9aa043a18395f
code in the gist.
Some code to paginate through elasticsearch API. This is an API over the elasticsearch API, and the docs where not so clear. Tried scroll, no sucess. This solutions uses search_after parameter without point in time, because the endpoint is not available. Some times the servers refuses the request and it is necessary to verify with response.status_code==502.
The code is messy and need refactoring. But it works. The final tenders_array contains all objects.

JSON parsing error in django post request

I'm trying to send data through POST request in django
url = 'http://db-003:8013/v1/upgrade-ce'
payload = {
"cluster_name": cluster_name,
"cec_id": cec_id,
"new_version": new_version,
"cr_number": cr_number,
}
response = requests.post(url, data=payload)
On receiver end post method:
cluster name = request.data.get('cluster_name')
Data on receiver's end
<QueryDict: {'cluster_name': ['abcd'], 'cec_id': ['abc'], 'new_version': ['8.0.23'], 'cr_number': ['6587657']}>
The obtained data is a list, and not an individual string string.
Tried json.dumps() , but on the receiver end, data is empty.
How do i get an individual string
Sending Content-Type as application/json in headers and json.dumps(payload) should work.
url = 'http://db-003:8013/v1/upgrade-ce'
payload = {
"cluster_name": cluster_name,
"cec_id": cec_id,
"new_version": new_version,
"cr_number": cr_number,
}
headers = {'Content-Type': 'application/json'}
response = requests.post(url, data=json.dumps(payload), headers=headers)

Python - Get Request with Cookies

I've got a puzzling requests that I do not seem able to dig myself out of, despite several attempts.
Context / Workflow:
1. Logging to a webservice
2. Make a Get request
3. Obtain JSoN
Issue:
- JSON obtained by going via browser is different (read: has more data) than the one obtained via my code
My code:
with requests.Session() as s:
s.headers = {'Accept': 'application/json; indent=4', 'Content-Type': 'application/json'}
secret = {
"client_id": "xxx",
"client_secret": "yyy"
}
datas = json.dumps(secret)
url = 'https://XXXX.yyy/sign_in'
response = s.post(url, data=json.dumps(secret), headers=s.headers, verify=False)
print (s.headers)
print(response)
This part works OK, returns me a cookie, which I save on
ck = s.cookies.get_dict()
I then need to make a Get request with the cookies saved after successful login
url = 'https://give.me/tests'
print ("Connecting to: " + url)
# here we do our get, passing the cookies
response = s.get(url, cookies=ck, verify=False)
data = response.text
# print (s.headers) # is OK, returns 200
# print(data)
with open('data.txt', 'w') as f:
f.write(data)
return 0
Expected Result:
"phase": {
"type": "phase",
"activity_level": null,
"logical_name": "phase.test_manual.obsolete",
"name": "Obsolete",
"index": 4,
"id": "phase.test_manual.obsolete"
},
Actual Result:
"phase": {
"type": "phase",
"id": "phase.test_manual.obsolete"
},
Documentation, in case I'm doing something wrong functionally:

Categories

Resources