I have a file in my google drive, How can I update the permissions for that file in python.
Since I am very new to programming, please suggest some possible solutions.
import json
import requests
FILE_ID = '###############'
access_token = '##############'
url = 'https://www.googleapis.com/drive/v2/files/'+ FILE_ID +'/permissions'
meta_data = {
"type": "user",
"emailAddress": 'user#gmail.com',
"role": "writer"
}
headers = {'Authorization': 'Bearer ' + access_token}
response = requests.post(url, headers=headers, data=json.dumps(meta_data))
This is what I tried but I am getting "permission type required" error.
I recommend following Googles quickstart then you should be able to use the following code.
from apiclient import errors
# ...
def update_permission(service, file_id, permission_id, new_role):
"""Update a permission's role.
Args:
service: Drive API service instance.
file_id: ID of the file to update permission for.
permission_id: ID of the permission to update.
new_role: The value 'owner', 'writer' or 'reader'.
Returns:
The updated permission if successful, None otherwise.
"""
try:
# First retrieve the permission from the API.
permission = service.permissions().get(
fileId=file_id, permissionId=permission_id).execute()
permission['role'] = new_role
return service.permissions().update(
fileId=file_id, permissionId=permission_id, body=permission).execute()
except errors.HttpError, error:
print 'An error occurred: %s' % error
return None
Related
I tried following this Creating Quick Links using the Branch HTTP API? , however I think there's been an update where there's no more type 2.
How do you create quick links through branch io api? Here's my current code
import requests
import json
def branch (medium,source,campaign,test,link):
url = "https://api2.branch.io/v1/url"
headers = {'Content-Type': 'application/json'}
data = json.dumps({
"branch_key": '<branch key>',
"channel": f"{source}",
"feature": f"{medium}",
"campaign": f"{campaign}",
"data":{
"$og_title":f"{name}",
"$marketing_title":"test",
"~creation_source":1,
"$og_description":f"{test}",
"~feature":f"{medium}",
"+url":f"https://lilnk.link/{test}",
"$ios_deeplink_path":f"{link}",
"$android_deeplink_path":f"{link}",
"~marketing":'true',
"$one_time_use":'false',
"~campaign":"testing",
"~channel":f"{source}"
})
resp = requests.post(url, headers=headers, data=data)
print(resp.status_code)
This actually gets a 200 code, however I did not find it in the quick links.
I've checked through network where the url is supposed to be https://dashboard.branch.io/v1/link/marketing
and tried using the payload. However 403 error occurs.
How can I create a quicklink?
I am trying to send a POST request to a Google App Engine service with a JSON body accompanied by an authorization token. I am generating the access token from a local service account key JSON file. The code below is generating a credential but finally the authorization is being rejected. I also tried different ways already. Even tried writing the request in Postman with a Bearer token in the Header, or even as a plain cURL command. But whatever I try, getting a 401 authentication error. I need to make sure whether the problem is in my side or on the other side with the service. Explored every documentation avaliable but no luck.
from google.auth.transport import requests
from google.oauth2 import service_account
from google.auth.transport.requests import AuthorizedSession
CREDENTIAL_SCOPES = ["https://www.googleapis.com/auth/cloud-platform"]
CREDENTIALS_KEY_PATH = 'my-local-service-account-key-file.json'
#the example service url I am trying to hit with requests
url = 'https://test.appspot.com/submit'
headers = {"Content-Type": "application/json"}
#example data I am sending with the request body
payload = {
"key1": "value 1",
"key2": "value 2"
}
credentials = service_account.Credentials.from_service_account_file(
CREDENTIALS_KEY_PATH,
scopes=CREDENTIAL_SCOPES
)
credentials.refresh(requests.Request())
authed_session = AuthorizedSession(credentials)
response = authed_session.request('POST',
url,
headers=headers,
data=payload
)
#adding some debug lines for your help
print(response.text)
print(response.status_code)
print(response.headers)
Getting the Output:
Invalid IAP credentials: Unable to parse JWT
401
{'X-Goog-IAP-Generated-Response': 'true', 'Date': 'Mon, 03 May 2021 06:52:11 GMT', 'Content-Type': 'text/html', 'Server': 'Google Frontend', 'Content-Length': '44', 'Alt-Svc': 'h3-29=":443"; ma=2592000,h3-T051=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"'}
IAP expects a JWT(OpenID Connect (OIDC)) token in the Authorization header while your method will attach an access token the the Authorization header instead. Take a look at the below code snippet to make a request to an IAP secured resource.
Your code needs to be something like the following:
from google.auth.transport.requests import Request
from google.oauth2 import id_token
import requests
def make_iap_request(url, client_id, method='GET', **kwargs):
"""Makes a request to an application protected by Identity-Aware Proxy.
Args:
url: The Identity-Aware Proxy-protected URL to fetch.
client_id: The client ID used by Identity-Aware Proxy.
method: The request method to use
('GET', 'OPTIONS', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE')
**kwargs: Any of the parameters defined for the request function:
https://github.com/requests/requests/blob/master/requests/api.py
If no timeout is provided, it is set to 90 by default.
Returns:
The page body, or raises an exception if the page couldn't be retrieved.
"""
# Set the default timeout, if missing
if 'timeout' not in kwargs:
kwargs['timeout'] = 90
# Obtain an OpenID Connect (OIDC) token from metadata server or using service
# account.
open_id_connect_token = id_token.fetch_id_token(Request(), client_id)
# Fetch the Identity-Aware Proxy-protected URL, including an
# Authorization header containing "Bearer " followed by a
# Google-issued OpenID Connect token for the service account.
resp = requests.request(
method, url,
headers={'Authorization': 'Bearer {}'.format(
open_id_connect_token)}, **kwargs)
if resp.status_code == 403:
raise Exception('Service account does not have permission to '
'access the IAP-protected application.')
elif resp.status_code != 200:
raise Exception(
'Bad response from application: {!r} / {!r} / {!r}'.format(
resp.status_code, resp.headers, resp.text))
else:
return resp.text
Note: The above method works with implicit credentials that can be set by running command: export GOOGLE_APPLICATION_CREDENTIALS=my-local-service-account-key-file.json to set the path to your service account in the environment and then run the python code from the same terminal.
Take a look at this link for more info.
I am fetching google photos from my account using Google Photo API. Now there is a need for me to execute that php file via terminal, but the problem is that I can't authenticate with Google API in doing so. Is there a way to do this, and if yes, then how shall it be done?
Yes, it is possible, you need an interactive login for the first authentication but then you can save the token and refresh it automatically as required.
I have implemented this class in Python to do just that.
from requests.adapters import HTTPAdapter
from requests_oauthlib import OAuth2Session
from pathlib import Path
from urllib3.util.retry import Retry
from typing import List, Optional
from json import load, dump, JSONDecodeError
import logging
log = logging.getLogger(__name__)
# OAuth endpoints given in the Google API documentation
authorization_base_url = "https://accounts.google.com/o/oauth2/v2/auth"
token_uri = "https://www.googleapis.com/oauth2/v4/token"
class Authorize:
def __init__(
self, scope: List[str], token_file: Path,
secrets_file: Path, max_retries: int = 5
):
""" A very simple class to handle Google API authorization flow
for the requests library. Includes saving the token and automatic
token refresh.
Args:
scope: list of the scopes for which permission will be granted
token_file: full path of a file in which the user token will be
placed. After first use the previous token will also be read in from
this file
secrets_file: full path of the client secrets file obtained from
Google Api Console
"""
self.max_retries = max_retries
self.scope: List[str] = scope
self.token_file: Path = token_file
self.session = None
self.token = None
try:
with secrets_file.open('r') as stream:
all_json = load(stream)
secrets = all_json['installed']
self.client_id = secrets['client_id']
self.client_secret = secrets['client_secret']
self.redirect_uri = secrets['redirect_uris'][0]
self.token_uri = secrets['token_uri']
self.extra = {
'client_id': self.client_id,
'client_secret': self.client_secret}
except (JSONDecodeError, IOError):
print('missing or bad secrets file: {}'.format(secrets_file))
exit(1)
def load_token(self) -> Optional[str]:
try:
with self.token_file.open('r') as stream:
token = load(stream)
except (JSONDecodeError, IOError):
return None
return token
def save_token(self, token: str):
with self.token_file.open('w') as stream:
dump(token, stream)
self.token_file.chmod(0o600)
def authorize(self):
""" Initiates OAuth2 authentication and authorization flow
"""
token = self.load_token()
if token:
self.session = OAuth2Session(self.client_id, token=token,
auto_refresh_url=self.token_uri,
auto_refresh_kwargs=self.extra,
token_updater=self.save_token)
else:
self.session = OAuth2Session(self.client_id, scope=self.scope,
redirect_uri=self.redirect_uri,
auto_refresh_url=self.token_uri,
auto_refresh_kwargs=self.extra,
token_updater=self.save_token)
# Redirect user to Google for authorization
authorization_url, _ = self.session.authorization_url(
authorization_base_url,
access_type="offline",
prompt="select_account")
print('Please go here and authorize,', authorization_url)
# Get the authorization verifier code from the callback url
response_code = input('Paste the response token here:')
# Fetch the access token
self.token = self.session.fetch_token(
self.token_uri, client_secret=self.client_secret,
code=response_code)
self.save_token(self.token)
# note we want retries on POST as well, need to review this once we
# start to do methods that write to Google Photos
retries = Retry(total=self.max_retries,
backoff_factor=0.1,
status_forcelist=[500, 502, 503, 504],
method_whitelist=frozenset(['GET', 'POST']),
raise_on_status=False)
self.session.mount('https://', HTTPAdapter(max_retries=retries))
I'm using the following code to fetch data from Firebase on Raspberry pi but it shows following error. However i'm able to fetch data without authentication.
from firebase.firebase import FirebaseApplication
from firebase.firebase import FirebaseAuthentication
firebase = firebase.FirebaseApplication('https://myapp.firebaseio.com/',
authentication =None)
authentication = firebase.Authentication('secretkey',
'prateekrai266#gmail.com', extra={'id': 123})
firebase.authentication = authentication
print (authentication.extra)
user = authentication.get_user()
print (user.firebase_auth_token)
result = firebase.get('/messages', None)
it shows following error
Traceback (most recent call last):
File "/home/pi/code/dataauth.py", line 7, in authentication =
firebase.Authentication('secretkey', 'prateekrai266#gmail.com',
extra={'id': 123}) AttributeError: 'FirebaseApplication' object has no
attribute 'Authentication'
I'm able to fetch data without authentication i.e. setting rules to true, by following code
from firebase.firebase import FirebaseApplication
firebase = firebase.FirebaseApplication('https://myapp.firebaseio.com/',
None)
result = firebase.get('/messages', None)
I presume you are using python-firebase which is a bit deprecated and not updated for long time. I've tried to fix your problem, found solution for your issue, but problem with authenticating still occurs.
Code:
from firebase.firebase import FirebaseApplication
from firebase.firebase import FirebaseAuthentication
DSN = config['databaseURL'] # 'https://myapp.firebaseio.com/'
SECRET = config['userPass'] # 'secretkey'
EMAIL =config['userEmail'] # 'prateekrai266#gmail.com'
authentication = FirebaseAuthentication(SECRET,EMAIL, True, True)
firebase = FirebaseApplication(DSN, authentication)
firebase.get('/messages', None)
I would suggest to move into pyrebase which is more updated and as I've just checked works.
https://github.com/thisbejim/Pyrebase
Code that works for me:
import pyrebase
config = {
'apiKey': "YYY",
'authDomain': "XXXXXXXX.firebaseapp.com",
'databaseURL': "https://XXXXXXXX.firebaseio.com",
'projectId': "XXXXXXXX",
'storageBucket': "XXXXXXXX.appspot.com",
'messagingSenderId': "ZZZ",
}
firebase = pyrebase.initialize_app(config)
userEmail = 'youremailadresthatyouaddedtofirebasedatabaseauthenticatedusers'
userPass = 'yourpasswordsetupforthisemail'
auth = firebase.auth()
# Log the user in
user = auth.sign_in_with_email_and_password(userEmail, userPass)
# Get a reference to the database service
db = firebase.database()
# data to save
data = {
"name": "Mortimer 'Morty' Smith"
}
# Pass the user's idToken to the push method
results = db.child("test").push(data, user['idToken'])
print results
results = db.child("test").get(user['idToken'])
print results.val()
I'm getting an HTTP 500 error when trying to run the sample code (python) for inserting an activity on behalf of a user. I've set up domain wide delegation and have included all the correct scopes. I've successfully run with domain delegation for creating circles, adding people to circles, reading posts, comments and profiles but for some reason I cannot get the code to work for inserting a post on behalf of a user. Any ideas?
Code and error follow (private info redacted):
import httplib2
import pprint
from apiclient.discovery import build
from oauth2client.client import SignedJwtAssertionCredentials
SERVICE_ACCOUNT_EMAIL = 'svc-acct#developer.gserviceaccount.com'
SERVICE_ACCOUNT_PKCS12_FILE_PATH = '/path/privatekey.pem'
USER_EMAIL = 'email#domain.com'
SCOPES = ['https://www.googleapis.com/auth/plus.me',
'https://www.googleapis.com/auth/plus.stream.read',
'https://www.googleapis.com/auth/plus.stream.write',
'https://www.googleapis.com/auth/plus.circles.read',
'https://www.googleapis.com/auth/plus.circles.write',
'https://www.googleapis.com/auth/plus.profiles.read']
def authenticate():
print 'Authenticate the domain for %s' % USER_EMAIL
f = open(SERVICE_ACCOUNT_PKCS12_FILE_PATH, 'rb')
key = f.read()
f.close()
credentials = SignedJwtAssertionCredentials(SERVICE_ACCOUNT_EMAIL, key,
scope=SCOPES, sub=USER_EMAIL)
http = httplib2.Http()
http = credentials.authorize(http)
return build('plusDomains', 'v1', http=http)
def activitiesInsert(service):
user_id = 'me'
print 'Inserting activity'
result = service.activities().insert(
userId = user_id,
body = {
'object' : {
'originalContent' : 'Happy Monday! #caseofthemondays'
},
'access' : {
'items' : [{
'type' : 'domain'
}],
# Required, this does the domain restriction
'domainRestricted': True
}
}).execute()
print 'result = %s' % pprint.pformat(result)
if __name__ == '__main__':
service = authenticate()
activitiesInsert(service)
python addpost.py
Authenticate the domain for email#domain.com
Inserting activity
Traceback (most recent call last):
File "addpost.py", line 72, in
activitiesInsert(service)
File "addpost.py", line 64, in activitiesInsert
'domainRestricted': True
File "build/bdist.macosx-10.6-intel/egg/oauth2client/util.py", line 132, in
positional_wrapper
File "build/bdist.macosx-10.6-intel/egg/apiclient/http.py",
line 723, in execute
apiclient.errors.httperror
HttpError 500 when requesting https://www.googleapis.com/plusDomains/v1/people/me/activities?alt=json returned ""