Flask html response minifier

Overview

Flask-HTMLmin

PyPI version Supported Python Versions License tests codecov

Minify flask text/html mime type responses. Just add MINIFY_HTML = True to your deployment config to minify HTML and text responses of your flask application.

Installation

To install Flask-HTMLmin, simply use pip:

pip install Flask-HTMLmin

Or use pipenv:

pipenv install Flask-HTMLmin

Or use poetry:

poetry add Flask-HTMLmin

Or alternatively, you can download the repository and install it manually by doing:

git clone [email protected]:hamidfzm/Flask-HTMLmin.git
cd Flask-HTMLmin
python setup.py install

Example

from flask import Flask, render_template
from flask_htmlmin import HTMLMIN
    
app = Flask(__name__)
app.config['MINIFY_HTML'] = True

htmlmin = HTMLMIN(app)
# or you can use HTMLMIN.init_app(app)
# pass additional parameters to htmlmin
# HTMLMIN(app, **kwargs)
# example:
# htmlmin = HTMLMIN(app, remove_comments=False, remove_empty_space=True, disable_css_min=True)


@app.route('/')
def main():
    # index.html will be minimized !!!
    return render_template('index.html')


@app.route('/exempt')
@htmlmin.exempt
def exempted_route():
    # index.html will be exempted and not blessed by holy htmlmin !!!
    return render_template('index.html')


if __name__ == '__main__':
    app.run()

TODO

  • Test cases
  • Route (or URL rule) exemption
  • Caching (in progress)
  • Minify inline CSS
  • Minify inline Javascript
  • Type hints
