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 文档中文翻译

Flask 中文文档 这里是 Flask 文档中文翻译项目,欢迎参与! 在开始翻译之前,请务必阅读下面的 Contributing Guide 了解贡献流程,然后阅读这个 Issue 了解翻译要求,在这个 Discussion 投票选出你认为合适的翻译词汇,在这个 Discussion 投票选出你喜

Grey Li 93 Nov 28, 2022
A simple FastAPI web service + Vue.js based UI over a rclip-style clip embedding database.

Explore CLIP Embeddings in a rclip database A simple FastAPI web service + Vue.js based UI over a rclip-style clip embedding database. A live demo of

18 Oct 15, 2022
Socket.IO integration for Flask applications.

Flask-SocketIO Socket.IO integration for Flask applications. Installation You can install this package as usual with pip: pip install flask-socketio

Miguel Grinberg 4.9k Jan 02, 2023
Regex Converter for Flask URL Routes

Flask-Reggie Enable Regex Routes within Flask Installation pip install flask-reggie Configuration To enable regex routes within your application from

Rhys Elsmore 48 Mar 07, 2022
A Fast API style support for Flask. Gives you MyPy types with the flexibility of flask

Flask-Fastx Flask-Fastx is a Fast API style support for Flask. It Gives you MyPy types with the flexibility of flask. Compatibility Flask-Fastx requir

Tactful.ai 18 Nov 26, 2022
Boilerplate code for basic flask web apps

Flask Boilerplate This repository contains boilerplate code to start a project instantly It's mainly for projects which you plan to ship in less than

Abhishek 6 Sep 27, 2021
OpenTracing instrumentation for the Flask microframework

Flask-OpenTracing This package enables distributed tracing in Flask applications via The OpenTracing Project. Once a production system contends with r

3rd-Party OpenTracing API Contributions 133 Dec 19, 2022
Boilerplate template formwork for a Python Flask application with Mysql,Build dynamic websites rapidly.

Overview English | 简体中文 How to Build dynamic web rapidly? We choose Formwork-Flask. Formwork is a highly packaged Flask Demo. It's intergrates various

aswallz 81 May 16, 2022
Flask pre-setup architecture. This can be used in any flask project for a faster and better project code structure.

Flask pre-setup architecture. This can be used in any flask project for a faster and better project code structure. All the required libraries are already installed easily to use in any big project.

Ajay kumar sharma 5 Jun 14, 2022
A template for Flask APIs.

FlaskAPITempate A template for a Flask API. Why tho? I just wanted an easy way to create a Flask API. How to setup First, use the template. You can do

TechStudent10 1 Dec 28, 2021
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
Map Matching & Weight Completion service - Java (Springboot) & Python(Flask)

Map Matching service to match coordinates to roads using Java and Springboot. Weight Completion service to fill in missing weights in a graph, using Python and Flask.

2 May 13, 2022
i18n and l10n support for Flask based on Babel and pytz

Flask Babel Implements i18n and l10n support for Flask. This is based on the Python babel module as well as pytz both of which are installed automatic

397 Dec 15, 2022
A template themes for phyton flask website

Flask Phyton Web template A template themes for phyton flask website

Mesin Kasir 2 Nov 29, 2021
Flask Multiple Database Login

Flask Multiple Database Login Handle login with flask using two diferent databases: UE | European; BR | Brazilian; These databases are separed to resp

Jose Pedro 1 Dec 16, 2021
É uma API feita em Python e Flask que pesquisa informações em uma tabela .xlsx e retorna o resultado.

API de rastreamento de pacotes É uma API feita em Python e Flask que pesquisa informações de rastreamento de pacotes em uma tabela .xlsx e retorna o r

Marcos Beraldo Barros 4 Jun 27, 2021
The Snoopy boilerplate in flask framework for development enterprise application.

Snoopy What is snoopy! The "Snoopy" boilerplate in flask framework for development enterprise application. Motivation In my 10 years of development ex

Bekhzod 2 Sep 29, 2022
Flask app + (html+css+ajax) contain ability add employee and place where employee work - plant or salon

#Manage your employees! With all employee information stored in one place, you no longer have to sift through hoards of spreadsheets to manually searc

Kateryna 1 Dec 22, 2021
A simple demo of using aiogram + async sqlalchemy 1.4+

aiogram-and-sqlalchemy-demo A simple demo of using aiogram + async sqlalchemy 1.4+ Used tech: aiogram SQLAlchemy 1.4+ PostgreSQL as database asyncpg a

Aleksandr 68 Dec 31, 2022
Open-source Flask Sample built on top of flask-dance library

Open-source Flask Sample built on top of flask-dance library. The project implements the social login for Github and Twitter - Originally coded by TestDriven.IO.

App Generator 4 Jul 26, 2022