Passing file and data to requests, error at every turn - python

Python 3.6.7, Requests 2.21.0
I have an issue that gives me a new error at every solution.
What I want: To send a file with data in a POST command using the requests library.
url_upload = BASE_URL + "upload?action=save"
data = {'data':{'name':'test.txt','contenttype':'text/plain', 'size':37}}
files = {'file': open('/home/user/test.txt', 'rb')}
req = session.post(url=url_upload, files=files, data=data)
The end server is using Spring (I assume) and the response text contains this error:
"net.sf.json.JSONException: A JSONObject text must begin with \'{\' at character 1 of name"
So, I try
data = json.dumps(data)
But, of course requests doesn't want that:
ValueError: Data must not be a string.
If I add the headers:
headers = {'Content-type': 'multipart/form-data'}
org.apache.commons.fileupload.FileUploadException: the request was rejected because no multipart boundary was found
Help would be appreciated.

What I needed to do was:
req = session.post(url=url_upload, files=files, data={'data': json.dumps(data)})
That way I'm giving the function variable 'data' the form-data variable name 'data' which contains the variable that has the key 'data'...
http://www.trekmate.org.uk/wp-content/uploads/2015/02/Data-star-trek-the-next-generation-31159191-1024-768.png

Related

How change the encoding in POST method in CaseInsensitiveDict()?

First thank you for your time. I'm trying to do an insert using a Rest-API POST, I'm working with Python. Among my messages I have special characters that I want to keep in the destination, which by the way returns an error for them since by default the messages are in UTF-8, but I want them in "ISO-8859-1".
For this I have created the line: headers["Charset"] = "ISO-8859-1" . Python does not give me an error but I continue with the same problem.
The error is:
400 Client Error: Bad Request for url: https://api.example.com/
Here is my code:
import requests
from requests.structures import CaseInsensitiveDict
url = 'https://api.example.com/'
headers = CaseInsensitiveDict()
headers["Accept"] = "application/json"
headers["Authorization"] = "Bearer "
headers["Content-Type"] = "application/json"
headers["Charset"] = "ISO-8859-1"
collet_x = df_spark.collect()
for row in collet_x:
#insert
resp = requests.post(url, headers=headers, data=row['JSON'])
v_respuesta = resp.text
print(resp.status_code)
print(v_respuesta)
How else can I change the encoding?
From already thank you very much.
Regards

requests.post returns isSuccess:false even though Postman returns true

I am trying to post some information into an API based on their recommended format. When I use Postman( tool to test APIs), I see that the response has the isSuccess flag set to true. However, when I write the same code in Python using the requests library, I get the isSuccess flag as false
As mentioned about, I verified the headers and the json data object, both are the same yet the results defer
import requests
data = {"AccountNumber":"100007777",
"ActivityID":"78",
"ActivityDT":"2019-08-07 12:00:00",
"ActivityValue":"1"
}
url = "http://<IP>/<API_PATH>"
headers = {
"X-Tenant":"Default",
"Content-Type":"application/json"
}
response = requests.post(url,data=data, headers = headers)
print(response.content)
This code should successfully post the data and I should get a isSuccess:true in my response variable.
Can anyone help me figure out what might be wrong?
Can you try to change;
response = requests.post(url,data=data, headers = headers)
to;
response = requests.post(url,json=data, headers = headers)
or;
response = requests.post(url,body=data, headers = headers)

Getting an error with syntax getting a JSON file