Comments
  • utf8 crash

    utf8 crash

    Hello

    Tried out the module .. ran into an error. [2018-08-01 11:14:04 +0000] [2320] [INFO] Starting gunicorn 19.9.0 [2018-08-01 11:14:04 +0000] [2320] [INFO] Listening at: http://0.0.0.0:5000 (2320) [2018-08-01 11:14:04 +0000] [2320] [INFO] Using worker: gevent [2018-08-01 11:14:04 +0000] [2324] [INFO] Booting worker with pid: 2324 [2018-08-01 11:14:04 +0000] [2325] [INFO] Booting worker with pid: 2325 [2018-08-01 11:14:09 +0000] [2325] [ERROR] Error handling request / Traceback (most recent call last): File "/home/anon/miniconda2/lib/python2.7/site-packages/gunicorn/workers/base_async.py", line 56, in handle self.handle_request(listener_name, req, client, addr) File "/home/anon/miniconda2/lib/python2.7/site-packages/gunicorn/workers/ggevent.py", line 160, in handle_request addr) File "/home/anon/miniconda2/lib/python2.7/site-packages/gunicorn/workers/base_async.py", line 107, in handle_request respiter = self.wsgi(environ, resp.start_response) File "/home/anon/miniconda2/lib/python2.7/site-packages/flask/app.py", line 2309, in call return self.wsgi_app(environ, start_response) File "/home/anon/miniconda2/lib/python2.7/site-packages/flask/app.py", line 2295, in wsgi_app response = self.handle_exception(e) File "/home/anon/miniconda2/lib/python2.7/site-packages/flask/app.py", line 1741, in handle_exception reraise(exc_type, exc_value, tb) File "/home/anon/miniconda2/lib/python2.7/site-packages/flask/app.py", line 2292, in wsgi_app response = self.full_dispatch_request() File "/home/anon/miniconda2/lib/python2.7/site-packages/flask/app.py", line 1816, in full_dispatch_request return self.finalize_request(rv) File "/home/anon/miniconda2/lib/python2.7/site-packages/flask/app.py", line 1833, in finalize_request response = self.process_response(response) File "/home/anon/miniconda2/lib/python2.7/site-packages/flask/app.py", line 2112, in process_response response = handler(response) File "/home/anon/miniconda2/lib/python2.7/site-packages/flask_htmlmin/init.py", line 35, in response_minify self.html_minify.minify(response.get_data(as_text=True)) File "/home/anon/miniconda2/lib/python2.7/site-packages/werkzeug/wrappers.py", line 989, in get_data rv = rv.decode(self.charset) File "/home/anon/miniconda2/lib/python2.7/encodings/utf_8.py", line 16, in decode return codecs.utf_8_decode(input, errors, True) UnicodeDecodeError: 'utf8' codec can't decode byte 0x8b in position 1: invalid start byte

    wontfix 
    opened by ra-esmith 18
  • OpenTagNotFoundError() redirect code 302

    OpenTagNotFoundError() redirect code 302

    https://github.com/hamidfzm/Flask-HTMLmin/blob/82f828bc6a39d2672bfd152db353e0ee563b48c1/flask_htmlmin.py#L32

    if you use flask.redirect, this redirection with code 302 and the response: https://github.com/pallets/werkzeug/blob/4397e61daf66ad43bd5668741c5d876de116a71f/werkzeug/utils.py#L373

    '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">\n'
    '<title>Redirecting...</title>\n'
    '<h1>Redirecting...</h1>\n'
    '<p>You should be redirected automatically to target URL: '
    '<a href="%s">%s</a>. If not click the link.'
    

    for htmlmin.parser is not valid: https://github.com/mankyd/htmlmin/blob/dff1163a1ec25fe94aeaeefe702377b5a9e912b3/htmlmin/parser.py#L261

    that gives an error OpenTagNotFoundError()

    bug 
    opened by citijk 11
  • unexpected call to parse_endtag

    unexpected call to parse_endtag

    Hi. Getting a sporadic error 'unexpected call to parse_endtag". I haven't been able to replicate the issue reliably.

    Occurs here in parse.py file in htmlmin. assert rawdata[i:i+2] == "</", "unexpected call to parse_endtag"

    However as a suggestion, perhaps a try except AssertionError should be added to the reponse_minify method. This way even if the error does occur, the final webpage is still rendered as the original unminified response is returned.

    wontfix 
    opened by arcane99 4
  • Stop using pytest-runner

    Stop using pytest-runner

    setup_requires and tests_requires are firmly deprecated by setuptools upstream, and pytest-runner similarly, since it makes use of functionality that setuptools would like to remove. Stop setting {setup,test}_requires in setup.py, and remove pytest-runner from Pipfile.

    Fixes #29

    opened by s-t-e-v-e-n-k 3
  • Can we read htmlmin options from the flask config file?

    Can we read htmlmin options from the flask config file?

    Hi, thanks for the tool!

    What do you think about allowing these settings to be set in the app.config?

    default_options = {
                'remove_comments': True,
                'reduce_empty_attributes': True,
                'remove_optional_attribute_quotes': False
            }
    default_options.update(kwargs)
    

    As well as the other options for htmlmin from https://htmlmin.readthedocs.io/en/latest/reference.html?

    Personally, I'd really like to add the "remove_empty_space". Somehow my output has whitespace between all tags, for example the closing tags on my homepage look like this -

    </div> </div> </div> </body> </html>
    
    opened by christopherpickering 2
  • Example not working

    Example not working

    I'm testing the example provided in README:

    from flask import Flask, render_template
    from flask_htmlmin import HTMLMIN
        
    app = Flask(__name__)
    app.config['MINIFY_PAGE'] = True
    
    htmlmin = HTMLMIN(app)
    # or you can use HTMLMIN.init_app(app)
    # pass additional parameters to htmlmin
    # HTMLMIN(app, **kwargs)
    
    @app.route('/')
    def main():
        # index.html will be minimized !!!
        return render_template('index.html')
    
    
    @app.route('/exempt')
    @htmlmin.exempt
    def exempted_route():
        # index.html will be exempted and not blessed by holy htmlmin !!!
        return render_template('index.html')
    
    
    if __name__ == '__main__':
        app.run()
    

    And this is my templates/index.html

    <html>
      <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8">
      </head>
    
      <body>
        <div>
          Hello
        </div>
        <div>
          World
        </div>
      </body>
    </html>
    

    I'm using python 3.7.2 and there is no minified output.

    opened by wiltonsr 2
  • Example not working

    Example not working

    I don't know exactly why, but the example doesn't work in my environment. No minify output.

    However your other answer works fine.

    http://stackoverflow.com/a/26139704/564979

    ty

    enhancement 
    opened by ar-anvd 2
  • disable_css_min argument leads to error in initialization

    disable_css_min argument leads to error in initialization

    Using the example I get this:

    htmlmin = HTMLMIN(app, remove_comments=False, remove_empty_space=True, disable_css_min=True)

    TypeError: unexpected keyword argument 'disable_css_min'

    Also, when I install via pip, I get this: Using legacy setup.py install for Flask-HTMLmin, since package 'wheel' is not installed.

    bug 
    opened by akcode47 1
  • Bump urllib3 from 1.26.4 to 1.26.5

    Bump urllib3 from 1.26.4 to 1.26.5

    Bumps urllib3 from 1.26.4 to 1.26.5.

    Release notes

    Sourced from urllib3's releases.

    1.26.5

    :warning: IMPORTANT: urllib3 v2.0 will drop support for Python 2: Read more in the v2.0 Roadmap

    • Fixed deprecation warnings emitted in Python 3.10.
    • Updated vendored six library to 1.16.0.
    • Improved performance of URL parser when splitting the authority component.

    If you or your organization rely on urllib3 consider supporting us via GitHub Sponsors

    Changelog

    Sourced from urllib3's changelog.

    1.26.5 (2021-05-26)

    • Fixed deprecation warnings emitted in Python 3.10.
    • Updated vendored six library to 1.16.0.
    • Improved performance of URL parser when splitting the authority component.
    Commits
    • d161647 Release 1.26.5
    • 2d4a3fe Improve performance of sub-authority splitting in URL
    • 2698537 Update vendored six to 1.16.0
    • 07bed79 Fix deprecation warnings for Python 3.10 ssl module
    • d725a9b Add Python 3.10 to GitHub Actions
    • 339ad34 Use pytest==6.2.4 on Python 3.10+
    • f271c9c Apply latest Black formatting
    • 1884878 [1.26] Properly proxy EOF on the SSLTransport test suite
    • See full diff in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 1
  • Adding test cases

    Adding test cases

    Hi @hamidfzm thanks for the extension. I'm adding test cases with pytest and 100% coverage tested on py2.7 and py.3.6 to run test python setup.py test

    opened by mrf345 1
  • Ignore OpenTagNotFoundError errors from htmlmin

    Ignore OpenTagNotFoundError errors from htmlmin

    htmlmin raises OpenTagNotFoundError in some cases (origin unclear). Catch the exception and pass the input through un-minified.

    Works around #10, mankyd/htmlmin#46.

    opened by df7cb 1
