I'm working to modify a cookiecutter Flask app. I'm working locally on WIN7 and attempting to deploy to heroku. I'm currently trying to add a datepicker to a page. I've found https://eonasdan.github.io/bootstrap-datetimepicker/. The structure of myflaskapp:
I've set up bower to install the front end dependencies under the static root by using a .bowerrc file in the document root containing:
{ "directory" : "myflaskapp/static/bower_components" }
This cookiecutter uses flask-assets to manage the project assets. Following https://adambard.com/blog/fresh-flask-setup/ I've modified myflaskapp/assets.py file :
from flask_assets import Bundle, Environment
import os
css = Bundle(
"libs/bootstrap/dist/css/spacelab/bootstrap.css",
"bower_components/eonasdan-bootstrap-datetimepicker/build/css/bootstrap-datetimepicker.css",
"css/style.css",
"css/home.css",
# "css/style.css",
filters="cssmin",
output="public/css/common.css"
)
js = Bundle(
"libs/jQuery/dist/jquery.js",
"libs/bootstrap/dist/js/bootstrap.js",
"bower_components/moment/moment.js",
"bower_components/eonasdan-bootstrap-datetimepicker/build/js/bootstrap-datetimepicker.min.js",
"js/plugins.js",
filters='jsmin',
output="public/js/common.js"
)
assets = Environment()
assets.register("js_all", js)
assets.register("css_all", css)
myflaskapp/app.py initializes the assets:
from flask import Flask, render_template
from myflaskapp.assets import assets
"""
:param config_object: The configuration object to use.
"""
app = Flask(__name__)
app.config.from_object(config_object)
register_extensions(app)
register_blueprints(app)
register_errorhandlers(app)
return app
def register_extensions(app):
assets.init_app(app)
def register_blueprints(app):
app.register_blueprint(public.blueprint)
app.register_blueprint(user.blueprint)
In the myflaskapp/settings.py , during testing, I have set:
ASSETS_DEBUG = True # Don't bundle/minify static assets
Locally, there are no errors in the console. On heroku , I get an Internal server error. Logs:
←[33m2016-03-19T18:02:12.464159+00:00 app[web.1]:←[0m for org, cnt in self.resolve_contents(ctx):
←[33m2016-03-19T18:02:12.464161+00:00 app[web.1]:←[0m raise BundleError(e)
←[33m2016-03-19T18:02:12.464162+00:00 app[web.1]:←[0m BundleError: 'bower_components/eonasdan-bootstrap-datetimepicker/build/css/bootstrap-datetimepicker.css' not found in load path:
['/app/myflaskapp/static']
←[33m2016-03-19T18:02:12.464150+00:00 app[web.1]:←[0m rv = template.render(context)
←[33m2016-03-19T18:02:12.464151+00:00 app[web.1]:←[0m File "/app/.heroku/python/lib/python2.7/site-packages/jinja2/environment.py", line 969, in render
←[33m2016-03-19T18:02:12.464152+00:00 app[web.1]:←[0m File "/app/.heroku/python/lib/python2.7/site-packages/jinja2/environment.py", line 742, in handle_exception
←[33m2016-03-19T18:02:12.464154+00:00 app[web.1]:←[0m {% extends "layout.html" %}
←[33m2016-03-19T18:02:12.464157+00:00 app[web.1]:←[0m urls = bundle.urls()
←[33m2016-03-19T18:02:12.464153+00:00 app[web.1]:←[0m reraise(exc_type, exc_value, tb)
As you can see in the top screenshot it is there. How can I fix this?
Note: I've been looking at https://github.com/mitsuhiko/flask/issues/348, which may have a bearing on this.
Try checking your .gitignore, build is often ignored which would exclude your static files here: bower_components/eonasdan-bootstrap-datetimepicker/build/*
Related
I have recently changed my main flask app file from inputServer.py to app.py to increase ease of use.
My code that throws the error is as follows:
def readBackupPlayers(objectFile):
with open(objectFile, 'rb') as openedFile:
manager.playerList = pickle.load(openedFile)
print('Backup of players retrieved')
^
Function that read a custom pickle file used for backing up a list stored inside a custom object
class PlayerManager:
def __init__(self):
self.playerList = []
self.ID = len(self.playerList) + 1
self.currentGame = None
self.tournament = None
manager = PlayerManager()
^
Code that declares the class and creates an instance of it to use to store variables across the program.
Error message:
File "c:\users\simon\appdata\local\programs\python\python38-32\lib\site-packages\flask\app.py", line 1936, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "C:\Users\simon\OneDrive\Documents\AtomTesting\app.py", line 356, in setup
readBackupPlayers('Backups/playerBackup')
File "C:\Users\simon\OneDrive\Documents\AtomTesting\app.py", line 72, in readBackupPlayers
manager.playerList = pickle.load(openedFile)
ModuleNotFoundError: No module named 'inputServer'
Directory:
AtomTesting -
Backups -
playerBackup
tournamentBackup
Static -
static Flask files (not relevant)
templates -
Flask templates (not relevant)
app.py (renamed from inputServer.py)
config.py
README.md
Here's what's happening. Python's pickle module serializes and deserializes (dumps and loads) Python objects based on their name. Since the name of the module where your class lives changed, Pickle can't figure out how to re-instanciate those objects.
There is, however, a solution which is detailed on the Python wiki. It involves mapping old names to new names:
import pickle
renametable = {
'inputServer': 'app',
}
def mapname(name):
if name in renametable:
return renametable[name]
return name
def mapped_load_global(self):
module = mapname(self.readline()[:-1])
name = mapname(self.readline()[:-1])
klass = self.find_class(module, name)
self.append(klass)
def loads(str):
file = StringIO(str)
unpickler = pickle.Unpickler(file)
unpickler.dispatch[pickle.GLOBAL] = mapped_load_global
return unpickler.load()
Alternatively, and this is probably a better approach, you shouldn't use pickle for any serious data store, especially when something might be used between versions of your app.
You might consider using an ORM with a lightweight database, like SQLite.
I am currently trying to build an api using connexion. However, I am having some issues using relative local module imports through the connexion module, which modifies the underlying flask app. Here is a simplified overview of my file structure:
hall_of_fame_api
controller
____init____.py
routes.py
model
____init____.py
routes.py
____init____.py
config.py
create_db.py
swagger.yml
I am getting an error when I try to run 'python config.py' in my terminal. Here is config.py:
import os
import connexion
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
basedir = os.path.abspath(os.path.dirname(__file__))
# Create the Connexion application instance
connex_app = connexion.App(__name__, specification_dir=basedir)
# Get the underlying Flask app instance
app = connex_app.app
connex_app.add_api('swagger.yml')
# Configure the SQLAlchemy part of the app instance
app.config['SQLALCHEMY_ECHO'] = True
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://doadmin:password#nba-player-db-do-user-7027314-0.db.ondigitalocean.com:25060/nba_test_1?sslmode=require'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
# Create the SQLAlchemy db instance
db = SQLAlchemy(app)
# Initialize Marshmallow
ma = Marshmallow(app)
And here is the error it gives:
Failed to add operation for GET /api/players
Failed to add operation for GET /api/players
Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/connexion/apis/abstract.py", line 209, in add_paths
self.add_operation(path, method)
File "/usr/local/lib/python3.7/site-packages/connexion/apis/abstract.py", line 173, in add_operation
pass_context_arg_name=self.pass_context_arg_name
File "/usr/local/lib/python3.7/site-packages/connexion/operations/__init__.py", line 8, in make_operation
return spec.operation_cls.from_spec(spec, *args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/connexion/operations/swagger2.py", line 137, in from_spec
**kwargs
File "/usr/local/lib/python3.7/site-packages/connexion/operations/swagger2.py", line 96, in __init__
pass_context_arg_name=pass_context_arg_name
File "/usr/local/lib/python3.7/site-packages/connexion/operations/abstract.py", line 96, in __init__
self._resolution = resolver.resolve(self)
File "/usr/local/lib/python3.7/site-packages/connexion/resolver.py", line 40, in resolve
return Resolution(self.resolve_function_from_operation_id(operation_id), operation_id)
File "/usr/local/lib/python3.7/site-packages/connexion/resolver.py", line 66, in resolve_function_from_operation_id
raise ResolverError(str(e), sys.exc_info())
connexion.exceptions.ResolverError: <ResolverError: module 'controller.routes' has no attribute 'read_all'>
This error comes specifically from line 12 where connexion is trying to add the swagger.yml file, here is that for reference as well:
swagger: "2.0"
info:
description: This is the swagger file that goes with our server code
version: "1.0.0"
title: Swagger REST Article
consumes:
- "application/json"
produces:
- "application/json"
basePath: "/api"
# Paths supported by the server application
paths:
/players:
get:
operationId: "controller.routes.read_all"
tags:
- "People"
summary: "The people data structure supported by the server application"
description: "Read the list of people"
responses:
200:
description: "Successful read people list operation"
schema:
type: "array"
items:
properties:
fname:
type: "string"
lname:
type: "string"
timestamp:
type: "string"
Now here is where I am confused, because my routes.py file does have a function defined as read_all(), here is that file:
from model.models import Regseason, RegSchema, Playoffs, PlayoffSchema
def read_all():
return Regseason.query.all()
I have been racking my brain over this bug for almost 24 hours, any guidance would be greatly appreciated. Thanks in advance!
Please add a extra field x-openapi-router-controller below operationid. It is used by Connexion to map which module to send requests to. It is combined together with OperationId to go to correct module and function.
I am trying to run multiple Bokeh servers in the flask app , the plots function correctly on their own using method like this:
def getTimePlot():
script = server_document('http://localhost:5006/timeseries')
return render_template("displaytimeseries.html", script=script, template="Flask")
def startPlotserver():
server.start()
server = Server({'/timeseries': modifyTimeSeries}, io_loop=IOLoop(), allow_websocket_origin=["localhost:8000"])
server.io_loop.start()
if __name__ == '__main__':
print('Opening single process Flask app with embedded Bokeh application on http://localhost:8000/')
print()
print('Multiple connections may block the Bokeh app in this configuration!')
print('See "flask_gunicorn_embed.py" for one way to run multi-process')
app.run(port=5000, debug=True)
but when i try to embed two servers together to flask using this approach that's where i get the problems:
file structure:
|--app4
|---webapp2.py
|---bokeh
|--timeseries.py
|--map.py
I think i have found the workaround in here Link To Question
I am have trying now to import the map server to flak using the similar method mentioned and ended up with something like this:
1. File builder (not sure why it's not picking it up)
def build_single_handler_applications(paths, argvs=None):
applications = {}
argvs = {} or argvs
for path in paths:
application = build_single_handler_application(path, argvs.get(path, []))
route = application.handlers[0].url_path()
if not route:
if '/' in applications:
raise RuntimeError("Don't know the URL path to use for %s" % (path))
route = '/'
applications[route] = application
return applications
2. Code to find file and create connection
files=[]
for file in os.listdir("bokeh"):
if file.endswith('.py'):
file="map"+file
files.append(file)
argvs = {}
urls = []
for i in files:
argvs[i] = None
urls.append(i.split('\\')[-1].split('.')[0])
host = 'http://localhost:5006/map'
apps = build_single_handler_applications(files, argvs)
bokeh_tornado = BokehTornado(apps, extra_websocket_origins=["localhost:8000"])
bokeh_http = HTTPServer(bokeh_tornado)
sockets, port = bind_sockets("localhost:8000", 5000)
bokeh_http.add_sockets(sockets)
3. Code which calls the server and renders template
#app.route('/crimeMap', methods=['GET'])
def getCrimeMap():
bokeh_script = server_document("http://localhost:5006:%d/map" % port)
return render_template("displaymap1.html", bokeh_script=bokeh_script)
i am running both of my Bokeh servers in single command like this
bokeh serve timeseries.py map.py --allow-websocket-origin=127.0.0.1:5000
but when i run webapp2.py i am getting this error:
(env1) C:\Users\Dell1525\Desktop\flaskapp\env1\app4>webapp2.py
Traceback (most recent call last):
File "C:\Users\Dell1525\Desktop\flaskapp\env1\app4\webapp2.py", line 113, in <module>
apps = build_single_handler_applications(files, argvs)
File "C:\Users\Dell1525\Desktop\flaskapp\env1\app4\webapp2.py", line 29, in build_single_handler_applications
application = build_single_handler_application(path, argvs.get(path, []))
NameError: name 'build_single_handler_application' is not defined
i found and added build_single_handler_application function from Bokeh docs only because of this error so i am not sure if it was even required or is correct. I am wondering what am i missing to make this work just in case it is positioning error or missing imports i am attaching full flask webapp2.py code here :
Full Code
Thak you so much for help
i have found an easier solution by tweaking this example a little: Link To Original Post Note this requires you to have tornado 4.4.1 as its not working with newer versions
trick is to run all servers individually and on different ports with same socket access like this
bokeh serve timeseries.py --port 5100 --allow-websocket-origin=localhost:5567
bokeh serve map.py --port 5200 --allow-websocket-origin=localhost:5567
for those who might find this useful i have included full working solution Link To Working Code
I have been creating a web app that uses webapp2 framework and hosted with Google App Engine. So in order to run the webapp on LOCALHOST, I use the following command.
dev_appserver.py app.yaml
The python script that I am trying to run is in the same project folder as well, when the script is executed, I get the following error.
File "C:\Program Files (x86)\Google\google_appengine\google\appengine\ext\remote_api\remote_api_stub.py", line 256, in _MakeRealSyncCall
raise pickle.loads(response_pb.exception())
RuntimeError: NotImplementedError()
I have no clue, why it is showing this error. I tried looking at python documentation.
exception NotImplementedError:
This exception is derived from RuntimeError. In user defined base classes, abstract methods should raise this exception when they require derived classes to override the method, or while the class is being developed to indicate that the real implementation still needs to be added.
https://docs.python.org/3/library/exceptions.html#NotImplementedError
As being new to programming, unfortunately it makes no sense to me.
I might be getting this error because of:
1.The application is running on different server and I am trying to run a script that is on my PC. But the demo I downloaded also has some python scripts that are been executed by clicking a button on html page and those work fine.
The script I am trying to execute, uses selenium web driver, it might be conflicting with the webapp2 framework.
I am not sure, why is that happening. Any suggestions please. Thanks!
UPDATE
full traceback
Traceback (most recent call last):
File "C:\Program Files (x86)\Google\google_appengine\google\appengine\tools\devappserver2\api_server.py", line 375, in _handle_POST
api_response = _execute_request(request).Encode()
File "C:\Program Files (x86)\Google\google_appengine\google\appengine\tools\devappserver2\api_server.py", line 231, in _execute_request
make_request()
File "C:\Program Files (x86)\Google\google_appengine\google\appengine\tools\devappserver2\api_server.py", line 226, in make_request
request_id)
File "C:\Program Files (x86)\Google\google_appengine\google\appengine\api\apiproxy_stub.py", line 151, in MakeSyncCall
method(request, response)
File "C:\Program Files (x86)\Google\google_appengine\google\appengine\api\remote_socket\_remote_socket_stub.py", line 234, in _Dynamic_Listen
raise NotImplementedError()
NotImplementedError
Views.py
from handlers.api_handler import APIHandler
from handlers.ndb_handler import InitUser
import webapp2
import os
from google.appengine.ext.webapp import template
class Google_Login(webapp2.RequestHandler):
def post(self):
template_values = {
'back_msg': 'View Campaigns'
}
try:
app_user = InitUser()
handler = APIHandler(app_user.client_id,
app_user.client_secret,
app_user.refresh_token,
app_user.adwords_manager_cid,
app_user.developer_token)
handler.google_log()
self.redirect('/showCampaigns?clientCustomerId=%s''{{ccid}}')
except Exception as e:
template_values['error'] = str(e)
# Use template to write output to the page.
path = os.path.join(os.path.dirname(__file__),
'../templates/base_template.html')
self.response.out.write(template.render(path, template_values))
Api_handler.py (where the selenium webdriver is being used)
def google_log(self):
browser=webdriver.Firefox(executable_path=r'C:\Users\JASPREET\geckodriver.exe')
browser.maximize_window()
browser.get("https://accounts.google.com/ServiceLogin/identifier?continue=https%3A%2F%2Fadwords.google.com%2Fum%2Fidentity%3Fhl%3Den%26sourceid%3Dawo%26subid%3Dca-en-ha-g-aw-c-dr_df_1-b_ex!o2~-1340701349-261603328952-kwd-1329939046%26utm_campaign%3Dca-ww-di-g-aw-a-awhp_1!o2&hl=en&service=adwords&skipvpage=true<mpl=signin&flowName=GlifWebSignIn&flowEntry=AddSession")
username=browser.find_element_by_css_selector('#identifierId')
username.send_keys('#EMAIL')
next=browser.find_element_by_css_selector('#identifierNext').click()
time.sleep(1)
password= browser.find_element_by_xpath("//input[#name='password']")
password.send_keys('#PASSWORD')
login=browser.find_element_by_xpath('//*[#id="passwordNext"]')
login.click()
time.sleep(3)
browser.get('path to scripts')
time.sleep(7)
run=browser.find_element_by_xpath('/html/body/div[2]/root/div/div[1]/div[3]/awsm-child-content/div[2]/div/bulk-root/base-root/div[2]/div[1]/view-loader/script-editor-view/script-editor/div/buttonbar/pending-panel/div/div/material-button[2]').click()
time.sleep(2)
run_two=browser.find_element_by_xpath('/html/body/div[4]/div[2]/material-dialog/focus-trap/div[2]/div/footer/div/material-button[2]').click()
HTML FILE where I am calling the python script to execute "FB" is the name of view that links to API handler and calls the script.
<div class="">
<form action="/fb?clientCustomerId = {{ccid}}" method="post">
<input type="submit" name="" value="RUN">
</form>
</div>
UPDATE 2
APP.YAML
runtime: python27
api_version: 1
threadsafe: false
handlers:
- url: /stylesheets
static_dir: stylesheets
- url: /js
static_dir: js
- url: /.*
script: demo.main.app
login: required
secure: always
libraries:
- name: ssl
version: latest
MAIN.PY
"""App Engine application module.
Configures the web application that will display the AdWords UI.
"""
from demo import DEBUG
from views import AddAdGroup
from views import AddCampaign
from views import InitView
from views import ShowAccounts
from views import ShowAdGroups
from views import ShowBudget
from views import ShowCampaigns
from views import ShowCredentials
from views import UpdateBudget
from views import UpdateCredentials
from views import ShowPage
from views import ShowKeywords
from views import NonServing
from views import Google_Login
import webapp2
app = webapp2.WSGIApplication([('/', InitView),
('/showCredentials', ShowCredentials),
('/updateCredentials', UpdateCredentials),
('/showAccounts', ShowAccounts),
('/showCampaigns', ShowCampaigns),
('/addCampaign', AddCampaign),
('/showAdGroups', ShowAdGroups),
('/addAdGroup', AddAdGroup),
('/showBudget', ShowBudget),
('/updateBudget', UpdateBudget),
('/nonservingpause', NonServing),
('/keywords', ShowKeywords),
('/fb', Google_Login),
],
debug=DEBUG)
I am reading 'Head First Python'. I am on Chapter 10 where Google App Engine is introduced. The initial hello world of using Python and Google App Engine was successful but subsequent programs have all failed.
I have the following app.yaml file:
application: three
version: 1
runtime: python27
api_version: 1
threadsafe: false
handlers:
- url: /.*
script: page368b.py
libraries:
- name: django
version: "1.3"
With the following Python code (page368b.py):
import wsgiref.handlers
from google.appengine.ext import webapp
from google.appengine.ext import db
from google.appengine.ext.webapp import template
#this line throws the error when accessing the web-page
from google.appengine.ext.db import djangoforms
import birthDB
class BirthDetailsForm(djangoforms.ModelForm):
class Meta:
model = birthDB.BirthDetails
class SimpleInput(webapp.RequestHandler):
def get(self):
html = template.render('templates/header.html', {'title': 'Provide your birth details'})
html = html + template.render('templates/form_start.html', {})
html = html + str(BirthDetailsForm(auto_id=False))
html = html + template.render('templates/form_end.html', {'sub_title': 'Submit Details'})
html = html + template.render('templates/footer.html', {'links': ''})
self.response.out.write(html)
def main():
app = webapp.WSGIApplication([('/.*', SimpleInput)], debug=True)
wsgiref.handlers.CGIHandler().run(app)
if __name__ == '__main__':
main()
Here is another Python module imported into the one above called birthDB.py:
from google.appengine.ext import db
class BirthDetails(db.Model):
name = db.StringProperty()
date_of_birth = db.DateProperty()
time_of_birth = db.TimeProperty()
There is a templates folder that the above Python module calls. They have HTML code in them with some Django code. Here is an example using the footer.html.
<p>
{{ links }}
</p>
</body>
</html>
The other HTML files are similar. I can start the Google App Engine with no problems using this command from BASH: python google_appengine/dev_appserver.py ~/Desktop/three The directory three contains the templates folder, the app.yaml file, the Python modules shown above.
My problem is when I access the web-page at http://localhost:8080 nothing is there and the BASH shell where the command is run to start this shows all the calls in the Python program that caused the problem and then finally says: ImportError: Settings cannot be imported, because environment variable DJANGO_SETTINGS_MODULE is undefined.
I have read in a few different places a few different things to try so I thought I would go ahead and make a new post and hope that some expert Python programmers would chime in and lend their assistance to a lost hobbit such as myself.
Also, the book says to install Python2.5 to use this code but Google App Engine now supports Python2.7 that was not available as of the time of the books writing. Also, I just checked and Python2.5 is not even an option to use with Google App Engine. Python2.5 deprecated
This is probably too complex to solve on here. I am surprised all of these different technologies are used in a Head First Python book. It is asking a lot of a Python noob. ^_^
Regards,
user_loser
UPDATE - I installed Django on my Ubuntu Operating System
When I change the line in the python module 368b.py from google.appengine.ext.db import djangoforms to from django import forms I receive the following error on the console when accessing the web-page on localhost:
loser#loser-basic-box:~/Desktop$ google_appengine/dev_appserver.py three
INFO 2014-09-06 21:08:36,669 api_server.py:171] Starting API server at: http://localhost:56044
INFO 2014-09-06 21:08:36,677 dispatcher.py:183] Starting module "default" running at: http://localhost:8080
INFO 2014-09-06 21:08:36,678 admin_server.py:117] Starting admin server at: http://localhost:8000
ERROR 2014-09-06 21:08:48,942 cgi.py:121] Traceback (most recent call last):
File "/home/loser/Desktop/three/page368b.py", line 13, in <module>
class BirthDetailsForm(forms.ModelForm):
File "/home/loser/Desktop/google_appengine/lib/django-1.3/django/forms/models.py", line 205, in __new__
opts.exclude, opts.widgets, formfield_callback)
File "/home/loser/Desktop/google_appengine/lib/django-1.3/django/forms/models.py", line 145, in fields_for_model
opts = model._meta
AttributeError: type object 'BirthDetails' has no attribute '_meta'
INFO 2014-09-06 21:08:48,953 module.py:652] default: "GET / HTTP/1.1" 500 -
ERROR 2014-09-06 21:08:49,031 cgi.py:121] Traceback (most recent call last):
File "/home/loser/Desktop/three/page368b.py", line 13, in <module>
class BirthDetailsForm(forms.ModelForm):
File "/home/loser/Desktop/google_appengine/lib/django-1.3/django/forms/models.py", line 205, in __new__
opts.exclude, opts.widgets, formfield_callback)
File "/home/loser/Desktop/google_appengine/lib/django-1.3/django/forms/models.py", line 145, in fields_for_model
opts = model._meta
AttributeError: type object 'BirthDetails' has no attribute '_meta'
Update Errors from running the program as is without making any changes:
loser#loser-basic-box:~/Desktop$ google_appengine/dev_appserver.py three/
INFO 2014-09-06 21:35:19,347 api_server.py:171] Starting API server at: http://localhost:60503
INFO 2014-09-06 21:35:19,356 dispatcher.py:183] Starting module "default" running at: http://localhost:8080
INFO 2014-09-06 21:35:19,358 admin_server.py:117] Starting admin server at: http://localhost:8000
ERROR 2014-09-06 21:35:25,011 cgi.py:121] Traceback (most recent call last):
File "/home/loser/Desktop/three/page368b.py", line 13, in <module>
class BirthDetailsForm(djangoforms.ModelForm):
File "/home/loser/Desktop/google_appengine/google/appengine/ext/db/djangoforms.py", line 772, in __new__
form_field = prop.get_form_field()
File "/home/loser/Desktop/google_appengine/google/appengine/ext/db/djangoforms.py", line 370, in get_form_field
return super(DateProperty, self).get_form_field(**defaults)
File "/home/loser/Desktop/google_appengine/google/appengine/ext/db/djangoforms.py", line 353, in get_form_field
return super(DateTimeProperty, self).get_form_field(**defaults)
File "/home/loser/Desktop/google_appengine/google/appengine/ext/db/djangoforms.py", line 200, in get_form_field
return form_class(**defaults)
File "/home/loser/Desktop/google_appengine/lib/django-1.3/django/forms/fields.py", line 340, in __init__
super(DateField, self).__init__(*args, **kwargs)
File "/home/loser/Desktop/google_appengine/lib/django-1.3/django/forms/fields.py", line 99, in __init__
widget = widget()
File "/home/loser/Desktop/google_appengine/lib/django-1.3/django/forms/widgets.py", line 382, in __init__
self.format = formats.get_format('DATE_INPUT_FORMATS')[0]
File "/home/loser/Desktop/google_appengine/lib/django-1.3/django/utils/formats.py", line 67, in get_format
if use_l10n or (use_l10n is None and settings.USE_L10N):
File "/home/loser/Desktop/google_appengine/lib/django-1.3/django/utils/functional.py", line 276, in __getattr__
self._setup()
File "/home/loser/Desktop/google_appengine/lib/django-1.3/django/conf/__init__.py", line 40, in _setup
raise ImportError("Settings cannot be imported, because environment variable %s is undefined." % ENVIRONMENT_VARIABLE)
ImportError: Settings cannot be imported, because environment variable DJANGO_SETTINGS_MODULE is undefined.
I assume you're working with the example code that accompanies the book, available from this website: http://examples.oreilly.com/0636920003434/
If you download and expand the chapter 10 archive (chapter10.zip), you'll see several example files, and also several .zip archives. The page368b.py file corresponds with the webapp-chapter10-simpleform.zip archive. Open that archive to create a webapp-chapter10-simpleform directory. This directory contains an app.yaml file, the simpleform.py file (identical to page368b.py), birthDB.py (an ext.db model class), and static and template file directories.
Unfortunately, as you may have already noticed, the example doesn't work out of the box with the latest SDK. (I'm using version 1.9.10 of the SDK, which was just released.) It reports "ImportError: No module named django.core.exceptions" when you attempt to load the page. Strictly speaking, this example is not a Django application, but is merely trying to use a library that depends on Django being present.
The Python 2.5 runtime environment, which is selected by the app.yaml file included with this example, is meant to include Django 0.96 by default. However, this behavior has changed in the SDK since Head First Python was written. The smallest fix to get this example to work is to add these lines to simpleform.py prior to the import of djangoforms:
import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
from google.appengine.dist import use_library
use_library('django', '0.96')
Then create a file named settings.py in your application root directory (the webapp-chapter10-simpleform directory). This file can be empty in this case. (As other commenters have noted, there is a better way to generate this file when using the Django framework, but in this case we just need the import to succeed.)
To upgrade this example to use the Python 2.7 runtime environment, modify app.yaml as follows:
application: simpleform
version: 1
runtime: python27
api_version: 1
threadsafe: true
handlers:
- url: /static
static_dir: static
- url: /*.
script: simpleform.app
The changes:
runtime: is now python27
threadsafe: true is added
The reference to simpleform.py is now a Python object path to the global variable app.
Then modify simpleform.py so that everything following the definition of the SimpleInput class is replaced with:
app = webapp.WSGIApplication([('/.*', SimpleInput)], debug=True)
Instead of running the simpleform.py script, the Python 2.7 runtime environment imports it as a module, then looks for a WSGI application object in a global variable. The lines we removed executed the app, and that's now done for us by the runtime environment.
From here, you can use a libraries: clause as you have done to select a newer version of Django, if you wish. A quick test in a dev server shows that the modified example works with Django 1.5, which is the latest supported version.