I found that in flask >= 0.5 there is autoescaping enabled only for the little amount of extensions not including j2. I use j2 extentions for my templates to get coloring and another features from my editor. So how can I enable autoescaping for certain file extentions in Flask in the most simple and convenient way?
See http://jinja.pocoo.org/docs/2.10/api/#autoescaping
To enable it globally you can use :
from jinja2 import select_autoescape
app.jinja_env.autoescape = select_autoescape(
default_for_string=True,
default=True
)
Or for specified extensions :
app.jinja_env.autoescape = select_autoescape(
default_for_string=True,
enabled_extensions=('html', 'xml', 'j2')
)
Related
I am using sanic/sanic-ext 22.9.0 , I need to load a static open api yaml or json file rather than autogenerate so that when I access it as <url>/docs, the static yaml file is loaded and UI display either Swagger or redoc version of UI with the API definition.
Any suggestion on how to achieve this.
You have a few options.
OPTION 1
Load your custom OAS into Sanic, and server that.
#app.before_server_start
async def load_oas(app: Sanic):
custom_oas_dict = load_spec_from_yaml()
app.ext.openapi.raw(custom_oas_dict)
OPTION 2
Turn off OAS and roll your own solution, including swagger/redoc, etc
app.config.OAS = False
OPTION 3
Serve your custom OAS, and overwrite the HTML to point to your custom file.
app.config.OAS_PATH_TO_REDOC_HTML = "/path/to/custom/redoc.html"
app.config.OAS_PATH_TO_SWAGGER_HTML = "/path/to/custom/swagger.html"
app.static("/custom/oas.json", "/path/to/custom/oas.json")
I have tried to get the autoprefixer filter to work with flask_assets by following the instructions in the Flask_Assets documentation, but it does not appear to apply the filter. Here is my code:
# construct flask app object
from flask import Flask, render_template_string
flask_args = { 'import_name': __name__ }
flask_app = Flask(**flask_args)
from flask_assets import Environment, Bundle
assets = Environment(flask_app)
assets.config['AUTOPREFIXER_BIN'] = 'postcss'
assets.config['AUTOPREFIXER_BROWSERS'] = [ '> 1%' ]
css_min = Bundle('../styles/mycss.css', filters='autoprefixer', output='styles/test.css')
assets.register('css_assets', css_min)
#flask_app.route('/')
def landing_page():
html = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">\
<head>{% assets "css_assets" %}\
<link rel="stylesheet" href="{{ ASSET_URL }}" type="text/css">\
{% endassets %}\
<title>Hello</title>\
</head>\
<h1>Hello World</h1>\
<p>Just a test of flask</p>'
return render_template_string(html), 200
if __name__ == '__main__':
flask_app.run(host='0.0.0.0', port=5000)
I have been able to apply the cssmin, pyscss, uglifyjs and jsmin filters successfully. I can also run autoprefixer on the command line to successfully compile a transformed output:
postcss --use autoprefixer --autoprefixer.browsers "> 1%" -o test.css mycss.css
However, when trying to run autoprefixer through flask_assets registration, the process neither throws an error nor does it seem to take the required time to compile. It does produce the output file but when I examine the resulting file, none of the prefixes have been applied.
UPDATE: This problem seems to occur whenever attempting to configure options for ANY filter. I have not been able to get uglifyjs to accept 'UGLIFYJS_EXTRA_ARGS' or for the pyscss filter to adopt a new style using 'PYSCSS_STYLE' either. I have tried to set these configuration as environmental variables using os.environ['AUTOPREFIXER_BIN'] as well as attempting to pass them through flask.config['AUTOPREFIXER_BIN']. But none of the configuration settings have been applied when the filter is run. It is also not clear to me where in the code itself the configuration options are constructed by either Bundle or Environment.
One SO post claims to have found a way to get a configuration setting to work, but the post does not show the entire workflow of how flask_assets needs to be setup to ingest these options.
Perhaps someone can help me understand what I am doing wrong?
Autoprefixer:
There is nothing wrong with your code1. You are just not using the correct filter for the latest version of Autoprefixer. If you look at the history of the releases in that link, since version 6.0.0, it started using postcss. Your code will work for versions older than 6.0.0.
Webassets has provided support for versions after 6.0.0 (inclusive), by providing the autoprefixer6 filter.
Therefore all you have to do is change the filter(s) while initializing your bundle, like so:
css_min = Bundle('../styles/mycss.css', filters='autoprefixer6', output='styles/test.css')
Other Filters' Configurations:
Don't use os.environ, that is not the way to set configuration variables for Flask and flask-extensions. The most common (and preferred) way to set configuration for extensions is by using the flask Config itself, and in large projects this is done using a separate config file. The extensions will pickup its configuration options from flask's config.
Depending on which extension you use, you can also set the config separately like you have done, but that is rarely used, from what I have seen so far.
Please check the Flask's Configuration related documentation for some good examples on how to setup configuration for your app "properly".
from flask import Flask, render_template_string
from flask_assets import Environment, Bundle
# construct flask app object
flask_args = {'import_name': __name__}
flask_app = Flask(**flask_args)
assets = Environment(flask_app)
# specify the bin path (optional), required only if not globally installed
assets.config['AUTOPREFIXER_BIN'] = 'path/to/postcss'
assets.config['AUTOPREFIXER_BROWSERS'] = ['> 1%', ]
# use the autoprefixer6 updated filter
css_min = Bundle('../styles/mycss.css', filters='autoprefixer6',
output='styles/test.css')
assets.register('css_assets', css_min)
#flask_app.route('/')
def landing_page():
html = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">\
<head>{% assets "css_assets" %}\
<link rel="stylesheet" href="{{ ASSET_URL }}" type="text/css">\
{% endassets %}\
<title>Hello</title>\
</head>\
<h1>Hello World</h1>\
<p>Just a test of flask</p>'
return render_template_string(html), 200
if __name__ == '__main__':
flask_app.run(host='0.0.0.0', port=5000)
Remember to clean out the previously generated files, if the source css/js has not changed, i.e remove the output files, and the .webassets-cache folder.
1Except for code style & formatting conventions!
I'm using django-pipeline with s3. I'm successfully using collectstatic to combined my Javascript files and store them in my s3 bucket, but they are not getting compressed for some reason (verified by looking at the file, its size, and its content-encoding). Otherwise things are working correctly with the combined scripts.js that is produced.
Here are the changes I made to use django-pipeline:
Added pipeline to installed apps.
Added 'pipeline.finders.PipelineFinder' to STATICFILES_FINDERS.
Set STATICFILES_STORAGE = 'mysite.custom_storages.S3PipelineManifestStorage' where this class is as defined in the documentation, as seen below.
Set PIPELINE_JS as seen below, which works but just isn't compressed.
PIPELINE_ENABLED = True since DEBUG = True and I'm running locally.
PIPELINE_JS_COMPRESSOR = 'pipeline.compressors.yuglify.YuglifyCompressor' even though this should be default.
Installed the Yuglify Compressor with npm -g install yuglify.
PIPELINE_YUGLIFY_BINARY = '/usr/local/bin/yuglify' even though the default with env should work.
Using the {% load pipeline %} and {% javascript 'scripts' %} which work.
More detail:
PIPELINE_JS = {
'scripts': {
'source_filenames': (
'lib/jquery-1.11.1.min.js',
...
),
'output_filename': 'lib/scripts.js',
}
}
class S3PipelineManifestStorage(PipelineMixin, ManifestFilesMixin, S3BotoStorage):
location = settings.STATICFILES_LOCATION
As mentioned, collectstatic does produce scripts.js just not compressed. The output of that command includes:
Post-processed 'lib/scripts.js' as 'lib/scripts.js'
I'm using Django 1.8, django-pipeline 1.5.2, and django-storages 1.1.8.
Similar questions:
django-pipeline not compressing
django pipeline with S3 storage not compressing
The missing step was to also extend GZipMixin, AND, it has to be first in the list of parents:
from pipeline.storage import GZIPMixin
class S3PipelineManifestStorage(GZIPMixin, PipelineMixin, ManifestFilesMixin, S3BotoStorage):
location = settings.STATICFILES_LOCATION
Now collectstatic produces a .gz version of each file as well, but my templates still weren't referencing the .gz version.
To address this the author says:
To make it work with S3, you would need to change the staticfiles
storage url method to return .gz urls (and staticfiles/pipeline
template tags depending if you care for clients that don't support
gzip). Also don't forget to setup the proper header on s3 to serve
theses assets as being gzipped.
I adapted an example he provided elsewhere, which overrides the url method:
class S3PipelineManifestStorage(GZIPMixin, PipelineMixin, ManifestFilesMixin, S3BotoStorage):
location = settings.STATICFILES_LOCATION
def url(self, name, force=False):
# Add *.css if you are compressing those as well.
gzip_patterns = ("*.js",)
url = super(GZIPMixin, self).url(name, force)
if matches_patterns(name, gzip_patterns):
return "{0}.gz".format(url)
return url
This still doesn't handle setting the Content-Encoding header.
A simpler alternative is to use the S3Boto Storages option AWS_IS_GZIPPED which performs gzipping AND sets the appropriate header.
More is required to support clients without gzip, however.
Also useful are these instructions from Amazon on serving compressed files from S3.
I'm trying to create a website using GAE(Google App Engine) as the server and Having pages rendered using the GAE Django API. The CSS style I'd like to use is the 960 Grid System, specifically the adaptive version found here.
My page is being rendered with Django in GAE as usual:
class MainPage(webapp.RequestHandler):
def get(self):
featuredPic = "img/featuredPic.jpg"
values = {
'featuredPic' : featuredPic,
}
self.response.out.write(template.render('index.html', values))
application = webapp.WSGIApplication([('/', MainPage)], debug=True)
And my index.html file also includes the code neccassarry for an adaptive grid system:
<script src="/js/adapt.js"></script>
<script>
// Edit to suit your needs.
var ADAPT_CONFIG = {
// Where is your CSS?
path : '/css/',
// false = Only run once, when page first loads.
// true = Change on window resize and page tilt.
dynamic : true,
// First range entry is the minimum.
// Last range entry is the maximum.
// Separate ranges by "to" keyword.
range : [ '0px to 760px = mobile.min.css',
'760px to 980px = 720.min.css',
'980px to 1280px = 960.min.css',
'1280px to 1600px = 1200.min.css',
'1600px to 1940px = 1560.min.css',
'1940px to 2540px = 1920.min.css',
'2540px = 2520.min.css' ]
};
</script>
Also I am including the css,js,img, and other folders in the app.yaml, yet despite all this the resulting HTML does not follow the 960 Grid System classes I have set to the divs. Does GAE disable JS or am I making some other mistake?
Actually, I am not that good at GAE, but I can help you, i guess.
I've also made a page on GAE and that has also template html file which uses the .js and .css files
At the template html file, I've written the script tag like the below.
<script type="application/x-javascript" src="iui/iui.js"></script>
and i put the .js file at the below path.
<app_name>\iui\iui.js
<app_name> has the models.py, urls.py, views.py, etc.
In addition, I've added the following statements on my app.yaml, "muchart" is <app_name>
app.yaml
...
handlers:
- url: /muchart/js
static_dir: muchart/js
- url: /muchart/iui
static_dir: muchart/iui
This doesn't exactly answer my question but I instead switched to the successor of 960.gs, Unsemantic, available here. It works really well with my project, as it was pretty much what I was looking for in the adaptive version of 960.gs. Also I had no issues setting it up.
Is Sphinx, is there way to automatically link text like #112 or r1023 to the corresponding tickets/changesets in Trac?
For eg:
#112 -> http://mytracsite/tickets/112
r1023 -> http://mytracsite/changeset/1023
See TracLinks for more examples.
If you put this in your config.py
trac_url = 'http://mytratsite/'
from docutils import nodes, utils
from docutils.parsers.rst import roles
import urllib
def trac_role(role, rawtext, text, lineno, inliner, options={}, content=[]):
ref = trac_url + '/intertrac/' + urllib.quote(text, safe='')
node = nodes.reference(rawtext, utils.unescape(text), refuri=ref, **options)
return [node],[]
roles.register_canonical_role('trac', trac_role)
Then you can use :trac:`#123` and :trac:`r1023` in your documents.
This is probably the easiest way to make quick links to a trac site. It automatically works for all kinds of TracLinks because it uses the intertrac mechanism for the links.
Sphinx 1.0 now supports external links using the extlinks extension. Using a configurable role name (e.g. 'issue') you can write your links like:
:issue:`123`
and it will be converted to http://mytracsite/123.