How to enable/configure Jinja line statements in Flask 1.0.4? - python

The Jinja documentation states the following regarding line statements:
If line statements are enabled by the application, it’s possible to mark a line as a statement.
In this video, line statements are enabled/configured like this:
from flask import Flask
app = Flask(__name__)
app.jinja_env.line_statement_prefix = '%'
However, in Flask 1.0.4 my application object does not have this attribute.
How can I enable and configure line statements?

So according to the source, app.jinja_env is a locked_cached_property which is created the first time it is accessed. So we can't set options directly on app.jinja_env.
What we can do is set app.jinja_options when we are creating our app so that when jinja goes to load the environment it looks at the default app.jinja_options in Flask already which are
jinja_options = {"extensions": ["jinja2.ext.autoescape", "jinja2.ext.with_"]}
So with that, I believe the following should do what we need
from flask import Flask
Flask.jinja_options = {'extensions': ['jinja2.ext.autoescape', 'jinja2.ext.with_'], 'line_statement_prefix': '%'}
app = Flask(__name__)
Flask breaks up the options object, passes that to the Environment which is a subclass of Jinja Environment which then assigns the line_statement_prefix.

Related

Having trouble with Flask in python, either says render_template doesn't exist, or that my template doesn't exist

I am doing an assignment to integrate a python script with HTML templates, and while the IDE is giving me no errors, when I try to actually run the website it gives me an "internal server error" and in the debug menu it says either that it doesn't recognize the Flask command "render_template" or doesn't recognize the HTML file it's supposed to render. The HTML file is stored both in the same folder as the python file and a copy is stored in a seperate "templates" folder located in the same folder as the python file. I really have no idea what's going on, the teacher has been no help.
I tried renaming the files, spell checked the imports repeated, checked all the commands, made copies of the python and Html files to see if the directorry was the problem. I really am not sure what else to try
...from flask import Flask
...from flask import render_template
...from flask import request
...from flask import flash
...import datetime
...app = Flask(__name__)
```#app.route('/')
...#the home page
...def home():
... return render_template('home_page.html')
```#app.route('/clock/')
...#the clock site
...def time_site():
... return date_and_time()
...def date_and_time():
... cur_time = str(datetime.now())
...return render_template('clock.html', cur_time)
```if __name__ == "__main__":
...app.run()

Is there anyway to specify templates and static folders(other than default) for Connexion app?

I'm initializing app using connexion 2.4.0 library like this:
connex_app = connexion.App(__name__, specification_dir='./')
app = connex_app.app
I need to specify the path to my static and templates directories somehow since they are not located in the root directory.
In Flask I would use something like this
app = Flask(__name__, static_folder='../frontEnd/static', template_folder='../frontEnd/templates')
I know that connexion looks for static and templates in the root by default, but is there any way to indicate another path?
Has an opening issue about this problem:
https://github.com/zalando/connexion/issues/441
And a opening pull request:
https://github.com/zalando/connexion/pull/710
But the problem is not solved.
You can you this approach How to set static_url_path in Flask application just remember to use app.app to access the flask instance.
This is now possible following the merge of https://github.com/spec-first/connexion/pull/1173
You can now specify these arguments in the server_args constructor argument e.g.
connexion.FlaskApp(
server_args={'static_url_path': '/your/path/'}
)
Gids is technically correct, you can now pass flask keyword arguments to the created app.
The correct combination for your two code snippets would be:
connex_app = connexion.App(__name__, specification_dir='./', server_args={'static_folder'='../frontEnd/static', 'template_folder'='../frontEnd/templates'})
app = connex_app.app

Configure Python Flask RESTplus app via TOML file

Based on the Configuration Handling Documents for Flask the section of Configuring from Files mentions a possibility to configure the App using files however it provides no example or mention of files that are not Python Files.
Is it possible to configure apps via files like config.yml or config.toml?
My Current flask app has configurations for two distinct databases and since I am using flask-restplus there are additional configurations for Swagger documentations.
Snippet:
from flask import Flask
app = Flask(__name__)
def configure_app(flask_app):
# MongoDB Setting
flask_app.config['MONGO_URI'] = 'mongodb://user:password#mongo_db_endpoint:37018/myDB?authSource=admin'
flask_app.config['MONGO_DBNAME'] = 'myDB'
# InfluxDB Setting
flask_app.config['INFLUXDB_HOST'] = 'my_influxdb_endpoint'
flask_app.config['INFLUXDB_PORT'] = 8086
flask_app.config['INFLUXDB_USER'] = 'influx_user'
flask_app.config['INFLUXDB_PASSWORD'] = 'influx_password'
flask_app.config['INFLUXDB_SSL'] = True
flask_app.config['INFLUXDB_VERIFY_SSL'] = False
flask_app.config['INFLUXDB_DATABASE'] = 'IoTData'
# Flask-Restplus Swagger Configuration
flask_app.config['RESTPLUS_SWAGGER_UI_DOC_EXPANSION'] = 'list'
flask_app.config['RESTPLUS_VALIDATE'] = True
flask_app.config['RESTPLUS_MASK_SWAGGER'] = False
flask_app.config['ERROR_404_HELP'] = False
def main():
configure_app(app)
if __name__ == "__main__":
main()
I would like to avoid setting large number of Environment Variables and wish to configure them using a config.toml file?
How is this achieved in flask?
You can use the .cfg files and from_envvar to achieve this. Create config file with all your environment variables.
my_config.cfg
MONGO_URI=mongodb://user:password#mongo_db_endpoint:37018
..
..
ERROR_404_HELP=False
Then set the env var APP_ENVS=my_config.cfg. Now all you need to do is use from_envvars given by Flask.
def configure_app(flask_app):
flask_app.config.from_envvar('APP_ENVS')
# configure any other things
# register blue prints if you have any
Quoting from documentation:
Configuring from Data Files
It is also possible to load configuration from a file in a format of
your choice using from_file(). For example to load from a TOML file:
import toml
app.config.from_file("config.toml", load=toml.load)
Or from a JSON file:
import json
app.config.from_file("config.json", load=json.load)
EDIT: The above feature is new for v2.0.
Link to the documentation reference:
Class Flask.config, method from_file(filename, load, silent=False)

Retrieving config from a blueprint in Sanic app

I have a Sanic application, and want to retrieve app.config from a blueprint as it holds MONGO_URL, and I will pass it to a repository class from the blueprint.
However, I could not find how to get app.config in a blueprint. I have also checked Flask solutions, but they are not applicable to Sanic.
My app.py:
from sanic import Sanic
from routes.authentication import auth_route
from routes.user import user_route
app = Sanic(__name__)
app.blueprint(auth_route, url_prefix="/auth")
app.blueprint(user_route, url_prefix="/user")
app.config.from_envvar('TWEETBOX_CONFIG')
app.run(host='127.0.0.1', port=8000, debug=True)
My auth blueprint:
import jwt
from sanic import Blueprint
from sanic.response import json, redirect
from domain.user import User
from repository.user_repository import UserRepository
...
auth_route = Blueprint('authentication')
mongo_url = ?????
user_repository = UserRepository(mongo_url)
...
#auth_route.route('/signin')
async def redirect_user(request):
...
The Sanic way...
Inside a view method, you can access the app instance from the request object. And, therefore access your configuration.
#auth_route.route('/signin')
async def redirect_user(request):
configuration = request.app.config
2021-10-10 Update
There are two newer ways to get to the configuration values (or, perhaps more accuratlely getting the application instance from which you can get the configuration). The first version might be more on point to answering the question of how to get to the config from the blueprint. However, the second option is probably the preferred method since it is precisely intended for this kind of use.
Alternative #1
Blueprints have access to the Sanic applications they are attached to beginning with v21.3.
Therefore, if you have a blueprint object, you can trace that back to the application instance, and therefore also the config value.
app = Sanic("MyApp")
bp = Blueprint("MyBlueprint")
app.blueprint(bp)
assert bp.apps[0] is app
The Blueprint.apps property is a set because it is possible to attach a single blueprint to multiple applications.
Alternative #2
Sanic has a built-in method for retrieving an application instance from the global scope beginning in v20.12. This means that once an application has been instantiated, you can retrieve it using: Sanic.get_app().
app = Sanic("MyApp")
assert Sanic.get_app() is app
This method will only work if there is a single Sanic instance available. If you have multiple application instances, you will need to use the optional name argument:
app1 = Sanic("MyApp")
app2 = Sanic("MyOtherApp")
assert Sanic.get_app("MyApp") is app1
I would suggest a slightly different approach, based on the 12 Factor App (very interesting read which, among others, provides a nice guideline on how to protect and isolate your sensitive info).
The general idea is to place your sensitive and configuration variables in a file that is going to be gitignored and therefore will only be available locally.
I will try to present the method I tend to use in order to be as close as possible to the 12 Factor guidelines:
Create a .env file with your project variables in it:
MONGO_URL=http://no_peeking_this_is_secret:port/
SENSITIVE_PASSWORD=for_your_eyes_only
CONFIG_OPTION_1=config_this
DEBUG=True
...
(Important) Add .env and .env.* on your .gitignore file, thus protecting your sensitive info from been uploaded to GitHub.
Create an env.example (be careful not to name it with a . in the beginning, because it will get ignored).
In that file, you can put an example of the expected configuration in order to be reproducible by simply copy, paste, rename to .env.
In a file named settings.py, use decouple.config to read your config file into variables:
from decouple import config
MONGO_URL = config('MONGO_URL')
CONFIG_OPTION_1 = config('CONFIG_OPTION_1', default='')
DEBUG = config('DEBUG', cast=bool, default=True)
...
Now you can use these variables wherever is necessary for your implementation:
myblueprint.py:
import settings
...
auth_route = Blueprint('authentication')
mongo_url = settings.MONGO_URL
user_repository = UserRepository(mongo_url)
...
As a finisher, I would like to point out that this method is framework (and even language) agnostic so you can use it on Sanic as well as Flask and everywhere you need it!
I think you can create a config.py to save your configuration, just like
config.py
config = {
'MONGO_URL':'127.0.0.1:27017'
}
and use it in app.py
from config import config
mongo_url = config['MONGO_URL']
There is a variable named current_app in Flask. You can use current_app.config["MONGO_URL"].
But I am not familiar with Sanic.

Cant fetch production db results using Google app engine remote_api

Hey, I'm trying to work out with /remote_api with a django-patch app engine app i got running.
i want to select a few rows from my online production app locally.
i cant seem to manage to do so, everything authenticates fine, it doesnt breaks on imports, but when i try to fetch something it just doesnt print anything.
Placed the test python inside my local app dir.
#!/usr/bin/env python
#
import os
import sys
# Hardwire in appengine modules to PYTHONPATH
# or use wrapper to do it more elegantly
appengine_dirs = ['myworkingpath']
sys.path.extend(appengine_dirs)
# Add your models to path
my_root_dir = os.path.abspath(os.path.dirname(__file__))
sys.path.insert(0, my_root_dir)
from google.appengine.ext import db
from google.appengine.ext.remote_api import remote_api_stub
import getpass
APP_NAME = 'Myappname'
os.environ['AUTH_DOMAIN'] = 'gmail.com'
os.environ['USER_EMAIL'] = 'myuser#gmail.com'
def auth_func():
return (raw_input('Username:'), getpass.getpass('Password:'))
# Use local dev server by passing in as parameter:
# servername='localhost:8080'
# Otherwise, remote_api assumes you are targeting APP_NAME.appspot.com
remote_api_stub.ConfigureRemoteDatastore(APP_NAME,
'/remote_api', auth_func)
# Do stuff like your code was running on App Engine
from channel.models import Channel, Channel2Operator
myresults = mymodel.all().fetch(10)
for result in myresults:
print result.key()
it doesn't give any error or print anything. so does the remote_api console example google got. when i print the myresults i get [].
App Engine patch monkeypatches the ext.db module, mutilating the kind names. You need to make sure you import App Engine patch from your script, to give it the opportunity to mangle things as per usual, or you won't see any data returned.

Categories