TWILIO API ERROR Credentials are required to create a TwilioClient django - python

I am trying to include TWILIO API to my project. It should send sms. I have finished tutorial, but then i get error Credentials are required to create a TwilioClient. I have credentials in .env file and then i try to import them to settings and then get this credentials from settings to views.
This is when i get error.
.env
TWILIO_ACCOUNT_SID= 'xxxxxxxxxxxxxxxxxxxxxx'
TWILIO_AUTH_TOKEN= 'xxxxxxxxxxxxxxxxxxxxxxx'
TWILIO_NUMBER= 'xxxxxxxxxxxxxxxxxx'
settings.py
import os
TWILIO_ACCOUNT_SID = os.getenv('TWILIO_ACCOUNT_SID')
TWILIO_AUTH_TOKEN = os.getenv('TWILIO_AUTH_TOKEN')
TWILIO_NUMBER = os.getenv('TWILIO_NUMBER')
SMS_BROADCAST_TO_NUMBERS = [
'+111111111',
]
views
from django.conf import settings
from django.http import HttpResponse
from twilio.rest import Client
def broadcast_sms(request):
message_to_broadcast = ("Have you played the incredible TwilioQuest "
"yet? Grab it here: https://www.twilio.com/quest")
client = Client(settings.TWILIO_ACCOUNT_SID, settings.TWILIO_AUTH_TOKEN)
for recipient in settings.SMS_BROADCAST_TO_NUMBERS:
if recipient:
client.messages.create(to=recipient,
from_=settings.TWILIO_NUMBER,
body=message_to_broadcast)
return HttpResponse("messages sent!", 200)
and here is when code work, but i want to import this from settings..
# def sms(request):
# TWILIO_ACCOUNT_SID = "xxxxxxxxxxxxxxxxxxxxxxx"
# TWILIO_AUTH_TOKEN = "xxxxxxxxxxxxxxxxx"
# TWILIO_NUMBER = "xxxxxxxxxxxxx"
# message_to_broadcast = ("Have you played the incredible TwilioQuest "
# "yet? Grab it here: https://www.twilio.com/quest")
#
# client = Client(TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN)
# for recipient in settings.SMS_BROADCAST_TO_NUMBERS:
# if recipient:
# client.messages.create(to=+xxxxxxxxx,
# from_=+xxxxxxxxxx,
# body=message_to_broadcast)
# return HttpResponse("messages sent!", 200)
Any idea how to solve this?

So you are using a .env file rather than setting your OS's environmental variables? If so, there is and article below, pointing to https://github.com/theskumar/python-dotenv.
How To Set Environment Variables

Related

I keep getting authentication errors with the Google API

I've been trying to make a script that update the YouTube title with the video views, like the Tom Scott video. But I keep getting this error with the authentication.
I get the code to authenticate it but it just says I don't have enough permission.
<HttpError 400 when requesting https://youtube.googleapis.com/youtube/v3/videos?part=%28%27snippet%2Cstatus%2Clocalizations%27%2C%29&alt=json returned "'('snippet'". Details: "[{'message': "'('snippet'", 'domain': 'youtube.part', 'reason': 'unknownPart', 'location': 'part', 'locationType': 'parameter'}]"> File "C:\Users\erik\Documents\PYTHON CODE\view_changer\example.py", line 49, in main response_update = request_update.execute().
Here's my code:
import os
import google_auth_oauthlib.flow
import googleapiclient.discovery
import googleapiclient.errors
scopes = ["https://www.googleapis.com/auth/youtube"]
api_key = "..."
video_1_part_view = 'statistics'
video_1_id_view = 'hVuoPgZJ3Yw'
video_1_part_update= "snippet,status,localizations",
video_1_part_body_update= { "id": "1y94SadSsMU",
"localizations": {"es": { "title": "no hay nada a ver aqui",
"description": "Esta descripcion es en español."
}
}
}
def main():
# 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 = (r"C:\Users\erik\Documents\PYTHON CODE\view_changer\client_secret_379587650859-bbl63je7sh6kva19l33auonkledt09a9.apps.googleusercontent.com.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)
#check views
request_view= youtube.videos().list( part = video_1_part_view, id = video_1_id_view )
respons_view = request_view.execute()
views = respons_view['items'][0]['statistics']['viewCount']
print (views)
#update video
request_update = youtube.videos().update(part= video_1_part_update, body = video_1_part_body_update)
response_update = request_update.execute()
print(response_update)
main()
# if __name__ == "__main__":
# main()
If the problem is not in the code I might have an other idea of what it might be. When I was first setting up the OAuth, I didn't know I needed to pick what the user would be giving permission to (I know rookie mistake(: ), but since I updated it, when I ask for permission after going to the authentication link the code gives me back, it doesn't ask permission for all the things I told it to do.
According to the official documentation, the request parameter part of the Videos.list API endpoint is defined as:
part (string)
The part parameter specifies a comma-separated list of one or more video resource properties that the API response will include.
[...]
But you're having that request parameter set as:
('snippet,status,localizations',).
That's because (though your code above doesn't show it) you have the variable video_1_part_view defined as:
video_1_part_view = "snippet,status,localizations",
(Do notice the trailing comma). That makes video_1_part_view a Python tuple, which is not what you need to send to the API endpoint.
The same is true for your variable video_1_part_update.
Just remove the trailing commas and things will work OK.

