In Google App Engine, I have the following code which shows a simple HTML page.
import os
from google.appengine.ext.webapp import template
from google.appengine.ext import webapp
class IndexHandler(webapp.RequestHandler):
def get(self):
template_values = { }
path = os.path.join(os.path.dirname(__file__), '../templates/index.html')
self.response.out.write(template.render(path, template_values))
The issue is that the page isn't always rendered. The index.html is a simple "Hello World!". After a couple of page refresh the page is displayed properly (i.e. the index.html file is found...). I tried to call flush at the end, but it didn't help. I am able to repro this with the SDK and on their server.
Am I missing something? Does someone have an idea of what is going on?
Thanks
Your handler script (the one referenced by app.yaml) has a main() function, but needs this stanza at the end:
if __name__ == '__main__':
main()
What's happening is that the first time your script is run in a given interpreter, it interprets your main script, which does nothing (thus returning a blank response). On subsequent invocations, the interpreter simply executes your main() (a documented optimization), which generates the page as expected. Adding the stanza above will cause it to execute main on initial import, too.
Can't reproduce -- with directory changed to ./templates (don't have a ../templates in my setup), and the usual main function added, and this script assigned in app.yaml to some arbitrary URL, it serves successfully "Hello World" every time. Guess we need more info to help -- log entries (maybe add logging.info calls here?), app.yaml, where's main, etc, etc...
Related
Background/Goal
I'm trying to create a study prep website and as part of it I would like to initialize a database labelled "Topic" with some default values. The contents of this table are just meant to be initialized once when the database is first created. I'm using Flask and SQLAlchemy for this project.
The Problem
I've tried to achieve this by defining a function like so (Note: The "..." mark pieces of code present which I believe aren't very relevant to this problem. If you feel like I'm likely leaving out something important, please inform me)
db = SQLAlchemy()
DB_NAME = "database.db"
def create_app():
app = Flask(__name__)
app.config["SECRET_KEY"] = "hwiu2222"
app.config["SQLALCHEMY_DATABASE_URI"] = f"sqlite:///{DB_NAME}"
db.init_app(app)
...
from .models import User, Topic
create_database(app)
...
#listens_for(Topic.__table__, "after_create")
def insert_topics(*args, **kwargs):
topics = (genfromtxt("src/static/topics.csv", delimiter=',', skip_header=1, dtype=None)).tolist()
for topic in topics:
new_topic = Topic(title=topic[0], subject=topic[1], level=topic[2])
db.session.add(new_topic)
db.session.commit()
return app
def create_database(app):
if not path.exists("CIE Website/" + DB_NAME):
db.create_all(app=app)
To clarify, this "create_app" function is located in an init file in my directory and is called within a separate main python script.
from src import create_app
app = create_app()
if __name__ == "__main__":
app.run(debug=True)
This code runs just fine and I'm able to open my website without any errors, but the problem is that the default values I wanted to be initialized don't actually get initialized. My "Topic" table just remains empty.
What I've Tried
So what I assume is going wrong is that the "insert_topics" function is not getting called for whatever reason. To try and fix this I've attempted to simply relocate said function, such as to before the "create_database" call or within my main script after calling the "create_app" function, but all of that just results in the same error (There's even more to this error message, but it's quite long and I'm not sure how important the other information is, so I'm only including this ending statement for now).
RuntimeError: No application found. Either work inside a view function or push an application context. See http://flask-sqlalchemy.pocoo.org/contexts/.
Now, all of this stuff is still very much new to me so what I assume to be going wrong may be completely off the mark. It's also possible that I'm overlooking some glaring mistake that's causing all of this. For example, there could be something wrong with the "insert_topics" function itself. Regardless, I hope that one of you will be able to help me figure this out.
P.S.
I apologize in advance for any mistakes I may have made in writing this quesiton. It's my first time doing anything like this.
it seems that this problem only arises when i am using flask application factory method
here is the link to repl, and
here is the link to post i made asking fro help (Kindly read the comment section)
I have commented the app.run() part so that it won't start server
#!main.py l:3
#if __name__ == '__main__':
# app.run(host='0.0.0.0')
After running the repl once on the console side i typed
from app.main.models import *
with app.app_context():
db.create_all()
now in theory these line of code should create database with table defined init such that if i do Food.query.all it should return (in theory) an empty list => [] but it returns an error RuntimeError: No application found.
note : Kindly fork the repl you don't need an account for that just click on the fork button beside run because it might show wired when many people run it together
It seems that you've not commit the session & it's not the best practice to import function by *. You should specify specicfic module or Maybe you haven't insert any values in db so you are getting an empty list. I'm not sure about this.But your solution might be in between.
I'm going through Miguel Grinbergs Flask book and at one point he uses the following line:
request.endpoint[:5] != 'auth.'
I know [:5] is a slice operation, but I'm not sure why it is being used here. What does the list consist of that we only want elements 0-5?
What does the list consist of that we only want elements 0-5?
To be precise, request.endpoint is not a list, it's a string. And it doesn't matter what the rest of it contains, the code is only concerned with it beginning with 'auth.':
('auth.somethingsomething'[:5] == 'auth.') is True
request.endpoint is the name the current view function was registered as, for example auth.login is the name of the def login(): view. Views that have a prefix like prefix. were registered on a blueprint, which groups related views. So the code is checking if the current view being handled is part of the auth blueprint.
If you're curious about what value it contains, you can add a debugging breakpoint to the code and inspect it:
# ... previous app code ...
import pdb; pdb.set_trace()
request.endpoint[:5] != 'auth.'
Then run and test the code. When it hits that point, it'll pause execution and give you a pdb shell, which will let you look at the request object and its endpoint attribute.
you can checking on terminal by
venv $ python manage.py shell
import flask from request
print(request.endpoint)
I'm using cherrypy with Mako as a template engine.
I want Mako to lookup different directories based on what app is being requested.
I.e.
I have three 'apps': Site, Admin and Install.
They all have their own template folder, structure looking something like:
/template
/template/site
/template/admin
/template/install
/template/system
/system contains some system wide templates, like 404 pages, etc.
I'm using Twiseless as a reference whilst trying to get to grips with cherrypy / mako, but I'm stuck with how to do this.
Read on for a brief overview of how I've tried to do this, but a warning: I think I'm going about this completely the wrong way! :) So, if you have any ideas/pointers, it might be a good idea to save yourself the trouble of reading any further than this.
In my main file, server.py, I do something like:
from libs.plugins.template import MakoTemplatePlugin
engine = cherrypy.engine
makoTemplate = MakoTemplatePlugin(engine, self.base_dir)
setTemplateDirs(makoTemplate, self.template_path)
MakoTemplatePlugin is a slightly modified version of the plugin by the same name found in Twiseless, linked above.
What this code does is set the TemplateLookup to use the default template directories from my global config file. i.e.
/template
/template/system
Then, each time an app is loaded, I call a function (setTemplateDirs) to update the directories where Mako searches.
I thought this would work, but it doesn't. Initially I made the error of creating a new instance of MakoTemplatePlugin for each app. This just resulted in them all being called on each page load, starting with the first one instantiated, containing just the basic, non-app specific directories.
As this was called first, it was triggering a 404 error, as it was searching in the wrong folders.
I instead made sure to pass a reference to the MakeTemplatePlugin to all of my apps. I thought if I ran setTemplateDirs each time each app is called, this would solve the problem... but it doesn't.
I don't know where to put the function so it will run every time a page is requested...
e.g.
# /apps/site/app.py
import somemodule.setTemplateDirs
class Site(object, params):
def __init__(self):
self.params = params
self.makoTemplate = params['makoTemplate']
self.base_path = params['base_path']
setTemplateDirs(self.makoTemplate, self.base_path, '', '/')
#cherrypy.expose
#cherrypy.tools.render(template='index.html')
def index(self):
pass
This obviously just works when the application is first loaded... I tried moving the update function call into a seperate method update and tried calling that for each page, e.g:
#cherrypy.exposed
#cherrypy.tools.render(template='index.html')
#update
def index(self):
pass
But this just gives me config related errors.
Rather than to continue to mess about with this, there must be an easier way.
How would you do it?
Thanks a lot,
Tom
I got this working. Thanks to stephan for providing the link to the mako tool example: http://tools.cherrypy.org/wiki/Mako.
I just modified that slightly to get it working.
If anyone's wondering, the basis of it is that you define tools.mako.directories in your global config, you can then override that in individual app config files.
e.g.
server.conf
...
tools.mako.directories: ['', 'system']
...
site.conf
...
tools.mako.directories: ['site', 'system']
...
I did some extra work to translate the relative URIs to absolute paths, but the crux of it is explained above.
I have a fair bit of experience with PHP frameworks and Python for scripting so am now taking the step to Pyramid.
I'd like to know what is the 'correct' way to run a script in Pyramid. That is, how should I set it up so that it is part of the application and has access to config and thus database but does not run through paster (or whatever WSGI).
As an example, say I have a web application which while a user is offline grabs Facebook updates through a web service. I want to write a script to poll that service and store in the database ready for next login.
How should I do this in terms of:
Adding variables in the ini file
Starting the script correctly
I understand the basics of Python modules and packages; however I don't fully understand Configurator/Paster/package setup, wherein I suspect the answer lies.
Thanks
Update:
Thanks, this seems along the lines of what I am looking for. I note that you have to follow a certain structure (eg have summary and parser attributes set) and that the function called command() will always be run. My test code now looks something like this:
class AwesomeCommand(Command):
max_args = 2
min_args = 2
usage = "NAME"
# These are required
summary = "Say hello!"
group_name = "My Package Name"
# Required:
parser = Command.standard_parser(verbose=True)
def command(self):
# Load the config file/section
config_file, section_name = self.args
# What next?
I'm now stuck as to how to get the settings themselves. For example, in init.py you can do this:
engine = engine_from_config(settings, 'sqlalchemy.')
What do I need to do to transform the config file into the settings?
EDIT: The (simpler) way to do this in Pylons is here:
Run Pylons controller as separate app?
As of Pyramid 1.1, this is handled by the framework:
http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/commandline.html#writing-a-script
paster starts an application given an ini file that describes that application. the "serve" command is a built in command for starting a wsgi application and serving it. BUT, you can write other commands.
from paste.script.command import Command
class AwesomeCommand(Command):
def command(self):
print "the awesome thing it does"
and then register them as entry points in your setup.py.
setup(...
entry_points="""
[paste.app_factory]
.....
[paste.global_paster_command]
myawesome-command = mypackage.path.to.command:AwesomeCommand """)
pyramid adds it's own commands this way like the pshell command.
After going to the pylons discuss list, I came up with an answer. Hope this helps somebody:
#Bring in pyramid application--------------------------------------
import pyramid
from paste.deploy import appconfig
config_file = '/path_to_config_file/configname.ini'
name = 'app_name'
config_name = 'config:%s' % config_file
here_dir = os.getcwd()
conf = appconfig(config_name, name, relative_to=here_dir)
from main_package import main
app = main(conf.global_conf, **conf.local_conf)
#--------------------------------------------------------------------------
you need to make view for that action and then run it using:
paster request development.ini /url_to_your_view