Freezes a Flask application into a set of static files.

Overview

Frozen-Flask

https://img.shields.io/pypi/v/Frozen-Flask.svg?maxAge=2592000

Freezes a Flask application into a set of static files. The result can be hosted without any server-side software other than a traditional web server.

See documentation: https://pythonhosted.org/Frozen-Flask/

Build Status

https://github.com/Frozen-Flask/Frozen-Flask/workflows/CI/badge.svg?branch=master

Contributing

  • Fork the upstream repository and clone your fork
  • Create a feature branch for the thing you want to work on
  • Create a virtual environment and activate it
  • Run pip install -e . to install dependencies
  • Use tox or python -m flask_frozen.tests to run tests
  • Do your changes, make sure tests pass
  • Send a Pull Request to the upstream repository

License

Frozen-Flask uses a BSD 3-clause license. See LICENSE.

Comments
  • Ignore certain endpoints

    Ignore certain endpoints

    Ok, I think I have a real "issue" this time. :)

    I am running my app through Frozen Flask and the app has basic CRUD operations. The problem that I'm encountering is that the freeze process is following the delete endpoint. This has the unfortunate side-effect of actually deleting all the page content in my app. Thus, the next time I run the freeze method, there is a lot less frozen stuff.

    I didn't see any method in the documentation for getting freeze to ignore certain endpoints. Is this possible or desired?

    opened by mblayman 18
  • Add .freeze_yield() that freezes the app and yields URLs and paths

    Add .freeze_yield() that freezes the app and yields URLs and paths

    This change enables the user of Frozen-Flask to iterate over the URLs beeing frozen and visualize the progress (i.e. by printing the URLs to the stdout or using some kind of progressbar).

    opened by hroncok 12
  • Compatibility with Python 3.9

    Compatibility with Python 3.9

    I'm getting following warnings:

    /Users/honza/.local/share/virtualenvs/python.cz-s2NxYiyq/lib/python3.7/site-packages/flask_frozen/__init__.py:29
      /Users/honza/.local/share/virtualenvs/python.cz-s2NxYiyq/lib/python3.7/site-packages/flask_frozen/__init__.py:29:
      DeprecationWarning: Using or importing the ABCs from 'collections' instead
      of from 'collections.abc' is deprecated since Python 3.3,and in 3.9 it will stop working
        from collections import Mapping, namedtuple
    
    tests/views_test.py::test_get_involved_cs_renders_ordinary_issue
      /Users/honza/.local/share/virtualenvs/python.cz-s2NxYiyq/lib/python3.7/site-packages/ics/icalendar.py:59:
      DeprecationWarning: Using or importing the ABCs from 'collections' instead
      of from 'collections.abc' is deprecated since Python 3.3,and in 3.9 it will stop working
        elif isinstance(imports, collections.Iterable):
    
    opened by honzajavorek 10
  • Add an ignored files config to prevent freezing from overwriting/removing files

    Add an ignored files config to prevent freezing from overwriting/removing files

    I am using Frozen-Flask to create my blog which I publish through Github Pages. The problem is that freezing removes all of the files in the .git directory of the blog's github repo which kills the repository. I could build to a different destination and then copy over all of the files to my github repo, but that is a tedious and error prone process. Instead, it would be nice to have a config setting that would allow you to specify files and directories to ignore during the freezing process (something akin to the .gitignore file).

    The changes I've made in this pull request introduce a new config setting FREEZER_IGNORED_FILES to fix this issue. The ignored files setting takes a list of file and directory names (relative to the destination directory) and expands those into a list of ignored file paths.

    So, for example, if you wanted to ignore all files within the .git directory of a Git repo and a CNAME file within the top level of the destination directory, you could add the following to your script:

    FREEZER_IGNORED_FILES = ['.git', 'CNAME']
    
    opened by croach 10
  • Project maintenance

    Project maintenance

    Hi all,

    Having moved on to other things, I’m not interested in spending time on Frozen-Flask anymore. It has been effectively abandoned for some time. Still, there are a few open issues and pull requests and people occasionally file/submit new ones. The project needs a maintainer to live on, but it won’t be me.

    I’ve you’d like to do this, comment here and I’ll give you access on github and PyPI. (Please include your PyPI username in the comment.)

    CC people who have contributed pull requests: @tswast, @smbsimon, @MykolaBilyi, @mblayman, @aventurella, @singingwolfboy, @sodastsai, @mivade, @max-k, @HeyImAlex, @homeworkprod, @croach, @grayj, @vaus, @equalsraf, @benvinegar, @jokull, @amit-bansil, @rduplain.

    opened by SimonSapin 9
  • Add FREEZER_STATIC_IGNORE config option.

    Add FREEZER_STATIC_IGNORE config option.

    Allows you to stop certain static files (anything served by send_static_file) from being built with your project based on a list of fnmatch style patterns. Had to add a main.js static file to the test app and change the test_all_urls_method to work with the built_app context manager.

    opened by heyimalex 9
  • Add file extension to files without extensions

    Add file extension to files without extensions

    Assume you have a site that looks something like this...

    @app.route('/')
    def index():
        #...
    
    @app.route('/archive')
    def archive():
        #...
    
    @app.route('/archive/<int:year>')
    def archive_year(year):
        #...
    

    This should generate urls such as below:

    • /
    • /archive
    • /archive/2013

    The way I've handled these URLs in the past is to have my URLs mapped to the filenames shown below using the web server (Nginx):

    • / => /index.html
    • /archive => /archive.html
    • /archive/2013 => /archive/2013.html

    I don't see a way to generate the filenames the way I've shown with Frozen Flask. For example, the "archive" page will always be created as the filename /archive. I can't change the URL from /archive to /archive/ or /archive.html without breaking existing links. I also can't change the web server to just look for /archive at /archive/index.html because Frozen-Flask can't actually generate the application I've shown above (since it will create the archive file, and then be unable to create the archive directory).

    I am thinking on working on a patch that would add a new configuration item, something like FREEZER_FORCE_HTML_EXTENSION. This would take any file that wouldn't ordinarily have a .html extension for the generated file and give it one (if the response was actually an HTML content type). Thus, when /archive is generated, the view renders it as text/html, and therefore gives it an html file extension when generated.

    Before putting effort into this, I wanted to see if this is a feature that would be accepted if I created it. Additionally, I am wondering if you had any input or tips on its development, specifically on writing the tests. It seems all of the tests work on the assumption that the files will always be generated with the same names, where as this feature would obviously not hold to that assumption.

    opened by markhildreth 8
  • Add `Freezer.error_handler_spec` for saving errors

    Add `Freezer.error_handler_spec` for saving errors

    I needed to be able to generate a 404 page when freezing my Flask application, so I figured I'd add a generic way to make Frozen-Flask freeze any HTTP error page. The code works, and the unit test suite has been updated as well, but there is currently not documentation. I decided to mirror Flask.error_handler_spec as closely as possible, but I'm not certain that was the right decision, since it means that we have to use a nested dictionary due to blueprints providing their own exception handlers. I'm open to suggestions for other ways to implement this that make sense.

    opened by singingwolfboy 8
  • save html with wrong guessed mimetype as folder with index.html

    save html with wrong guessed mimetype as folder with index.html

    These patches rewrite the destination paths for html content with the wrong guessed mimetype to be stored as index.html. For example for a path /site/content/ the content wound be stored in /site/content/index.html. The commit adds a new option FREEZER_REWRITE_HTML_AS_FOLDER (default False) that enables this behaviour.

    This trick works well for web servers that accept paths with or without the trailing slash as being the equivalent. This is the case for github's static pages (for example http://equalsraf.github.com/ was generated from http://ruiabreu.org/). However this does not work for Freezer.run().

    opened by equalsraf 8
  • Not clear how to write URL generators based on documentation

    Not clear how to write URL generators based on documentation

    I've read the documentation found at https://pythonhosted.org/Frozen-Flask/#url-generators and to be fair I'm just confused by it.

    I've tried a multitude of approaches, but nothing worked.

    Here's my current code:

    @app.route('/category/<category_slug>')
    def articles(category_slug):
        data = []
        for article in ARTICLES:
            if article.metadata['category'] == category_slug:
                data.append(article)
        return render_template('category.html', articles=data)
    
    
    @freezer.register_generator
    def articles_generator():
        for article in ARTICLES:
            yield {'/articles/' + article.metadata['slug'], article}
    
    
    @app.route('/articles/<slug>')
    def article(slug):
        for article in ARTICLES:
            if article.metadata['slug'] == slug:
                return render_template('article.html', article=article, thumb=article.metadata['thumb'])
        return page_not_found(404)
    
    @freezer.register_generator
    def article_generator():
        yield {'article', article.metadata['slug']}
    

    the error I get is as follows:

    MissingURLGeneratorWarning: Nothing frozen for endpoints articles, article. Did you forget a URL generator?
      return set(page.url for page in self.freeze_yield())
    

    Any clarifications would be greatly appreciated.

    opened by Zenahr 7
  • Support unquoting URLs that contain multi-byte unicode characters

    Support unquoting URLs that contain multi-byte unicode characters

    The Python 2.7 urllib.unquote implementation does not handle decoding non-ASCII characters; instead use werkzeug's encoding-aware implementation.

    Fixes #103

    opened by jayaddison 7
  • New feature: pretty relative urls

    New feature: pretty relative urls

    Hey Frozen-Flask team! I was going through my old issues and decided to have another shot at a feature request I made here 4 years ago. I'm too deep into JS now, so I actually don't know if kids new to programming these days still build websites with Python and then host them on static servers like I used to, but if they do, now they can have pretty URLs without the ugly /index.html just like I wanted to.


    Why it's necessary to first append the /index.html and then remove it (i.e. why the approach I said I tried in the original issue didn't work): if the index.html isn't there, relpath resolves a path to the directory itself, which obviously doesn't include the trailing slash. But after that it isn't anymore possible to disambiguate if the resolved URL is a directory ../example, or a file ../example. So we need to keep it, resolve the relpath, and then again strip query+fragment, check for index.html, remove it and then put everything back together again.

    Fixes #90

    opened by mvolfik 0
  • docs: fix simple typo, unmodifies -> unmodified

    docs: fix simple typo, unmodifies -> unmodified

    There is a small typo in flask_frozen/init.py.

    Should read unmodified rather than unmodifies.

    Semi-automated pull request generated by https://github.com/timgates42/meticulous/blob/master/docs/NOTE.md

    opened by timgates42 0
  • Question: What is the best way to have run multiple threads/processes?

    Question: What is the best way to have run multiple threads/processes?

    the whole process of freezing ~2k urls takes upto 20 mins. Is there a way to run the freeze script with multiple threads/processes to speed up the static site generation?

    I have implemented something here, and appreciate any feedback for improvements, thanks :) reference: https://github.com/vedupraity/ancientknowledgewebserver/blob/master/freeze.py

    opened by vedupraity 2
  • Question about URL generators

    Question about URL generators

    So, I am making a blog and I am trying to freeze it with Frozen-Flask. I have the following URL generator in my code:

    @app.route('/blog/<path:path>.html')
    def page(path):
        page = pages.get_or_404(path)
        return render_template('page.html', page=page)
    

    How can I make Frozen-Flask register the URL generator?

    opened by ghost 1
  • How to remove trailing slash?

    How to remove trailing slash?

    Hi,

    I made a site with this (https://util123.com/) but i need now remove the last slash.

    Can anyone help me?

    The main project is Kaktos (https://github.com/paulocoutinhox/kaktos).

    Thanks for any help.

    opened by paulocoutinhox 2
  • During build: string concatenation in url_for() fails when data comes from render_template()

    During build: string concatenation in url_for() fails when data comes from render_template()

    When running Flask normally, everything described below works absolutely fine.

    When running a build in Frozen-Flask however, I run into the issue where my dynamically built route string won't allow me to concatenate a variable (containing a string) with a string for use in a url_for() function within Jinja2. But only when the variable data is originating from Python such as render_template().

    routes.py

    @app.route('/some-route/')
    def some_route():
        return render_template('my_template.html', foo='bar')
    

    base.html

    {% import "includes.html" as includes %}
    {{ includes.my_macro(foo) }}
    

    includes.html

    # The following does NOT work
    {% macro my_macro(foo) %}
        <a href="{{ url_for('index_' ~ foo) }}">Link text</a>
    {% endmacro %}
    

    Although the above runs fine in Flask, when I do a build with Frozen-Flask I get the following error:

    werkzeug.routing.BuildError: Could not build url for endpoint 'index_'. Did you mean...
    

    As you can see, the value of foo (or the string value bar) is missing. It should have been index_bar.

    So I tried this instead:

    # This also does NOT work
    {% macro my_macro(foo) %}
        {% set route = 'index_' ~ foo %}
        <a href="{{ url_for(route) }}">Link text</a>
    {% endmacro %}
    

    The above produces the exact same error.

    So I tried this to try to better understand the problem:

    # This works correctly
    {% macro my_macro(foo) %}
        {% set route = 'index_' ~ 'bar' %}
        <a href="{{ url_for(route) }}">Link text</a>
    {% endmacro %}
    

    So I further tried this:

    # This also works correctly
    {% macro my_macro(foo) %}
        {% set foo2 = 'bar' %}
        {% set route = 'index_' ~ foo2 %}
        <a href="{{ url_for(route) }}">Link text</a>
    {% endmacro %}
    

    So basically, I can create a dynamic route string for use by url_for() but only when the variable data doesn't come from the Flask routes file (such as my routes.py), only if the variable is created within Jinja2.

    opened by LokiWijnen 2
Releases(v0.15)
Flask-Starter is a boilerplate starter template designed to help you quickstart your Flask web application development.

Flask-Starter Flask-Starter is a boilerplate starter template designed to help you quickstart your Flask web application development. It has all the r

Kundan Singh 259 Dec 26, 2022
a flask profiler which watches endpoint calls and tries to make some analysis.

Flask-profiler version: 1.8 Flask-profiler measures endpoints defined in your flask application; and provides you fine-grained report through a web in

Mustafa Atik 718 Dec 20, 2022
Flask webassets integration.

Integrates the webassets library with Flask, adding support for merging, minifying and compiling CSS and Javascript files. Documentation: https://flas

Michael Elsdörfer 433 Dec 29, 2022
Mixer -- Is a fixtures replacement. Supported Django, Flask, SqlAlchemy and custom python objects.

The Mixer is a helper to generate instances of Django or SQLAlchemy models. It's useful for testing and fixture replacement. Fast and convenient test-

Kirill Klenov 870 Jan 08, 2023
Flask starter template for better structuring.

Flask Starter app Flask starter template for better structuring. use the starter plate step 1 : cloning this repo through git clone the repo git clone

Tirtharaj Sinha 1 Jul 26, 2022
PatientDB is a flask app to store patient information.

PatientDB PatientDB on Heroku "PatientDB is a simple web app that stores patient information, able to edit the information, and able to query the data

rbb 2 Jan 31, 2022
Flask-Bcrypt is a Flask extension that provides bcrypt hashing utilities for your application.

Flask-Bcrypt Flask-Bcrypt is a Flask extension that provides bcrypt hashing utilities for your application. Due to the recent increased prevelance of

Max Countryman 310 Dec 14, 2022
A flask template with Bootstrap 4, asset bundling+minification with webpack, starter templates, and registration/authentication.

cookiecutter-flask A Flask template for cookiecutter. (Supports Python ≥ 3.6) See this repo for an example project generated from the most recent vers

4.3k Jan 06, 2023
A web application that consists of a collection of board games

PyBoardGame About This website contains a collection of board games for users to enjoy, as well as various guides for the games. The web app is built

Larry Shi 0 Aug 11, 2021
Find and notify users in your Active Directory with weak passwords

Crack-O-Matic Find and notify users in your Active Directory with weak passwords. Features: Linux-based Flask-based web app Hashcat or John cracker Au

Adrian Vollmer 92 Dec 31, 2022
Flask Application Structure with MongoDB

This application aims to serve as a template for APIs that intend to use mongoengine and flask-restx

Tiago Franco 5 Jun 25, 2022
Forum written for learning purposes in flask and sqlalchemy

Flask-forum forum written for learning purposes using SQLalchemy and flask How to install install requirements pip install sqlalchemy flask clone repo

Kamil 0 May 23, 2022
A Python, Flask login system

Python Login System This is a basic login + authenticason system for flask using Flask_Login and Flask_SQLAlchemy Get started on your own To use this

MrShoe 0 Feb 02, 2022
Geometry Dash Song Bypass with Python Flask Server

Geometry Dash Song Bypass with Python Flask Server

pixelsuft‮ 1 Nov 16, 2021
SeCl - A really easy to deploy and use made-on Flask API to manage your files remotely from Terminal

SeCl SeCl it's a really easy to deploy and use made-on Flask API to manage your

ZSendokame 3 Jan 15, 2022
Library books management program, built with Flask, Python

Library books management program, With many features and good User Interface. built with Flask, Python. (Include Screenshots) and documentation on how to run it! Thank you :)

Thierry Mugisha 1 May 03, 2022
A web application made with Flask that works with a weather service API to get the current weather from all over the world.

Weather App A web application made with Flask that works with a weather service API to get the current weather from all over the world. Uses data from

Christian Jairo Sarmiento 19 Dec 02, 2022
An flask app for fake image detector

fake_img_detector This is a ml based project: frameworks used:- Flask Google collab #Description: Here you can Upload two different looking image with

shivam kumar 7 Jun 29, 2022
Full-Stack application that visualizes amusement park safety.

Amusement Park Ride Safety Analysis Project Proposal We have chosen to look into amusement park data to explore ride safety relationships visually, in

Michael Absher 0 Jul 11, 2021
Getting Started with Docker and Flask

Getting-Started-with-Docker-and-Flask Introduction Docker makes it easier, simpler and safer to build, deploy and manage applications in a docker cont

Phylis Jepchumba 1 Oct 08, 2021