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
The program converts Swiss notes into American notes

Informatik-Programmieren Einleitung: Das Programm rechnet Schweizer Noten in das Amerikanische Noten um. Der Benutzer kann seine Note eingeben und der

2 Dec 16, 2021
Openfe - Alchemical free energy calculations for the masses

The Open Free Energy library Alchemical free energy calculations for the masses.

33 Dec 22, 2022
This alerts you when the avalanche score a goal

This alerts you when the avalanche score a goal

Davis Burrill 1 Jan 15, 2022
Reproducible nvim completion framework benchmarks.

Nvim.Bench Reproducible nvim completion framework benchmarks. Runs inside Docker. Fair and balanced Methodology Note: for all "randomness", they are g

i love my dog 14 Nov 20, 2022
An execution framework for systematic strategies

WAGMI is an execution framework for systematic strategies. It is very much a work in progress, please don't expect it to work! Architecture The Django

Rich Atkinson 10 Mar 28, 2022
Interpreting-compiling programming language.

HoneyASM The programming language written on Python, which can be as interpreted as compiled. HoneyASM is easy for use very optimized PL, which can so

TalismanChet 1 Dec 25, 2021
A free and powerful system for awareness and research of the American judicial system.

CourtListener Started in 2009, CourtListener.com is the main initiative of Free Law Project. The goal of CourtListener.com is to provide high quality

Free Law Project 332 Dec 25, 2022
Random Programming Language Project

Crastle Random Programming Language Project Freedom of expression Are you a fan of curly brace languages? Then use curly braces! Not a fan of curly br

DevNugget 2 Dec 23, 2021
Solve various integral equations using numerical methods in Python

Solve Volterra and Fredholm integral equations This Python package estimates Volterra and Fredholm integral equations using known techniques. Installa

Matthew Wildrick Thomas 18 Nov 28, 2022
Qt-creator-boost-debugging-helper - Qt Creator Debugging Helper for Boost Library

Go to Tools Options Debugger Locals & Expressions. Paste the script path t

Dmitry Bravikov 2 Apr 22, 2022
A web-based chat application that enables multiple users to interact with one another

A web-based chat application that enables multiple users to interact with one another, in the same chat room or different ones according to their choosing.

3 Apr 22, 2022
Find Transposon Element insertions using long reads (nanopore), by alignment directly. (minimap2)

find_te_ins find_te_ins is designed to find Transposon Element (TE) insertions using long reads (nanopore), by alignment directly. (minimap2) Install

Ming Wang 1 Feb 09, 2022
Run Windows Applications on Linux as if they are native, Use linux applications to launch files files located in windows vm without needing to install applications on vm. With easy to use configuration GUI

Run Windows Applications on Linux as if they are native, Use linux applications to launch files files located in windows vm without needing to install applications on vm. With easy to use configurati

Casu Al Snek 2k Jan 02, 2023
JARVIS PC Assistant is an assisting program to make your computer easier to use

JARVIS-PC-Assistant JARVIS PC Assistant is an assisting program to make your computer easier to use Welcome to the J.A.R.V.I.S. PC Assistant help file

Dasun Nethsara 2 Dec 02, 2022
The CS Netlogo Helper is a small python script I made, to make computer science homework easier.

The CS Netlogo Helper is a small python script I made, to make computer science homework easier. This project is really ironic now that I think about it.

1 Jan 13, 2022
Python language from the beginning.

Python For Beginners Python Programming Language ♦️ Python is a very powerful and user friendly programming language. ❄️ ♦️ There are some basic sytax

Randula Yashasmith Mawaththa 6 Sep 18, 2022
This python application let you check for new announcements from MMLS, take attendance while your lecturer is sharing QR Code on the screen.

This python application let you check for new announcements from MMLS, take attendance while your lecturer is sharing QR Code on the screen.

wyhong3103 5 Jul 17, 2022
Subnet calculator script using python

subnetCalculator Subnet calculator script using python3 Interactive Version Define the subnet variable interactively Use: subnetDict = subnetCalculato

1 Feb 15, 2022
Alerts for Western Australian Covid-19 exposure locations via email and Slack

WA Covid Mailer Sends alerts from Healthy WA's Covid19 Exposure Locations via email and slack. Setup Edit the configuration items in wacovidmailer.py

13 Mar 29, 2022
Collatz Sanısını Test Eden Ve Kanıtlayan Bir Python Programı

Collatz Sanısı Collatz Sanısını Test Eden Ve Kanıtlayan Bir Python Programı. Kullanım Terminalde: 1- git clone https://github.com/detherminal/Collatz-

Cemal Mert 2 May 07, 2022