How to make Raw REST Call for Azure using Python - python

I am trying to make REST Call for azure using python,
Have created Access token using ADAL in python.
But getting Error called "provided Authorization header is in invalid format."
Here is the code for that:
import adal
import requests
token_response = adal.acquire_token_with_username_password(
'https://login.windows.net/abcd.onmicrosoft.com',
'user-name',
'password'
)
access_token = token_response.get('accessToken')
url = 'https://management.azure.com/subscriptions/{subscription- id}/providers/Microsoft.Network/virtualnetworks?api-version=2015-06-15'
headers = {'Content-Type': 'application/json',
'Authorization': access_token}
response = requests.get(url=url,headers = headers)
print(response.status_code)
print(response.text)
Can anyone tell me how the access-token should look like?
And is this the correct way to generate token for REST in python?
I am reffering this link for above code:
https://msdn.microsoft.com/en-us/library/azure/mt163557.aspx

As #GauravMantri said, the format of the value of the header Authorization is Bearer <access-token> that you can refer to the section Calling ARM REST APIs of the doc "Resource Manager REST APIs".
For example in the section above.
GET /subscriptions/SUBSCRIPTION_ID/resourcegroups?api-version=2015-01-01 HTTP/1.1
Host: management.azure.com
Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: application/json

You would need to prepend Bearer to your token. Something like:
headers = {'Content-Type': 'application/json',
'Authorization': 'Bearer ' + access_token}

Related

Failed to decode basic authentication token Python 3.10

