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.
Related
I have the following main.py:
...
app = FastAPI(docs_url="/jopapi/documentation", redoc_url=None)
password_encryptor = PasswordEncryptor(
os.environ.get("JUPYTERHUB_COOKIE_SECRET"), fernet=Fernet
)
...
I already tried to use a custom fixture like this:
#mock.patch.dict(os.environ, {"JUPYTERHUB_COOKIE_SECRET": "471bAcmHjbIdu3KLWphYpgXSW1HNC8q7"}, clear=True)
#pytest.fixture(name="client")
def client_fixture():
client = TestClient(app)
yield client
But the following test:
def test_generic(client: TestClient):
response = client.get("/jobapi/generic")
assert response.status_code == 200
still fails, since the environment variable seems not to get set, which results in None
from src.app.main import app
src\app\main.py:38: in <module>
password_encryptor = PasswordEncryptor(
src\app\auth.py:33: in __init__
self.fernet = fernet(self._generate_fernet_key(self.secret))
src\app\auth.py:36: in _generate_fernet_key
bytestring = secret.encode()
E AttributeError: 'NoneType' object has no attribute 'encode'
When I set the env variable in the main.py file per hand, it works. How can I fix this?
I think you need to create a .env at the root of your project and then read that file using python's dotenv, so finally you can easily use it with os.environ.get() later in your main.py file,
.env
JUPYTERHUB_COOKIE_SECRET=471bAcmHjbIdu3KLWphYpgXSW1HNC8q7
main.py
import os
basedir = path.abspath(path.dirname(__file__))
load_dotenv(path.join(basedir, ".env"))
app = FastAPI(docs_url="/jopapi/documentation", redoc_url=None)
password_encryptor = PasswordEncryptor(
os.environ.get("JUPYTERHUB_COOKIE_SECRET"), fernet=Fernet
)
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 have written my 1st Python API project with Flask and now am trying to deploy it to Netlify.
Searched online and found I need to use Flask-Frozen to generate a static website.
Not sure I'm doing it correctly, because my project is a API project not a website project, so may be I should not use Flask-Frozen(FF)?
But if I could still use FF to generate static website for my API project, here is my project:
--
app.py
mazesolver
mazeapi.py
Here is the app.py
from flask_frozen import Freezer
from mazesolver import mazeapi
# Call the application factory function to construct a Flask application
# instance using the development configuration
# app = mazeapi()
# Create an instance of Freezer for generating the static files from
# the Flask application routes ('/', '/breakfast', etc.)
freezer = Freezer(mazeapi)
if __name__ == '__mazeapi__':
# Run the development server that generates the static files
# using Frozen-Flask
freezer.run(debug=True)
mazeapi.py
import io
from mazesolver.solver import MazeSolver
from markupsafe import escape
from flask import Flask, flash, request, redirect, send_file
from werkzeug.utils import secure_filename
ALLOWED_EXTENSIONS = { 'png', 'jpg', 'jpeg' }
app = Flask(__name__)
app.config['MAX_CONTENT_LENGTH'] = 5 * 1024 * 1024
#app.route('/maze/<mazename>')
def maze(mazename):
return 'maze 4 %s' % escape(mazename)
Whenever I run:
python app.py
I got this error:
Traceback (most recent call last):
File "app.py", line 10, in <module>
freezer = Freezer(mazeapi)
File "/home/winstonfan/anaconda3/envs/maze/lib/python3.7/site-packages/flask_frozen/__init__.py", line 98, in __init__
self.init_app(app)
File "/home/winstonfan/anaconda3/envs/maze/lib/python3.7/site-packages/flask_frozen/__init__.py", line 108, in init_app
self.url_for_logger = UrlForLogger(app)
File "/home/winstonfan/anaconda3/envs/maze/lib/python3.7/site-packages/flask_frozen/__init__.py", line 588, in __init__
self.app.url_default_functions.setdefault(None, []).insert(0, logger)
AttributeError: module 'mazesolver.mazeapi' has no attribute 'url_default_functions'
I had the same issue and added
url_default_functions={}
to the app, right before
if __name__ == "__main__":
app.run()
I guess you could put it right after
app = Flask(__name__)
and the error went way... but there are many more :) It seems that frozen-flask isn't working with the lastest flask, but I couldn't get any other versions working with it.
Did you manage to get it working?
You have a simple namespace bug.
In the code you've posted, you are freezing your module mazeapi, not the actual Flask application, mazeapi.app.
Try changing your Freezer call in line 10 of app.py to:
freezer = Freezer(mazeapi.app)
Here's the code I have. Basically I have the Shebang line in there because the psycopg2 wasn't working without it.
But now when I have this line in there it doesn't allow me to run the database, it just says "no module named 'flask'"
#!/usr/bin/python3.4
#
# Small script to show PostgreSQL and Pyscopg together
#
from flask import Flask, render_template
from flask import request
from flask import *
from datetime import datetime
from functools import wraps
import time
import csv
import psycopg2
app = Flask(__name__)
app.secret_key ='lukey'
def getConn():
connStr=("dbname='test' user='lukey' password='lukey'")
conn=psycopg2.connect(connStr)
return conn
#app.route('/')
def home():
return render_template(index.html)
#app.route('/displayStudent', methods =['GET'])
def displayStudent():
residence = request.args['residence']
try:
conn = None
conn = getConn()
cur = conn.cursor()
cur.execute('SET search_path to public')
cur.execute('SELECT stu_id,student.name,course.name,home_town FROM student,\
course WHERE course = course_id AND student.residence = %s',[residence])
rows = cur.fetchall()
if rows:
return render_template('stu.html', rows = rows, residence = residence)
else:
return render_template('index.html', msg1='no data found')
except Exception as e:
return render_template('index.html', msg1='No data found', error1 = e)
finally:
if conn:
conn.close()
##app.route('/addStudent, methods =['GET','POST']')
#def addStudent():
if __name__ == '__main__':
app.run(debug = True)
This is an environment problem, not a flask, postgres or shebang problem. A specific version of Python is being called, and it is not being given the correct path to its libraries.
Depending on what platform you are on, changing you shebang to #! /usr/bin/env python3 can fix the problem, but if not (very likely not, though using env is considered better/portable practice these days), then you may need to add your Python3 libs location manually in your code.
sys.path.append("/path/to/your/python/libs")
If you know where your Python libs are (or maybe flask is installed somewhere peculiar?) then you can add that to the path and imports following the line where you added to the path will include it in their search for modules.
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!