unable to run requests for flask on internal server - python

Running a server on
> http://127.0.0.1:5000/
and trying to do a post request (the actual code is a bit more complicated but this is the part I cannot get working). Basically, trying to get something like the following to work but this returns and error saying its not found.
r = requests.post('http://127.0.0.1:5000/api/user')
I also tried something like the following but it returns:
url = url_for('api.userlistapi')
payload = {'email':email, 'password':password,'profile_verified':False}
r = requests.post(url)
self.prepare_url(url, params)
File "....appp/flask/lib/python2.7/site-packages/requests/models.py", line 360, in prepare_url
"Perhaps you meant http://{0}?".format(url))
MissingSchema: Invalid URL u'/api/user': No schema supplied. Perhaps you meant http:///api/user?
Any help would be appreciated! It might just be something dumb with routing or that a post request should be done differntly? I am also using angular and those requests to the same domain work.

You were on the right tracks with the second solution you tested.
You just have to add _external=True to url_for arguments:
url = url_for('api.userlistapi', _external=True)
payload = {'email':email, 'password':password,'profile_verified':False}
r = requests.post(url)
This way, Flask is able to construct a full url with domain included. Otherwise, url_for only builds a relative url meant to be called from within your domain.
--
Also, as a side note, you can pass your parameters directly with requests the following way:
r = requests.post(url, params=payload)
But it depends on other factors in the rest of your code, based on what you want to do.

Related

python requests with slash parameters for exchange API

I am trying to use the request with the post method. And one of my parameters has "/"(slash) so the response turns into an error. When I look at the post URL then it seems "/" was written as "%2F". The code and results are like following:
link="https://api.someexchange.com"
sub_url="/open/v1/orders"
stamp = str(int(time.time())*1000)
headers={}
headers["Content-Type"]="application/x-www-form-urlencoded"
parameters={"symbol":"BTC/TRY",
"side":1,
"type":1,
"quantity":0.001,
"price":321000,
"timestamp":stamp,
"api_key":"api_key"}
r=requests.post(link+sub_url,params=parameters,headers=headers)
print(r.url)
'https://api.someexchange.com/open/v1/orders?symbol=BTC%2FTRY&side=1&type=1&quantity=0.001&price=321000&timestamp=1669994305000&api_key=api_key'
as you can see, the URL has "BTC%2FTRY" instead of "BTC/TRY" when I try manually from the URL bar, It works fine.

Hasura API with Python POST gives 404 Error

