Unable to import template - python

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.

Related

Complaining not a "package" though there is a __init__.py file in the folder

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.

flask run giving me ModuleNotFoundError

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.

Flask circular import issue - import variables from __init__.py into views

This is my project structure:
myproject
myproject
__init__.py
static
templates
views
__init.py__
home.py
venv
myproject.wsgi
requirements.txt
setup.py
This is my __init__.py:
from flask import Flask, request, Response, render_template
from myproject.views import home
app = Flask(__name__, static_folder="static", static_url_path='/static')
test_string = "Hello World!"
app.register_blueprint(home.home)
And this is my views/home.py:
from flask import Flask, request, Response, Blueprint
import json
import requests
from myproject import test_string
home = Blueprint('home', __name__)
#home.route('/', methods=['GET'])
def test():
return(test_string)
When I visit the page, I get an error ImportError: cannot import name test_string. The Python import system is really confusing and I am not sure what I am doing wrong here, but I suspect this is a circular import issue.
How do I solve this?
Try to move, in __init__.py, the line from myproject.views import home after the line test_string = "Hello World!".
This way Python will be find the test_string name.
To understand circular imports you have to "think like the interpreter", when you execute __init__.py the interpreter will:
execute line 1 of __init__.py
execute all the code that this line implies (importing stuff from flask)
execute line 2 of __init__.py
execute line 1 of views/home.py (importing only Blueprint from flask, for it's the onnly non-already-imported thing)
execute lines 2+3 of views/home.py (import json and requests)
execute line 4 of views/home.py
go back to what he executed in __init__.py and search for the name test_string
here it raises an error, because what he executed do not comprehend test_string. If you move the import after the execution of test_string = "Hello World!" the interpreter will find this name in the namespace.
This is commonly recognized as bad design though, IMHO the best place to store test_string would be a config.py file, in which no imports from other project modules are performed, avoiding circulat imports.

Flask render_template TemplateNotFound [duplicate]

This question already has answers here:
Flask raises TemplateNotFound error even though template file exists
(13 answers)
Closed 7 years ago.
I'm tinkering around with Flask to play around with Postgres, and the db stuff is going swimmingly, but vexingly, I cannot get render_template to work. Here are the relevant bits:
app.py
from flask import Flask, render_template
app = Flask(__name__)
#app.route("/test2/")
def test2():
return render_template('test2.html')
if __name__ == "__main__":
app.debug = True
app.run()
The file test2.html is located in the ./templates directory. When I run the app and hit that url I get jinja2.exceptions.TemplateNotFound
So I've looked at this:
Python - Flask: render_template() not found
And it's not particularly enlightening. My templates folder is next to the application in the directory tree. I'm sure it's something dead simple, but I'm not seeing it.
Well, I'm a dope. Went to git commit my changes on the command line and saw that the templates directory was in the parent directory. It did not look that way in Finder.

web.py class importing error

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!

Categories

Resources