403 IAM permission 'dialogflow.sessions.detectIntent' error in flask

I am trying to use Dialogflow in my Flask app but I am getting 403 IAM permission 'dialogflow.sessions.detectIntent' I have checked twice my role is project owner in cloud console. I am following this tutorial.
This is my app.py
from flask import Flask
from flask import request, jsonify
import os
import dialogflow
from google.api_core.exceptions import InvalidArgument
import requests
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = 'service_key.json'
DIALOGFLOW_PROJECT_ID = 'whatsappbotagent-gmsl'
DIALOGFLOW_LANGUAGE_CODE = 'en'
SESSION_ID = 'me'
app = Flask(__name__)
app.config["DEBUG"] = True
#app.route('/')
def root():
return "Hello World"
#app.route('/api/getMessage', methods = ['POST'])
def home():
message = request.form.get('Body')
mobnu = request.form.get('From')
session_client = dialogflow.SessionsClient()
session = session_client.session_path(DIALOGFLOW_PROJECT_ID, SESSION_ID)
text_input = dialogflow.types.TextInput(text = message, language_code = DIALOGFLOW_LANGUAGE_CODE)
query_input = dialogflow.types.QueryInput(text = text_input)
try:
response = session_client.detect_intent(session = session, query_input = query_input)
except InvalidArgument:
raise
print("Query text: ", response.query_result.query_text)
# sendMessage()
return response.query_result.fullfilment_text
if __name__ == '__main__':
app.run()
OK, so after a lot of searching and trial and error I found the issue.
Actually while creating a service account the user gets a service email and that email will have access to use the project but I was not adding that email in project permission emails. Adding that email in IAM & Admin > IAM > +ADD will make it work.
Maybe there was a better solution but this is what works for me and hopefully solves others problem if have similar issue like this.

How to use dialogflow Client In Python

what i am trying is to get the response in python
import dialogflow
from google.api_core.exceptions import InvalidArgument
DIALOGFLOW_PROJECT_ID = 'imposing-fx-333333'
DIALOGFLOW_LANGUAGE_CODE = 'en'
GOOGLE_APPLICATION_CREDENTIALS = 'imposing-fx-333333-e6e3cb9e4adb.json'
text_to_be_analyzed = "Hi! I'm David and I'd like to eat some sushi, can you help me?"
session_client = dialogflow.SessionsClient()
session = session_client.session_path(DIALOGFLOW_PROJECT_ID, SESSION_ID)
text_input = dialogflow.types.TextInput(text=text_to_be_analyzed,
language_code=DIALOGFLOW_LANGUAGE_CODE)
query_input = dialogflow.types.QueryInput(text=text_input)
try:
response = session_client.detect_intent(session=session, query_input=query_input)
except InvalidArgument:
raise
print("Query text:", response.query_result.query_text)
print("Detected intent:", response.query_result.intent.display_name)
print("Detected intent confidence:", response.query_result.intent_detection_confidence)
print("Fulfillment text:", response.query_result.fulfillment_text)
And i am getting unable to verify credentials
google.auth.exceptions.DefaultCredentialsError: Could not automatically determine credentials. Please set GOOGLE_APPLICATION_CREDENTIALS or explicitly create credentials and re-run the application. For more information, please see https://cloud.google.com/docs/authentication/getting-started
This is my first question in stackoverflow :) i know i have done many
You need to export Service Account Key (JSON) file from your , and set an environment variable GOOGLE_APPLICATION_CREDENTIALS to the file path of the JSON file that contains your service account key. Then you can make call to dialogflow.
Steps to get Service Account Key:
Make sure you are using Dialogflow v2.
Go to general settings and click on your Service Account. This will redirect you to Google Cloud Platform project’s service account page.
Next step is to create a new key for the service account. Now create a service account and choose JSON as output key. Follow the instructions and a JSON file will be downloaded to your computer. This file will be used as GOOGLE_APPLICATION_CREDENTIALS.
Now in code,
import os
import dialogflow
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "/path/to/file.json"
project_id = "your_project_id"
session_id = "your_session_id"
language_code = "en"
session_client = dialogflow.SessionsClient()
session = session_client.session_path(project_id, session_id)
text_input = dialogflow.types.TextInput(text=text, language_code=language_code)
query_input = dialogflow.types.QueryInput(text=text_input)
response_dialogflow = session_client.detect_intent(session=session, query_input=query_input)
This one works too in case you want to pick up the file from file system.
Recomended way is using env variables thoguh
import json
from google.cloud import dialogflow_v2
from google.oauth2 import *
session_client = None
dialogflow_key = None
creds_file = "/path/to/json/file.json"
dialogflow_key = json.load(open(creds_file))
credentials = (service_account.Credentials.from_service_account_info(dialogflow_key))
session_client = dialogflow_v2.SessionsClient(credentials=credentials)
print("it works : " + session_client.DEFAULT_ENDPOINT) if session_client is not None
else print("does not work")
I forgot to add the main article sorry...
Here it is :
https://googleapis.dev/python/google-auth/latest/user-guide.html#service-account-private-key-files

