Added virtual environment and directory structure
parent
249c5e9343
commit
7cb99cd04f
24
config.py
24
config.py
|
@ -1,6 +1,30 @@
|
|||
# App configuration
|
||||
DEBUG = False
|
||||
|
||||
# Define the application directory
|
||||
import os
|
||||
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
# Define the database - we are working with
|
||||
# SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(BASE_DIR, 'app.db')
|
||||
# DATABASE_CONNECT_OPTIONS = {}
|
||||
|
||||
# Application threads. A common general assumption is
|
||||
# using 2 per available processor cores - to handle
|
||||
# incoming requests using one and performing background
|
||||
# operations using the other.
|
||||
THREADS_PER_PAGE = 2
|
||||
|
||||
# Enable protection agains *Cross-site Request Forgery (CSRF)*
|
||||
CSRF_ENABLED = True
|
||||
|
||||
# Use a secure, unique and absolutely secret key for
|
||||
# signing the data.
|
||||
CSRF_SESSION_KEY = "secret"
|
||||
|
||||
# Secret key for signing cookies
|
||||
SECRET_KEY = "secret"
|
||||
|
||||
# MQTT configuration
|
||||
MQTT_BROKER_URL = 'mybroker.com'
|
||||
MQTT_BROKER_PORT = 1883
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/Python
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/include/python3.6m
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/__future__.py
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/_bootlocale.py
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/_collections_abc.py
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/_dummy_thread.py
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/_weakrefset.py
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/abc.py
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/base64.py
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/bisect.py
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/codecs.py
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/collections
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/config-3.6m-darwin
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/copy.py
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/copyreg.py
|
|
@ -0,0 +1,101 @@
|
|||
import os
|
||||
import sys
|
||||
import warnings
|
||||
import imp
|
||||
import opcode # opcode is not a virtualenv module, so we can use it to find the stdlib
|
||||
# Important! To work on pypy, this must be a module that resides in the
|
||||
# lib-python/modified-x.y.z directory
|
||||
|
||||
dirname = os.path.dirname
|
||||
|
||||
distutils_path = os.path.join(os.path.dirname(opcode.__file__), 'distutils')
|
||||
if os.path.normpath(distutils_path) == os.path.dirname(os.path.normpath(__file__)):
|
||||
warnings.warn(
|
||||
"The virtualenv distutils package at %s appears to be in the same location as the system distutils?")
|
||||
else:
|
||||
__path__.insert(0, distutils_path)
|
||||
real_distutils = imp.load_module("_virtualenv_distutils", None, distutils_path, ('', '', imp.PKG_DIRECTORY))
|
||||
# Copy the relevant attributes
|
||||
try:
|
||||
__revision__ = real_distutils.__revision__
|
||||
except AttributeError:
|
||||
pass
|
||||
__version__ = real_distutils.__version__
|
||||
|
||||
from distutils import dist, sysconfig
|
||||
|
||||
try:
|
||||
basestring
|
||||
except NameError:
|
||||
basestring = str
|
||||
|
||||
## patch build_ext (distutils doesn't know how to get the libs directory
|
||||
## path on windows - it hardcodes the paths around the patched sys.prefix)
|
||||
|
||||
if sys.platform == 'win32':
|
||||
from distutils.command.build_ext import build_ext as old_build_ext
|
||||
class build_ext(old_build_ext):
|
||||
def finalize_options (self):
|
||||
if self.library_dirs is None:
|
||||
self.library_dirs = []
|
||||
elif isinstance(self.library_dirs, basestring):
|
||||
self.library_dirs = self.library_dirs.split(os.pathsep)
|
||||
|
||||
self.library_dirs.insert(0, os.path.join(sys.real_prefix, "Libs"))
|
||||
old_build_ext.finalize_options(self)
|
||||
|
||||
from distutils.command import build_ext as build_ext_module
|
||||
build_ext_module.build_ext = build_ext
|
||||
|
||||
## distutils.dist patches:
|
||||
|
||||
old_find_config_files = dist.Distribution.find_config_files
|
||||
def find_config_files(self):
|
||||
found = old_find_config_files(self)
|
||||
system_distutils = os.path.join(distutils_path, 'distutils.cfg')
|
||||
#if os.path.exists(system_distutils):
|
||||
# found.insert(0, system_distutils)
|
||||
# What to call the per-user config file
|
||||
if os.name == 'posix':
|
||||
user_filename = ".pydistutils.cfg"
|
||||
else:
|
||||
user_filename = "pydistutils.cfg"
|
||||
user_filename = os.path.join(sys.prefix, user_filename)
|
||||
if os.path.isfile(user_filename):
|
||||
for item in list(found):
|
||||
if item.endswith('pydistutils.cfg'):
|
||||
found.remove(item)
|
||||
found.append(user_filename)
|
||||
return found
|
||||
dist.Distribution.find_config_files = find_config_files
|
||||
|
||||
## distutils.sysconfig patches:
|
||||
|
||||
old_get_python_inc = sysconfig.get_python_inc
|
||||
def sysconfig_get_python_inc(plat_specific=0, prefix=None):
|
||||
if prefix is None:
|
||||
prefix = sys.real_prefix
|
||||
return old_get_python_inc(plat_specific, prefix)
|
||||
sysconfig_get_python_inc.__doc__ = old_get_python_inc.__doc__
|
||||
sysconfig.get_python_inc = sysconfig_get_python_inc
|
||||
|
||||
old_get_python_lib = sysconfig.get_python_lib
|
||||
def sysconfig_get_python_lib(plat_specific=0, standard_lib=0, prefix=None):
|
||||
if standard_lib and prefix is None:
|
||||
prefix = sys.real_prefix
|
||||
return old_get_python_lib(plat_specific, standard_lib, prefix)
|
||||
sysconfig_get_python_lib.__doc__ = old_get_python_lib.__doc__
|
||||
sysconfig.get_python_lib = sysconfig_get_python_lib
|
||||
|
||||
old_get_config_vars = sysconfig.get_config_vars
|
||||
def sysconfig_get_config_vars(*args):
|
||||
real_vars = old_get_config_vars(*args)
|
||||
if sys.platform == 'win32':
|
||||
lib_dir = os.path.join(sys.real_prefix, "libs")
|
||||
if isinstance(real_vars, dict) and 'LIBDIR' not in real_vars:
|
||||
real_vars['LIBDIR'] = lib_dir # asked for all
|
||||
elif isinstance(real_vars, list) and 'LIBDIR' in args:
|
||||
real_vars = real_vars + [lib_dir] # asked for list
|
||||
return real_vars
|
||||
sysconfig_get_config_vars.__doc__ = old_get_config_vars.__doc__
|
||||
sysconfig.get_config_vars = sysconfig_get_config_vars
|
|
@ -0,0 +1,6 @@
|
|||
# This is a config file local to this virtualenv installation
|
||||
# You may include options that will be used by all distutils commands,
|
||||
# and by easy_install. For instance:
|
||||
#
|
||||
# [easy_install]
|
||||
# find_links = http://mylocalsite
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/encodings
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/enum.py
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/fnmatch.py
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/functools.py
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/genericpath.py
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/hashlib.py
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/heapq.py
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/hmac.py
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/imp.py
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/importlib
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/io.py
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/keyword.py
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/lib-dynload
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/linecache.py
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/locale.py
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ntpath.py
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/operator.py
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/os.py
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/posixpath.py
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/random.py
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/re.py
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/reprlib.py
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/rlcompleter.py
|
|
@ -0,0 +1 @@
|
|||
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/shutil.py
|
|
@ -0,0 +1,46 @@
|
|||
Flask
|
||||
-----
|
||||
|
||||
Flask is a microframework for Python based on Werkzeug, Jinja 2 and good
|
||||
intentions. And before you ask: It's BSD licensed!
|
||||
|
||||
Flask is Fun
|
||||
````````````
|
||||
|
||||
Save in a hello.py:
|
||||
|
||||
.. code:: python
|
||||
|
||||
from flask import Flask
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route("/")
|
||||
def hello():
|
||||
return "Hello World!"
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run()
|
||||
|
||||
And Easy to Setup
|
||||
`````````````````
|
||||
|
||||
And run it:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
$ pip install Flask
|
||||
$ python hello.py
|
||||
* Running on http://localhost:5000/
|
||||
|
||||
Ready for production? `Read this first <http://flask.pocoo.org/docs/deploying/>`.
|
||||
|
||||
Links
|
||||
`````
|
||||
|
||||
* `website <http://flask.pocoo.org/>`_
|
||||
* `documentation <http://flask.pocoo.org/docs/>`_
|
||||
* `development version
|
||||
<http://github.com/pallets/flask/zipball/master#egg=Flask-dev>`_
|
||||
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
pip
|
|
@ -0,0 +1,33 @@
|
|||
Copyright (c) 2015 by Armin Ronacher and contributors. See AUTHORS
|
||||
for more details.
|
||||
|
||||
Some rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms of the software as well
|
||||
as documentation, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
|
||||
* The names of the contributors may not be used to endorse or
|
||||
promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
|
||||
NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE AND DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGE.
|
|
@ -0,0 +1,75 @@
|
|||
Metadata-Version: 2.0
|
||||
Name: Flask
|
||||
Version: 0.12.2
|
||||
Summary: A microframework based on Werkzeug, Jinja2 and good intentions
|
||||
Home-page: http://github.com/pallets/flask/
|
||||
Author: Armin Ronacher
|
||||
Author-email: armin.ronacher@active-4.com
|
||||
License: BSD
|
||||
Platform: any
|
||||
Classifier: Development Status :: 4 - Beta
|
||||
Classifier: Environment :: Web Environment
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: License :: OSI Approved :: BSD License
|
||||
Classifier: Operating System :: OS Independent
|
||||
Classifier: Programming Language :: Python
|
||||
Classifier: Programming Language :: Python :: 2
|
||||
Classifier: Programming Language :: Python :: 2.6
|
||||
Classifier: Programming Language :: Python :: 2.7
|
||||
Classifier: Programming Language :: Python :: 3
|
||||
Classifier: Programming Language :: Python :: 3.3
|
||||
Classifier: Programming Language :: Python :: 3.4
|
||||
Classifier: Programming Language :: Python :: 3.5
|
||||
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
||||
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
||||
Requires-Dist: Jinja2 (>=2.4)
|
||||
Requires-Dist: Werkzeug (>=0.7)
|
||||
Requires-Dist: click (>=2.0)
|
||||
Requires-Dist: itsdangerous (>=0.21)
|
||||
|
||||
Flask
|
||||
-----
|
||||
|
||||
Flask is a microframework for Python based on Werkzeug, Jinja 2 and good
|
||||
intentions. And before you ask: It's BSD licensed!
|
||||
|
||||
Flask is Fun
|
||||
````````````
|
||||
|
||||
Save in a hello.py:
|
||||
|
||||
.. code:: python
|
||||
|
||||
from flask import Flask
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route("/")
|
||||
def hello():
|
||||
return "Hello World!"
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run()
|
||||
|
||||
And Easy to Setup
|
||||
`````````````````
|
||||
|
||||
And run it:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
$ pip install Flask
|
||||
$ python hello.py
|
||||
* Running on http://localhost:5000/
|
||||
|
||||
Ready for production? `Read this first <http://flask.pocoo.org/docs/deploying/>`.
|
||||
|
||||
Links
|
||||
`````
|
||||
|
||||
* `website <http://flask.pocoo.org/>`_
|
||||
* `documentation <http://flask.pocoo.org/docs/>`_
|
||||
* `development version
|
||||
<http://github.com/pallets/flask/zipball/master#egg=Flask-dev>`_
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
Flask-0.12.2.dist-info/DESCRIPTION.rst,sha256=DmJm8IBlBjl3wkm0Ly23jYvWbvK_mCuE5oUseYCijbI,810
|
||||
Flask-0.12.2.dist-info/LICENSE.txt,sha256=hLgKluMRHSnxG-L0EmrqjmKgG5cHlff6pIh3rCNINeI,1582
|
||||
Flask-0.12.2.dist-info/METADATA,sha256=OgSkJQ_kmrz4qEkS-OzYtL75uZmXAThymkOcGR4kXRQ,1948
|
||||
Flask-0.12.2.dist-info/RECORD,,
|
||||
Flask-0.12.2.dist-info/WHEEL,sha256=o2k-Qa-RMNIJmUdIc7KU6VWR_ErNRbWNlxDIpl7lm34,110
|
||||
Flask-0.12.2.dist-info/entry_points.txt,sha256=jzk2Wy2h30uEcqqzd4CVnlzsMXB-vaD5GXjuPMXmTmI,60
|
||||
Flask-0.12.2.dist-info/metadata.json,sha256=By8kZ1vY9lLEAGnRiWNBhudqKvLPo0HkZVXTYECyPKk,1389
|
||||
Flask-0.12.2.dist-info/top_level.txt,sha256=dvi65F6AeGWVU0TBpYiC04yM60-FX1gJFkK31IKQr5c,6
|
||||
flask/__init__.py,sha256=sHdK1v6WRbVmCN0fEv990EE7rOT2UlamQkSof2d0Dt0,1673
|
||||
flask/__main__.py,sha256=cldbNi5zpjE68XzIWI8uYHNWwBHHVJmwtlXWk6P4CO4,291
|
||||
flask/_compat.py,sha256=VlfjUuLjufsTHJIjr_ZsnnOesSbAXIslBBgRe5tfOok,2802
|
||||
flask/app.py,sha256=6DPjtb5jUJWgL5fXksG5boA49EB3l-k9pWyftitbNNk,83169
|
||||
flask/blueprints.py,sha256=6HVasMcPcaq7tk36kCrgX4bnhTkky4G5WIWCyyJL8HY,16872
|
||||
flask/cli.py,sha256=2NXEdCOu5-4ymklxX4Lf6bjb-89I4VHYeP6xScR3i8E,18328
|
||||
flask/config.py,sha256=Ym5Jenyu6zAZ1fdVLeKekY9-EsKmq8183qnRgauwCMY,9905
|
||||
flask/ctx.py,sha256=UPA0YwoIlHP0txOGanC9lQLSGv6eCqV5Fmw2cVJRmgQ,14739
|
||||
flask/debughelpers.py,sha256=z-uQavKIymOZl0WQDLXsnacA00ERIlCx3S3Tnb_OYsE,6024
|
||||
flask/exthook.py,sha256=SvXs5jwpcOjogwJ7SNquiWTxowoN1-MHFoqAejWnk2o,5762
|
||||
flask/globals.py,sha256=I3m_4RssLhWW1R11zuEI8oFryHUHX3NQwjMkGXOZzg8,1645
|
||||
flask/helpers.py,sha256=KrsQ2Yo3lOVHvBTgQCLvpubgmTOpQdTTyiCOOYlwDuQ,38452
|
||||
flask/json.py,sha256=1zPM-NPLiWoOfGd0P14FxnEkeKtjtUZxMC9pyYyDBYI,9183
|
||||
flask/logging.py,sha256=UG-77jPkRClk9w1B-_ArjjXPuj9AmZz9mG0IRGvptW0,2751
|
||||
flask/sessions.py,sha256=QBKXVYKJ-HKbx9m6Yb5yan_EPq84a5yevVLgAzNKFQY,14394
|
||||
flask/signals.py,sha256=MfZk5qTRj_R_O3aGYlTEnx2g3SvlZncz8Ii73eKK59g,2209
|
||||
flask/templating.py,sha256=u7FbN6j56H_q6CrdJJyJ6gZtqaMa0vh1_GP12gEHRQQ,4912
|
||||
flask/testing.py,sha256=II8EO_NjOT1LvL8Hh_SdIFL_BdlwVPcB9yot5pbltxE,5630
|
||||
flask/views.py,sha256=6OPv7gwu3h14JhqpeeMRWwrxoGHsUr4_nOGSyTRAxAI,5630
|
||||
flask/wrappers.py,sha256=1S_5mmuA1Tlx7D9lXV6xMblrg-PdAauNWahe-henMEE,7612
|
||||
flask/ext/__init__.py,sha256=UEezCApsG4ZJWqwUnX9YmWcNN4OVENgph_9L05n0eOM,842
|
||||
../../../bin/flask,sha256=1ow220Ff1jdiAk6Kq--IP8c1BYJdNqtYXFLTS5ul3yA,266
|
||||
Flask-0.12.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||
flask/ext/__pycache__/__init__.cpython-36.pyc,,
|
||||
flask/__pycache__/blueprints.cpython-36.pyc,,
|
||||
flask/__pycache__/logging.cpython-36.pyc,,
|
||||
flask/__pycache__/sessions.cpython-36.pyc,,
|
||||
flask/__pycache__/templating.cpython-36.pyc,,
|
||||
flask/__pycache__/cli.cpython-36.pyc,,
|
||||
flask/__pycache__/config.cpython-36.pyc,,
|
||||
flask/__pycache__/signals.cpython-36.pyc,,
|
||||
flask/__pycache__/testing.cpython-36.pyc,,
|
||||
flask/__pycache__/views.cpython-36.pyc,,
|
||||
flask/__pycache__/ctx.cpython-36.pyc,,
|
||||
flask/__pycache__/app.cpython-36.pyc,,
|
||||
flask/__pycache__/exthook.cpython-36.pyc,,
|
||||
flask/__pycache__/__main__.cpython-36.pyc,,
|
||||
flask/__pycache__/_compat.cpython-36.pyc,,
|
||||
flask/__pycache__/helpers.cpython-36.pyc,,
|
||||
flask/__pycache__/wrappers.cpython-36.pyc,,
|
||||
flask/__pycache__/__init__.cpython-36.pyc,,
|
||||
flask/__pycache__/debughelpers.cpython-36.pyc,,
|
||||
flask/__pycache__/globals.cpython-36.pyc,,
|
||||
flask/__pycache__/json.cpython-36.pyc,,
|
|
@ -0,0 +1,6 @@
|
|||
Wheel-Version: 1.0
|
||||
Generator: bdist_wheel (0.29.0)
|
||||
Root-Is-Purelib: true
|
||||
Tag: py2-none-any
|
||||
Tag: py3-none-any
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
|
||||
[console_scripts]
|
||||
flask=flask.cli:main
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"classifiers": ["Development Status :: 4 - Beta", "Environment :: Web Environment", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Topic :: Internet :: WWW/HTTP :: Dynamic Content", "Topic :: Software Development :: Libraries :: Python Modules"], "extensions": {"python.commands": {"wrap_console": {"flask": "flask.cli:main"}}, "python.details": {"contacts": [{"email": "armin.ronacher@active-4.com", "name": "Armin Ronacher", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst", "license": "LICENSE.txt"}, "project_urls": {"Home": "http://github.com/pallets/flask/"}}, "python.exports": {"console_scripts": {"flask": "flask.cli:main"}}}, "extras": [], "generator": "bdist_wheel (0.29.0)", "license": "BSD", "metadata_version": "2.0", "name": "Flask", "platform": "any", "run_requires": [{"requires": ["Jinja2 (>=2.4)", "Werkzeug (>=0.7)", "click (>=2.0)", "itsdangerous (>=0.21)"]}], "summary": "A microframework based on Werkzeug, Jinja2 and good intentions", "version": "0.12.2"}
|
|
@ -0,0 +1 @@
|
|||
flask
|
|
@ -0,0 +1,173 @@
|
|||
# Flask-MQTT
|
||||
|
||||
Flask Extension for the [MQTT protocol][1]. Basically it is a thin wrapper
|
||||
around [paho-mqtt][0] and aimes to simplify MQTT integration in Flask. MQTT is a
|
||||
machine-to-machine "Internet of Things" protocol and was designed for extremely
|
||||
lightweight publish/subscribe messaging transport.
|
||||
|
||||
[![Documentation Status](https://readthedocs.org/projects/flask-mqtt/badge/?version=latest)](http://flask-mqtt.readthedocs.io/en/latest/?badge=latest) [![PyPI version](https://badge.fury.io/py/Flask-MQTT.svg)](https://badge.fury.io/py/Flask-MQTT) [![Travis CI](https://travis-ci.org/stlehmann/Flask-MQTT.svg?branch=master)](https://travis-ci.org/stlehmann/Flask-MQTT.svg?branch=master)
|
||||
|
||||
Find the documentation on [http://flask-mqtt.readthedocs.io][2].
|
||||
|
||||
## Features
|
||||
|
||||
* configuration via Flask config variables
|
||||
* auto-connect on start of your web application
|
||||
* publish and subscribe messages
|
||||
* use callbacks for certain topics
|
||||
* use one callback for all subscribed topics
|
||||
|
||||
## Installation
|
||||
|
||||
Simply install the package as usual via pip:
|
||||
|
||||
```bash
|
||||
$ pip install flask-mqtt
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic Setup
|
||||
|
||||
```python
|
||||
from flask import Flask
|
||||
from flask_mqtt import Mqtt
|
||||
|
||||
app = Flask(__name__)
|
||||
app.config['MQTT_BROKER_URL'] = 'mybroker.com'
|
||||
app.config['MQTT_BROKER_PORT'] = 1883
|
||||
app.config['MQTT_USERNAME'] = 'user'
|
||||
app.config['MQTT_PASSWORD'] = 'secret'
|
||||
app.config['MQTT_REFRESH_TIME'] = 1.0 # refresh time in seconds
|
||||
mqtt = Mqtt(app)
|
||||
|
||||
@app.route('/')
|
||||
def index():
|
||||
return render_template('index.html')
|
||||
|
||||
```
|
||||
|
||||
### Subscribe to a topic
|
||||
|
||||
To subscribe to a topic simply use `mqtt.subscribe()`. To make sure the
|
||||
subscription gets handled correctly on startup place the subscription inside
|
||||
an `on_connect()` callback function.
|
||||
|
||||
```python
|
||||
@mqtt.on_connect()
|
||||
def handle_connect(client, userdata, flags, rc):
|
||||
mqtt.subscribe('home/mytopic')
|
||||
```
|
||||
|
||||
To handle the subscribed messages you can define a handling function by
|
||||
decorating it with `@mqtt.on_message()`.
|
||||
|
||||
```python
|
||||
@mqtt.on_message()
|
||||
def handle_mqtt_message(client, userdata, message):
|
||||
data = dict(
|
||||
topic=message.topic,
|
||||
payload=message.payload.decode()
|
||||
)
|
||||
```
|
||||
|
||||
To unsubscribe do:
|
||||
|
||||
```python
|
||||
mqtt.unsubscribe('home/mytopic')
|
||||
```
|
||||
|
||||
Or if you want to unsubscribe all topics use `unsubscribe_all()`.
|
||||
|
||||
```python
|
||||
mqtt.unsubscribe_all()
|
||||
```
|
||||
|
||||
### Publish
|
||||
|
||||
To publish a message you can use the `publish()` method.
|
||||
|
||||
```python
|
||||
mqtt.publish('home/mytopic', 'this is my message')
|
||||
```
|
||||
|
||||
### Small publish/subscribe MQTT client
|
||||
|
||||
```python
|
||||
"""
|
||||
|
||||
A small Test application to show how to use Flask-MQTT.
|
||||
|
||||
"""
|
||||
|
||||
import eventlet
|
||||
import json
|
||||
from flask import Flask, render_template
|
||||
from flask_mqtt import Mqtt
|
||||
from flask_socketio import SocketIO
|
||||
from flask_bootstrap import Bootstrap
|
||||
|
||||
eventlet.monkey_patch()
|
||||
|
||||
app = Flask(__name__)
|
||||
app.config['SECRET'] = 'my secret key'
|
||||
app.config['TEMPLATES_AUTO_RELOAD'] = True
|
||||
app.config['MQTT_BROKER_URL'] = 'broker.hivemq.com'
|
||||
app.config['MQTT_BROKER_PORT'] = 1883
|
||||
app.config['MQTT_USERNAME'] = ''
|
||||
app.config['MQTT_PASSWORD'] = ''
|
||||
app.config['MQTT_KEEPALIVE'] = 5
|
||||
app.config['MQTT_TLS_ENABLED'] = False
|
||||
|
||||
# Parameters for SSL enabled
|
||||
# app.config['MQTT_BROKER_PORT'] = 8883
|
||||
# app.config['MQTT_TLS_ENABLED'] = True
|
||||
# app.config['MQTT_TLS_INSECURE'] = True
|
||||
# app.config['MQTT_TLS_CA_CERTS'] = 'ca.crt'
|
||||
|
||||
mqtt = Mqtt(app)
|
||||
socketio = SocketIO(app)
|
||||
bootstrap = Bootstrap(app)
|
||||
|
||||
|
||||
@app.route('/')
|
||||
def index():
|
||||
return render_template('index.html')
|
||||
|
||||
|
||||
@socketio.on('publish')
|
||||
def handle_publish(json_str):
|
||||
data = json.loads(json_str)
|
||||
mqtt.publish(data['topic'], data['message'])
|
||||
|
||||
|
||||
@socketio.on('subscribe')
|
||||
def handle_subscribe(json_str):
|
||||
data = json.loads(json_str)
|
||||
mqtt.subscribe(data['topic'])
|
||||
|
||||
|
||||
@mqtt.on_message()
|
||||
def handle_mqtt_message(client, userdata, message):
|
||||
data = dict(
|
||||
topic=message.topic,
|
||||
payload=message.payload.decode()
|
||||
)
|
||||
socketio.emit('mqtt_message', data=data)
|
||||
|
||||
|
||||
@mqtt.on_log()
|
||||
def handle_logging(client, userdata, level, buf):
|
||||
print(level, buf)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
socketio.run(app, host='0.0.0.0', port=5000, use_reloader=True, debug=True)
|
||||
|
||||
```
|
||||
|
||||
[0]: https://github.com/eclipse/paho.mqtt.python
|
||||
[1]: http://mqtt.org/
|
||||
[2]: http://flask-mqtt.readthedocs.io/en/latest/
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
pip
|
|
@ -0,0 +1,194 @@
|
|||
Metadata-Version: 2.0
|
||||
Name: Flask-MQTT
|
||||
Version: 1.0.3
|
||||
Summary: Flask extension for the MQTT protocol
|
||||
Home-page: https://github.com/MrLeeh/Flask-MQTT
|
||||
Author: Stefan Lehmann
|
||||
Author-email: stefan.st.lehmann@gmail.com
|
||||
License: MIT
|
||||
Platform: any
|
||||
Classifier: Development Status :: 5 - Production/Stable
|
||||
Classifier: Environment :: Web Environment
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: License :: OSI Approved :: MIT License
|
||||
Classifier: Programming Language :: Python
|
||||
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
||||
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
||||
Description-Content-Type: text/markdown
|
||||
Requires-Dist: Flask
|
||||
Requires-Dist: typing
|
||||
Requires-Dist: paho-mqtt
|
||||
|
||||
# Flask-MQTT
|
||||
|
||||
Flask Extension for the [MQTT protocol][1]. Basically it is a thin wrapper
|
||||
around [paho-mqtt][0] and aimes to simplify MQTT integration in Flask. MQTT is a
|
||||
machine-to-machine "Internet of Things" protocol and was designed for extremely
|
||||
lightweight publish/subscribe messaging transport.
|
||||
|
||||
[![Documentation Status](https://readthedocs.org/projects/flask-mqtt/badge/?version=latest)](http://flask-mqtt.readthedocs.io/en/latest/?badge=latest) [![PyPI version](https://badge.fury.io/py/Flask-MQTT.svg)](https://badge.fury.io/py/Flask-MQTT) [![Travis CI](https://travis-ci.org/stlehmann/Flask-MQTT.svg?branch=master)](https://travis-ci.org/stlehmann/Flask-MQTT.svg?branch=master)
|
||||
|
||||
Find the documentation on [http://flask-mqtt.readthedocs.io][2].
|
||||
|
||||
## Features
|
||||
|
||||
* configuration via Flask config variables
|
||||
* auto-connect on start of your web application
|
||||
* publish and subscribe messages
|
||||
* use callbacks for certain topics
|
||||
* use one callback for all subscribed topics
|
||||
|
||||
## Installation
|
||||
|
||||
Simply install the package as usual via pip:
|
||||
|
||||
```bash
|
||||
$ pip install flask-mqtt
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic Setup
|
||||
|
||||
```python
|
||||
from flask import Flask
|
||||
from flask_mqtt import Mqtt
|
||||
|
||||
app = Flask(__name__)
|
||||
app.config['MQTT_BROKER_URL'] = 'mybroker.com'
|
||||
app.config['MQTT_BROKER_PORT'] = 1883
|
||||
app.config['MQTT_USERNAME'] = 'user'
|
||||
app.config['MQTT_PASSWORD'] = 'secret'
|
||||
app.config['MQTT_REFRESH_TIME'] = 1.0 # refresh time in seconds
|
||||
mqtt = Mqtt(app)
|
||||
|
||||
@app.route('/')
|
||||
def index():
|
||||
return render_template('index.html')
|
||||
|
||||
```
|
||||
|
||||
### Subscribe to a topic
|
||||
|
||||
To subscribe to a topic simply use `mqtt.subscribe()`. To make sure the
|
||||
subscription gets handled correctly on startup place the subscription inside
|
||||
an `on_connect()` callback function.
|
||||
|
||||
```python
|
||||
@mqtt.on_connect()
|
||||
def handle_connect(client, userdata, flags, rc):
|
||||
mqtt.subscribe('home/mytopic')
|
||||
```
|
||||
|
||||
To handle the subscribed messages you can define a handling function by
|
||||
decorating it with `@mqtt.on_message()`.
|
||||
|
||||
```python
|
||||
@mqtt.on_message()
|
||||
def handle_mqtt_message(client, userdata, message):
|
||||
data = dict(
|
||||
topic=message.topic,
|
||||
payload=message.payload.decode()
|
||||
)
|
||||
```
|
||||
|
||||
To unsubscribe do:
|
||||
|
||||
```python
|
||||
mqtt.unsubscribe('home/mytopic')
|
||||
```
|
||||
|
||||
Or if you want to unsubscribe all topics use `unsubscribe_all()`.
|
||||
|
||||
```python
|
||||
mqtt.unsubscribe_all()
|
||||
```
|
||||
|
||||
### Publish
|
||||
|
||||
To publish a message you can use the `publish()` method.
|
||||
|
||||
```python
|
||||
mqtt.publish('home/mytopic', 'this is my message')
|
||||
```
|
||||
|
||||
### Small publish/subscribe MQTT client
|
||||
|
||||
```python
|
||||
"""
|
||||
|
||||
A small Test application to show how to use Flask-MQTT.
|
||||
|
||||
"""
|
||||
|
||||
import eventlet
|
||||
import json
|
||||
from flask import Flask, render_template
|
||||
from flask_mqtt import Mqtt
|
||||
from flask_socketio import SocketIO
|
||||
from flask_bootstrap import Bootstrap
|
||||
|
||||
eventlet.monkey_patch()
|
||||
|
||||
app = Flask(__name__)
|
||||
app.config['SECRET'] = 'my secret key'
|
||||
app.config['TEMPLATES_AUTO_RELOAD'] = True
|
||||
app.config['MQTT_BROKER_URL'] = 'broker.hivemq.com'
|
||||
app.config['MQTT_BROKER_PORT'] = 1883
|
||||
app.config['MQTT_USERNAME'] = ''
|
||||
app.config['MQTT_PASSWORD'] = ''
|
||||
app.config['MQTT_KEEPALIVE'] = 5
|
||||
app.config['MQTT_TLS_ENABLED'] = False
|
||||
|
||||
# Parameters for SSL enabled
|
||||
# app.config['MQTT_BROKER_PORT'] = 8883
|
||||
# app.config['MQTT_TLS_ENABLED'] = True
|
||||
# app.config['MQTT_TLS_INSECURE'] = True
|
||||
# app.config['MQTT_TLS_CA_CERTS'] = 'ca.crt'
|
||||
|
||||
mqtt = Mqtt(app)
|
||||
socketio = SocketIO(app)
|
||||
bootstrap = Bootstrap(app)
|
||||
|
||||
|
||||
@app.route('/')
|
||||
def index():
|
||||
return render_template('index.html')
|
||||
|
||||
|
||||
@socketio.on('publish')
|
||||
def handle_publish(json_str):
|
||||
data = json.loads(json_str)
|
||||
mqtt.publish(data['topic'], data['message'])
|
||||
|
||||
|
||||
@socketio.on('subscribe')
|
||||
def handle_subscribe(json_str):
|
||||
data = json.loads(json_str)
|
||||
mqtt.subscribe(data['topic'])
|
||||
|
||||
|
||||
@mqtt.on_message()
|
||||
def handle_mqtt_message(client, userdata, message):
|
||||
data = dict(
|
||||
topic=message.topic,
|
||||
payload=message.payload.decode()
|
||||
)
|
||||
socketio.emit('mqtt_message', data=data)
|
||||
|
||||
|
||||
@mqtt.on_log()
|
||||
def handle_logging(client, userdata, level, buf):
|
||||
print(level, buf)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
socketio.run(app, host='0.0.0.0', port=5000, use_reloader=True, debug=True)
|
||||
|
||||
```
|
||||
|
||||
[0]: https://github.com/eclipse/paho.mqtt.python
|
||||
[1]: http://mqtt.org/
|
||||
[2]: http://flask-mqtt.readthedocs.io/en/latest/
|
||||
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
Flask_MQTT-1.0.3.dist-info/DESCRIPTION.rst,sha256=scdzeVK9SyGF_ZYEjSy07Lvbkx3VKOH5KwRt8oNRx7s,4225
|
||||
Flask_MQTT-1.0.3.dist-info/METADATA,sha256=Sz1g2z9KQFIaAlv4kh2ga0sCeX2GbQb2PAnlyYcKt94,4946
|
||||
Flask_MQTT-1.0.3.dist-info/RECORD,,
|
||||
Flask_MQTT-1.0.3.dist-info/WHEEL,sha256=0mO7-aKM6K9CHeURc5NDYZyLWH5lmR-r4TtPinHxz7Y,93
|
||||
Flask_MQTT-1.0.3.dist-info/metadata.json,sha256=8k4mdFdGj0w-NXl0Q3hK4CX4B0fiqDu-GzTakg9HlQc,901
|
||||
Flask_MQTT-1.0.3.dist-info/top_level.txt,sha256=rDSXoP_WPnaqCmGIyZOn1ieidQ63URSSX4KvlN3HzL8,11
|
||||
flask_mqtt/__init__.py,sha256=SAbjc3stsoQIxpD8IfS__mqSNxgZNhtBo2W4Xn7A2Bg,13391
|
||||
Flask_MQTT-1.0.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||
flask_mqtt/__pycache__/__init__.cpython-36.pyc,,
|
|
@ -0,0 +1,5 @@
|
|||
Wheel-Version: 1.0
|
||||
Generator: bdist_wheel (0.30.0)
|
||||
Root-Is-Purelib: true
|
||||
Tag: cp36-none-any
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"classifiers": ["Development Status :: 5 - Production/Stable", "Environment :: Web Environment", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python", "Topic :: Internet :: WWW/HTTP :: Dynamic Content", "Topic :: Software Development :: Libraries :: Python Modules"], "description_content_type": "text/markdown", "extensions": {"python.details": {"contacts": [{"email": "stefan.st.lehmann@gmail.com", "name": "Stefan Lehmann", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}, "project_urls": {"Home": "https://github.com/MrLeeh/Flask-MQTT"}}}, "extras": [], "generator": "bdist_wheel (0.30.0)", "license": "MIT", "metadata_version": "2.0", "name": "Flask-MQTT", "platform": "any", "run_requires": [{"requires": ["Flask", "paho-mqtt", "typing"]}], "summary": "Flask extension for the MQTT protocol", "version": "1.0.3"}
|
|
@ -0,0 +1 @@
|
|||
flask_mqtt
|
|
@ -0,0 +1,37 @@
|
|||
|
||||
Jinja2
|
||||
~~~~~~
|
||||
|
||||
Jinja2 is a template engine written in pure Python. It provides a
|
||||
`Django`_ inspired non-XML syntax but supports inline expressions and
|
||||
an optional `sandboxed`_ environment.
|
||||
|
||||
Nutshell
|
||||
--------
|
||||
|
||||
Here a small example of a Jinja template::
|
||||
|
||||
{% extends 'base.html' %}
|
||||
{% block title %}Memberlist{% endblock %}
|
||||
{% block content %}
|
||||
<ul>
|
||||
{% for user in users %}
|
||||
<li><a href="{{ user.url }}">{{ user.username }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endblock %}
|
||||
|
||||
Philosophy
|
||||
----------
|
||||
|
||||
Application logic is for the controller but don't try to make the life
|
||||
for the template designer too hard by giving him too few functionality.
|
||||
|
||||
For more informations visit the new `Jinja2 webpage`_ and `documentation`_.
|
||||
|
||||
.. _sandboxed: https://en.wikipedia.org/wiki/Sandbox_(computer_security)
|
||||
.. _Django: https://www.djangoproject.com/
|
||||
.. _Jinja2 webpage: http://jinja.pocoo.org/
|
||||
.. _documentation: http://jinja.pocoo.org/2/documentation/
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
pip
|
|
@ -0,0 +1,31 @@
|
|||
Copyright (c) 2009 by the Jinja Team, see AUTHORS for more details.
|
||||
|
||||
Some rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
|
||||
* The names of the contributors may not be used to endorse or
|
||||
promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -0,0 +1,68 @@
|
|||
Metadata-Version: 2.0
|
||||
Name: Jinja2
|
||||
Version: 2.10
|
||||
Summary: A small but fast and easy to use stand-alone template engine written in pure python.
|
||||
Home-page: http://jinja.pocoo.org/
|
||||
Author: Armin Ronacher
|
||||
Author-email: armin.ronacher@active-4.com
|
||||
License: BSD
|
||||
Description-Content-Type: UNKNOWN
|
||||
Platform: UNKNOWN
|
||||
Classifier: Development Status :: 5 - Production/Stable
|
||||
Classifier: Environment :: Web Environment
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: License :: OSI Approved :: BSD License
|
||||
Classifier: Operating System :: OS Independent
|
||||
Classifier: Programming Language :: Python
|
||||
Classifier: Programming Language :: Python :: 2
|
||||
Classifier: Programming Language :: Python :: 2.6
|
||||
Classifier: Programming Language :: Python :: 2.7
|
||||
Classifier: Programming Language :: Python :: 3
|
||||
Classifier: Programming Language :: Python :: 3.3
|
||||
Classifier: Programming Language :: Python :: 3.4
|
||||
Classifier: Programming Language :: Python :: 3.5
|
||||
Classifier: Programming Language :: Python :: 3.6
|
||||
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
||||
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
||||
Classifier: Topic :: Text Processing :: Markup :: HTML
|
||||
Requires-Dist: MarkupSafe (>=0.23)
|
||||
Provides-Extra: i18n
|
||||
Requires-Dist: Babel (>=0.8); extra == 'i18n'
|
||||
|
||||
|
||||
Jinja2
|
||||
~~~~~~
|
||||
|
||||
Jinja2 is a template engine written in pure Python. It provides a
|
||||
`Django`_ inspired non-XML syntax but supports inline expressions and
|
||||
an optional `sandboxed`_ environment.
|
||||
|
||||
Nutshell
|
||||
--------
|
||||
|
||||
Here a small example of a Jinja template::
|
||||
|
||||
{% extends 'base.html' %}
|
||||
{% block title %}Memberlist{% endblock %}
|
||||
{% block content %}
|
||||
<ul>
|
||||
{% for user in users %}
|
||||
<li><a href="{{ user.url }}">{{ user.username }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endblock %}
|
||||
|
||||
Philosophy
|
||||
----------
|
||||
|
||||
Application logic is for the controller but don't try to make the life
|
||||
for the template designer too hard by giving him too few functionality.
|
||||
|
||||
For more informations visit the new `Jinja2 webpage`_ and `documentation`_.
|
||||
|
||||
.. _sandboxed: https://en.wikipedia.org/wiki/Sandbox_(computer_security)
|
||||
.. _Django: https://www.djangoproject.com/
|
||||
.. _Jinja2 webpage: http://jinja.pocoo.org/
|
||||
.. _documentation: http://jinja.pocoo.org/2/documentation/
|
||||
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
Jinja2-2.10.dist-info/DESCRIPTION.rst,sha256=b5ckFDoM7vVtz_mAsJD4OPteFKCqE7beu353g4COoYI,978
|
||||
Jinja2-2.10.dist-info/LICENSE.txt,sha256=JvzUNv3Io51EiWrAPm8d_SXjhJnEjyDYvB3Tvwqqils,1554
|
||||
Jinja2-2.10.dist-info/METADATA,sha256=18EgU8zR6-av-0-5y_gXebzK4GnBB_76lALUsl-6QHM,2258
|
||||
Jinja2-2.10.dist-info/RECORD,,
|
||||
Jinja2-2.10.dist-info/WHEEL,sha256=kdsN-5OJAZIiHN-iO4Rhl82KyS0bDWf4uBwMbkNafr8,110
|
||||
Jinja2-2.10.dist-info/entry_points.txt,sha256=NdzVcOrqyNyKDxD09aERj__3bFx2paZhizFDsKmVhiA,72
|
||||
Jinja2-2.10.dist-info/metadata.json,sha256=NPUJ9TMBxVQAv_kTJzvU8HwmP-4XZvbK9mz6_4YUVl4,1473
|
||||
Jinja2-2.10.dist-info/top_level.txt,sha256=PkeVWtLb3-CqjWi1fO29OCbj55EhX_chhKrCdrVe_zs,7
|
||||
jinja2/__init__.py,sha256=xJHjaMoy51_KXn1wf0cysH6tUUifUxZCwSOfcJGEYZw,2614
|
||||
jinja2/_compat.py,sha256=xP60CE5Qr8FTYcDE1f54tbZLKGvMwYml4-8T7Q4KG9k,2596
|
||||
jinja2/_identifier.py,sha256=W1QBSY-iJsyt6oR_nKSuNNCzV95vLIOYgUNPUI1d5gU,1726
|
||||
jinja2/asyncfilters.py,sha256=cTDPvrS8Hp_IkwsZ1m9af_lr5nHysw7uTa5gV0NmZVE,4144
|
||||
jinja2/asyncsupport.py,sha256=UErQ3YlTLaSjFb94P4MVn08-aVD9jJxty2JVfMRb-1M,7878
|
||||
jinja2/bccache.py,sha256=nQldx0ZRYANMyfvOihRoYFKSlUdd5vJkS7BjxNwlOZM,12794
|
||||
jinja2/compiler.py,sha256=BqC5U6JxObSRhblyT_a6Tp5GtEU5z3US1a4jLQaxxgo,65386
|
||||
jinja2/constants.py,sha256=uwwV8ZUhHhacAuz5PTwckfsbqBaqM7aKfyJL7kGX5YQ,1626
|
||||
jinja2/debug.py,sha256=WTVeUFGUa4v6ReCsYv-iVPa3pkNB75OinJt3PfxNdXs,12045
|
||||
jinja2/defaults.py,sha256=Em-95hmsJxIenDCZFB1YSvf9CNhe9rBmytN3yUrBcWA,1400
|
||||
jinja2/environment.py,sha256=VnkAkqw8JbjZct4tAyHlpBrka2vqB-Z58RAP-32P1ZY,50849
|
||||
jinja2/exceptions.py,sha256=_Rj-NVi98Q6AiEjYQOsP8dEIdu5AlmRHzcSNOPdWix4,4428
|
||||
jinja2/ext.py,sha256=atMQydEC86tN1zUsdQiHw5L5cF62nDbqGue25Yiu3N4,24500
|
||||
jinja2/filters.py,sha256=yOAJk0MsH-_gEC0i0U6NweVQhbtYaC-uE8xswHFLF4w,36528
|
||||
jinja2/idtracking.py,sha256=2GbDSzIvGArEBGLkovLkqEfmYxmWsEf8c3QZwM4uNsw,9197
|
||||
jinja2/lexer.py,sha256=ySEPoXd1g7wRjsuw23uimS6nkGN5aqrYwcOKxCaVMBQ,28559
|
||||
jinja2/loaders.py,sha256=xiTuURKAEObyym0nU8PCIXu_Qp8fn0AJ5oIADUUm-5Q,17382
|
||||
jinja2/meta.py,sha256=fmKHxkmZYAOm9QyWWy8EMd6eefAIh234rkBMW2X4ZR8,4340
|
||||
jinja2/nativetypes.py,sha256=_sJhS8f-8Q0QMIC0dm1YEdLyxEyoO-kch8qOL5xUDfE,7308
|
||||
jinja2/nodes.py,sha256=L10L_nQDfubLhO3XjpF9qz46FSh2clL-3e49ogVlMmA,30853
|
||||
jinja2/optimizer.py,sha256=MsdlFACJ0FRdPtjmCAdt7JQ9SGrXFaDNUaslsWQaG3M,1722
|
||||
jinja2/parser.py,sha256=lPzTEbcpTRBLw8ii6OYyExHeAhaZLMA05Hpv4ll3ULk,35875
|
||||
jinja2/runtime.py,sha256=DHdD38Pq8gj7uWQC5usJyWFoNWL317A9AvXOW_CLB34,27755
|
||||
jinja2/sandbox.py,sha256=TVyZHlNqqTzsv9fv2NvJNmSdWRHTguhyMHdxjWms32U,16708
|
||||
jinja2/tests.py,sha256=iJQLwbapZr-EKquTG_fVOVdwHUUKf3SX9eNkjQDF8oU,4237
|
||||
jinja2/utils.py,sha256=q24VupGZotQ-uOyrJxCaXtDWhZC1RgsQG7kcdmjck2Q,20629
|
||||
jinja2/visitor.py,sha256=JD1H1cANA29JcntFfN5fPyqQxB4bI4wC00BzZa-XHks,3316
|
||||
Jinja2-2.10.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||
jinja2/__pycache__/lexer.cpython-36.pyc,,
|
||||
jinja2/__pycache__/sandbox.cpython-36.pyc,,
|
||||
jinja2/__pycache__/debug.cpython-36.pyc,,
|
||||
jinja2/__pycache__/constants.cpython-36.pyc,,
|
||||
jinja2/__pycache__/idtracking.cpython-36.pyc,,
|
||||
jinja2/__pycache__/parser.cpython-36.pyc,,
|
||||
jinja2/__pycache__/exceptions.cpython-36.pyc,,
|
||||
jinja2/__pycache__/ext.cpython-36.pyc,,
|
||||
jinja2/__pycache__/meta.cpython-36.pyc,,
|
||||
jinja2/__pycache__/environment.cpython-36.pyc,,
|
||||
jinja2/__pycache__/loaders.cpython-36.pyc,,
|
||||
jinja2/__pycache__/asyncsupport.cpython-36.pyc,,
|
||||
jinja2/__pycache__/asyncfilters.cpython-36.pyc,,
|
||||
jinja2/__pycache__/tests.cpython-36.pyc,,
|
||||
jinja2/__pycache__/optimizer.cpython-36.pyc,,
|
||||
jinja2/__pycache__/compiler.cpython-36.pyc,,
|
||||
jinja2/__pycache__/bccache.cpython-36.pyc,,
|
||||
jinja2/__pycache__/_identifier.cpython-36.pyc,,
|
||||
jinja2/__pycache__/_compat.cpython-36.pyc,,
|
||||
jinja2/__pycache__/defaults.cpython-36.pyc,,
|
||||
jinja2/__pycache__/utils.cpython-36.pyc,,
|
||||
jinja2/__pycache__/nodes.cpython-36.pyc,,
|
||||
jinja2/__pycache__/filters.cpython-36.pyc,,
|
||||
jinja2/__pycache__/runtime.cpython-36.pyc,,
|
||||
jinja2/__pycache__/__init__.cpython-36.pyc,,
|
||||
jinja2/__pycache__/nativetypes.cpython-36.pyc,,
|
||||
jinja2/__pycache__/visitor.cpython-36.pyc,,
|
|
@ -0,0 +1,6 @@
|
|||
Wheel-Version: 1.0
|
||||
Generator: bdist_wheel (0.30.0)
|
||||
Root-Is-Purelib: true
|
||||
Tag: py2-none-any
|
||||
Tag: py3-none-any
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
|
||||
[babel.extractors]
|
||||
jinja2 = jinja2.ext:babel_extract[i18n]
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"classifiers": ["Development Status :: 5 - Production/Stable", "Environment :: Web Environment", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Topic :: Internet :: WWW/HTTP :: Dynamic Content", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Text Processing :: Markup :: HTML"], "description_content_type": "UNKNOWN", "extensions": {"python.details": {"contacts": [{"email": "armin.ronacher@active-4.com", "name": "Armin Ronacher", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst", "license": "LICENSE.txt"}, "project_urls": {"Home": "http://jinja.pocoo.org/"}}, "python.exports": {"babel.extractors": {"jinja2": "jinja2.ext:babel_extract [i18n]"}}}, "extras": ["i18n"], "generator": "bdist_wheel (0.30.0)", "license": "BSD", "metadata_version": "2.0", "name": "Jinja2", "run_requires": [{"extra": "i18n", "requires": ["Babel (>=0.8)"]}, {"requires": ["MarkupSafe (>=0.23)"]}], "summary": "A small but fast and easy to use stand-alone template engine written in pure python.", "version": "2.10"}
|
|
@ -0,0 +1 @@
|
|||
jinja2
|
|
@ -0,0 +1,115 @@
|
|||
MarkupSafe
|
||||
==========
|
||||
|
||||
Implements a unicode subclass that supports HTML strings:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> from markupsafe import Markup, escape
|
||||
>>> escape("<script>alert(document.cookie);</script>")
|
||||
Markup(u'<script>alert(document.cookie);</script>')
|
||||
>>> tmpl = Markup("<em>%s</em>")
|
||||
>>> tmpl % "Peter > Lustig"
|
||||
Markup(u'<em>Peter > Lustig</em>')
|
||||
|
||||
If you want to make an object unicode that is not yet unicode
|
||||
but don't want to lose the taint information, you can use the
|
||||
``soft_unicode`` function. (On Python 3 you can also use ``soft_str`` which
|
||||
is a different name for the same function).
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> from markupsafe import soft_unicode
|
||||
>>> soft_unicode(42)
|
||||
u'42'
|
||||
>>> soft_unicode(Markup('foo'))
|
||||
Markup(u'foo')
|
||||
|
||||
HTML Representations
|
||||
--------------------
|
||||
|
||||
Objects can customize their HTML markup equivalent by overriding
|
||||
the ``__html__`` function:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> class Foo(object):
|
||||
... def __html__(self):
|
||||
... return '<strong>Nice</strong>'
|
||||
...
|
||||
>>> escape(Foo())
|
||||
Markup(u'<strong>Nice</strong>')
|
||||
>>> Markup(Foo())
|
||||
Markup(u'<strong>Nice</strong>')
|
||||
|
||||
Silent Escapes
|
||||
--------------
|
||||
|
||||
Since MarkupSafe 0.10 there is now also a separate escape function
|
||||
called ``escape_silent`` that returns an empty string for ``None`` for
|
||||
consistency with other systems that return empty strings for ``None``
|
||||
when escaping (for instance Pylons' webhelpers).
|
||||
|
||||
If you also want to use this for the escape method of the Markup
|
||||
object, you can create your own subclass that does that:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from markupsafe import Markup, escape_silent as escape
|
||||
|
||||
class SilentMarkup(Markup):
|
||||
__slots__ = ()
|
||||
|
||||
@classmethod
|
||||
def escape(cls, s):
|
||||
return cls(escape(s))
|
||||
|
||||
New-Style String Formatting
|
||||
---------------------------
|
||||
|
||||
Starting with MarkupSafe 0.21 new style string formats from Python 2.6 and
|
||||
3.x are now fully supported. Previously the escape behavior of those
|
||||
functions was spotty at best. The new implementations operates under the
|
||||
following algorithm:
|
||||
|
||||
1. if an object has an ``__html_format__`` method it is called as
|
||||
replacement for ``__format__`` with the format specifier. It either
|
||||
has to return a string or markup object.
|
||||
2. if an object has an ``__html__`` method it is called.
|
||||
3. otherwise the default format system of Python kicks in and the result
|
||||
is HTML escaped.
|
||||
|
||||
Here is how you can implement your own formatting:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
class User(object):
|
||||
|
||||
def __init__(self, id, username):
|
||||
self.id = id
|
||||
self.username = username
|
||||
|
||||
def __html_format__(self, format_spec):
|
||||
if format_spec == 'link':
|
||||
return Markup('<a href="/user/{0}">{1}</a>').format(
|
||||
self.id,
|
||||
self.__html__(),
|
||||
)
|
||||
elif format_spec:
|
||||
raise ValueError('Invalid format spec')
|
||||
return self.__html__()
|
||||
|
||||
def __html__(self):
|
||||
return Markup('<span class=user>{0}</span>').format(self.username)
|
||||
|
||||
And to format that user:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> user = User(1, 'foo')
|
||||
>>> Markup('<p>User: {0:link}').format(user)
|
||||
Markup(u'<p>User: <a href="/user/1"><span class=user>foo</span></a>')
|
||||
|
||||
Markupsafe supports Python 2.6, 2.7 and Python 3.3 and higher.
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
pip
|
|
@ -0,0 +1,33 @@
|
|||
Copyright (c) 2010 by Armin Ronacher and contributors. See AUTHORS
|
||||
for more details.
|
||||
|
||||
Some rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms of the software as well
|
||||
as documentation, with or without modification, are permitted provided
|
||||
that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
|
||||
* The names of the contributors may not be used to endorse or
|
||||
promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
|
||||
NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE AND DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGE.
|
|
@ -0,0 +1,135 @@
|
|||
Metadata-Version: 2.0
|
||||
Name: MarkupSafe
|
||||
Version: 1.0
|
||||
Summary: Implements a XML/HTML/XHTML Markup safe string for Python
|
||||
Home-page: http://github.com/pallets/markupsafe
|
||||
Author: Armin Ronacher
|
||||
Author-email: armin.ronacher@active-4.com
|
||||
License: BSD
|
||||
Platform: UNKNOWN
|
||||
Classifier: Development Status :: 5 - Production/Stable
|
||||
Classifier: Environment :: Web Environment
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: License :: OSI Approved :: BSD License
|
||||
Classifier: Operating System :: OS Independent
|
||||
Classifier: Programming Language :: Python
|
||||
Classifier: Programming Language :: Python :: 3
|
||||
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
||||
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
||||
Classifier: Topic :: Text Processing :: Markup :: HTML
|
||||
|
||||
MarkupSafe
|
||||
==========
|
||||
|
||||
Implements a unicode subclass that supports HTML strings:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> from markupsafe import Markup, escape
|
||||
>>> escape("<script>alert(document.cookie);</script>")
|
||||
Markup(u'<script>alert(document.cookie);</script>')
|
||||
>>> tmpl = Markup("<em>%s</em>")
|
||||
>>> tmpl % "Peter > Lustig"
|
||||
Markup(u'<em>Peter > Lustig</em>')
|
||||
|
||||
If you want to make an object unicode that is not yet unicode
|
||||
but don't want to lose the taint information, you can use the
|
||||
``soft_unicode`` function. (On Python 3 you can also use ``soft_str`` which
|
||||
is a different name for the same function).
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> from markupsafe import soft_unicode
|
||||
>>> soft_unicode(42)
|
||||
u'42'
|
||||
>>> soft_unicode(Markup('foo'))
|
||||
Markup(u'foo')
|
||||
|
||||
HTML Representations
|
||||
--------------------
|
||||
|
||||
Objects can customize their HTML markup equivalent by overriding
|
||||
the ``__html__`` function:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> class Foo(object):
|
||||
... def __html__(self):
|
||||
... return '<strong>Nice</strong>'
|
||||
...
|
||||
>>> escape(Foo())
|
||||
Markup(u'<strong>Nice</strong>')
|
||||
>>> Markup(Foo())
|
||||
Markup(u'<strong>Nice</strong>')
|
||||
|
||||
Silent Escapes
|
||||
--------------
|
||||
|
||||
Since MarkupSafe 0.10 there is now also a separate escape function
|
||||
called ``escape_silent`` that returns an empty string for ``None`` for
|
||||
consistency with other systems that return empty strings for ``None``
|
||||
when escaping (for instance Pylons' webhelpers).
|
||||
|
||||
If you also want to use this for the escape method of the Markup
|
||||
object, you can create your own subclass that does that:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from markupsafe import Markup, escape_silent as escape
|
||||
|
||||
class SilentMarkup(Markup):
|
||||
__slots__ = ()
|
||||
|
||||
@classmethod
|
||||
def escape(cls, s):
|
||||
return cls(escape(s))
|
||||
|
||||
New-Style String Formatting
|
||||
---------------------------
|
||||
|
||||
Starting with MarkupSafe 0.21 new style string formats from Python 2.6 and
|
||||
3.x are now fully supported. Previously the escape behavior of those
|
||||
functions was spotty at best. The new implementations operates under the
|
||||
following algorithm:
|
||||
|
||||
1. if an object has an ``__html_format__`` method it is called as
|
||||
replacement for ``__format__`` with the format specifier. It either
|
||||
has to return a string or markup object.
|
||||
2. if an object has an ``__html__`` method it is called.
|
||||
3. otherwise the default format system of Python kicks in and the result
|
||||
is HTML escaped.
|
||||
|
||||
Here is how you can implement your own formatting:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
class User(object):
|
||||
|
||||
def __init__(self, id, username):
|
||||