Here is my index.py (it is in the folder /NetWeave_Custom)
import web
import lib.html
web.config.debug = True
urls = (
'/', 'index',
)
class index:
def GET(self):
markup = html.abstr()
print markup.element
if __name__ == "__main__":
app.run()
app = web.application(urls, globals(), autoreload=False)
application = app.wsgifunc()
And then here is my html.py (it is in /NetWeave_Custom/lib/)
class abstr:
element = 'Hello World';
However I am getting a 500 internal server error. Can anyone tell me what I am doing wrong? I am new to the web.py framework. Thanks!
EDIT:
With the code above I get the errror:
ImportError: no module named lib.html
FINAL EDIT:
Working code looked like this:
import web
from lib import html
web.config.debug = True
urls = (
'/', 'index',
)
class index:
def GET(self):
markup = html.abstr()
return markup.element
if __name__ == "__main__":
app = web.application(urls, globals(), autoreload=False)
app.run()
application = app.wsgifunc()
And then here is my html.py (it is in /NetWeave_Custom/lib/)
class abstr:
element = 'Hello World';
The browser displayed: 'Hello World'
So the changes were defining app before calling it (not really relevant but for you stricties it is necessary -- it did work fine without this), returning markup.element rather than printing it, and creating a blank __init__.py file in the lib subdirectory so lib would be viewed as a module (or package?) as I understand it.
Thanks!
You import lib.html, but don't use that full name. Instead, you refer only to html.
If you get an import error, the lib package is not being found; there may be one of two things wrong:
You should use import html instead, which would also solve the incorrect reference.
The lib directory is missing it's __init__.py file (can be empty). That file would make it a package and would allow you to import it. Then change the references to html to lib.html:
class index:
def GET(self):
markup = lib.html.abstr()
print markup.element
or change the import to read:
from lib import html
You also try to run app before it is defined. Change the last lines to:
if __name__ == "__main__":
app = web.application(urls, globals(), autoreload=False)
app.run()
Last but not least, you need to add the NetWeave_Custom directory (full, absolute path) to the PYTHONPATH; if you are using mod_wsgi look at the WSGIPythonPath directive.
The answer was two-fold. I did not have an __init__.py file in the lib sub-directory. The other error was that I wrote print and not return markup.element... Doh!
Related
I am a Flask beginner, please excuse me if the answer to my question is obvious.
I have been working on a project using an OVH server. I have been using this tutorial to set up a first "Hello world": https://docs.ovh.com/gb/en/web-power/python-install-flask/
Here is the structure of my project :
www/
venv/
myapp.py
At this point, everything is working fine. When I connect to my website, it shows a good "Hello, world !" as expected.
However I now want to add a template to my page, I have therefore added a few lines :
this_file = "venv/bin/activate_this.py"
exec(open(this_file).read(), {'__file__': this_file})
from flask import Flask, render_template
application = Flask(__name__)
#application.route('/')
#application.route('/index')
def index():
return render_template('index.html')
I have imported render_template and changed from "return 'Hello'" to "return render_template('index.html')".
Unfortunately, my website now displays "Incomplete response received from application". I have tried these 2 structures :
www/
venv/
myapp.py
templates/
index.html
and :
www/
templates/
index.html
venv/
myapp.py
But it doesn't change anything... Does any know how to return a template?
instead of starting the venv up from within the program with
this_file = "venv/bin/activate_this.py"
exec(open(this_file).read(), {'__file__': this_file})
(works only on mac/Linux) you might want to do that in the terminal instead,
as
venv/bin/activate
source: https://uoa-eresearch.github.io/eresearch-cookbook/recipe/2014/11/26/python-virtual-env/
then, to run your file, you can add this:
from flask import Flask, render_template
application = Flask(__name__)
#application.route('/')
#application.route('/index')
def index():
return render_template('index.html')
if __name__ == '__main__':
application.run(debug=True)
the last lines are good habit for projects like these, debugger on is extremely useful. Your structure is fine. I understand why you might want to add the first few lines, I am working on a venv flask app too. However, I tried implementing the windows version of those lines, which did not work... even if that works fine for you, please consider adding
if __name__ == '__main__':
application.run(debug=True)
either way.
The Following is my code hierarchy.
I am trying to create a package for my project, "UIGenerator" but it is giving me following error.
traceback (most recent call last):
File "run.py", line 1, in <module>
from UIGenerator import app
File "/Users/______/Desktop/UIGenerator/UIGenerator/__init__.py", line 2, in <module>
from site.routes import site
ModuleNotFoundError: No module named 'site.routes'; 'site' is not a package
Here is the code for run.py =>
from UIGenerator import app
#app.route('/')
def test_connection():
return "<h1>Connected<h1>"
if __name__ == '__main__':
app.run(debug=True)
There is nothing in site =>__init__.py file and in site=>routes.py, I have some sample code to test-
from flask import Blueprint
site = Blueprint('site', __name__)
#site.route('/site')
def site():
return "this is test for site package"
The following is my code for the UIGenerator's init.py file =>
from flask import Flask
from site.routes import site
def getApp():
app = Flask(__name__)
app.register_blueprint(site)
return app
app = getApp()
Can anyone give me any clue, please.
One way to fix this is to build a Python package with you files, like outlined here. This will be better in the long run if you want to scale this project up, and will allow you to declare things in init
That being said, I think you can get your setup working by moving this chunk of code
def getApp():
app = Flask(__name__)
app.register_blueprint(site)
return app
app = getApp()
to the run.py file for the time being.
So, here is what I found out from a different post. In my site=>routes, I declared a global blueprint with the name, site and later I created a site() function which somehow masked my site blueprint. If I just renamed the site method name, it works.
I'm relatively new to python and am trying to build a flask server. What I would like to do is have a package called "endpoints" that has a list of modules where each module defines a subset of application routes. When I make a file called server.py with the following code this works like so
import os
from flask import Flask
app = Flask(__name__)
from endpoint import *
if __name__ == '__main__':
app.run(debug=True, use_reloader=True)
Right now there's only one endpoint module called hello.py and it looks like this
from __main__ import app
# a simple page that says hello
# #app.route defines the url off of the BASE url e.g. www.appname.com/api +
# #app.route
# in dev this will be literally http://localhost:5000/hello
#app.route('/hello')
def hello():
return 'Hello, World!'
So... the above works when I run python server.py, the issue happens when I try to run the app using flask.
Instead of server.py it just calls __init__.py which looks like this
import os
from flask import Flask
# create and configure the app
# instance_relative_config states that the
# config files are relative to the instance folder
app = Flask(__name__, instance_relative_config=True)
# ensure the instance folder exists
try:
os.makedirs(app.instance_path)
except OSError:
pass
from endpoint import *
When I run flask run in terminal I get ModuleNotFoundError: No module named 'endpoint'
but again if I change the code so it looks like the following below, then flask run works.
import os
from flask import Flask
# create and configure the app
# instance_relative_config states that the
# config files are relative to the instance folder
app = Flask(__name__, instance_relative_config=True)
# ensure the instance folder exists
try:
os.makedirs(app.instance_path)
except OSError:
pass
# a simple page that says hello
# #app.route defines the url off of the BASE url e.g. www.appname.com/api +
# #app.route
# in dev this will be literally http://localhost:5000/hello
#app.route('/hello')
def hello():
return 'Hello, World!'
I'm pretty sure this is happening because I don't fully understand how imports work...
So, how do I set up __init__.py so that it imports all the modules from the "endpoint" package and works when I call flask run?
When you use a __init__.py file, which you should, Python treats the directory as a package.
This means, you have to import from the package, and not directly from the module.
Also, usually you do not put much or any code in a __init__.py file.
Your directory structure could look like this, where stack is the name of the package I use.
stack/
├── endpoint.py
├── __init__.py
└── main.py
You __init__.py file is empty.
main.py
import os
from flask import Flask
# create and configure the app
# instance_relative_config states that the
# config files are relative to the instance folder
app = Flask(__name__, instance_relative_config=True)
# ensure the instance folder exists
try:
os.makedirs(app.instance_path)
except OSError:
pass
from stack.endpoint import *
endpoint
from stack.main import app
# a simple page that says hello
# #app.route defines the url off of the BASE url e.g. www.appname.com/api +
# #app.route
# in dev this will be literally http://localhost:5000/hello
#app.route('/hello')
def hello():
return 'Hello, World!'
You can then run your app...
export FLASK_APP=main.py
# followed by a...
flask run
This all said, when I create a new Flask app, I usually only use one file, this makes initial development easier, and only split into modules when the app really grows bigger.
Also, for separating views or let's call it sub packages, Flask offers so called Blue prints. This is nothing you have to worry about right now, but comes especially handy when trying to split the app into sub applications.
Im trying to import files on Flask app in base of url route. I started to coding python few days ago so i havent idea if i doing it well. I write this on :
#app.route('/<file>')
def call(file):
__import__('controller.'+file)
hello = Example('Hello world')
return hello.msg
And i have other file called example.py into a controller folder that contains this:
class Example:
def __init__(self, msg):
self.msg = msg
So i start from terminal the app and i try to enter to localhost:5000/example.
Im trying to show in screen Hello world but give me the next error:
NameError: global name 'Example' is not defined
Thanks for all!
__import__ returns the newly imported module; names from that module are not added to your globals, so you need to get the Example class as an attribute from the returned module:
module = __import__('controller.'+file)
hello = module.Example('Hello world')
__import__ is rather low-level, you probably want to use importlib.import_module() instead:
import importlib
module = importlib.import_module('controller.'+file)
hello = module.Example('Hello world')
If you need to dynamically get the classname too, use getattr():
class_name = 'Example'
hello_class = getattr(module, class_name)
hello = hello_class('Hello world')
The Werkzeug package (used by Flask) offers a helpful functions here: werkzeug.utils.import_string() imports an object dynamically:
from werkzeug.utils import import_string
object_name = 'controller.{}:Example'.format(file)
hello_class = import_string(object_name)
This encapsulates the above process.
You'll need to be extremely careful with accepting names from web requests and using those as module names. Please do sanitise the file argument and only allow alphanumerics to prevent relative imports from being used.
You could use the werkzeug.utils.find_modules() function to limit the possible values for file here:
from werkzeug.utils import find_modules, import_string
module_name = 'controller.{}'.format(file)
if module_name not in set(find_modules('controller')):
abort(404) # no such module in the controller package
hello_class = import_string(module_name + ':Example')
I think you might not add the directory to the file, add the following code into the previous python program
# Add another directory
import sys
sys.path.insert(0, '/your_directory')
from Example import Example
There are two ways for you to do imports in Python:
import example
e = example.Example('hello world')
or
from example import Example
e = Example('hello world')
I installed Flask-FlatPages and am trying to run this simple app (to display .md files):
import sys
from flask import Flask, render_template
from flask_flatpages import FlatPages, pygments_style_defs
DEBUG = True
FLATPAGES_AUTO_RELOAD = DEBUG
FLATPAGES_EXTENSION = '.md'
FLATPAGES_ROOT = 'content'
POST_DIR = 'posts'
app = Flask(__name__)
flatpages = FlatPages(app)
app.config.from_object(__name__)
#app.route("/posts/")
def posts():
posts = [p for p in flatpages if p.path.startswith(POST_DIR)]
posts.sort(key=lambda item:item['date'], reverse=False)
return render_template('posts.html', posts=posts)
#app.route('/posts/<name>/')
def post(name):
path = '{}/{}'.format(POST_DIR, name)
post = flatpages.get_or_404(path)
return render_template('post.html', post=post)
if __name__ == "__main__":
app.run(host='0.0.0.0', debug=True)
Whenever I run the app, I get this error:
NameError: name 'unicode' is not defined
The trackback (flask-flatpages) is this:
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/flask_flatpages/__init__.py", line 290, in _pages
_walk(unicode(self.root))
I know unicode is now str in Python 3 -- can I fix the issue from my app (without modifying the package)?
Well if the package does not support Python 3, then you cannot easily make it work. You can wait for support or find alternative package. If the only problem is missing definition for unicode, then it can be monkeypathed like
import builtins
builtins.unicode = str
before importing flask_flatpages. But I doubt missing unicode is the only problem.