I am creating script to send calls to API endpoints via simple python functions. I have the following function to retrieve my OAuth2 token (I will remove the URLs and credentials and nevermind the padding)
def get_new_token():
auth_server_url = "my auth url here"
client_id = "my client id here"
client_secret = "my secret here"
auth_headers = {'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded'}
token_req_payload = {'grant_type': 'client_credentials'}
token_response = requests.post(auth_server_url,
data=token_req_payload, verify=False, allow_redirects=False,
auth=(client_id, client_secret), headers=auth_headers)
I am then successfully retrieving token with the following line:
return token_response.json()["access_token"]
Then, I can successfully make a request to one of the endpoints, here is my function (also, nevermind the padding):
def call_api_v1_accounts(token):
api_call_headers = {
'Content-Length': '10204',
'Content-Type': 'application/json',
'User-Agent': 'removed',
'Authorization': 'Bearer ' + token}
data = {"here": "is my payload"}
api_call_response = requests.post(my_url, headers=api_call_headers, data=json.dumps(data), verify=False)
print(api_call_response.text)
This request go through fine and I retrieve the information I need, here is the sample of response (I also removed actual data due to security reasons)
{"timestamp":"2022-08-09T10:24:29.713Z","account":{"id":"omitted"},"web":{"href":"omitted"},"sdk":{"token":"omitted"},"workflowExecution":{"id":"omitted","credentials":[{"id":"omitted","category":"ID","omitted":["WEB","API","SDK"],"api":{"token":"ommitted]}]}}
Here is my problem, finally. I have another function which uses the same token, function is below (nevermind the padding)
def call_api_netverify_acquisitions(token):
api_call_headers = {
'Content-Length': '10204',
'Content-Type': 'application/json',
'User-Agent': 'removed',
'Authorization': 'Basic ' + token}
data = {'mydata':'ishere'}
api_call_response = requests.post(my_url, headers=api_call_headers, data=json.dumps(data), verify=True)
print(api_call_response.text)
And the response I receive with it is the following:
{"message":"Failed to decode basic authentication token.","httpStatus":401,"requestUri":"endpoint_url_here"}
I really have no idea what's wrong with that? I printed the len(token) and it returned 867 so I decided I need to add one more symbol to that (so it can be divided by 4), I've added "=" or "===" or "=======" and the result is the same. I understand that one function uses 'Bearer' and other one uses 'Basic', but I still have no idea what to look for.
I am really struggling, please help.

Python requests PUT

I need to send a PUT request with authentication in one time.
When I use Postman for that and input
headers = {'Authorization': 'Basic Token', 'Content-Type': 'application/json'}
Authorization = Basic Auth Username = 'login' Password = 'pass'
Body = data
everything goes well.
If I try to write request in python:
req = r.put(url, headers={'Authorization': 'Basic Token', 'Content-Type': 'application/json'}, auth=HTTPBasicAuth('login','password'), data=data)
I get response 400 Bad Request
Whats wrong with my request?
I don't know if this works for your case, but I did use Basic authentication a while ago to authenticate with the Reddit API.
Here's my code:
import requests
client_auth = requests.auth.HTTPBasicAuth("put something here","put something here")
headers = {"User-Agent": "manage your reddit easily by u/0xff"}
code = "ajkldjfalkdjflajfd;lakdjfa"
data = {
"code":code,
"grant_type":"authorization_code",
"redirect_uri":"http://127.0.0.1:3000/authorize_callback"
}
r = requests.post("https://www.reddit.com/api/v1/access_token", auth=client_auth, data=data, headers=headers);
print(r.content)
Just make the appropriate changes for your case and try it.
You are setting authorization information twice, and different HTTP libraries will handle this conflict in different ways.
HTTP Basic Authorization uses the Authorization header, encoding the username and password (separated by :) as base64 and setting the header to the value Basic plus space plus the base64 encoded string. You are telling both POSTman and requests to set the Authorization header to the string Basic Token and to use a username and password for Basic Auth, so the clients will have to make a choice between these two options.
Trying this out in requests version 2.25.1 I see that the auth information will win here:
>>> from requests import Session, Request
>>> from requests.auth import HTTPBasicAuth
>>> req = Request(
... "PUT",
... "http://example.com",
... headers={
... 'Authorization': 'Basic Token',
... 'Content-Type': 'application/json'
... },
... auth=HTTPBasicAuth('login','password'),
... data=b"{}"
... )
>>> session = Session()
>>> prepped = session.prepare_request(req)
>>> from pprint import pp
>>> pp(dict(prepped.headers))
{'User-Agent': 'python-requests/2.25.1',
'Accept-Encoding': 'gzip, deflate',
'Accept': '*/*',
'Connection': 'keep-alive',
'Authorization': 'Basic bG9naW46cGFzc3dvcmQ=',
'Content-Type': 'application/json',
'Content-Length': '2'}
The above session creates a prepared request so I can inspect the effect of the auth argument on the headers given to the request, and as you can see the Authorization header has been set to a base64 value created from the login and password pair.
It looks like Postman will do the same, the UI even tells you so:
You didn't share any details about what web service you are using or what expectations that service has for headers or request contents. If this a OAuth2-protected service, then you should not confuse obtaining a token with using that token for subsequent requests to protected URLs. For a grant_type="password" token request, it could be that the server expects you to use the username and password in a Basic Auth header, but it may also expect you to use client_id and client_secret values for that purpose and put the username and password in the POST body. You'll need to carefully read the documentation.
Other than that, you could replace your destination URL with an online HTTP echo service such as httpbin. The URL https://httpbin.org/put will give you a JSON response with the headers that the service received as well as the body of your request.
Further things you probably should be aware of:
requests can encode JSON data for you if you use the json argument, and if you do, the Content-Type header is generated for you.
You don't need to import the HTTPBasicAuth object, as auth=(username, password) (as a tuple) works too.

Setting Token Header in Python Requests

I am calling my REST services with the following command using curl
export TOKEN= '<random>'
curl -X "GET" -H "Content-Type:application/json" -H "Authorization:Bearer ${TOKEN}" http://my-server.com
I am trying to map the same code using requests library of Python
import requests
url = 'https://httpbin.org/bearer'
headers = {'Authorization': 'Bearer', 'Content-Type':'application/json'}
r = requests.get(url, headers=headers)
print(r.status_code)
My question is, how can I set my TOKEN value in the code?
The authorization token can be added in a dict form to the headers argument as shown below:
hed = {'Authorization': 'Bearer ' + auth_token,
'Content-Type': 'application/json'}
r = requests.post(url=url, headers=hed)
I suggest reading up on this https://2.python-requests.org/en/master/user/quickstart/
Just replace your current line for this one
headers = {'Authorization': 'Bearer ' + token, 'Content-Type':'application/json'}
Depends now where you get the token from, but to include the token that's the way.

Basecamp 3 API - basic projects.json call

I'm a Python user, beginner level. I'm trying to follow this instruction on Basecamp 3. Documentation: https://github.com/basecamp/bc3-api
I've successfully gone through the authorization step and was able to retrieve the access token (which consists of 3 keys: access_token, expires_in and refresh_token.
Now i'm trying to pull some actual data from Basecamp, and the most basic call is to https://3.basecampapi.com/999999999/projects.json (with 99999999 being my account number, which I have).
The instruction has an example in curl: curl -H "Authorization: Bearer $ACCESS_TOKEN" -H 'User-Agent: MyApp (yourname#example.com)' https://3.basecampapi.com/999999999/projects.json
But I cannot translate this to Python. I tried many methods of passing the keys to the header call but none works. Can anyone help me out?
Code:
url = "3.basecampapi.com/99999999/projects.json"
headers = {'Content-Type': 'application/json',
'User-Agent': 'MyApp (myemail#gmail.com)',
'access_token': 'Access_Token_String',
'expires_in': '1209600',
'refresh_token': 'Refresh_token_string'}
result = requests.post(url, headers=headers)
This is an old question, but posting an answer for anyone who happens to stumble upon this.
url = f'3.basecampapi.com/{PROJECT_ID}/projects.json'
headers = {'User-Agent': 'MyApp (myemail#gmail.com)',
'Content-Type': 'application/json; charset=utf-8',
'Authorization': f'Bearer {ACCESS_TOKEN}'
response = requests.get(url, headers=headers)
Then view the output via response.json()

Google Drive API POST requests?

I'm trying to interact with the Google Drive API and while their example is working, I'd like to learn how to make the POST requests in python instead of using their pre-written methods. For example, in python how would I make the post request to insert a file?
Insert a File
How do I add requests and parameters to the body?
Thanks!
UPDATE 1:
headers = {'Content-Type': 'application/json', 'Authorization': 'Bearer ' + 'my auth token'}
datax = {'name': 'upload.xlsx', 'parents[]': ['0BymNvEruZwxmWDNKREF1cWhwczQ']}
r = requests.post('https://www.googleapis.com/upload/drive/v3/files/', headers=headers, data=json.dumps(datax))
response = json.loads(r.text)
fileID = response['id']
headers2 = {'Authorization': 'Bearer ' + 'my auth token'}
r2 = requests.patch('https://www.googleapis.com/upload/drive/v3/files/' + fileID + '?uploadType=media', headers=headers2)
To insert a file:
Create a file in Google drive and get its Id in response
Insert a file using Id
Here are the POST parameters for both operations:
URL: 'https://www.googleapis.com/drive/v3/files'
headers: 'Authorization Bearer <Token>'
Content-Type: application/json
body: {
"name": "temp",
"mimeType": "<Mime type of file>"
}
In python you can use "Requests"
import requests
import json
headers = {'Content-Type': 'application/json','Authorization': 'Bearer <Your Oauth token' }
data = {'name': 'testing', 'mimeType': 'application/vnd.google-apps.document'}
r = requests.post(url,headers=headers,data=json.dumps(data))
r.text
Above POST response will give you an id.
To insert in file use PATCH request with following parameters
url: 'https://www.googleapis.com/upload/drive/v3/files/'<ID of file created> '?uploadType=media'
headers: 'Authorization Bearer <Token>'
Content-Type: <Mime type of file created>
body: <Your text input>
I hope you can convert it in python requests.

Categories

Resources