Releases(v2.2.1)
  • v2.2.1(Oct 24, 2022)

    What's Changed

    • Stop using pytest-runner by @s-t-e-v-e-n-k in https://github.com/hamidfzm/Flask-HTMLmin/pull/31
    • Fix documentation error in README by @bfontaine in https://github.com/hamidfzm/Flask-HTMLmin/pull/32
    • Fix https://github.com/hamidfzm/Flask-HTMLmin/issues/30 by @hamidfzm

    New Contributors

    • @s-t-e-v-e-n-k made their first contribution in https://github.com/hamidfzm/Flask-HTMLmin/pull/31
    • @bfontaine made their first contribution in https://github.com/hamidfzm/Flask-HTMLmin/pull/32

    Full Changelog: https://github.com/hamidfzm/Flask-HTMLmin/compare/v2.2.0...v2.2.1

    Source code(tar.gz)
    Source code(zip)
  • v2.2.0(Oct 18, 2021)

  • v2.1.0(Feb 10, 2021)

  • v2.0.3(Feb 10, 2021)

  • v2.0.2(Mar 30, 2020)

  • v2.0.1(Mar 30, 2020)

  • v2.0.0(Mar 30, 2020)

    This release comes in the midst of a global pandemic. Wish you a healthy life with lots of success.

    • Dropped support for Python 2.7 (setuptools stopped supporting it so basically you can't install this project in Python 2.7)
    • Migrate from Travis CI to Github Actions
    • Migrate from Coveralls to Codecov
    • Update README
    • Update PyPI description
    • Fix comments typo (@timgates42)
    Source code(tar.gz)
    Source code(zip)
  • v1.5.2(Oct 24, 2019)

    • Fix setup.py issues
    • Update setup.py categories
    • Fix tests
    • Change MINIFY_PAGE to MINIFY_HTML
    • Add deprecation warning for old config

    I'm going to implement a caching solution for minified HTML. Any suggestions would be greatly appreciated.

    Source code(tar.gz)
    Source code(zip)
  • v1.5.0(Oct 20, 2018)

    • Add Route (or URL rule) exemption (@hamidfzm)
    • Update tests (@hamidfzm)
    • Add python 3.7 support (@hamidfzm)
    • Update README (@hamidfzm)
      • Example
      • Badges
    Source code(tar.gz)
    Source code(zip)
  • v1.4.0(Jul 22, 2018)

  • v1.3.2(Mar 18, 2018)

  • v1.3.1(Oct 7, 2017)

  • v1.3.0(Oct 5, 2017)

  • v1.2.1(Jul 17, 2017)

  • v1.2(Jun 30, 2016)

  • v1.1(Jan 14, 2016)

Owner
Hamid Feizabadi
Web Developer, Python, Go
Hamid Feizabadi
Ellipitical Curve Table Generator

Ellipitical-Curve-Table-Generator This script generates a table of elliptical po

Nishaant Goswamy 1 Jan 02, 2022
Reactjs web app written entirely in python, using transcrypt compiler.

Reactjs web app written entirely in python, using transcrypt compiler.

Dan Shai 22 Nov 27, 2022
Empresas do Brasil (CNPJs)

Biblioteca em Python que coleta informações cadastrais de empresas do Brasil (CNPJ) obtidas de fontes oficiais (Receita Federal) e exporta para um formato legível por humanos (CSV ou JSON).

BR-API: Democratizando dados do Brasil. 8 Aug 17, 2022
A Powerful Tool For Making Combo List(All possible modes)

ComboMaker A Powerful Tool For Making Combo List Introduction Check out all possible Combo list build modes with this tool =) How to Install Open the

