How do I send authenticated https requests using Python? - python

What is the equivalent Python to the following curl command?
curl https://www.streak.com/api/v1/boxes/{Keyhere}/ -u passwordhere:
I tried this but I get 400 errors:
requests.get('https://www.streak.com/api/v1/boxes/{Key}/threads -u PASSWORD:', auth=HTTPBasicAuth('USER', 'pass'))

This type of authentication is very common and the requests documentation covers it.
requests.get('https://www.streak.com/api/v1/boxes/{Key}/threads', auth=(YOUR_API_KEY, ''))
You need to remove the -u PASSWORD: from your destination.
An alternative is to use the streak_client package on PiPY or GitHub

Related

can connect to URL with curl but not with requests (i.e. requests ignoring my CA bundle?)

I am able to connect to a certain URL with cURL, after I installed the corresponding SSL certificates:
$ export MY_URL=https://www.infosubvenciones.es/bdnstrans/GE/es/convocatoria/616783
$ curl -vvvv $MY_URL # Fails
$ sudo openssl x509 -inform pem -outform pem -in /tmp/custom-cert.pem -out /usr/local/share/ca-certificates/custom-cert.crt
$ sudo update-ca-certificates
$ curl -vvvv $MY_URL # OK
However, requests (or httpx, or any other library I use) refuses to do so:
In [1]: import os
...: import requests
...: requests.get(os.environ["MY_URL"])
---------------------------------------------------------------------------
SSLCertVerificationError Traceback (most recent call last)
...
SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:997)
My understanding is that requests uses certifi and as such these custom certificates are not available here:
In [1]: import certifi
In [2]: certifi.where()
Out[2]: '/tmp/test_ca/.venv/lib/python3.10/site-packages/certifi/cacert.pem'
I have already tried a number of things, like trying to use the system CA bundle:
export REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt same error
requests.get(..., verify="/etc/ssl/certs/ca-certificates.crt") same error
switched to httpx + a custom SSL context as explained in the docs, same error
attempted truststore as discussed in this httpx issue, same error
How can I make Python (requests, httpx, raw ssl, anything) use the same certificates that cURL is successfully using?
The only thing that worked so far, inspired by this hackish SO answer, is to do verify=False. But I don't want to do that.
In [9]: requests.get(
...: my_url,
...: verify=False,
...: )
/tmp/test_ca/.venv/lib/python3.10/site-packages/urllib3/connectionpool.py:1043: InsecureRequestWarning: Unverified HTTPS request is being made to host 'xxx'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html#ssl-warnings
i tried your stuff on my system (Manjaro Linux, python 3.10) i can make a connection. I downloaded the complete certificate chain from the website (with my browser). After that i can use it with:
r = requests.get(url=URL, verify=<path to pem file>)
and with
export REQUESTS_CA_BUNDLE=<path to pem>
r = requests.get(url=URL)
I tried the export within pyCharm.
So the python stuff is working and you may have a problem in your certificates. Without this stuff i get the ssl error (of course), because python does not use the system certs as you mentioned correct. In my pem-file i have 3 certificates. Maybe you have only 1 and the others are in the global store, so that curl does not need the complete chain, instead of python. You should try to download the complete chain with your browser and try again.

python - convert curl command

I have this curl command.
This works
curl -O -H "X-Api:3433432" -X GET "https://website.com/file.zip"
Trying to figure it out how to convert it to something python understands.
curl -O -H "X-Api:3433432" -X GET "https://website/file.zip"
Perhaps you're looking for the "Requests" module?
It allows you to create a GET request in a similar way you would use a curl command.
You can find some documentation at:
https://www.w3schools.com/PYTHON/ref_requests_get.asp
Edit: There's also https://curlconverter.com/ which should convert it automatically for you.
try using module requests:
import requests
headers = {
'X-Api': '3433432',
}
response = requests.get('https://website.com/file.zip', headers=headers)

Extract Token from Curl Request

I have the following request:
curl --user world:hello http://127.0.0.1:9000/api/auth/
which returns following outpu:
{"status":"SUCCESS","token":"Mjg2NDA3NDUzMzY0MDgyMDc3NzM5NDg3MjcwODA4ODU5MTIyMjE0"}
How can I store token in a variable for later use? as below
'Content-Type': 'application/json'
'Token': 'TOKENadasfsdfsdfsdfsdsfgsfgfgfadfdgdf'
Python's json and subprocess libraries will help - just invoke the curl command from a Python subprocess, parse the resulting JSON, and save the result to a variable.
Since you are using cURL and asking for python solution I suggest passing that curl output to python and execute this code which decode input's json and print's the token:
curl --user world:hello http://127.0.0.1:9000/api/auth/ | python -c "import sys,json;print(json.load(sys.stdin)['token'])"

Curl command in Requests Python

I am trying write a python equivalent script for the cURLcommand below using Requests library. I am not able to find relevant flags to disable SSL verification and set no proxy.
curl -v -k -T debug.zip https://url-to-no-ssl-server/index.aspx --noproxy url-to-no-ssl-server -X POST -H "filename: debug.zip"
How do I convert this command to python-requests?
This SO Answer shows how to disable proxies:
session = requests.Session()
session.trust_env = False
The documentation for requests has disabling SSL verification:
Requests can also ignore verifying the SSL certificate if you set verify to False:
requests.get('https://kennethreitz.com', verify=False)
<Response [200]>
By default, verify is set to True. Option verify only applies to host certs.

Can't use CNTLM to connect to pip

I'm trying to use Pip behind a proxy server which requires authentication. I've installed cntlm and filled out the hashed passwords. When I run this:
cntlm -c cntlm.ini -I -M http://www.google.co.uk
I enter my password and then get this as a result:
Config profile 1/4... Auth not required (HTTP code: 200)
Config profile 2/4... Auth not required (HTTP code: 200)
Config profile 3/4... Auth not required (HTTP code: 200)
Config profile 4/4... Auth not required (HTTP code: 200)
Your proxy is open, you don't need another proxy.
However, pip doesn't work, still giving me a timeout. Knowing that I don't need another proxy is all fine and dandy, but pip still times out. Port 3128 is working because I can telnet on that port and it shows as listening under netstat. So what should I do from here?
Thank you.
I have had the exact same issue.
Cntlm is used for authentication proxy servers, these statements mean that your server does not require authentication.
The pip command does have a --proxy option. Try using something like:
pip install --proxy=10.0.0.1:80 package_name
If this works, you know that you don't need authentication to access the web. If it still fails try:
pip install --proxy=user:password#10.0.0.1:80 package_name
This works to get around authentication. I have written a small cmd script to get around this in windows:
#echo off
:: GetPwd.cmd - Get password with no echo.
setlocal
<nul: set /p passwd=
for /f "delims=" %%i in ('python -c "from getpass import getpass; pwd = getpass();print pwd;"') do set passwd=%%i
echo.
::Prompt for the package name
set /p package=What package would you like to get:
::Get the package with PIP
pip install --proxy="admin:%passwd%#PROXY_ADDRESS:80" %package%
endlocal

Categories