Does anybody here have any experience in using the YouTube API? I'm currently trying to automate uploading my videos by having an OAuth application, but, because its not verified, my videos get locked instantly and set to private. I cannot get my OAuth application verified due to not having a website.
Is there any other way I can do this without using an OAuth application?
def uploadClip(clip):
# Disable OAuthlib's HTTPS verification when running locally.
# *DO NOT* leave this option enabled in production.
os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1"
api_service_name = "youtube"
api_version = "v3"
client_secrets_file = "client_secrets.json"
# Get credentials and create an API client
flow = google_auth_oauthlib.flow.InstalledAppFlow.from_client_secrets_file(client_secrets_file, scopes)
credentials = flow.run_console()
youtube = googleapiclient.discovery.build(api_service_name, api_version, credentials=credentials)
request = youtube.videos().insert(
part="snippet,status",
body={
"snippet": {
"categoryId": "22",
"description": ".",
"title": "H "
},
"status": {
"privacyStatus": "public"
}
},
# TODO: For this request to work, you must replace "YOUR_FILE"
# with a pointer to the actual file you are uploading.
media_body=clip
)
response = request.execute()
Related
I'm creating an application in Azure AD as a daemon to get user phone
authentication methods using the python msal library and calling the following following endpoint GET https://graph.microsoft.com/beta/users/{id | UPN}/authentication/phoneMethods but i get the following error
{
"error": {
"code": "accessDenied",
"message": "Request Authorization failed",
"innerError": {
"message": "Request Authorization failed",
"date": "2020-11-19T19:26:28",
"request-id": "11975e07-ee6b-4bd2-9a74-7c175c5da560",
"client-request-id": "11975e07-ee6b-4bd2-9a74-7c175c5da560"
}
}
}
My app has the required application permissions to get the info i'm looking for, which are UserAuthenticationMethod.Read.All and UserAuthenticationMethod.ReadWrite.All and it already works with different end points such as GET https://graph.microsoft.com/beta/users/{id | UPN}, this is the code i'm using in order to get the access token required and call the graph api
import json
import logging
import requests
import msal
config = {
"authority": "https://login.microsoftonline.com/TENANT_NAME",
"client_id": "APP_ID",
"scope": ["https://graph.microsoft.com/.default"],
"secret": "APP_SECRET",
"endpoint": "https://graph.microsoft.com/beta/users/{USER_ID}/authentication/phoneMethods"
}
app = msal.ConfidentialClientApplication(
config["client_id"], authority=config["authority"],
client_credential=config["secret"],
)
result = None
result = app.acquire_token_silent(config["scope"], account=None)
if not result:
logging.info("No suitable token exists in cache. Let's get a new one from AAD.")
result = app.acquire_token_for_client(scopes=config["scope"])
if "access_token" in result:
graph_data = requests.get(
config["endpoint"],
headers={'Authorization': 'Bearer ' + result['access_token']}, ).json()
print("Graph API call result: ")
print(json.dumps(graph_data, indent=2))
else:
print(result.get("error"))
print(result.get("error_description"))
print(result.get("correlation_id"))
i tried to do the same thing using curl or postman and i get the exact same error, so i'm guessing it's an access token issue maybe ?
Thanks in advance
The api call does not support application permissions. You need to grant delegated permissions to the application, and then use the auth code flow to obtain the token.
Trying to deploy an App Engine instance from Python by using service account. The goal is to spin up a lot of instances, do some heavy network task (download and upload files) and shut them down afterwords.
I'm trying to do it with service account from Python runtime, but getting the following error
TypeError: Missing required parameter "servicesId"
What could be wrong or is there a better solution for such task? Thanks and the code is below:
SCOPES = ['https://www.googleapis.com/auth/cloud-platform']
SERVICE_ACCOUNT_FILE = 'service.json'
credentials = service_account.Credentials.from_service_account_file(
SERVICE_ACCOUNT_FILE, scopes=SCOPES)
gcp = build('appengine', 'v1', credentials=credentials)
res = gcp.apps().create(body={"id":"251499913983"})
app_json = {
"deployment": {
"files": {
"my-resource-file1": {
"sourceUrl": "https://storage.googleapis.com/downloader_sources/hello-world/main.py"
}
}
},
"handlers": [
{
"script": {
"scriptPath": "main.app"
},
"urlRegex": "/.*"
}
],
"runtime": "python27",
"threadsafe": True
}
res2 = gcp.apps().services().versions().create(body=app_json)
I guess you need to specify the service you want to deploy to. You could use default:
gcp.apps().services().versions().create(serviceID=default, body=app_json)
See doc for more details.
I am trying to get the list of followers via Instagram API.
At the process, Instagram API does not give me a key of pagination as follows.
I'm at Sandbox mode and creating the app for passing the review of Instagram API. Also tried to get data directly via Python library but still does not work.
Could you tell me how to get a key of pagination?
from instagram.client import InstagramAPI
access_token = "ACCESS_TOKEN"
client_secret = "CLIENT_SECRET"
api = InstagramAPI(access_token=access_token, client_secret=client_secret)
followed_by, next = api.user_followed_by()
print next # -> None
# 'pagination' key is empty.
# https://api.instagram.com/v1/users/self/followed-by.json?access_token=ACCESS_TOKEN
# {
# "pagination": {},
# "data": [
# {
# "id": "1111111111",
# "username": "xxxx_xxxx",
# "full_name": "xxxxxxxxx",
# "profile_picture": "..."
# },
# {
# "id": "2222222222",
# "username": "yyyy_yyyy",
# "full_name": "yyyyyyyyy",
# "profile_picture": "..."
# },
# ],
# "meta": {"code": 200}
# }
You will not get pagination in sandbox mode, you will only get 20 items in response in sandbox mode, once you go live after approval, you will get pagination data to request more users.
https://www.instagram.com/developer/sandbox/
The behavior of the API when you are in sandbox mode is the same as
when your app is live, but comes with the following restrictions:
Data is restricted to sandbox users and the 20 most recent media from each sandbox user
I created a web app in python to copy files between my Google Drive accounts. Public shared files to my account.
I got the following error
{
"error": {
"errors": [
{
"domain": "usageLimits",
"reason": "dailyLimitExceededUnreg",
"message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup.",
"extendedHelp": "https://code.google.com/apis/console"
}
],
"code": 403,
"message": "Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup."
}
}
I tried everything, change scopes, enable SDK in Google Console, etc. The problem is that this error seems to appear only when I am copying some files, and the app works properly for other files, even files in the same account.
I am using pydrive to handle the authentication, following how I am doing it:
def LogIn(self):
extDataDir = os.getcwd()
ext_config = os.path.join(extDataDir, 'client_secrets.json')
dir_path = extDataDir
temp_folder = extDataDir
gauth = GoogleAuth(os.path.join(extDataDir,'settings.yaml'))
gauth.DEFAULT_SETTINGS['client_config_file'] = ext_config
gauth.settings['save_credentials_file'] = os.path.join(temp_folder, "cred_copyfiles.txt")
gauth.LoadCredentialsFile(os.path.join(temp_folder, "cred_copyfiles.txt"))
if gauth.credentials is None:
# Authenticate if they're not there
gauth.LocalWebserverAuth()
elif gauth.access_token_expired:
# Refresh them if expired
try:
gauth.Refresh()
except:
gauth.LocalWebserverAuth()
else:
gauth.Authorize()
return GoogleDrive(gauth)
This is my settings.yaml
client_config_backend: settings
client_config:
client_id: my_clent_di
client_secret: my_client_secret
save_credentials: True
save_credentials_backend: file
save_credentials_file: cred_copyfiles.txt
get_refresh_token: True
oauth_scope:
- https://www.googleapis.com/auth/drive
I copy the files using as example in Google's drive API documentation
drive.auth.service.files().copy(fileId=f['id'],body={"parents": [{"kind": "drive#fileLink","id": save_folder_id}]}).execute()
Again, It seems it is not a problem with authentication, since it works for some files and not for others. Even files in the same account. Does anyone know a solution for this problem?
EDIT: Following the suggestion, I build the authentication using the DriveAPI, by passing the pydrive, and I got the same error.
I found out how to get the request:
drive.auth.service.files().copy(fileId=f['id'],body={"parents": [{"kind": "drive#fileLink","id": save_folder_id}]}).to_json()
Here the request
{"resumable_uri": null, "resumable": null, "uri": "https://www.googleapis.com/drive/v2/files/file_id/copy?alt=json", "body_size": 79, "response_callbacks": [], "body": "{\"parents\": [{\"id\": \"file_id\", \"kind\": \"drive#fileLink\"}]}", "resumable_progress": 0, "_in_error_state": false, "method": "POST", "methodId": "drive.files.copy", "headers": {"user-agent": "google-api-python-client/1.6.1 (gzip)", "content-type": "application/json", "accept-encoding": "gzip, deflate", "accept": "application/json"}}
The most likely explanation for that error message is that you are making a Drive request without an Authorization http header. I suggest try to capture the http request/response that is failing and paste that into your question.
Using the Python Quickstart example for the v4 Google Sheets API as a starting point, I've tried to make a library with read and write functions which can then be used by higher-level classes to easily interact with my sheet. This only works if I use the library itself as a script to call the read/write functions. Both read and write throw the following error if I use them after importing into an external script located in a different directory:
HttpError 404 when requesting https://sheets.googleapis.com/$discovery/v4/spreadsheets/
That URL looks malformed with "$discovery" in it.
Here's my library with a main section which works well if this library is run as a script:
# sheetlib.py
""" Google Docs Spreadsheets wrapper
"""
import httplib2
import os
import json
json.JSONEncoder.default=str
from apiclient import discovery
from oauth2client import client
from oauth2client import tools
from oauth2client.file import Storage
SCOPES = 'https://www.googleapis.com/auth/spreadsheets'
CLIENT_SECRET_FILE = 'client_secret.json'
CREDENTIAL_PATH = 'sheets.googleapis.test.json'
APPLICATION_NAME = 'Test Sheet'
SPREADSHEET_ID = 'abcdefg'
def get_credentials():
"""Gets valid user credentials from storage.
If nothing has been stored, or if the stored credentials are invalid,
the OAuth2 flow is completed to obtain the new credentials.
Returns:
Credentials, the obtained credential.
"""
store = Storage(CREDENTIAL_PATH)
print 'Environment: {}'.format(json.dumps(os.environ.__dict__['data']))
print 'Loaded store from {}: {}'.format(CREDENTIAL_PATH, json.dumps(store.__dict__))
credentials = store.get()
if not credentials or credentials.invalid:
flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
flow.user_agent = APPLICATION_NAME
credentials = tools.run_flow(flow, store)
print 'Storing credentials to ' + CREDENTIAL_PATH
return credentials
def build_service():
""" Returns service object for reading/writing to spreadsheet """
credentials = get_credentials()
print "credentials: {}".format(json.dumps(credentials.__dict__))
http = credentials.authorize(httplib2.Http())
discoveryUrl = ('https://sheets.googleapis.com/$discovery/rest?version=v4')
service = discovery.build('sheets', 'v4', http=http, discoveryServiceUrl=discoveryUrl)
print 'service: {}'.format(json.dumps(service._http.__dict__))
return service
def write(range, values):
service = build_service()
body = {
'values': values
}
service.spreadsheets().values().append(
spreadsheetId=SPREADSHEET_ID, range=range,
valueInputOption='RAW', body=body, insertDataOption='INSERT_ROWS').execute()
def read(range):
""" Pass a range to read, like 'RawData!A:E' """
service = build_service()
resp = service.spreadsheets().values().get(spreadsheetId=SPREADSHEET_ID, range=range).execute()
return resp
class Magic():
"""Reads and writes to the Magic tab of sheet"""
def spell_list(self):
return [r for r in read('Magic!A1:G100')['values'][1:]]
if __name__ == '__main__':
m = Magic()
print m.spell_list()
If I move the Magic class to another file located in a different directory and try to use imported read, it throws the 404 error:
# magic_test.py
from sheetlib import read
class BadMagic():
"""Reads and writes to the Magic tab of sheet"""
def spell_list(self):
return [r for r in read('Magic!A1:G100')['values'][1:]]
m = BadMagic()
m.spell_list()
Traceback (most recent call last):
File "magic_test.py", line 0, in main
return [r[0] for r in read('Magic!A2:A100')['values']]
File "sheetlib.py", line 0, in read
resp = service.spreadsheets().values().get(spreadsheetId=SPREADSHEET_ID, range=range).execute()
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/google-api-python-client/apiclient/http.py", line 292, in execute
raise HttpError(resp, content, self.uri)
apiclient.errors.HttpError: <HttpError 404 when requesting https://sheets.googleapis.com/$discovery/v4/spreadsheets/abcdefg/values/Magic%21A2%3AA100?alt=json returned "Not Found">
Exploring further, I see that the credentials: and service: output from the build_service() function is different depending on which script is using it:
Calling from sheetlib.py (working)
credentials:
{
"scopes": "set([u'https://www.googleapis.com/auth/spreadsheets'])",
"revoke_uri": "https://accounts.google.com/o/oauth2/revoke",
"access_token": "asdf",
"token_uri": "https://accounts.google.com/o/oauth2/token",
"token_info_uri": "https://www.googleapis.com/oauth2/v3/tokeninfo",
"token_response": {
"access_token": "asdf",
"token_type": "Bearer",
"expires_in": 3600
},
"invalid": false,
"refresh_token": "qwer",
"client_id": "1234.apps.googleusercontent.com",
"id_token": null,
"client_secret": "zxcv",
"token_expiry": "2017-03-08 17:01:42",
"store": "<oauth2client.file.Storage object at 0x10bbd6690>",
"user_agent": "Magic Sheet"
}
service:
{
"force_exception_to_status_code": false,
"forward_authorization_headers": false,
"authorizations": [],
"proxy_info": "<function proxy_info_from_environment at 0x10af9aed8>",
"follow_redirects": true,
"cache": null,
"request": "<function new_request at 0x10b3dba28>",
"connections": {},
"certificates": "<httplib2.KeyCerts object at 0x10b3df3d0>",
"optimistic_concurrency_methods": [
"PUT",
"PATCH"
],
"follow_all_redirects": false,
"timeout": null,
"ignore_etag": false,
"ca_certs": null,
"credentials": "<httplib2.Credentials object at 0x10b3df410>",
"disable_ssl_certificate_validation": false
}
Calling from magic_test.py (broken)
credentials:
{
"access_token": "asdf",
"token_uri": "https://accounts.google.com/o/oauth2/token",
"invalid": false,
"refresh_token": "qwer",
"client_id": "1234.apps.googleusercontent.com",
"id_token": null,
"client_secret": "zxcv",
"token_expiry": "2017-03-08 17:01:42",
"store": "<oauth2client.file.Storage object at 0x1101a2e50>",
"user_agent": "Accounting Sheet"
}
service:
{
"force_exception_to_status_code": false,
"forward_authorization_headers": false,
"authorizations": [],
"proxy_info": "<bound method type.from_environment of <class 'httplib2.ProxyInfo'>>",
"follow_redirects": true,
"cache": null,
"request": "<function new_request at 0x1101bae60>",
"connections": {
"https:sheets.googleapis.com": "<httplib2.HTTPSConnectionWithTimeout instance at 0x1101b1ea8>"
},
"certificates": "<httplib2.KeyCerts object at 0x1101c2890>",
"optimistic_concurrency_methods": [
"PUT",
"PATCH"
],
"follow_all_redirects": false,
"timeout": null,
"ignore_etag": false,
"ca_certs": null,
"credentials": "<httplib2.Credentials object at 0x1101c28d0>",
"disable_ssl_certificate_validation": false
}
Any clue why different parts of http2lib would be used depending on which script called it?
You may refer with this thread. Be noted that the body arg included in update(), although shown in the documentation as json, actually needs to be a regular python dictionary. Also, your 404 error means that you requested something that doesn't exist (or that it doesn't want you to know exists). Here's an article which might help you in fixing 404 error.