I am trying to access my own docs & spreadsheets via onedrive's api. I have:
import requests
client_id = 'my_id'
client_secret = 'my_secret'
scopes = 'wl.offline_access%20wl.signin%20wl.basic'
response_type = 'token' # also have tried "code"
redirect_uri = 'https://login.live.com/oauth20_desktop.srf'
base_url = 'https://apis.live.net/v5.0/'
r = requests.get('https://login.live.com/oauth20_authorize.srf?client_id=%s&scope=%s&response_type=%s&redirect_uri=%s' % (client_id, scopes, response_type, redirect_uri))
print r.text
(For my client I've also tried both "Mobile or desktop client app:" set to "Yes" and "No")
This will return the html for the user to manually click on. Since the user is me and it's my account how do I access the API without user interaction?
EDIT #1:
For those confused on what I'm looking for it would be the equivalent of Google's Service Account (OAuth2): https://console.developers.google.com/project
You cannot "bypass" the user interaction.
However you are very close to getting it to work. If you want to gain an access token in python you have to do it through the browser. You can use the web browser library to open the default web browser. It will look something like this (your app must be a desktop app):
import webbrowser
webbrowser.open("https://login.live.com/oauth20_authorize.srf?client_id=foo&scope=bar&response_type=code&redirect_uri=https://login.live.com/oauth20_desktop.srf")
This will bring you to the auth page, sign in and agree to the terms (it will differ depending on scope). It will direct you to a page where the url looks like:
https://login.live.com/oauth20_desktop.srf?code=<THISISTHECODEYOUWANT>&lc=foo
Copy this code from the browser and have your python script take it as input.
You can then make a request as described here using the code you received from the browser.
You will receive a response described here
Related
I'm working on an app using the Spotify API but I'm a bit new to all of this. I'm trying to get the Authorization Code with Proof Key for Code Exchange (PKCE) (https://developer.spotify.com/documentation/general/guides/authorization-guide/#authorization-code-flow-with-proof-key-for-code-exchange-pkce)
My problem is how do I redirect the user to the query where he has to ACCEPT the authorization and make my app to wait until the user clicks on ACCEPT. When he does this, the user will be redirected and that new URL (as the docs said) will contain the authorization code that I need to then exchange it for an authorization token.
This is my function so far to get that authorization code:
def get_auth_code(self):
code_challenge = self.get_code_challenge_PKCE()
scopes_needed = "user-read-email%20user-read-private%20playlist-read-collaborative%20playlist-modify-public%20playlist-read-private%20playlist-modify-private%20user-library-modify%20user-library-read"
endpoint = "https://accounts.spotify.com/authorize"
query = f"{endpoint}?client_id={self.client_ID}&response_type=code&redirect_uri={self.redirect_uri}&scope={scopes_needed}&code_challenge_method=S256&code_challenge={code_challenge}"
webbrowser.open(query)
Set up a web server.
To programmatially extract the access tokens you need a web server to handle the redirection after the user logs in on Spotify (which you redirected them to). Now this server can be the user pasting the URI to an input field on a terminal, but obviously this isn't ideal for user experience. It leaves room for lots of mistakes.
I've authored a Spotify Web API client, whose internals might be useful for you to examine. For example, you can use Flask to construct the server. The main principle is using one endpoint (i.e. /login) to redirect (code 307 worked for me browsers won't remember it) the user to a callback (i.e. /callback) which recieves the code parameter with which you can request an access token.
OAuth2 can be a bit of a pain to implement locally, I know. In my library I also made a similar function that you are constructing using webbrowser, but it does have the manual copy-pasting quirk. To use functions you can define yourself for brevity, the gist of it is:
verifier = secrets.token_urlsafe(32) # for PKCE, not in my library yet
url = user_authorisation_url(scope, state, verifier)
# Communicate with the user
print('Opening browser for Spotify login...')
webbrowser.open(url)
redirected = input('Please paste redirect URL: ').strip()
code = parse_code_from_url(redirected)
state_back = parse_state_from_url(redirected)
assert state == state_back # For that added security juice
token = request_user_token(code, verifier)
When writing an Azure Function in Python, I would expect to be able to access the host and function keys from the environment. Is this possible? All the examples I've seen do it by calling a get request, which seems like a lot of code to access something that I've set through the website.
This question is very similar, but not language specific.
It sounds like you want to get the response of the Host API admin/host/keys of Azure Functions as below, so please refer to Azure Functions wiki page Key management API
Here is my sample code.
# App Credentials, to get it see the figures below
username = "<your username like `$xxxxx`>"
password = "<your password>"
functionapp_name = "<your function app name>"
api_url = f"https://{functionapp_name}.scm.azurewebsites.net/api"
site_url = f"https://{functionapp_name}.azurewebsites.net"
import base64
import requests
auth_info = f"{username}:{password}"
base64_auth = base64.b64encode(str.encode(auth_info)).decode()
print(base64_auth)
jwt_resp = requests.get(f"{api_url}/functions/admin/token", headers={"Authorization": f"Basic {base64_auth}"})
jwt = jwt_resp.text.replace("\"", "", -1)
print(jwt)
keys_resp = requests.get(f"{site_url}/admin/host/keys", headers={"Authorization": f"Bearer {jwt}"})
print(keys_resp.text)
It works and its result as below.
For getting the username and password of App Credentials, please see the figures below.
Fig 1. On Azure portal, open the Platform features tab of your Function App and click the Deployment Center link
Fig 2. Select the FTP option in the first step of SOURCE CONTROL and click the Dashboard button to copy the values of Username and Password, but just use the part of Username with $ prefix as username variable in my script. Ofcouse, you also can use them in tab User Credentials tab.
Also, you can refer to my answer for the similar SO thread Unable to access admin URL of Azure Functions using PowerShell, and my figures below come from that.
Update: For using Azure Function for Python in container, please refer to the figure below to get the deployment credentials.
I am working to create a pipeline with the spotify API that logs my streaming history. I am planning to automate it by uploading it as a lambda function and scheduling it to run every few hours. I have everything mostly in order, except for that on the first run the API requires web authentication. Here is my code:
import spotipy
import spotipy.util as util
import urllib3
un = USERNAME
scope = 'user-read-recently-played'
cid = CLIENT_ID
csid = CLIENT_SECRET_ID
redr = r'http://localhost:8888/callback/'
token = util.prompt_for_user_token(un,scope,cid,csid,redr)
When this is run for the first time, this message pops up:
User authentication requires interaction with your
web browser. Once you enter your credentials and
give authorization, you will be redirected to
a url. Paste that url you were directed to to
complete the authorization.
Opened <LINK HERE> in your browser
Enter the URL you were redirected to:
And then I have to copy the link from my browser into that space. I can get the URL that I need to paste using urllib3:
req_adr = ADDRESS_IT_OPENS_IN_BROWSER
http = urllib3.PoolManager()
resp = http.request('GET',req_adr)
redrurl = resp.geturl()
But I don't know how to pass it into the input prompt from the util.prompt_for_user_token response
Any suggestions would be very welcome.
So it turns out there is a workaround. You can run it one time on a local machine and that generates a a file called .cache-USERNAME. If you include that file in your deployment package you don't have to copy/paste the URL and it is able to be automated with a lambda function in AWS.
How can i call Google+ API using access token in python, currently i am using the flow method which first exchanges the authentication url then it exchange credentials.
My code is this:
FLOW = OAuth2WebServerFlow(
client_id=client id,
client_secret=secret,
scope=scope,
user_agent=user_agent,redirect_uri=redirect_uri)
auth_uri = FLOW.step1_get_authorize_url()
credentials=FLOW.step2_exchange(code)
people_service = apiclient.discovery.build('people', 'v1',credentials=credentials)
connections = people_service.people().connections().list(resourceName='people/me').execute()
You need to actually visit the auth_uri web page, the user would log in and get an authentication code and it would redirect back to your application.
In a non-browser application you would do this out-of-band (OOB) and with redirect_uri='urn:ietf:wg:oauth:2.0:oob' and you could print(auth_uri), cut & paste it into a browser address bar and enter your user credentials.
When you get the authentication code you need to assign it to code in your script above, e.g. (for OOB):
code = input("Code: ") # raw_input() in Py2
Then the rest of your code would work fine.
I would consider looking at the oauthclient.<type>.Storage modules to store the credentials received from FLOW.step2_exchange(). So you don't necessarily need to do this exchange each time.
I'm trying to get this example to work from https://github.com/ozgur/python-linkedin. I'm using his example. When I run this code. I don't get the RETURN_URL and authorization_code talked about in the example. I'm not sure why, I think it is because I'm not setting up the HTTP API example correctly. I can't find http_api.py, and when I visit http://localhost:8080, I get a "this site can't be reached".
from linkedin import linkedin
API_KEY = 'wFNJekVpDCJtRPFX812pQsJee-gt0zO4X5XmG6wcfSOSlLocxodAXNMbl0_hw3Vl'
API_SECRET = 'daJDa6_8UcnGMw1yuq9TjoO_PMKukXMo8vEMo7Qv5J-G3SPgrAV0FqFCd0TNjQyG'
RETURN_URL = 'http://localhost:8000'
authentication = linkedin.LinkedInAuthentication(API_KEY, API_SECRET, RETURN_URL, linkedin.PERMISSIONS.enums.values())
# Optionally one can send custom "state" value that will be returned from OAuth server
# It can be used to track your user state or something else (it's up to you)
# Be aware that this value is sent to OAuth server AS IS - make sure to encode or hash it
#authorization.state = 'your_encoded_message'
print authentication.authorization_url # open this url on your browser
application = linkedin.LinkedInApplication(authentication)
http_api.py is one of the examples provided in the package. This is an HTTP server that will handle the response from LinkedIn's OAuth end point, so you'll need to boot it up for the example to work.
As stated in the guide, you'll need to execute that example file to get the server working. Note you'll also need to supply the following environment variables: LINKEDIN_API_KEY and LINKEDIN_API_SECRET.
You can run the example file by downloading the repo and calling LINKEDIN_API_KEY=yourkey LINKEDIN_API_SECRET=yoursecret python examples/http_api.py. Note you'll need Python 3.4 for it to work.