Google App Engine with local Django 1.1 gets Intermittent Failures - python

I'm using the Windows Launcher development environment for Google App Engine.
I have downloaded Django 1.1.2 source, and un-tarrred the "django" subdirectory to live within my application directory (a peer of app.yaml)
At the top of each .py source file, I do this:
import settings
import os
os.environ["DJANGO_SETTINGS_MODULE"] = 'settings'
In my file settings.py (which lives at the root of the app directory, as well), I do this:
DEBUG = True
TEMPLATE_DIRS = ('html')
INSTALLED_APPS = ('filters')
import os
os.environ["DJANGO_SETTINGS_MODULE"] = 'settings'
from google.appengine.dist import use_library
use_library('django', '1.1')
from django.template import loader
Yes, this looks a bit like overkill, doesn't it?
I only use django.template. I don't explicitly use any other part of django.
However, intermittently I get one of two errors:
1) Django complains that DJANGO_SETTINGS_MODULE is not defined.
2) Django complains that common.html (a template I'm extending in other templates) doesn't exist.
95% of the time, these errors are not encountered, and they randomly just start happening. Once in that state, the local server seems "wedged" and re-booting it generally fixes it.
What's causing this to happen, and what can I do about it? How can I even debug it?
Here is the traceback from the error:
Traceback (most recent call last):
File "C:\code\kwbudget\edit_budget.py", line 34, in get
self.response.out.write(t.render(template.Context(values)))
File "C:\code\kwbudget\django\template\__init__.py", line 165, in render
return self.nodelist.render(context)
File "C:\code\kwbudget\django\template\__init__.py", line 784, in render
bits.append(self.render_node(node, context))
File "C:\code\kwbudget\django\template\__init__.py", line 797, in render_node
return node.render(context)
File "C:\code\kwbudget\django\template\loader_tags.py", line 71, in render
compiled_parent = self.get_parent(context)
File "C:\code\kwbudget\django\template\loader_tags.py", line 66, in get_parent
raise TemplateSyntaxError, "Template %r cannot be extended, because it doesn't exist" % parent
TemplateSyntaxError: Template u'common.html' cannot be extended, because it doesn't exist
And edit_budget.py starts with exactly the lines that I included up top.
All templates live in a directory named "html" in my root directory, and "html/common.html" exists. I know the template engine finds them, because I start out with "html/edit_budget.html" which extends common.html.
It looks as if the settings module somehow isn't applied (because that's what adds html to the search path for templates).

Firstly, although django is now a LOT more compatible with app engine than it once, some major incompatibilities still exist between the two platforms, meaning that you can't just dump a stock copy of django into your appengine directory and have it work out of the box. Things will error in strange ways.
There are a number of projects which aim to improve compatibility between the two projects, the most prominent is app-engine-patch. I highly suggest reading the following article http://code.google.com/appengine/articles/app-engine-patch.html and the rest of the articles located at code.google.com/appengine/articles/ under the django tab.
as for some of you're specific problems, you could try this within your setup script:
#setup django environment
from django.core.management import setup_environ
import settings
setup_envion(settings)
this is what django uses internally for setting up the environment within manage.py and is the accepted best practice for setting up django for use with scripts (like app engine).

I'm having exactly the same issue, and I haven't been able to work around it... though I've noticed it happens a LOT less with the real GAE than it does with the development server I run on my Linux workstation.

Related

Unable to mailmerge into a template word document when launched on heroku

I am working on a django application in which users input is inserted into a template word document. I used the mailmerge library to achieve this. It was all working fine on my local server but when I deployed the app to heroku it started giving me errors. The system doesn’t crush or anything. The ajax request made to call the function that mailmerges the document is returning the error function The error I get on the heroku logs is:
File "/app/input/merge.py", line 69, in merge
2019-12-02T07:55:48.252446+00:00 app[web.1]: document.write('documents/'+name+'.docx')
2019-12-02T07:55:48.252449+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/mailmerge.py", line 120, in write
2019-12-02T07:55:48.252451+00:00 app[web.1]: with ZipFile(file, 'w', ZIP_DEFLATED) as output:
I don't understand why it is giving me this error. The documents generated are saved into a folder named documents in the root directory of the project.

Blueprints in Flask "Attribute 'function' object has no attribute 'name'

