I am trying to use YouTube data API for searching videos in Python. I have read full tutorial and I am able to authorize and authenticate the user from the local machine, But when I deployed the same code in the server I am getting bellow listed errors in logs. and browser displays 'Internal server error'
[ N 2019-02-01 04:12:09.9860 4335/Tq age/Cor/CoreMain.cpp:1117 ]: Checking whether to disconnect long-running connections for process 20744, application /home/pricemon/YT_VDO_search_1 (production)
App 20744 output: File "/home/pricemon/virtualenv/YT__VDO__search__1/3.6/lib/python3.6/site-packages/oauthlib/oauth2/rfc6749/parameters.py", line 262, in parse_authorization_code_response
App 20744 output: File "/home/pricemon/virtualenv/YT__VDO__search__1/3.6/lib/python3.6/site-packages/oauthlib/oauth2/rfc6749/clients/web_application.py", line 203, in parse_request_uri_response
App 20744 output: File "/home/pricemon/virtualenv/YT__VDO__search__1/3.6/lib/python3.6/site-packages/requests_oauthlib/oauth2_session.py", line 208, in fetch_token
App 20744 output: File "/home/pricemon/YT_VDO_search_1/one.py", line 88, in oauth2callback
App 20744 output: File "/home/pricemon/virtualenv/YT__VDO__search__1/3.6/lib/python3.6/site-packages/flask/app.py", line 1799, in dispatch_request
App 20744 output: File "/home/pricemon/virtualenv/YT__VDO__search__1/3.6/lib/python3.6/site-packages/flask/app.py", line 1813, in full_dispatch_request
App 20744 output: File "/home/pricemon/virtualenv/YT__VDO__search__1/3.6/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
App 20744 output: File "/home/pricemon/virtualenv/YT__VDO__search__1/3.6/lib/python3.6/site-packages/flask/app.py", line 1718, in handle_user_exception
App 20744 output: File "/home/pricemon/virtualenv/YT__VDO__search__1/3.6/lib/python3.6/site-packages/flask/app.py", line 1815, in full_dispatch_request
App 20744 output: File "/home/pricemon/virtualenv/YT__VDO__search__1/3.6/lib/python3.6/site-packages/flask/app.py", line 2292, in wsgi_app
I am trying the coed from This guide from Google
I have replaced the redirected URL path in the Google API console.
Bellow is my code.
def oauth2callback():
# Specify the state when creating the flow in the callback so that it can
# verified in the authorization server response.
state = flask.session['state']
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
CLIENT_SECRETS_FILE, scopes=SCOPES, state=state)
flow.redirect_uri = flask.url_for('oauth2callback', _external=True)
# Use the authorization server's response to fetch the OAuth 2.0 tokens.
authorization_response = flask.request.url
flow.fetch_token(authorization_response=authorization_response)
# Store credentials in the session.
# ACTION ITEM: In a production app, you likely want to save these
# credentials in a persistent database instead.
credentials = flow.credentials
flask.session['credentials'] = credentials_to_dict(credentials)
return flask.redirect(flask.url_for('test_api_request'))
I am getting error when I fetch token using command flow.fetch_token
Related
I am trying to send e-mails from a GAE application using this code:
from google.appengine.api.mail import send_mail
send_mail(
"sender#nowhere.com",
["user#example.com"],
"Subject",
"Body",
)
I have configured usage of the apis in app.yaml with:
app_engine_apis: true
And deploy to App Engine is done with gcloud beta app deploy.
However, I get this error:
Traceback (most recent call last):
File "/layers/google.python.pip/pip/lib/python3.9/site-packages/flask/app.py", line 2073, in wsgi_app response = self.full_dispatch_request()
File "/layers/google.python.pip/pip/lib/python3.9/site-packages/flask/app.py", line 1518, in full_dispatch_request rv = self.handle_user_exception(e)
File "/layers/google.python.pip/pip/lib/python3.9/site-packages/flask/app.py", line 1516, in full_dispatch_request rv = self.dispatch_request()
File "/layers/google.python.pip/pip/lib/python3.9/site-packages/flask/app.py", line 1502, in dispatch_request return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
File "/srv/infrastructure/view_modifiers.py", line 12, in view_method response_val = f(*args, **kwargs)
File "/srv/views/orders.py", line 25, in create_order vm.create_order()
File "/srv/viewmodels/orders/order_viewmodel.py", line 74, in create_order self._send_order_email()
File "/srv/viewmodels/orders/order_viewmodel.py", line 54, in _send_order_email send_mail(
File "/layers/google.python.pip/pip/lib/python3.9/site-packages/google/appengine/api/mail.py", line 401, in send_mail message.send(make_sync_call=make_sync_call)
File "/layers/google.python.pip/pip/lib/python3.9/site-packages/google/appengine/api/mail.py", line 1209, in send make_sync_call('mail', self._API_CALL, message, response)
File "/layers/google.python.pip/pip/lib/python3.9/site-packages/google/appengine/api/apiproxy_stub_map.py", line 96, in MakeSyncCall return stubmap.MakeSyncCall(service, call, request, response)
File "/layers/google.python.pip/pip/lib/python3.9/site-packages/google/appengine/api/apiproxy_stub_map.py", line 348, in MakeSyncCall assert stub, 'No api proxy found for service "%s"' % service AssertionError: No api proxy found for service "mail"
This seems to suggest that even for the default behavior of the mail service, some kind of proxy needs to be configured. However, I cannot find any information about the setup of this proxy.
And, my initial understanding was that setting up a proxy is only needed for unit-testing or local development.
Here is an example that works with fastapi. (answer to anton's comment)
from google.appengine.api import mail
from fastapi.middleware.wsgi import WSGIMiddleware
from google.appengine.api import wrap_wsgi_app
from flask import Flask
app = create_app() # this is just app = FastAPI() and somes middleware but but no relevance here
app_flask = Flask(__name__)
app_flask.wsgi_app = wrap_wsgi_app(app_flask.wsgi_app, use_deferred=True)
def send_approved_mail(sender_address):
# [START send_message]
message = mail.EmailMessage(
sender=sender_address,
subject="Your account has been approved")
message.to = "test#gmail.com"
message.body = """Dear Albert:
Your example.com account has been approved. You can now visit
http://www.example.com/ and sign in using your Google Account to
access new features.
Please let us know if you have any questions.
The example.com Team
"""
message.send()
#app_flask.route("/send_email", methods=['GET'])
def send_email():
send_approved_mail("registred_email#domain.com")
return "message sent"
app.mount("/v1", WSGIMiddleware(app_flask))
here app.yaml
runtime: python39
entrypoint: gunicorn -k uvicorn.workers.UvicornWorker app.main:app
instance_class: F1
app_engine_apis: true
inbound_services:
- mail
- mail_bounce
You will not see flask route on swagger.
and for some reason, i could not sent email with app engine's default service account. I had to register my email ( with same domain) here : https://console.cloud.google.com/appengine/settings/emailsenders?project=your_project
I just tested this and it worked for me (i.e. I received the email I supplied for recipient_email_address in the code below). Note that sender must be a value specified under Email Senders in App Engine settings page
requirements.txt file
Flask
appengine-python-standard>=1.0.0
app.yaml file
runtime: python39
app_engine_apis: true
handlers:
- url: /static
static_dir: static/
- url: /.*
script: auto
main.py
from flask import Flask
from google.appengine.api import wrap_wsgi_app
from google.appengine.api.mail import send_mail
app = Flask(__name__)
app.wsgi_app = wrap_wsgi_app(app.wsgi_app)
#app.route("/")
def sendMail():
send_mail(sender= <authorized_email_sender>,
to= <recipient_email_address>,
subject="Testing Python3 sending mails",
body="""Dear Albert:
Your example.com account has been approved. You can now visit
http://www.example.com/ and sign in using your Google Account to
access new features.
Please let us know if you have any questions.
The example.com Team
""")
return "Mail was sent"
Here is my script
"""
Concerto library
"""
import win32com.client
def concerto_authenticate(encrypted_request, expiry, mac):
"""
Authenticate request
"""
concerto_request = win32com.client.Dispatch(
"Concerto4xSecurity.ValidatedRequest")
secret_key = "XXX"
concerto_request.SetSecretKey(secret_key)
concerto_request.setEncryptedRequest(encrypted_request)
concerto_request.SetExpiry(expiry)
concerto_request.SetMAC(mac)
concerto_request.Validate()
return concerto_request
I call it from another page as so:
concerto_request = concerto.concerto_authenticate(encrypted_request, expiry, mac)
This works fine in my DEV environment. I am using Windows 2016 and IIS. It's using the inbuilt server that comes with Flask. Nothing fancy.
I moved all my files to PROD. Both DEV and PROD sit on the same server so have access to the exact same libraries. The only difference is that PROD uses Waitress.
No, when I run my code in PROD I get the following. This does not happen on the DEV URL, just the PROD one. The only difference being PROD uses Waitress and DEV does not.
Any suggestions?
Traceback (most recent call last):
File "C:\Python310\lib\site-packages\flask\app.py", line 2077, in wsgi_app
response = self.full_dispatch_request()
File "C:\Python310\lib\site-packages\flask\app.py", line 1525, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Python310\lib\site-packages\flask\app.py", line 1523, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Python310\lib\site-packages\flask\app.py", line 1509, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
File "E:\Apps\prod\digital\gp_clinicals\gp_clinicals.py", line 43, in gp_clinicals
concerto_request = concerto.concerto_authenticate(encrypted_request, expiry, mac)
File "E:\Apps\prod\digital\concerto.py", line 11, in concerto_authenticate
concerto_request = win32com.client.Dispatch(
File "C:\Python310\lib\site-packages\win32com\client\__init__.py", line 117, in Dispatch
dispatch, userName = dynamic._GetGoodDispatchAndUserName(dispatch, userName, clsctx)
File "C:\Python310\lib\site-packages\win32com\client\dynamic.py", line 106, in _GetGoodDispatchAndUserName
return (_GetGoodDispatch(IDispatch, clsctx), userName)
File "C:\Python310\lib\site-packages\win32com\client\dynamic.py", line 88, in _GetGoodDispatch
IDispatch = pythoncom.CoCreateInstance(
pywintypes.com_error: (-2147221008, 'CoInitialize has not been called.', None, None)
2022-08-01 13:15:12,592 - ERROR - __init__.py - handle_error_500 - 88 - 500 Internal Server Error: The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.
prod wsgi.py
"""
Application entry point
"""
from digital import init_app
from waitress import serve
app = init_app()
if __name__ == "__main__":
serve(app, host="internal.prod", url_scheme='https')
dev wsgi.py
"""
Application entry point
"""
from digital import init_app
app = init_app()
if __name__ == "__main__":
app.run(host="internal.dev",threaded=True)
I am using Google AppEngine (GAE) Flexible environment with a custom runtime (python2.7). I am using custom so I can just manage a Dockerfile and have easy parity between my laptop and when deployed in GAE.
I have a python 2.7 Flask app that is doing a query against DataStore. I get the following (when starting python main.py in my local docker):
root#24dcf9b8712d:/home/vmagent/app# curl localhost:5000/things
'/home/vmagent/app/clientid-searchapp.json'
[2018-09-04 14:54:19,969] ERROR in app: Exception on /things [GET]
Traceback (most recent call last):
File "/env/local/lib/python2.7/site-packages/flask/app.py", line 2292, in wsgi_app
response = self.full_dispatch_request()
File "/env/local/lib/python2.7/site-packages/flask/app.py", line 1815, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/env/local/lib/python2.7/site-packages/flask/app.py", line 1718, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/env/local/lib/python2.7/site-packages/flask/app.py", line 1813, in full_dispatch_request
rv = self.dispatch_request()
File "/env/local/lib/python2.7/site-packages/flask/app.py", line 1799, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "main.py", line 55, in products
for rec in query.fetch(limit=100):
File "/env/lib/python2.7/site-packages/google/api_core/page_iterator.py", line 199, in _items_iter
for page in self._page_iter(increment=False):
File "/env/lib/python2.7/site-packages/google/api_core/page_iterator.py", line 230, in _page_iter
page = self._next_page()
File "/env/local/lib/python2.7/site-packages/google/cloud/datastore/query.py", line 517, in _next_page
query=query_pb,
File "/env/local/lib/python2.7/site-packages/google/cloud/datastore_v1/gapic/datastore_client.py", line 294, in run_query
request, retry=retry, timeout=timeout, metadata=metadata)
File "/env/lib/python2.7/site-packages/google/api_core/gapic_v1/method.py", line 139, in __call__
return wrapped_func(*args, **kwargs)
File "/env/lib/python2.7/site-packages/google/api_core/retry.py", line 260, in retry_wrapped_func
on_error=on_error,
File "/env/lib/python2.7/site-packages/google/api_core/retry.py", line 177, in retry_target
return target()
File "/env/lib/python2.7/site-packages/google/api_core/timeout.py", line 206, in func_with_timeout
return func(*args, **kwargs)
File "/env/lib/python2.7/site-packages/google/api_core/grpc_helpers.py", line 56, in error_remapped_callable
six.raise_from(exceptions.from_grpc_error(exc), exc)
File "/env/local/lib/python2.7/site-packages/six.py", line 737, in raise_from
raise value
PermissionDenied: 403 Missing or insufficient permissions.
127.0.0.1 - - [04/Sep/2018 14:54:19] "GET /things HTTP/1.1" 500 -
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>500 Internal Server Error</title>
<h1>Internal Server Error</h1>
<p>The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.</p>
Snippets from main.py
app = Flask(__name__)
ds = datastore.Client()
<snip>
#app.route("/things")
def things():
global ds
pprint(os.environ['GOOGLE_APPLICATION_CREDENTIALS'])
query = ds.query(kind='Things', order=('thing_name',))
results = list()
for rec in query.fetch(limit=100):
results.append(rec)
return jsonify(results)
Output of gcloud auth list:
root#24dcf9b8712d:/home/vmagent/app# gcloud auth list
Credentialed Accounts
ACTIVE ACCOUNT
* <myapp>#<project-name>.iam.gserviceaccount.com
This is the configured service account. I have over-privileged it with excessive Role membership; I'm pretty certain the service account isn't lacking in permissions. In fact, it has 'DataStore Owner'
In main.py I am outputting:
pprint(os.environ['GOOGLE_APPLICATION_CREDENTIALS'])
And this outputs the path to my client-<myapp>.json file for the service account. It is the same file supplied in the Dockerfile as:
RUN gcloud auth activate-service-account --key-file=clientid-<myapp>.json --project <project-name> --quiet
I get the same results when running the Flask app in my local Docker environment and when I deploy to GAE Flexible. The Flask app has other endpoints that work as they don't call any other services. Only /things uses an API to call DataStore and it receives the above error.
I've been through all the docs. I'm sure it's something basic and obvious but afaict, everything looks right.
UPDATE:
I've tried creating the DataStore client with an explicit pass of project name with no change in result. Also, I've run this command from within the Docker container and this seems like unusual output to me but I don't know that it's incorrect for a Service Account.
root#e02b74cd269d:/home/vmagent/app# gcloud projects list
API [cloudresourcemanager.googleapis.com] not enabled on project
[<project id>]. Would you like to enable and retry (this will take a
few minutes)? (y/N)? y
When I respond w/ Y,:
ERROR: (gcloud.projects.list) PERMISSION_DENIED: Not allowed to get project settings for project <project id>
Output of gcloud config list:
root#d18c83cae166:/home/vmagent/app# gcloud config list
[core]
account = <myapp>#<myproject>.iam.gserviceaccount.com
disable_usage_reporting = False
project = <myproject>
Your active configuration is: [default]
This question already has answers here:
demystify Flask app.secret_key
(2 answers)
Closed 7 years ago.
I'm developing an app in python that uses YT API. I decided to move it to the web and i'm using Flask. I took the auth example from Google guides. For testing purposes i'm trying to create a playlist after authentication. It looks like this:
#app.route('/')
def index():
if 'credentials' not in flask.session:
return flask.redirect(flask.url_for('oauth2callback'))
credentials = client.OAuth2Credentials.from_json(flask.session['credentials'])
if credentials.access_token_expired:
return flask.redirect(flask.url_for('oauth2callback'))
else:
http_auth = credentials.authorize(httplib2.Http())
yt_service = discovery.build('youtube', 'v3', http_auth)
playlists_insert_response = yt_service.playlists().insert(
part="snippet,status",
body=dict(
snippet=dict(
title="Test Playlist",
description="A private playlist created with the YouTube API v3"
),
status=dict(
privacyStatus="private"
)
)
).execute()
return playlists_insert_response["id"]
#app.route('/oauth2callback')
def oauth2callback():
flow = client.flow_from_clientsecrets('youtube/client_secret.json',scope='https://www.googleapis.com/auth/youtube',redirect_uri=flask.url_for('oauth2callback', _external=True))
if 'code' not in flask.request.args:
auth_uri = flow.step1_get_authorize_url()
return flask.redirect(auth_uri)
else:
auth_code = flask.request.args.get('code')
credentials = flow.step2_exchange(auth_code)
flask.session['credentials'] = credentials.to_json()
return flask.redirect(flask.url_for('index'))
So in browser I authenticate, accept app's permisions and then I see 500 internal error with ouath2callback URI and code parameter. In the error log I see this:
2015-09-07 10:23:08,319 :Successfully retrieved access token
2015-09-07 10:23:08,330 :Exception on /oauth2callback [GET]
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1687, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1360, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1358, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1344, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/home/Kraxi/youtube/playlist.py", line 63, in oauth2callback
flask.session['credentials'] = credentials.to_json()
File "/usr/local/lib/python2.7/dist-packages/werkzeug/local.py", line 339, in __setitem__
self._get_current_object()[key] = value
File "/usr/local/lib/python2.7/dist-packages/flask/sessions.py", line 57, in _fail
raise RuntimeError('the session is unavailable because no secret '
RuntimeError: the session is unavailable because no secret key was set. Set the secret_key on the application to something unique and secret.
I tihnk it might be something wrong with Flask session - maybe seassion type?
Using Flask 0.10
Any ideas, please?
In order to use sessions you need to set a SECRET_KEY.
Extracted from the docs:
# set the secret key. keep this really secret:
app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
I don't know why my project show the next cookie error. Could someone help me?
PATH
->test
->lib
->public
->templates
- app.yaml
- main.py
- client_secrets.json
- session-secret (python -c "import os;print os.urandom(64)" > session.secret)
When I use my App Engine Launcher (release: "1.7.5") and check out my localhost web page
I chose my Google account to add permissions in accounts.google.com/AccountChooser?service....... (redirect) and then accept conditions of the scopes
The log console shows the next error:
Traceback (most recent call last):
File "C:\Program Files\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 1535, in __call__
rv = self.handle_exception(request, response, e)
File "C:\Program Files\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 1529, in __call__
rv = self.router.dispatch(request, response)
File "C:\Program Files\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 1278, in default_dispatcher
return route.handler_adapter(request, response)
File "C:\Program Files\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 1102, in __call__
return handler.dispatch()
File "C:\Program Files\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 572, in dispatch
return self.handle_exception(e, self.app.debug)
File "C:\Program Files\Google\google_appengine\lib\webapp2-2.5.2\webapp2.py", line 570, in dispatch
return method(*args, **kwargs)
File "C:\Program Files\Google\google_appengine\pruebasDocs\main.py", line 320, in get
creds = self.GetCodeCredentials()
File "C:\Program Files\Google\google_appengine\pruebasDocs\main.py", line 194, in GetCodeCredentials
session.set_secure_cookie(name='userid', value=userid)
File "lib\sessions.py", line 160, in set_secure_cookie
self.set_cookie(name, value, expires_days=expires_days, **kwargs)
File "lib\sessions.py", line 141, in set_cookie
self.response.headers._headers.append(('Set-Cookie', str(vals.OutputString(None))))
**AttributeError: ResponseHeaders instance has no attribute '_headers'**
lo.....t:8080/?code=4/00VfZ4DJ8d0P99v1kwn0yjBofcbq.gn6ceL8RBx0XYKs_1NgQtmXj_6WohwI
MAIN.PY
def GetCodeCredentials(self):
# Other frameworks use different API to get a query parameter.
code = self.request.get('code')
if not code:
# returns None to indicate that no code was passed from Google Drive.
return None
# Auth flow is a controller that is loaded with the client information,
# including client_id, client_secret, redirect_uri etc
oauth_flow = self.CreateOAuthFlow()
# Perform the exchange of the code. If there is a failure with exchanging
# the code, return None.
try:
creds = oauth_flow.step2_exchange(code)
except FlowExchangeError:
return None
# Create an API service that can use the userinfo API. Authorize it with our
# credentials that we gained from the code exchange.
users_service = CreateService('oauth2', 'v2', creds)
# Make a call against the userinfo service to retrieve the user's information.
# In this case we are interested in the user's "id" field.
userid = users_service.userinfo().get().execute().get('id')
# Store the user id in the user's cookie-based session.
session = sessions.LilCookies(self, SESSION_SECRET)
session.set_secure_cookie(name='userid', value=userid)
SESSIONS.PY
# output all their cookies to the headers at once before a response flush.
for vals in new_cookie.values():
self.response.headers._headers.append(('Set-Cookie', vals.OutputString(None)))