When I run this helloworld code I get a "No socket could be created" error.
import web
urls = ("/.*", "hello")
app = web.application(urls, globals())
class hello:
def GET(self):
return 'Hello, world!'
app.run()
The same cod works fine if I enclose the call to app.run() inside of an if statement like this
if __name__ == "__main__":
app.run()
My understanding is that it shouldn't make any difference. Anyone have an explanation?
if you run a py file in command line,the default __name__ attribute will be __main__,and your code is executed from top to bottom.You can refer to this question What does if __name__ == "__main__": do?
Related
I'm new on flask.I configured a server with flask+gunicorn.
the code file called test.py like this:
from flask import Flask
app = Flask(__name__)
#app.route('/')
def test():
return aa+"world!"
if __name__ == '__main__':
aa = "hello"
app.run()
run it using:gunicorn -b 0.0.0.0:8080 test:app
I got a mistake:NameError: name 'aa' is not defined.
I want some codes like variable aa runing before gunicorn.
How to do that?
Put in a small block just before your #app.route and you dont need the last block in the question
#app.before_first_request
def _declareStuff():
global aa
aa='hello'
Just declare aa outside of "__main__", in the global scope of the file.
from flask import Flask
app = Flask(__name__)
#app.route('/')
def test():
return aa+"world!"
aa = "hello"
if __name__ == '__main__':
app.run()
The code in the if __name__ == '__main__': block executes only if the Python code is run as a script, e.g., from the command line. Gunicorn imports the file, so in that case the code in __main__ will not be executed.
Note that if it is your intention to modify the value of aa then different requests can produce different results depending on how many requests each gunicorn worker process has handled. e.g.:
from flask import Flask
app = Flask(__name__)
#app.route('/')
def test():
global counter
counter += 1
return "{} world! {}".format('aa', counter)
counter = 0
if __name__ == '__main__':
app.run()
Run the above script with more than one worker (gunicorn -w 2 ...) and make several requests to the URL. You should see that the counter is not always contiguous.
As of Flask 2.2, the #app.before_first_request decorator suggested by Vipluv in their answer is deprecated and will be removed in 2.3.
Deprecated since version 2.2: Will be removed in Flask 2.3. Run setup code when creating the application instead.
The equivalent can be done by manually pushing the app context, as suggested by Enkum :
# In place of something like this
#app.before_first_request
def create_tables():
db.create_all()
...
# USE THIS INSTEAD
with app.app_context():
db.create_all()
I'm trying to get access to the current app instance from a Flask-Script manager.command.
This errors out (url_map is a property of flask.app)
#manager.command
def my_function():
x = app.url_map # this fails, because app is a callable
print "hi"
This works, but I don't like having to add parens next to app.
#manager.command
def my_function():
x = app().url_map
print "hi"
The debugger shows that app is a callable. That has to do with the way that I'm creating the app instance. I'm following this pattern:
def create_app(settings=None, app_name=None, blueprints=None):
...lots of stuff...
app = flask.Flask(app_name)
...lots of stuff...
return app
def create_manager(app):
manager = Manager(app)
#manager.command
def my_function():
x = app.url_map
print "hi"
def main():
manager = create_manager(create_app)
manager.run()
if __name__ == "__main__":
main()
The docs from flask-script say about the app parameters on Manager(app):
app – Flask instance, or callable returning a Flask instance.
I'm comfortable with putting a callable in there because the docs say it's OK. :-) Plus I've seen others do it like that.
But now I have this peripheral command that I'd like to add and it's forcing me to use the app with parens and that smells wrong. What am I doing wrong?
EDIT: I did some experiments. This is definitely wrong. By adding the parens, the app instance is getting recreated a second time.
Use flask.current_app
This works:
import flask
... other stuff ...
#manager.command
def my_function():
x = flask.current_app.url_map
print "hi"
I 'overthunk' it. :-)
I am trying to break my app into separate scripts. Part of this effort meant breaking the api calls into it's own file. However the calls to the api (like http://example.com/api/game/new no longer work).
My app.yaml contains this:
- url: /api.*
script: api.py
which seems to be redirecting properly because this configuration works:
def main():
application = webapp.WSGIApplication([('/.*', TestPage)], debug=True)
util.run_wsgi_app(application)
however this one doesn't:
def main():
application = webapp.WSGIApplication([('/game/new$', CreateGame),
('/game/(d+)$', GameHandler)],
debug=True)
util.run_wsgi_app(application)
The URL patterns you use in the WSGI application have to be the full path - eg, /api/game/.... The App Engine infrastructure uses the regular expressions in app.yaml to route requests, but it does not modify the request path based on them.
My guess is you are trying to pass some arguments to your handler.
Try this. It will give you a hint.
#!/usr/bin/env python
import wsgiref.handlers
from google.appengine.ext import webapp
class MyHandler(webapp.RequestHandler):
def get(self, string=None):
if string:
self.response.out.write("Hello World!! %s" % string)
else:
self.response.out.write("Hello World!! (and no word)")
def main():
app = webapp.WSGIApplication([
(r'/word/(\w+)/?$', MyHandler),
(r'.*', MyHandler),
], debug=True)
wsgiref.handlers.CGIHandler().run(app)
if __name__ == "__main__":
main()
Hope it helps. Cheers.
I'm trying to get a web.py application running on GAE. I hoped that sth like the following might work
import web
from google.appengine.ext.webapp.util import run_wsgi_app
[...]
def main():
app = web.application(urls, globals())
run_wsgi_app(app)
But obviously the app object doesn't conform with the run_wsgi_app function's expectations. The error msg says sth like app has no __call__ function, so I tried passing app.run instead, but that didn't work either.
How can I make the call to run_wsgi_app work?
Here is a snippet of StackPrinter, a webpy application that runs on top of Google App Engine.
from google.appengine.ext.webapp.util import run_wsgi_app
import web
...
app = web.application(urls, globals())
def main():
application = app.wsgifunc()
run_wsgi_app(application)
if __name__ == '__main__':
main()
You don't need to import or use run_wsgi_app, web.py has a runcgi method that works perfectly!
if __name__ == '__main__':
app.cgirun()
I'm just starting learning google app engine.
When I enter the following code below, all I got is "Hello world!"
I think the desired result is "Hello, webapp World!"
What am I missing? I even try copying the google framework folder to live in the same folder as my app.
Thanks.
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)],
debug=True)
def main():
run_wsgi_app(application)
if __name__ == "__main__":
main()
Running exactly this code DOES give me the desired output. I suspect you must be erroneously running some other code, since there's absolutely no way this code as given could possibly emit what you observe.