Problem Description
Getting error message when trying to start Flask.
Traceback (most recent call last):
File "./run.py", line 3, in <module>
from app import app
File "/home/xxxxxx/xxxx.xxxxxxx.com/ClientTracker/app/__init__.py", line 13, in <module>
app.register_blueprint(admin)
File "/home/xxxxx/xxxxx.xxxxxxx.com/ClientTracker/env/local/lib/python2.7/site-packages/flask/app.py", line 65, in wrapper_func
return f(self, *args, **kwargs)
File "/home/xxxxx/xxxxx.xxxxxxx.com/ClientTracker/env/local/lib/python2.7/site-packages/flask/app.py", line 958, in register_blueprint
if blueprint.name in self.blueprints:
AttributeError: 'function' object has no attribute 'name'
This is a migration from a simpler hierarchy implementing Blueprints. I'm splitting out the function of the frontend and the admin panel.
I built this step by step and had both sides working fine.
Started migrating (functions and routes). After moving some code, I started getting an error message (basically the same as above, but different line).
Troubleshooting
Searched through related posts on stackO
Initially it was complaining about the second route statement I had. I
started removing code (rolling back) to what I (thought was) a known
good state. However I continued to have issues.
I have it down to the minimum code I believe I need but still getting
errors.
If I remove the registration in the init.py file, the frontend works
perfectly.
Code
#ClientTracker/run.py
#!env/bin/python
from app import app
app.run(host='0.0.0.0', port=8080, debug=False)
#ClientTracker/app/__init__.py
# Import flask and template operators
from flask import Flask, render_template
# Define the WSGI application object
app = Flask(__name__)
# Import a module / component using its blueprint handler variable (mod_auth)
#from app.mod_auth.controllers import mod_auth as auth_module
from app.admin.views import admin
from app.client.views import client
# Register blueprint(s)
app.register_blueprint(admin)
app.register_blueprint(client)
#ClientTracker/app/admin/views.py
from flask import render_template, request, Blueprint
from app import app
import MySQLdb
import datetime
admin = Blueprint(
'admin',
__name__,
url_prefix='/admin',
template_folder='templates',
static_folder='static'
)
#admin.route('/')
def admin():
return "ok"
I'm out of ideas.
Ok, so as seems to happen, I spend an hour looking, another 15 mins composing a question and then after I hit post, I find the answer.
I found a post (https://github.com/pallets/flask/issues/1327) that had the answer.
Basically, you cannot have a function name with the same name as your Blueprint name. Seems obvious now, but certainly stumped me for a while.
In thinking about it, my original "working" state had a dummy function name serving the '/'. When I rolled back, I didn't roll back far enough.
Replaced def admin(): with def admin1(): (will fix this better in prod) and all worked.
I hope this post helps someone else. Please still feel free to comment. As always, the group is always smarter than the individual. Lastly, thanks for reading this far. :-)
Your blueprint name is same with your function name, try to rename the function name instead.
Note that the blue print name and the function name can not be the same.
Make use if this tutorial to learn more about Blueprints, https://realpython.com/flask-blueprint/

Django 1.6.8 with ADMIN_URL

I would like to add the https://github.com/RobCombs/django-locking project to my Django 1.6.8 project's admin interface. I understand that this locking code is meant for an older version of Django, but I'd like to see if it's possible to install anyway.
While following step 7, I'm encountering this exception:
File "/usr/local/lib/python2.7/dist-packages/django_locking-0.3.2-py2.7.egg/locking/admin.py", line 15, in <module>
class LockableAdmin(admin.ModelAdmin):
File "/usr/local/lib/python2.7/dist-packages/django_locking-0.3.2-py2.7.egg/locking/admin.py", line 17, in LockableAdmin
class Media:
File "/usr/local/lib/python2.7/dist-packages/django_locking-0.3.2-py2.7.egg/locking/admin.py", line 21, in Media
_s.ADMIN_URL + "ajax/variables.js",
File "/usr/local/lib/python2.7/dist-packages/django/conf/__init__.py", line 55, in __getattr__
return getattr(self._wrapped, name)
AttributeError: 'Settings' object has no attribute 'ADMIN_URL'
Indeed my settings.py has nothing about ADMIN_URL. I can't find any documentation on how to set this, or otherwise proceed with adding this locking functionality.
Is it possible to continue from here on Django 1.6.8?
Apparently the construction with getattr() in settings.py of django-locking doesn't work anymore (because Django's Settings object raises AttributeError?) which is surprising to me. I can't test right now, unfortunately.
The good news is that simply setting ADMIN_URL = '/admin/' in your settings will most likely fix this issue.
The bad news is that you'll probably run into a few more that may not be easy to fix, but who knows...

Application ID error with GAE remote API

