python requests.post is interpreted as GET - python

I am interfacing with an external API using python's request module. When I submit the request using requests.post() the API returns with
{"Message":"The requested resource does not support http method 'GET'."}
When I try the exact same request with my browser's RESTED client (also using POST method), it works just fine.
Not really much in the way of sample code to give, it's just a simple
r = requests.post(url, data=data, headers=headers)
It would seem the fault is either on the API's side and/or python for not submitting an entirely standard POST request (since it works with RESTED). Has anyone ever run into this scenario before? Is there a python alternative to requests.post()?
I'm on Python 3.9.1 on Windows.

Related

Python external gRPC request using wrong protocal

I am writing an API for a website that involves making a request to their API. The link looks like this - https://search.api.company.com/company.content.search.v1.Search/Search.
The data looks very weird when viewed in dev tools shows a very odd payload being sent- The payload, as well as a very odd payload being received. My current python code is this
import requests
r = requests.post("https://search.api.company.com/company.content.search.v1.Search/Search")
print(r.text)
And my error is this -
gRPC requires HTTP/2
Is there any way to fix this?

GET request with files argument in requests library Python

I find this code and I really don't understand it, how is it possible to send data (not query) with GET request
response = requests.get(
check_all_info_url_2, files=multipart_form_data, timeout=30)
and what is files= argument in the get request.
Since requests.get is just a wrapper function this will just call requests.request. Unless requests.session implementes any checking, it will happily send off a GET request with multipart data in it.
Is this valid? Not to my knowledge, although I'm willing to be proven wrong. No api I have ever written would accept file upload on a GET request. But not every server will even check the method, so perhaps this code is interacting with a badly written server which doesn't reject for wrong method, or perhap's it's even interacting with a worse server which expects file upload with GET. There are lots of broken servers out there ;)
In any case, the reason this works with requests is that it just passes keyword arguments through to the underlying session without performing any kind of validation.

Python requests call fails with HTTPS

I am running a Flask restful API behind an NGINX web server on AWS. I am hitting that with a python module from my Pi.
Everything worked fine when I was using HTTP to make calls to the api. But I just locked down my api so only HTTPS is possible. I changed the UIRL used by my python module but it now fails. The code is quite simple...here is an extract:
jsonpkg = {'subscriberID': self.api_login, 'token': self.api_token,
'content': speech_content}
headers = {'Content-Type': 'application/json'}
r = requests.post(self.api_apiurl, data=json.dumps(jsonpkg), headers=headers)
The values are being correct set by the class init section. And I am importing the requests module at the top. Error messages indicate it is using python 2.7. However when I monitor the API I can see its not even hitting the server. I can point a browser to the api and its working fine.
Am I to understand the requests module in python 2.7 does not support https?
Are there additional parameters I need to send for https?
Aha! With a little more digging into the request module docs I found the answer. If I use the following
r = requests.post(self.api_apiurl, data=json.dumps(jsonpkg), headers=headers, verify=False)
then it works. So the issue is with verifying the cert. I am not quite sure why the browser gets by without this...but perhaps it does the extra stuff automatically. So I either need to NOT verify the cert or have a local copy(?) that can be verified.
Final Update:
I finally worked out how to concatenate my site certificate with the chain certificate (and understand why). This site here was a great help. Also, once they are concatenated you will probably get a second error, which if you google it you will find is caused by the need for a carriage return after the first certificate and before the second (edit the resulting concatenated file with notepad). I then was able to return the post to using "verify=True" which made the warnings about no verification go away.

HTTP PUT works in RESTClient but not in Postman or Python httplib

When I do a PUT request in RESTClient it works, but it fails in the Postman Chrome extension.
I need to call the Hadoop REST API. When I use curl all is okay, as with RESTClient. It fails when I use Python httplib, as with Postman.
Here is it working in RESTClient:
Here is it failing in Postman:
It returns a java.lang.UnsupportedOperationException with the message op=NULL is not supported.
How can I send this PUT request correctly with Python's httplib? For some reason curl is not suitable here.
It looks like the endpoint you're hitting requires an op argument to be provided in the query string. You have ?op=CREATE in your RESTClient screenshot, but it doesn't appear in your Postman screenshot.
I notice also that in your RESTClient screenshot the server is responding with a redirect to add an additional parameter overwrite=false; you may need to add this parameter to your request in order for the operation to actually be carried out.

Pyramid subrequests

I need to call GET, POST, PUT, etc. requests to another URI because of search, but I cannot find a way to do that internally with pyramid. Is there any way to do it at the moment?
Simply use the existing python libraries for calling other webservers.
On python 2.x, use urllib2, for python 3.x, use urllib.request instead. Alternatively, you could install requests.
Do note that calling external sites from your server while serving a request yourself could mean your visitors end up waiting for a 3rd-party web server that stopped responding. Make sure you set decent time outs.
pyramid uses webob which has a client api as of version 1.2
from webob import Request
r = Request.blank("http://google.com")
response = r.send()
generally anything you want to override for the request you would just pass in as a parameter.
from webob import Request
r = Request.blank("http://facebook.com",method="DELETE")
another handy feature is that you can see the request as the http that is passed over the wire
print r
DELETE HTTP/1.0
Host: facebook.com:80
docs
Also check the response status code: response.status_int
I use it for example, to introspect my internal URIs and see whether or not a given relative URI is really served by the framework (example to generate breadcrumbs and make intermediate paths as links only if there are pages behind)

Categories

Resources