Why can't I send Email on Google app engine? - python

I CAN NOT send email on Google app engine.
The sender_address is the owner of application. I want to use "cron" to send email to someone every day.
Here is my python code:
class Send_Email(webapp2.RequestHandler):
def post(self):
self.abort(405, headers = [('Allow', 'GET')])
def get(self):
if 'X-AppEngine-Cron' not in self.request.headers:
self.error(403)
sender_address = "David <z25189347#gmail.com>"
user_email = "chaowc#mail.ncnu.edu.tw"
subject = "Work Complete!"
body = "Picture uploaded!"
mail.send_mail(sender_address, user_email, subject, body)
app = webapp2.WSGIApplication([(r'/', MainPage),
(r'/sendemail', Send_Email),
], debug=True)
Here is my cron.yaml code:
cron:
- description: Send Email
url: /sendemail
schedule: every day 00:00
timezone: Asia/Taipei
Here is my app.yaml code:
handlers:
- url: /sendemail
script: main.app
- url: /.*
script: main.app
secure: always
When I run my application at localhost always show:
Request to /sendemail succeeded!
But when I deploy to Google app engine , the logs always show wrong messages:
InvalidSenderError: Unauthorized sender
I have no idea where I am doing wrong. Someone help me please! Thanks!

You need to add the sender email address to the list of authorized senders in your Developer console > App Engine > Settings > Application Settings.

Related

not able to protect the python flask rest api service using keycloak

I have keycloak server running in docker (192.168.99.100:8080) and python flask-oidc flask application running locally ( localhost:5000) i am not able to access the protected Rest Api even after getting the access_token. has anyone tried this code. if so please help me regarding this. thank you
this is my keycloak client using docker jboss/keycloak image
this is my newuser under the new realm
below is my flask-application
app.py
from flask import Flask, g
from flask_oidc import OpenIDConnect
import requests
secret_key = os.urandom(24).hex()
print(secret_key)
logging.basicConfig(level=logging.DEBUG)
app = Flask(__name__)
app.config["OIDC_CLIENT_SECRETS"]="client_secrets.json"
app.config["OIDC_COOKIE_SECURE"]=False
app.config["OIDC_SCOPES"]=["openid","email","profile"]
app.config["SECRET_KEY"]=secret_key
app.config["TESTING"]=True
app.config["DEBUG"] = True
app.config["OIDC_ID_TOKEN_COOKIE_SECURE"]=False
app.config["OIDC_REQUIRED_VERIFIED_EMAIL"]=False
app.config["OIDC_INTROSPECTION_AUTH_METHOD"]='client_secret_post'
app.config["OIDC_USER_INFO_ENABLED"]=True
oidc = OpenIDConnect(app)
#app.route('/')
def hello_world():
if oidc.user_loggedin:
return ('Hello, %s, See private '
'Log out') % \
oidc.user_getfield('preferred_username')
else:
return 'Welcome anonymous, Log in'
client_secrets.json
{
"web": {
"issuer": "http://192.168.99.100:8080/auth/realms/kariga",
"auth_uri": "http://192.168.99.100:8080/auth/realms/kariga/protocol/openid-connect/auth",
"client_id": "flask-app",
"client_secret": "eb11741d-3cb5-4457-8ff5-0202c6d6b250",
"redirect_uris": [
"http://localhost:5000/"
],
"userinfo_uri": "http://192.168.99.100:8080/auth/realms/kariga/protocol/openid-connect/userinfo",
"token_uri": "http://192.168.99.100:8080/auth/realms/kariga/protocol/openid-connect/token",
"token_introspection_uri": "http://192.168.99.100:8080/auth/realms/kariga/protocol/openid-connect/token/introspect"
}
}
when i launch the flask-app in web browser
i click on the Log in link
next it prompts for the user details (user created under my new realm)
it takes a couple of seconds then it redirects me to an error page
http://localhost:5000/oidc_callback?state=eyJjc3JmX3Rva2VuIjogIkZZbEpqb3ZHblZoUkhEbmJsdXhEVW
that says
httplib2.socks.HTTPError
httplib2.socks.HTTPError: (504, b'Gateway Timeout')
and also it is redirecting to /oidc_callback which is not mentioned anywhere
any help would be appreciated
the problem is occuring because keycloak server which is running
in docker(192.168.99.100)
is not able to hit the flask application server which is running locally(localhost)
better to run both as services in docker by creating a docker-compose file