403 Forbidden - cloud_storage_bucket get_media

import json
from httplib2 import Http
from oauth2client.client import SignedJwtAssertionCredentials
from googleapiclient.discovery import build
json_file = 'my.json'
client_email = json.loads(open(json_file).read())['client_email']
private_key = json.loads(open(json_file).read())['private_key']
cloud_storage_bucket = 'my_bucket'
report_to_download = 'sales/salesreport_201907.zip'
credentials = SignedJwtAssertionCredentials(client_email, private_key,['https://www.googleapis.com/auth/devstorage.read_only','https://www.googleapis.com/auth/devstorage.read_write','https://www.googleapis.com/auth/devstorage.full_control'])
storage = build('storage', 'v1', http=credentials.authorize(Http()))
object_metadata = storage.objects().get(bucket = cloud_storage_bucket, object = report_to_download).execute()
object_content = storage.objects().get_media(bucket = cloud_storage_bucket, object = report_to_download).execute()
I can read the object_metadata, but when requesting object content I get:
googleapiclient.errors.HttpError: <HttpError 403 when requesting https://www.googleapis.com/storage/v1/b/my_bucket/o/sales%2Fsalesreport_201907.zip?alt=media returned "Forbidden">
As u can see I added the three scopes in the credentials sections just to ensure to have all the permissions. Despite that I still getting the error.
I am using Python 2.7.
Edit:
I tried to download the file using gsutil and it works. So it isn't related with permissions.
Edit 2:
Changed the code to use a non deprecated library.
from logs import logger
import google.auth
import google.auth.transport.requests as tr_requests
from google.resumable_media.requests import Download
import os
os.environ["GOOGLE_APPLICATION_CREDENTIALS"]="my.json"
ro_scope=u'https://www.googleapis.com/auth/devstorage.full_control'
credentials,_ = google.auth.default(scopes=(ro_scope,))
transport = tr_requests.AuthorizedSession(credentials)
cloud_storage_bucket = 'pubsite_prod_rev_xxxx'
report_to_download = 'sales/salesreport_201907.zip'
#option 1
media_url='https://www.googleapis.com/download/storage/v1/b/pubsite_prod_rev_xxxx/o/sales%2Fsalesreport_201907.zip?generation=1234&alt=media'
#option 2
media_url='https://www.googleapis.com/storage/v1/b/pubsite_prod_rev_xxxx/o/sales%2Fsalesreport_201907.zip'
download = Download(media_url)
response = download.consume(transport)
print download.finished
When running the code with option 1 url the status is 200 but the response.content is just the metadata, has happened before with the get method.
When running the option 2, like get_media method, the error stills 403.
File "/anaconda2/envs/enviro27/lib/python2.7/site-packages/google/resumable_media/_helpers.py", line 93, in require_status_code
status_code, u'Expected one of', *status_codes)
google.resumable_media.common.InvalidResponse: (u'Request failed with status code', 403, u'Expected one of', 200, 206)
The doc of this code.
The solution has been to discover the true admin account.
Despite Google Play shows contact information to one email (the one that we believe to be the admin), the real admin is anothe account. After find it, we applied all the process explained here.
And with this code we are able to access the content:
from logs import logger
import google.auth
import google.auth.transport.requests as tr_requests
from google.resumable_media.requests import Download
import os
os.environ["GOOGLE_APPLICATION_CREDENTIALS"]="my.json"
ro_scope=u'https://www.googleapis.com/auth/devstorage.full_control'
credentials,_ = google.auth.default(scopes=(ro_scope,))
transport = tr_requests.AuthorizedSession(credentials)
cloud_storage_bucket = 'pubsite_prod_rev_xxxx'
report_to_download = 'sales/salesreport_201907.zip'
#option 1
media_url='https://www.googleapis.com/download/storage/v1/b/pubsite_prod_rev_xxxx/o/sales%2Fsalesreport_201907.zip?generation=1234&alt=media'
#option 2
media_url='https://www.googleapis.com/storage/v1/b/pubsite_prod_rev_xxxx/o/sales%2Fsalesreport_201907.zip'
download = Download(media_url)
response = download.consume(transport)
print download.finished