MasterBurnt 7 Jan 07, 2023
GCP Scripts and API Client Toolss

GCP Scripts and API Client Toolss Script Authentication The scripts and CLI assume GCP Application Default Credentials are set. Credentials can be set

3 Feb 21, 2022
Perform oocyst segmentation in mercurochrome stained mosquito midgut

Midgut_oocyst_segmentation Perform oocyst segmentation in mercurochrome stained mosquito midguts This oocyst segmentation model also powers the webtoo

Duo Peng 3 Oct 27, 2021
Meower a social media platform written in Scratch 3.0 and Python

Meower Meower is a social media platform written in Scratch 3.0 and Python, ported to HTML for self-hosting. Try Beta 4.6 Changelog for 4.6 Start impl

Meower Media Co. 23 Dec 02, 2022
Gives criticality score for an open source project

Open Source Project Criticality Score (Beta) This project is maintained by members of the Securing Critical Projects WG. Goals Generate a criticality

Open Source Security Foundation (OpenSSF) 1.1k Dec 23, 2022
An OBS script to fuze files together

OBS TEXT FUZE Fuze text files and inject the output into a text source. The Index file directory should be a list of file directorys for the text file

SuperZooper3 1 Dec 27, 2021
Video Stream is an Advanced Telegram Bot that's allow you to play Video & Music on Telegram Group Video Chat

Video Stream is an Advanced Telegram Bot that's allow you to play Video & Music on Telegram Group Video Chat 📊 Stats 🧪 Get SESSION_NAME from below:

dark phoenix 12 May 08, 2022
Python 3 script for installing kali tools on your linux machine

Python 3 script for installing kali tools on your linux machine

gh0st 2 Apr 20, 2022
Learn Python tips, tools, and techniques in around 5 minutes each.

Python shorts Learn Python tips, tools, and techniques in around 5 minutes each. Watch on YouTube Subscribe on YouTube to keep up with all the videos.

Michael Kennedy 28 Jan 01, 2023
Location of public benchmarking; primarily final results

CSL_public_benchmark This repo is intended to provide a periodically-updated, public view into genome sequencing benchmarks managed by HudsonAlpha's C

HudsonAlpha Institute for Biotechnology 15 Jun 13, 2022
Sailwind Mod Manager

Sailwind Mod Manager The Sailwind Mod Manager is an open source mod manager for the Sailwind community. It currently allows you to browse and download

Max 3 Jul 15, 2022
Скрипт позволяет выгрузить участников чатов/каналов(по чату для комментариев) и сообщения в различные форматы файлов.

TG-Parser Парсер участников и сообщений из ТГ-Чатов и чатов для комментариев в ТГ-Каналах Возможности Выгрузка участников групп/каналов(по чату для ко

50 Jan 06, 2023
This program goes thru reddit, finds the most mentioned tickers and uses Vader SentimentIntensityAnalyzer to calculate the ticker compound value.

This program goes thru reddit, finds the most mentioned tickers and uses Vader SentimentIntensityAnalyzer to calculate the ticker compound value.

195 Dec 13, 2022
Comics/doujinshi reader application. Web-based, will work on desktop and tablet devices with swipe interface.

Yomiko Comics/doujinshi reader application. Web-based, will work on desktop and tablet devices with swipe interface. Scans one or more directories of

Kyubi Systems 26 Aug 10, 2022
Easy to use phishing tool with 65 website templates. Author is not responsible for any misuse.

PyPhisher [+] Description : Ultimate phishing tool in python. Includes popular websites like facebook, twitter, instagram, github, reddit, gmail and m

KasRoudra 1.1k Dec 31, 2022
A comprensive software collection for nmea manipulation

nmeatoolkit A comprensive software collection for nmea manipulation; it includes a library and a collections of command line tools. Library pipes: con

Davide Gessa 1 Sep 14, 2022
solsim is the Solana complex systems simulator. It simulates behavior of dynamical systems—DeFi protocols, DAO governance, cryptocurrencies, and more—built on the Solana blockchain

solsim is the Solana complex systems simulator. It simulates behavior of dynamical systems—DeFi protocols, DAO governance, cryptocurrencies, and more—built on the Solana blockchain

William Wolf 12 Jul 13, 2022