Getting Error: redirect_uri_mismatch The redirect URI in the request: http://localhost:8080/oauth2callback did not match a registered redirect URI

I'm getting this error while trying to run my application...
The redirect URI in the request: http://localhost:8080/oauth2callback did not match a registered redirect URI
In google API console i have registered my redirect urls
Redirect URIs: http://localhost:8080/
And in the client_secrets.json also i'm using the same as redirect url
I'm following this tutorial
https://developers.google.com/bigquery/articles/dashboard#addoauth2
Edit:
I just made some changes to the existing code
Now the
redirect URIs in API console is http://localhost:8080/oauth2callback
And here is my app.yaml
application: hellomydashboard
version: 1
runtime: python
api_version: 1
handlers:
- url: /favicon\.ico
static_files: favicon.ico
upload: favicon\.ico
- url: /oauth2callback
script: oauth2client/appengine.py
- url: .*
script: main.py
Now though its not showing any error but it displays a blank page.
Here is my main.py
from bqclient import BigQueryClient
import httplib2
import os
from google.appengine.api import memcache
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from oauth2client.appengine import oauth2decorator_from_clientsecrets
# Project ID for project to receive bill.
# During limited availability preview, there is no bill.
# The value should be your quoted Client ID number
# which you previously recorded from code.google.com/apis/console
# REPLACE THIS NUMBER WITH YOUR CLIENT ID
PROJECT_ID = "My Project ID" #i just replaced dat
DATASET = "samples"
TABLE = "natality"
# CLIENT_SECRETS, name of a file containing the OAuth 2.0
# information for this application.
CLIENT_SECRETS = os.path.join(os.path.dirname(__file__),
'client_secrets.json')
http = httplib2.Http(memcache)
decorator = oauth2decorator_from_clientsecrets(CLIENT_SECRETS,
'https://www.googleapis.com/auth/bigquery')
bq = BigQueryClient(http, decorator)
class MainHandler(webapp.RequestHandler):
#decorator.oauth_required
def get(self):
self.response.out.write("Hello Dashboard!\n")
application = webapp.WSGIApplication([
('/', MainHandler),
], debug=True)
def main():
run_wsgi_app(application)
if __name__ == '__main__':
main()
So according to main.py if everything is fine it must print Hello Dashboard but it isn't
You will actually need to add the following to your redirect URIs:
http://localhost:8080/oauth2callback
Also, you may need to append a trailing / if the above doesn't match:
http://localhost:8080/oauth2callback/
using google openId I configured this
Redirect URIs: http://domain.com/authenticate/google
on https://code.google.com/apis/console, if you must create a app if you don't have one, note that must match entirely the url
In main.py functions main class add (decorator.callback_path, decorator.callback_handler()), and remove
- url: /oauth2callback
script: oauth2client/appengine.py
from app.yaml.
PS: You might get DownloadError if you have some proxy-configuration/webcontent-filter. If you disable these configurations or deploy it on Google Server, it will work just fine.
seems like google tries to match url with being case-sensitve cause when i tried it with /Authorize and /authorize, it gave me redirect_uri_mismatch error for first one but worked for latter one
someone try and let me know if i m wrong
In main.py file,
in the part where you create a wsgi application
under application = webapp.wsgiapplication(
add a handler
(decorator.callback_path,decorator.callback_handler()),

app engine: incoming emails get rejected

I'm trying to get a barebone app engine app to handle incoming email. I've followed the Receiving Email tutorial, and my code is really minimal.
However, when I send an email to say whatever#myapplication.appspot.com, Google rejects it before it gets to my app:
Delivery to the following recipient failed permanently:
whatever#myapplication.appspot.com
Technical details of permanent failure: Google tried to deliver your
message, but it was rejected by the recipient domain.
this is my app.yaml
application: myapplication
version: 1
runtime: python27
api_version: 1
threadsafe: false
handlers:
- url: /_ah/mail/.+
script: handle_incoming_email.py
- url: /.*
script: myapplication.app
inbound_services:
- mail
and handle_incoming_email.py is taken from the tutorial:
import logging, email
from google.appengine.ext import webapp
from google.appengine.ext.webapp.mail_handlers import InboundMailHandler
from google.appengine.ext.webapp.util import run_wsgi_app
class LogSenderHandler(InboundMailHandler):
def receive(self, mail_message):
logging.info("Received a message from: " + mail_message.sender)
Any idea why emails are being rejected?
It seems that you missed login: admin in the yaml file.
and it's whatever#myapplication.appspotmail.com not whatever#myapplication.appspot.com.

How does the warmup service work in python google app engine?

Can someone give an example of how the warmup inbound service works in the python runtime of Google App Engine?
I've read this: http://code.google.com/appengine/docs/python/config/appconfig.html#Inbound_Services, but it doesn't give me much of an example after the GET request is sent (I can't seem to ever pick it up)
My app.yaml looks like this:
application: whatevs
version: 1
runtime: python
api_version: 1
builtins:
- datastore_admin: on
inbound_services:
- warmup
handlers:
- url: /static
static_dir: static
- url: /_ah/warmup
script: main.py
login: admin
- url: /.*
script: main.py
my main.py looks like this:
def main():
application = webapp.WSGIApplication(
[("/", views.LandingPage),
("/_ah/warmup", views.WarmupHandler)
],
debug=True)
run_wsgi_app(application)
WarmupHandler looks like this:
class WarmupHandler(webapp.RequestHandler):
"""
Called on app init
"""
def get(self):
current_user = users.get_current_user()
return
However, WarmupHandler never seems to get called (I have breakpoints and lots of debug code). What am I doing wrong?
App Engine sends warm up requests only if there is some constant traffic on your app. It won't get always called if instances stand mostly idle.

Does main.py or app.yaml determine the URL used by the App Engine cron task in this example?

In this sample code the URL of the app seems to be determined by this line within the app:
application = webapp.WSGIApplication([('/mailjob', MailJob)], debug=True)
but also by this line within the app handler of app.yaml:
- url: /.*
script: main.py
However, the URL of the cron task is set by this line:
url: /tasks/summary
So it seems the cron utility will call "/tasks/summary" and because of the app handler, this will cause main.py to be invoked. Does this mean that, as far as the cron is concerned, the line in the app that sets the URL is extraneous:
application = webapp.WSGIApplication([('/mailjob', MailJob)], debug=True)
. . . since the only URL needed by the cron task is the one defined in app.yaml.
app.yaml
application: yourappname
version: 1
runtime: python
api_version: 1
handlers:
- url: /.*
script: main.py
cron.yaml
cron:
- description: daily mailing job
url: /tasks/summary
schedule: every 24 hours
main.py
#!/usr/bin/env python
import cgi
from google.appengine.ext import webapp
from google.appengine.api import mail
from google.appengine.api import urlfetch
class MailJob(webapp.RequestHandler):
def get(self):
# Call your website using URL Fetch service ...
url = "http://www.yoursite.com/page_or_service"
result = urlfetch.fetch(url)
if result.status_code == 200:
doSomethingWithResult(result.content)
# Send emails using Mail service ...
mail.send_mail(sender="admin#gmail.com",
to="someone#gmail.com",
subject="Your account on YourSite.com has expired",
body="Bla bla bla ...")
return
application = webapp.WSGIApplication([
('/mailjob', MailJob)], debug=True)
def main():
wsgiref.handlers.CGIHandler().run(application)
if __name__ == '__main__':
main()
You could do it like this:
app.yaml
application: yourappname
version: 1
runtime: python
api_version: 1
handlers:
- url: /tasks/.*
script: main.py
cron.yaml
cron:
- description: daily mailing job
url: /tasks/summary
schedule: every 24 hours
main.py
#!/usr/bin/env python
import cgi
from google.appengine.ext import webapp
from google.appengine.api import mail
from google.appengine.api import urlfetch
class MailJob(webapp.RequestHandler):
def get(self):
# Call your website using URL Fetch service ...
url = "http://www.yoursite.com/page_or_service"
result = urlfetch.fetch(url)
if result.status_code == 200:
doSomethingWithResult(result.content)
# Send emails using Mail service ...
mail.send_mail(sender="admin#gmail.com",
to="someone#gmail.com",
subject="Your account on YourSite.com has expired",
body="Bla bla bla ...")
return
application = webapp.WSGIApplication([
('/tasks/summary', MailJob)], debug=True)
def main():
wsgiref.handlers.CGIHandler().run(application)
if __name__ == '__main__':
main()
Looks like you're reading this page (even though you don't give us the URL). The configuration and code as presented won't run successfully: the cron task will try to visit URL path /tasks/summary, app.yaml will make that execute main.py, but the latter only sets up a handler for /mailjob, so the cron task's attempt will fail with a 404 status code.

Categories