I'm trying to use the Hasura API to get the contents of my database. The appropriate endpoint is v1alpha1/pg_dump.
I've tried doing the following in Python:
import requests
api_url = 'http://localhost:9695/v1alpha1/pg_dump'
header = {'Content-Type': 'application/json',
'x-hasura-admin-secret': 'MY_SECRET',
'X-Hasura-Role': 'admin'}
r = requests.post(url=api_url, headers=header)
If I do requests.get, I get information back (html code, although nothing particularly useful). However, if I do requests.post (which is required by Hasura: https://hasura.io/docs/1.0/graphql/core/api-reference/pgdump.html), I get a 404 error. I don't understand why. It's not an authentication error, but a page not found error.
Have I built my url incorrectly? Is there something I'm missing? The port is correct (and if I change it in the code, it gives me a different error telling me the port is invalid/closed). I'm not sure what else to change.
So, I have tried in my own Digital Ocean 1 click deployment environment. I have not secured it so I am not providing any headers. It works fine as follows:
import requests
import json
r = requests.post('http://address_of_hasura/v1alpha1/pg_dump',
data = json.dumps({
'opts' : ['-O', '-x', '--schema-only', '--schema', 'public'],
'clean_output': True
}) )
print r.text
If you have used the HASURA_GRAPHQL_ENABLED_APIS env variable and not included pgdump, that could be a reason it would be disabled.

Why does requests.post raise 404 Not found code?

does anyone have any idea, why the output of this script, where i use requests.post to login is code 404, Not found, and the same script, where I use only requests.get has code 200 OK? What should I change?
import requests
URL = 'https://www.stratfor.com/login'
session = requests.Session()
page = session.post(URL)
print(page.status_code, page.reason)
Thank you.
it seem to be worked with get request and should returned 405 but it depends on the server
One good way to note the right page to log in is to log the network calls.
After looking at the calls, a request is sent to
URL = https://www.stratfor.com/api/v3/user/login
The API endpoint actually expects a payload like this:
payload = {username: "YOU_USER", password: "YOUR_PASS"}
Try something like this:
r = requests.post(URL,json=payload)
You might need to pass more headers, which you can poke the network call log for. Although, it seems like that user and password are passed as raw strings here? If so, that's definitely not safe.

Python requests module not passing params in session

I am using am attempting to do a bulk download of a series of PDFs from a site that requires login authentication. I am able to successfully log in, however, when I attempt a GET request for '/transcripts/transcript.pdf?user_id=3007' but, the request returns the content for '/transcripts/transcript.pdf'.
Does anyone have any idea why the URL param is not sending? Or why it would be rerouted?
I have tried passing the parameter 'user_id' as data, params, and hardcoded in the URL.
I have removed the actual domain from the strings below just for privacy
with requests.Session() as s:
login = s.get('<domain>/login/canvas')
# print the html returned or something more intelligent to see if it's a successful login page.
print(login.text)
login_html = lxml.html.fromstring(login.text)
hidden_inputs = login_html.xpath(r'//form//input[#type="hidden"]')
form = {x.attrib["name"]: x.attrib["value"] for x in hidden_inputs}
print("form: ",form)
form['pseudonym_session[unique_id]']= username
form['pseudonym_session[password]']= password
response = s.post('<domain>/login/canvas',data=form)
print(response.url, response.status_code) # gets <domain>?login_success=1 200
# An authorised request.
data = { 'user_id':'3007'}
r = s.get('<domain>/transcripts/transcript.pdf?user_id=3007', data=data)
print(r.url) # gets <domain>/transcripts/transcript.pdf
print(r.status_code) # gets 200
with open('test.pdf', 'wb') as f:
f.write(r.content)
GET response returns /transcripts/transcript.pdf and not /transcripts/transcript.pdf?user_id=3007
From the looks of it, you are trying to use canvas. I'm pretty sure in canvas, you can bulk download all test attachments.
If that's not the case, There are a few things to try:
after logging in, try typing the url with user_id into a browser. Does that take you directly to the PDF file or links to one?
if so, look at the url, it may simply not display the parameters; some websites do this, don't worry about it
If not, GET may not be enough; perhaps the site uses javascript, etc.
after looking through the '.history' of the request I found a series of 302 redirects.
The first was to '/login?force_login=0&target_uri=%2Ftranscripts%2Ftranscript.pdf'
In a desperate attempt, I tried: s.get('/login?force_login=0&target_uri=%2Ftranscripts%2Ftranscript.pdf%3Fuser_id%3D3007') and this still rerouted me a few times but ultimately got me the file I wanted!
If anyone has a more elegant solution to this or any resources that I can read I would greatly appreciate it!

How can i post using Python urllib in html input type submit [duplicate]

I'm trying to create a super-simplistic Virtual In / Out Board using wx/Python. I've got the following code in place for one of my requests to the server where I'll be storing the data:
data = urllib.urlencode({'q': 'Status'})
u = urllib2.urlopen('http://myserver/inout-tracker', data)
for line in u.readlines():
print line
Nothing special going on there. The problem I'm having is that, based on how I read the docs, this should perform a Post Request because I've provided the data parameter and that's not happening. I have this code in the index for that url:
if (!isset($_POST['q'])) { die ('No action specified'); }
echo $_POST['q'];
And every time I run my Python App I get the 'No action specified' text printed to my console. I'm going to try to implement it using the Request Objects as I've seen a few demos that include those, but I'm wondering if anyone can help me explain why I don't get a Post Request with this code. Thanks!
-- EDITED --
This code does work and Posts to my web page properly:
data = urllib.urlencode({'q': 'Status'})
h = httplib.HTTPConnection('myserver:8080')
headers = {"Content-type": "application/x-www-form-urlencoded",
"Accept": "text/plain"}
h.request('POST', '/inout-tracker/index.php', data, headers)
r = h.getresponse()
print r.read()
I am still unsure why the urllib2 library doesn't Post when I provide the data parameter - to me the docs indicate that it should.
u = urllib2.urlopen('http://myserver/inout-tracker', data)
h.request('POST', '/inout-tracker/index.php', data, headers)
Using the path /inout-tracker without a trailing / doesn't fetch index.php. Instead the server will issue a 302 redirect to the version with the trailing /.
Doing a 302 will typically cause clients to convert a POST to a GET request.

Categories