Python: Upload a photo to photobucket

Can a Python script upload a photo to photo bucket and then retrieve the URL for it? Is so how?
I found a script at this link: http://www.democraticunderground.com/discuss/duboard.php?az=view_all&address=240x677
But I just found that confusing.
many thanks,
Phil
Yes, you can. Photobucket has a well-documented API, and someone wrote a wrapper around it.
Download the it and put it into your Python path, then download httplib2 (you can use easy_install or pip for this one).
Then, you have to request a key for the Photobucket API.
If you did everything right, you can write your script now. The Python wrapper is great, but is not documented at all which makes it very difficult to use it. I spent hours on understanding it (compare the question and response time here). As example, the script even has form/multipart support, but I had to read the code to find out how to use it. I had to prefix the filename with a #.
This library is a great example how you should NOT document your code!
I finally got it working, enjoy the script: (it even has oAuth handling!)
import pbapi
import webbrowser
import cPickle
import os
import re
import sys
from xml.etree import ElementTree
__author__ = "leoluk"
###############################################
## CONFIGURATION ##
###############################################
# File in which the oAuth token will be stored
TOKEN_FILE = "token.txt"
IMAGE_PATH = r"D:\Eigene Dateien\Bilder\SC\foo.png"
IMAGE_RECORD = {
"type": 'image',
"uploadfile": '#'+IMAGE_PATH,
"title": "My title", # <---
"description": "My description", # <---
}
ALBUM_NAME = None # default album if None
API_KEY = "149[..]"
API_SECRET = "528[...]"
###############################################
## SCRIPT ##
###############################################
api = pbapi.PbApi(API_KEY, API_SECRET)
api.pb_request.connection.cache = None
# Test if service online
api.reset().ping().post()
result = api.reset().ping().post().response_string
ET = ElementTree.fromstring(result)
if ET.find('status').text != 'OK':
sys.stderr.write("error: Ping failed \n"+result)
sys.exit(-1)
try:
# If there is already a saved oAuth token, no need for a new one
api.username, api.pb_request.oauth_token = cPickle.load(open(TOKEN_FILE))
except (ValueError, KeyError, IOError, TypeError):
# If error, there's no valid oAuth token
# Getting request token
api.reset().login().request().post().load_token_from_response()
# Requesting user permission (you have to login with your account)
webbrowser.open_new_tab(api.login_url)
raw_input("Press Enter when you finished access permission. ")
#Getting oAuth token
api.reset().login().access().post().load_token_from_response()
# This is needed for getting the right subdomain
infos = api.reset().album(api.username).url().get().response_string
ET = ElementTree.fromstring(infos)
if ET.find('status').text != 'OK':
# Remove the invalid oAuth
os.remove(TOKEN_FILE)
# This happend is user deletes the oAuth permission online
sys.stderr.write("error: Permission deleted. Please re-run.")
sys.exit(-1)
# Fresh values for username and subdomain
api.username = ET.find('content/username').text
api.set_subdomain(ET.find('content/subdomain/api').text)
# Default album name
if not ALBUM_NAME:
ALBUM_NAME = api.username
# Debug :-)
print "User: %s" % api.username
# Save the new, valid oAuth token
cPickle.dump((api.username, api.oauth_token), open(TOKEN_FILE, 'w'))
# Posting the image
result = (api.reset().album(ALBUM_NAME).
upload(IMAGE_RECORD).post().response_string)
ET = ElementTree.fromstring(result)
if ET.find('status').text != 'OK':
sys.stderr.write("error: File upload failed \n"+result)
sys.exit(-1)
# Now, as an example what you could do now, open the image in the browser
webbrowser.open_new_tab(ET.find('content/browseurl').text)
Use the python API by Ron White that was written to do just this

Categories

Resources