Redirecting Appspot URL to custom domain - python

I deployed a website (it consists of one index.html page and folders that contain js, image & css files) on the app-engine and linked it to my custom domain. I configured the CNAME and the site is opening on my domain, but the original appspot URL is not being redirected to the custom domain.
I did come across pages with similar questions which discussed about this problem. I tried implementing those, but they didn't seem to work.
Here is what I did, in the app.yaml file I replaced:
- url: /.*
static_files: static
upload: static
with
- url: /.*
script: main.application
and in the main.py, I erased all the content and added the following:
import webapp2
from google.appengine.ext.webapp.util import run_wsgi_app
application = webapp2.WSGIApplication([
webapp2.Route('/', webapp2.RedirectHandler, defaults={'_uri':'http://subdomain.domain.com}),
], debug=False)
def main():
application.run()
if __name__ == '__main__':
main()
(Modified code after suggestions by Jeff)
But it doesn't seem to work. The appspot URL is not being redirected but my custom domain is working alright. What changes should I make in the above code to make the redirection possible?
Thanks!

Your application variable is not doing anything if that is the entire contents of your main.py file.
Add the following to bottom of main.py:
def main():
application.run()
if __name__ == '__main__':
main()
Also you probably don't need AllHandler since the route is redirecting everything.

Related

App Engine - Python - Open local HTML file from script

When testing a Google App Engine app with the Launcher, the Launcher will start a local server, and open a tab listening to http://localhost:8080/ If the App.yaml file is configured to point to a html file, then the webpage will open. Like if your home page is index.html
app.yaml file
application: myProjectName
version: 2
runtime: python27
threadsafe: false
api_version: 1
handlers:
- url: .*
static_dir: index.html
If the app.yaml is configured to point to a python script in the root url, I don't know how to get the script to load a web page:
app.yaml file
- url: /.*
script: main.py
If my main.py Python script is:
import webbrowser
webbrowser.open_new("README.html")
That will open the README.html file in my browser when I run the code from the Python Shell, but if I launch the app from Google App Engine Launcher, it won't load the html file. How do I get the .py file to open an HTML file after the Launcher has started the app on the localhost:8000 ?
I'm looking at a Google example, and it uses a WSGIApplication webapp I guess. First the Python code goes through an authorization process, then at the end of the script, there is this code:
# Create an WSGI application suitable for running on App Engine
application = webapp.WSGIApplication(
[('/', MainPage), ('/svc', ServiceHandler), ('/about', AboutHandler),
('/user', UserHandler)],
# XXX Set to False in production.
debug=True
)
def main():
"""Main entry point for executing a request with this handler."""
run_wsgi_app(application)
if __name__ == "__main__":
main()
I'd appreciate any feedback from anyone who has any experience with this.
The simplest example that I know is the hello world in the documentation:
# helloworld.py
import webapp2
class MainPage(webapp2.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/plain'
self.response.write('Hello, World!')
application = webapp2.WSGIApplication([
('/', MainPage),
], debug=True)
The corresponding app.yaml is:
application: your-app-id
version: 1
runtime: python27
api_version: 1
threadsafe: true
handlers:
- url: /.*
script: helloworld.application
You create a class MainPage -- whenever you make a request to localhost:8080/ (note the slash is unncessary), you will be directed to the main page. the application is responsible for routing the request to the proper class and creating a new instance of that class for each request. It also calls the get or post or whatever HTTP method. Whatever you write into the response is what gets returned to the browser as the web page.
Now a single page isn't all that interesting. Maybe you want localhost:8080/goodbye as well. Then you just add another class and "register" it with the application:
# helloworld.py
import webapp2
class MainPage(webapp2.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/plain'
self.response.write('Hello, World!')
class GoodbyePage(webapp2.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/plain'
self.response.write('Goodbye, World. Time to sleep.')
application = webapp2.WSGIApplication([
('/', MainPage),
('/goodbye', GoodbyePage),
], debug=True)
No changes to app.yaml are necessary at this point.
Life might be kind of frustrating if you needed to keep all your pages in a single file though. We can break this into 2 (or more) files by modifying app.yaml.
application: your-app-id
version: 1
runtime: python27
api_version: 1
threadsafe: true
handlers:
- url: /goodbye
script: goodbye.app
- url: /.*
script: helloworld.application
helloworld.py is the same as the first example. goodbye.py looks like this:
# goodbye.py
import webapp2
class GoodbyePage(webapp2.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/html'
self.response.write('<html><head></head><body>Goodbye!</body></html>')
app = webapp2.WSGIApplication([
('/goodbye', GoodbyePage),
], debug=True)
The urls in app.yaml are regular expressions -- you want to order them from most specific to least specific (otherwise, you might handle the request with the wrong handler). Also note that the convention in app.yaml is script: <module_name>.<variable_name> when we set it up this way.
Here is another example without Jinja2. To serve HTML with Python you simply need these 3 simple things.
1) Use the webapp2 Python module.
import webapp2
2) Read your HTML file into a variable:
INDEX_HTML = open('index.html').read()
3) Then write it out when a certain URL is sent:
self.response.out.write(INDEX_HTML)
This is the full Python script:
import cgi
import webapp2
class MainPage(webapp2.RequestHandler):
def get(self):
INDEX_HTML = open('index.html').read()
self.response.out.write(INDEX_HTML)
class PageTwo(webapp2.RequestHandler):
def post(self):
self.response.write('<html><body>You wrote:<pre>')
self.response.write(cgi.escape(self.request.get('content')))
self.response.write('</pre></body></html>')
application = webapp2.WSGIApplication([
('/', MainPage),
('/sign', PageTwo),
], debug=True)
Note that your app.yaml configuration needs to be correct, and you need an HTML file. The webapp2 module provides a RequestHandler that can route your URL requests. (Display different webpage content) Here is a GitHub repository with the code, manifest app.yaml file and the index.html file.
Serve HTML with Python
This gets the HTML from a file, then writes it to the browser. This is actually more of what I was looking for:
class MainPage(webapp2.RequestHandler):
def get(self):
template = JINJA_ENVIRONMENT.get_template('index.html')
self.response.write(template.render())
This is the entire module:
import cgi
import os
import jinja2
import webapp2
JINJA_ENVIRONMENT = jinja2.Environment(
loader=jinja2.FileSystemLoader(os.path.dirname(__file__)),
extensions=['jinja2.ext.autoescape'],
autoescape=True)
class MainPage(webapp2.RequestHandler):
def get(self):
template = JINJA_ENVIRONMENT.get_template('index.html')
self.response.write(template.render())
class PageTwo(webapp2.RequestHandler):
def post(self):
self.response.write('<html><body>You wrote:<pre>')
self.response.write(cgi.escape(self.request.get('content')))
self.response.write('</pre></body></html>')
application = webapp2.WSGIApplication([
('/', MainPage),
('/sign', PageTwo),
], debug=True)
Here is a link to the Git Hub repository:
Get Template HTML, and write to browser
I saw an interesting variation of the app.yaml configuration file in a code example:
- url: /
static_files: index.html
upload: index.html
Even though the webbapp2 Request Handler is serving a particular HTML file based on the URL, the app.yaml file also controls what happens when different URL's are sent. The app.yaml file can be configured to run the python script AND upload a particular HTML file. If your application has lots of sub-directories, and the main.py script doesn't load until the end of your app.yaml file, configuring the app.yaml file to load static HTML right up front may cause your main page to load faster:
application: YourProjectNameHere
version: 1
runtime: python27
api_version: 1
threadsafe: true
handlers:
#Even though the main.py script also loads the index,
#this is faster if lots of processing
- url: /
static_files: index.html
upload: index.html
- url: /Client_Style
static_dir: Client_Style
- url: /Client_Pages
static_dir: Client_Pages
- url: /Client_Script
static_dir: Client_Script
- url: /Library
static_dir: Library
- url: /apiclient
static_dir: apiclient
- url: /Client_Data
static_dir: Client_Data
- url: /oauth2client
static_dir: oauth2client
- url: /uritemplate
static_dir: uritemplate
- url: /.*
script: main.application
libraries:
- name: webapp2
version: latest

Changing URLs after deploying Flask app

So, I have a flask application that works well when it's not deployed. Imagine it has pages for /index/ and /home/ and /home/field/. Now that I have deployed the app using Apache and mod_wsgi, it needs to have a prefix for every URL.
Now, it should look like /newapp/index/ and /newapp/home/ and /newapp/home/field/.
So, I changed all of the URLs to include the new /newapp/ prefix, but the only URL that works with it is the original /index/ URL. All of the others return a
Not Found The requested URL was not found on the server.
in the browser when I click for that URL. I definitely handle that route in my main.py, so I don't know why it would not be found.
Anyone know what is going on?
EDIT: adding some code
Basically I changed all my code in main.py from:
Original:
#app.route('/')
#app.route('/index/', methods=['GET', 'POST'])
def index():
#Stuff
#app.route('/home/')
def farms():
#More stuff
#app.route('/home/<selector>')
def fields(selector):
#Further stuff
To....
New Code
#app.route('/newapp/')
#app.route('/newapp/index/', methods=['GET', 'POST'])
def index():
#Stuff
#app.route('/newapp/home/')
def farms():
#More stuff
#app.route('/newapp/home/<selector>')
def fields(selector):
#Further stuff
I did this because the domain I am using already has another Flask app, so I had to differentiate between the two. Also, I expect there to be more flask apps in the future, so this newapp will end up being an identifier for any given flask app.
I changed main.py as well has all of my hrefs in my templates. So, the hrefs went from
href=/index/
to
href=/newapp/index/
And, I get the error that I posted above whenever I try to click on a link
Further info:
So, checking out the apache error logs one error says, File does not exist: /var/www/flask_util.js, because in my main.py I call from flask_util_js import FlaskUtilJs. I'm not sure if this has anything to do with the URL routing, but it might
You don't need to add the prefix in your code.
Say you have code like
#app.route('/hi', methods = ['GET','POST'])
def myIndex():
return "Hello World!", 200
And you set your alias like to deploy it to www.myserver.com/app/
WSGIScriptAlias /app /var/www/myDir/myApp/app.wsgi
the server should automatically map www.myserver.com/app/hi to /hi in your application.
However if you set the mapping to
#app.route('/newapp/hi', methods = ['GET','POST'])
def myIndex():
return "Hello World!", 200
You WSGI app would only receive the call for /hi (server strips away the prefix) so it would find no matching Path and return not found.

Script Handler for Google App Engine

I am trying to study using Python in Google App Engine and can't get the tutorial to work. But ultimately, I would want to write a Python script that would return list of files in a folder in server to JavaScript.
Here's what I currently have:
+MainProj
+ static
+scripts
. __init__.py
. helloworld.py
. app.yaml
In helloworld.py
import webapp2
class MainPage(webapp2.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/plain'
self.response.write('Hello, webapp2 World!')
app = webapp2.WSGIApplication([('/.*', MainPage)], debug=True)
In app.yaml
application: applicationname
version: 1
runtime: python27
api_version: 1
threadsafe: yes
handlers:
- url: /.*
script: static.scripts.helloworld.app
I am getting a server error
HTTP Error 500 (Internal Server Error): An unexpected condition was encountered while the server was attempting to fulfill the request.
Anyone can help what's wrong with my setup?
Every folder in your package path ('static.scripts.helloworld.app') needs to have __init__.py in it to import properly, so either add one to 'static' or (more sensibly, in my opinion) move helloworld.py up to the top, and use 'helloworld.app' in your app.yaml.
All you need in your app.yaml handler is:
- url: /.*
script: static.scripts.helloworld.py
And make sure you also have in your helloworld.py at the bottom code to actually start the application and listener:
from google.appengine.ext.webapp import util
# granted, you might want to replace "webapp" with "webapp2" here
def main():
util.run_wsgi_app(app)
if __name__ == '__main__':
main()

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()),

Exclude One URL From Python URL Masking

I have never written a python script in my life, but I have a question that can hopefully be solved pretty quickly...
I'm using Google App Engine and Dropbprox. The script uses a custom domain to point to your public DropBox folder for better DropBox URLs. I'd like to be able to redirect users to my main site (jacob.bearce.me) if they visit my dropbox url (dl.bearce.me).
The problems that I'm having:
I've never used GAE or Python before, so I have no idea where to even begin
Putting a index.html file in my GAE project didn't fix it (I was hoping it'd just default to that if there was no filename specified, like it would on a normal site, but no cigar.)
Just a simple redirect if a users visits the main URL is all I'm after, nothing fancy.
My Python file: http://dl.bearce.me/mirror.py
Here's a main.py that issues a redirect for all requests, using the Python 2.5 runtime environment:
from google.appengine.ext import webapp
from google.appengine.ext.webapp import util
class MainHandler(webapp.RequestHandler):
def get(self):
self.redirect('http://jacob.bearce.me/')
application = webapp.WSGIApplication([('/.*', MainHandler)],
debug=True)
def main():
util.run_wsgi_app(application)
if __name__ == '__main__':
main()
And here's the app.yaml file you need to route URLs to this handler:
application: myapp
version: 1
runtime: python
api_version: 1
handlers:
- url: .*
script: main.py
(Replace myapp with your actual app ID.)
For more information about creating and uploading an App Engine app in Python, see the Getting Started tutorial.

Categories