I'm having a problem building a Twitter random quotes generator API. I'm following this tutorial:
https://www.twilio.com/blog/build-deploy-twitter-bots-python-tweepy-pythonanywhere
But I get an error that he doesn't have. This is the code:
import requests
api_key = '*****'
api_url = 'https://andruxnet-random-famous-quotes.p.rapidapi.com'
headers = {'afd9cbe77emshf06f5cb2f889689p1ca1c3jsne6e79ad808cc' :
api_key, 'http://andruxnet-random-famous-quotes.p.rapidapi.com' :
api_url}
# The get method is called when we
# want to GET json data from an API endpoint
quotes = requests.get(quotes = requests.get(api_url,
headers=headers)
print(quotes.json())
And this is the error:
File "twitter_bot.py", line 12
print(quotes.json())
SyntaxError: invalid syntax
What am I doing wrong?? (I put *** on the key on purpose, I know the proper key is supposed to go there)
Thank you!
You have a copy-and-paste error; somehow you've put quotes = requests.get( twice.
It should just be:
# The get method is called when we
# want to GET json data from an API endpoint
quotes = requests.get(api_url, headers=headers)
print(quotes.json())
Tutorial is not so old but it seems it is already out of date.
Using example from RapidAPI documentation (for Random Famous Quotes API) I created Python's code which gives some information from server (but still not quotes)
import requests
url = "https://andruxnet-random-famous-quotes.p.rapidapi.com/?count=10&cat=famous"
headers={
"X-RapidAPI-Host": "andruxnet-random-famous-quotes.p.rapidapi.com",
"X-RapidAPI-Key": "afd9cbe77emshf06f5cb2f889689p1ca1c3jsne6e79ad808cc",
}
quotes = requests.get(url, headers=headers)
print(quotes.text)
#print(quotes.json())
Result:
{"message":"You are not subscribed to this API."}
The same for POST
import requests
url = "https://andruxnet-random-famous-quotes.p.rapidapi.com/?count=10&cat=famous"
headers={
"X-RapidAPI-Host": "andruxnet-random-famous-quotes.p.rapidapi.com",
"X-RapidAPI-Key": "afd9cbe77emshf06f5cb2f889689p1ca1c3jsne6e79ad808cc",
"Content-Type": "application/x-www-form-urlencoded"
}
quotes = requests.post(url, headers=headers)
print(quotes.text)
#print(quotes.json())
Result:
{"message":"You are not subscribed to this API."}
It still need some work to get quotes.

How to call an API using Python Requests library

I can't figure out how to call this api correctly using python urllib or requests.
Let me give you the code I have now:
import requests
url = "http://api.cortical.io:80/rest/expressions/similar_terms?retina_name=en_associative&start_index=0&max_results=1&sparsity=1.0&get_fingerprint=false"
params = {"positions":[0,6,7,29]}
headers = { "api-key" : key,
"Content-Type" : "application/json"}
# Make a get request with the parameters.
response = requests.get(url, params=params, headers=headers)
# Print the content of the response
print(response.content)
I've even added in the rest of the parameters to the params variable:
url = 'http://api.cortical.io:80/rest/expressions/similar_terms?'
params = {
"retina_name":"en_associative",
"start_index":0,
"max_results":1,
"sparsity":1.0,
"get_fingerprint":False,
"positions":[0,6,7,29]}
I get this message back:
An internal server error has been logged # Sun Apr 01 00:03:02 UTC
2018
So I'm not sure what I'm doing wrong. You can test out their api here, but even with testing I can't figure it out. If I go out to http://api.cortical.io/, click on the Expression tab, click on the POST /expressions/similar_terms option then paste {"positions":[0,6,7,29]} in the body textbox and hit the button, it'll give you a valid response, so nothing is wrong with their API.
I don't know what I'm doing wrong. can you help me?
The problem is that you're mixing query string parameters and post data in your params dictionary.
Instead, you should use the params parameter for your query string data, and the json parameter (since the content type is json) for your post body data.
When using the json parameter, the Content-Type header is set to 'application/json' by default. Also, when the response is json you can use the .json() method to get a dictionary.
An example,
import requests
url = 'http://api.cortical.io:80/rest/expressions/similar_terms?'
params = {
"retina_name":"en_associative",
"start_index":0,
"max_results":1,
"sparsity":1.0,
"get_fingerprint":False
}
data = {"positions":[0,6,7,29]}
r = requests.post(url, params=params, json=data)
print(r.status_code)
print(r.json())
200
[{'term': 'headphones', 'df': 8.991197733061748e-05, 'score': 4.0, 'pos_types': ['NOUN'], 'fingerprint': {'positions': []}}]
So, I can't speak to why there's a server error in a third-party API, but I followed your suggestion to try using the API UI directly, and noticed you're using a totally different endpoint than the one you're trying to call in your code. In your code you GET from http://api.cortical.io:80/rest/expressions/similar_terms but in the UI you POST to http://api.cortical.io/rest/expressions/similar_terms/bulk. It's apples and oranges.
Calling the endpoint you mention in the UI call works for me, using the following variation on your code, which requires using requests.post, and as was also pointed out by t.m. adam, the json parameter for the payload, which also needs to be wrapped in a list:
import requests
url = "http://api.cortical.io/rest/expressions/similar_terms/bulk?retina_name=en_associative&start_index=0&max_results=1&sparsity=1.0&get_fingerprint=false"
params = [{"positions":[0,6,7,29]}]
headers = { "api-key" : key,
"Content-Type" : "application/json"}
# Make a get request with the parameters.
response = requests.post(url, json=params, headers=headers)
# Print the content of the response
print(response.content)
Gives:
b'[[{"term":"headphones","df":8.991197733061748E-5,"score":4.0,"pos_types":["NOUN"],"fingerprint":{"positions":[]}}]]'

Google returning 400 Parse Error

I've recently been getting a 400 bad request parse error when making a request to my timeline_url.
Im posting to this url timeline_url = 'https://www.googleapis.com/mirror/v1/timeline'
EDIT
Here is the code:
headers = {'Content-Type': 'application/json',
'Authorization' : 'Bearer %s' % access_token}
body = {"text" : "Waddup doe!"}
""" ***********THIS IS RETURNING ERROR 400 PARSE ERROR***********"""
send_request(timeline_url, headers, 'POST',body)
The send_request method is using requests
req = requests.post(url, data=body, headers=headers)
I'm just trying to insert plain text to my timeline.
body_bytes = sys.getsizeof(body)
headers['Content-Length'] = body_bytes
This is inserting an incorrect value into your request headers. sys.getsizeof describes how large the data structure is -- including pointers, counters, etc. It does NOT describe how many bytes the string representation takes on the HTTP stream.
Just delete these lines; requests will fill in Content-Length automatically.
You don't describe how you json-encode the payload. Perhaps you need to do this:
req = requests.post(url, data=json.dumps(body), headers=headers)
See: http://docs.python-requests.org/en/latest/user/quickstart/#more-complicated-post-requests

Categories

Resources