I am trying to use the Remote API in a local Client, following instructions given in Google documentation (https://developers.google.com/appengine/docs/python/tools/remoteapi).
I first tried from the Remote API shell, and everything is working fine. I can connect to my remote datastore and fetch data.
But when I run the following script, which is very similar to Google's example :
#!/opt/local/bin/python2.7
import sys
SDK_PATH = "/usr/local/google_appengine/"
sys.path.append(SDK_PATH)
import dev_appserver
dev_appserver.fix_sys_path()
from google.appengine.ext.remote_api import remote_api_stub
import model.account
def auth_func():
return ('myaccount', 'mypasswd')
remote_api_stub.ConfigureRemoteApi('myappid', '/_ah/remote_api', auth_func)
# Fetch some data
entries = model.account.list()
for a in entries:
print a.name
then I get an error :
Traceback (most recent call last):
File "./remote_script_test.py", line 26, in <module>
entries = model.account.list()
[...]
File "/Developer/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/datastore/datastore_rpc.py", line 1333, in check_rpc_success
raise _ToDatastoreError(err)
google.appengine.api.datastore_errors.BadRequestError: Application Id (app) format is invalid: '_'
It says my application ID is a plain underscore '_', which is not the case since my app.yaml is correctly configured and when I do a
print app_identity.get_application_id()
from that script I get the correct application ID. I am under the impression that the GAE environment is not properly setup, but I could not figure out how to make it work. Does anyone have a full piece of code that works in this context ?
I am using Mac Os X Mountain Lion.
You may wish to start with remote_api_shell.py and remove stuff until it breaks, rather than add in things until it works.
For instance there's a line after the one you copied: remote_api_stub.MaybeInvokeAuthentication() is that necessary? There may be a number of necessary lines in remote_api_shell.py, maybe better to customize that rather than start from scratch.

Cannot use jinja2 PackageLoader on Google App Engine

I'm trying to use the PackageLoader jinja2 provides but I cannot get it to work.
In my app.yaml I have the required libraries declared:
libraries:
- name: jinja2
version: latest
- name: setuptools
version: latest
The smallest example I could create:
import webapp2, sys
from jinja2 import Environment, PackageLoader
sys.path += ['lib/somepackage']
class Test(webapp2.RequestHandler):
def get(self):
env = Environment(loader=PackageLoader('common'))
self.response.write(env.get_template('test.html').render())
routes = [(r"/", Test)]
app = webapp2.WSGIApplication(routes, debug=True)
The package common exists in the directory lib/somepackage and has a package templates which contains a file test.html. The html file only contains the text 'test'.
When the PackageLoader is constructed it's provider is always a NullProvider when in Google App Engine. When I manually request a provider I get a DefaultProvider so obviously something is wrong here.
To request a provider I ensure lib/somepackage is in the sys.path by going to that dir, then:
>>> import pkg_resources
>>> provider = pkg_resources.get_provider('common')
>>> provider
<pkg_resources.DefaultProvider instance at 0x8490b2c>
When this fails in Google App Engine, this is the relevant part of the traceback:
File "/<>/test/main.py", line 7, in get
self.response.write(env.get_template('test.html').render())
File "/<>/google_appengine/lib/jinja2-2.6/jinja2/environment.py", line 719, in get_template
return self._load_template(name, self.make_globals(globals))
File "/<>/google_appengine/lib/jinja2-2.6/jinja2/environment.py", line 693, in _load_template
template = self.loader.load(self, name, globals)
File "/<>/google_appengine/lib/jinja2-2.6/jinja2/loaders.py", line 115, in load
source, filename, uptodate = self.get_source(environment, name)
File "/<>/google_appengine/lib/jinja2-2.6/jinja2/loaders.py", line 226, in get_source
if not self.provider.has_resource(p):
File "/<>/google_appengine/lib/setuptools-0.6c11/pkg_resources.py", line 1170, in has_resource
return self._has(self._fn(self.module_path, resource_name))
File "/<>/google_appengine/lib/setuptools-0.6c11/pkg_resources.py", line 1218, in _has
"Can't perform this operation for unregistered loader type"
NotImplementedError: Can't perform this operation for unregistered loader type
When I use a FileSystemLoader instead it works, however this won't work in a zip I guess:
import common.templates
env = Environment(loader=FileSystemLoader(common.templates.__path__))
I have seen this SO question but this isn't the problem.
Update:
I just tested the example in the 1.7.6 SDK and this works, however I'd love to see this working on a older SDK (or the old_dev_appserver).
The problem, I think, was with pkg_resources.
Some of the os related functionality isn't implemented in GAE but either jinja2 or Google provided a workaround it seems.
These links illustrate the issue:
http://code.google.com/p/googleappengine/issues/detail?id=60
https://github.com/mitsuhiko/jinja2/issues/143
Jinja2 PackageLoader on google app engine
https://bitbucket.org/tarek/distribute/issue/73/pkg_resources-fails-on-google-app-engine
I've used
jinja_environment = jinja2.Environment(autoescape=True,
loader=jinja2.FileSystemLoader(os.path.join(os.path.dirname(__file__), 'templates')))
as boilerplate to get the templates from the "template" directory in the same directory as the file that is setting the definition. But the question is about files zipped as eggs and using PackageLoader
Is there an __init__.py file inside the package? You said it worked on 1.7.6, though.

Categories