I am using the Google App Engine GUI. Not sure what I'm doing wrong since I'm following Google's lead on this one. In the GUI, the app is running on admin port 8000 and listening in on port 8080. When I go to localhost:8080, I get a 'Server Error' in Chrome. Is this a firewall problem or a GAE problem?
helloudacity.py
import webapp2
class mainPage(webapp2.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/plain'
self.response.write('Hello, Udacity!')
application = webapp2.WSGIApplication([
('/', MainPage),
], debug=true)
app.yaml
application: your-app-id
version: 1
runtime: python27
api_version: 1
threadsafe: true
handlers:
- url: /.*
script: helloudacity.application
You forgot to capitalize mainPage in your routes and debug=true to True. If you look at error console most of the errors should be there.
Try changing debug=true to debug=True.
The booleans on Python are True or False.
Google´s sample is right.
Related
I'm running a static site on GAE and using a custom domain (let's call it example.com) with SSL certificates enabled. I'd like to canonicalize URLs to https://www.example.com/. That means catching any requests to myproject.appspot.com, plain HTTP, and/or the naked domain, and redirecting to www over HTTPS.
I understand that it's not possible to put redirect logic in app.yaml, but ideally I'd like to keep the static file serving logic there, and only have app code for the redirect. (As opposed to doing the static serving in app code as well.)
Here's what I have so far:
Contents of the file app.yaml:
runtime: python27
api_version: 1
threadsafe: true
handlers:
- url: /
static_files: www/index.html
upload: www/index.html
- url: /(.*)
static_files: www/\1
upload: www/(.*)
Contents of the file dispatch.yaml:
dispatch:
- url: "myproject.appspot.com/*"
module: canonicalizer
Contents of the file canonicalizer.yaml:
module: canonicalizer
runtime: python27
api_version: 1
threadsafe: true
handlers:
- url: /.*
script: canonicalizer.app
Contents of the file canonicalizer.py:
import webapp2
def get_redirect_uri(handler, *args, **kwargs):
return 'https://www.example.com/' + kwargs.get('path')
app = webapp2.WSGIApplication([
webapp2.Route('/<path:.*>',
webapp2.RedirectHandler,
defaults={'_uri': get_redirect_uri, '_code': 302}),
], debug=True)
As you can see, I've only attempted to implement redirecting myproject.appspot.com so far. I haven't been able to get it working; myproject.appspot.com still serves content rather than redirecting to the custom domain.
I saw a similar SO question and used it as a basis for my code above. I followed it fairly closely, so I'm not sure if it's outdated or missing details.
I'm not very familiar with webapp2. Also open to solutions in a different framework or even different programming language.
As sllopis said in their answer, an HTTP to HTTPS redirect can be implemented via a secure: always element.
The rest of what I wanted to do needed to be done in app code. The code in my answer was on the right track, but I had some confusion about how services work in GAE and about dispatch.yaml. Here's my final code:
<application root>/app.yaml
runtime: python27
api_version: 1
threadsafe: true
handlers:
- url: /
static_files: www/index.html
upload: www/index.html
secure: always
redirect_http_response_code: 301
- url: /(.*)
static_files: www/\1
upload: www/(.*)
secure: always
redirect_http_response_code: 301
<application root>/dispatch.yaml
dispatch:
- url: "*.appspot.com/*"
service: canonicalizer
- url: "example.com/*"
service: canonicalizer
<application root>/canonicalizer/app.yaml
service: canonicalizer
runtime: python27
api_version: 1
threadsafe: true
handlers:
- url: /.*
script: canonicalizer.app
<application root>/canonicalizer/canonicalizer.py
import webapp2
def get_redirect_uri(handler, *args, **kwargs):
return 'https://www.justinforcentral.com/' + kwargs.get('path')
app = webapp2.WSGIApplication([
webapp2.Route('/<path:.*>',
webapp2.RedirectHandler,
defaults={'_uri': get_redirect_uri, '_code': 301}),
], debug=False)
This allows all the redirects to be done while still maintaining the ability to route the static site via static_files handlers.
As an aside, I also didn't realize that simply doing gcloud app deploy . from the application root only deploys the default service. To deploy this whole thing I had to run gcloud app deploy . dispatch.yaml canonicalizer.
Mapping Custom Domains to GAE
App Engine allows applications to be served via a custom domain, such as example.com, instead of the default appspot.com address. You can create a domain mapping for your App Engine app so that it uses a custom domain.
You will need to do the following:
Verify that you are the owner of your domain through Webmaster Central
Ensure that your domain has been verified.
Delegate the ownership of your domain to other users or service accounts, if needed.
Map your domain to your App Engine app.
Fill out the form with the listed resource records, including their type and canonical name (CNAME).
Add this information to the DNS configuration of your domain registrar.
Securing Custom Domains with SSL
By default, when you map your custom domain to your app, App Engine issues a managed certificate for SSL for HTTPS connections. Securing your custom domains with SSL offers more information about this.
Handling URL requests that do not use HTTPS
Any URL handler can use the secure setting, including script handlers and static file handlers. If secure is set to always, requests for a URL that match this handler that do not use HTTPS are automatically redirected to the HTTPS URL with the same path. Query parameters are preserved for the redirect.
Example in the app.yaml file:
handlers:
- url: /youraccount/.*
secure: always
script: auto
Conclusion
As a result, after following these steps, you should have a custom domain properly mapped to your App Engine site that uses SSL certificates to secure the custom domain.
Moreover, by adding the secure:always handler in your app.yaml file, any URL requests made against your App Engine site will be automatically redirected to the HTTPS URL with the same path.
Update - Redirect all URLs with Google App Engine
Credits to How to redirect all URLs with Google App Engine:
app.yaml
handlers:
- url: /.*
script: main.py
main.py
import webapp2
class MainPage(webapp2.RequestHandler):
def get(self):
self.redirect("https://example.com", True)
app = webapp2.WSGIApplication([
('/', MainPage),
], debug=True)
Then, you can adjust this code to your needs.
I'm refactoring an existing codebase. I switched from using the appcfg.py to using the gcloud command, which seemed to go fine. Our entire codebase was running on one default frontend instance, which I'm now trying to break into services. To start, I created one "worker" backend service, and I'm using a cron job to test.
I can see the worker in the console, but no instance is started. The logs for that service are rapidly flooded with 404's to /_ah/start. I've tried manual and basic scaling. The documentation states that it's okay not to have a startup script, and that a 404 at that endpoint is considered success. However, the instance is not starting.
Logs
worker.yaml
service: worker
runtime: python27
api_version: 1
instance_class: B2
manual_scaling:
instances: 1
threadsafe: false
handlers:
- url: /work/.*
script: worker.app
secure: always
login: admin
worker.py
import webapp2
import handlers
config = {
#...
}
app = webapp2.WSGIApplication([
webapp2.Route(
'/work/test<:/?>',
handlers.Test,
methods=['GET'],
),
], debug=True, config=config)
dispatch.yaml
dispatch:
- url: "*/work/*"
module: worker
I'm new to Google app engine not new to Python, there is a very confusing problem to me.
First of all, show you my version.
The problem is when I run the development server, there is a constant POST request to /PRC2, I have no idea where it came from.
See the screenshot below.
My main.py
from google.appengine.ext import webapp
import os
from handlers import MainHandler
CURRENT_VERSION_ID = os.environ.get('CURRENT_VERSION_ID', None)
if os.environ.get('SERVER_SOFTWARE', '').startswith('Google App Engine'):
DEVELOPMENT = False
else:
DEVELOPMENT = True
config = {
'DEBUG': DEVELOPMENT
}
routes = [
(r'/', MainHandler), # Homepage
]
app = webapp.WSGIApplication(
routes, debug=DEVELOPMENT, config=config
)
And app.yaml
application: xxxxxxxxxxxx
version: 1
runtime: python27
api_version: 1
threadsafe: true
handlers:
- url: /static
static_dir: static
- url: /.*
script: main.app
libraries:
- name: webapp2
version: "2.5.1"
- name: jinja2
version: "2.6"
Strange. Try another port and look if you keep this strange POST. Or serve the post in your app and look what is in the request, to find out where it comes from.
You're probably launching dev_appserver on some port where an XML-RPC application is looking for a particular API.
I have tried to move to Python 2.7 from Python 2.5 but I keep getting the same error everytime.
I have made a very simple test in Python 2.5 working with the app.yaml file and just one script main.py and it works fine. The script it just a Hello World type to check everythin works fine.
app.yaml
application: sparepartsfinder
version: 1
runtime: python
api_version: 1
handlers:
- url: /blog
script: main.py
- url: /blog/new_entry
script: main.py
main.py
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
class MainPage(webapp.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write('Hello, webapp World!')
application = webapp.WSGIApplication(
[('/', MainPage),
('/blog', MainPage),
('/blog/new_entry',MainPage),
('/blog/archive/.*',MainPage)],
debug=True)
def main():
run_wsgi_app(application)
if __name__ == "__main__":
main()
When I change to Python 2.7 I follow the documents on the Google App Engine to the letter making the changes in both the app.yaml and main.py script.
app.yaml
application: sparepartsfinder
version: 1
runtime: python27
api_version: 1
threadsafe: true
handlers:
- url: /blog
script: main.py
- url: /blog/new_entry
script: main.py
- url: /blog/archive/.*
script: main.py
- url: .*
script: main.py
main.py
import webapp2
class MainPage(webapp2.RequestHandler):
def get(self):
self.response.out.write('Hello prueba!')
app = webapp2.WSGIApplication([('/', MainPage),
('/blog', MainPage),
('/blog/new_entry',MainPage),
('/blog/archive/.*',MainPage)],
debug=True)
Unfortunately it doesn't work either in local or when I try to upload the new configuration to the Google App Engine. ( I get always the same mistake).
I may understand the problem in my machine ( I have both Python 2.5 and 2.7 ) on a Windows XP, but not when I upload.
This is the error:
2012-05-04 13:02:07 Running command: "[u'C:\Python25\python2.5.exe', '-u', 'C:\Archivos >de programa\Google\google_appengine\appcfg.py', '--no_cookies', u'--email=salvador.sanjuan#gmail.com', '--passin', 'update', 'C:\Documents and Settings\SSanjuan\Mis documentos\Dropbox\Dropbox\Python\SpareParts']"
Error parsing yaml file:
Invalid object:
threadsafe cannot be enabled with CGI handler: main.py
in "C:\Documents and Settings\SSanjuan\Mis documentos\Dropbox\Dropbox\Python\SpareParts\app.yaml", line 27, column 1
2012-05-04 13:02:31 (Process exited with code 1)
Use main.application instead of main.py in your app.yaml. You need the former in order to set threadsafe to true.
I've been having the same problem, and here's the answer.
For the Python 2.5 runtime, you are specifying a path to a file -- ie script: myfolder/myfile.py.
For the Python 2.7 runtime, you are specifying an Object. So assumping myfile.py contains an appropriate WSGI object 'app', it's specified as script: myfolder.myfile.app.
I am new to Google App Engine. I am able to start the appserver from the command prompt of Windows and its showing "Info : The server is running at http://localhost:8080/" but still when I enter the address on my browser its showing the Sever not found error.
There are a quite a few reasons this could be happening. If you have checked your firewall settings I'm willing to bet that there is an issue with your app.yaml file.
If your main python script is called main and is located in the root directory of your application code a working example of an app.yaml file is:
application: yourapplicationname
version: 1
runtime: python
api_version: 1
- url: .*
script: main.py
Also make sure that within your main.py file the routes are correct.
eg:
from google.appengine.ext import webapp
class Main(webapp.RequestHandler):
def get(self):
self.response.out.write('Hello World')
def main():
application = webapp.WSGIApplication([('/', Main)],
debug=True)
util.run_wsgi_app(application)
if __name__ == '__main__':
main()