@ -0,0 +1,23 @@
|
||||
environment: |
||||
global: |
||||
TOXENV: py |
||||
|
||||
matrix: |
||||
- PYTHON: C:\Python36 |
||||
- PYTHON: C:\Python27 |
||||
|
||||
init: |
||||
- SET PATH=%PYTHON%;%PATH% |
||||
|
||||
install: |
||||
- python -m pip install -U pip setuptools wheel tox |
||||
|
||||
build: false |
||||
|
||||
test_script: |
||||
- python -m tox |
||||
|
||||
branches: |
||||
only: |
||||
- master |
||||
- /^.*-maintenance$/ |
@ -0,0 +1,11 @@
|
||||
[run] |
||||
branch = True |
||||
source = |
||||
flask |
||||
tests |
||||
|
||||
[paths] |
||||
source = |
||||
flask |
||||
.tox/*/lib/python*/site-packages/flask |
||||
.tox/pypy/site-packages/flask |
@ -0,0 +1,33 @@
|
||||
**This issue tracker is a tool to address bugs in Flask itself. |
||||
Please use the #pocoo IRC channel on freenode or Stack Overflow for general |
||||
questions about using Flask or issues not related to Flask.** |
||||
|
||||
If you'd like to report a bug in Flask, fill out the template below. Provide |
||||
any any extra information that may be useful / related to your problem. |
||||
Ideally, create an [MCVE](http://stackoverflow.com/help/mcve), which helps us |
||||
understand the problem and helps check that it is not caused by something in |
||||
your code. |
||||
|
||||
--- |
||||
|
||||
### Expected Behavior |
||||
|
||||
Tell us what should happen. |
||||
|
||||
```python |
||||
Paste a minimal example that causes the problem. |
||||
``` |
||||
|
||||
### Actual Behavior |
||||
|
||||
Tell us what happens instead. |
||||
|
||||
```pytb |
||||
Paste the full traceback if there was an exception. |
||||
``` |
||||
|
||||
### Environment |
||||
|
||||
* Python version: |
||||
* Flask version: |
||||
* Werkzeug version: |
@ -1,2 +0,0 @@
|
||||
The issue tracker is a tool to address bugs. |
||||
Please use the #pocoo IRC channel on freenode or Stack Overflow for questions. |
@ -0,0 +1,16 @@
|
||||
Describe what this patch does to fix the issue. |
||||
|
||||
Link to any relevant issues or pull requests. |
||||
|
||||
<!-- |
||||
Commit checklist: |
||||
|
||||
* add tests that fail without the patch |
||||
* ensure all tests pass with ``pytest`` |
||||
* add documentation to the relevant docstrings or pages |
||||
* add ``versionadded`` or ``versionchanged`` directives to relevant docstrings |
||||
* add a changelog entry if this patch changes code |
||||
|
||||
Tests, coverage, and docs will be run automatically when you submit the pull |
||||
request, but running them yourself can save time. |
||||
--> |
@ -1,3 +0,0 @@
|
||||
[submodule "docs/_themes"] |
||||
path = docs/_themes |
||||
url = https://github.com/mitsuhiko/flask-sphinx-themes.git |
@ -1,114 +1,166 @@
|
||||
========================== |
||||
How to contribute to Flask |
||||
========================== |
||||
|
||||
Thanks for considering contributing to Flask. |
||||
Thank you for considering contributing to Flask! |
||||
|
||||
Support questions |
||||
================= |
||||
----------------- |
||||
|
||||
Please, don't use the issue tracker for this. Use one of the following |
||||
resources for questions about your own code: |
||||
|
||||
* The IRC channel ``#pocoo`` on FreeNode. |
||||
* The IRC channel ``#python`` on FreeNode for more general questions. |
||||
* The mailing list flask@python.org for long term discussion or larger issues. |
||||
* Ask on `Stack Overflow`_. Search with Google first using: |
||||
``site:stackoverflow.com flask {search term, exception message, etc.}`` |
||||
|
||||
Please, don't use the issue tracker for this. Check whether the ``#pocoo`` IRC |
||||
channel on Freenode can help with your issue. If your problem is not strictly |
||||
Werkzeug or Flask specific, ``#python`` is generally more active. |
||||
`Stack Overflow <https://stackoverflow.com/>`_ is also worth considering. |
||||
.. _Stack Overflow: https://stackoverflow.com/questions/tagged/flask?sort=linked |
||||
|
||||
Reporting issues |
||||
================ |
||||
---------------- |
||||
|
||||
- Under which versions of Python does this happen? This is even more important |
||||
if your issue is encoding related. |
||||
- Describe what you expected to happen. |
||||
- If possible, include a `minimal, complete, and verifiable example`_ to help |
||||
us identify the issue. This also helps check that the issue is not with your |
||||
own code. |
||||
- Describe what actually happened. Include the full traceback if there was an |
||||
exception. |
||||
- List your Python, Flask, and Werkzeug versions. If possible, check if this |
||||
issue is already fixed in the repository. |
||||
|
||||
- Under which versions of Werkzeug does this happen? Check if this issue is |
||||
fixed in the repository. |
||||
.. _minimal, complete, and verifiable example: https://stackoverflow.com/help/mcve |
||||
|
||||
Submitting patches |
||||
================== |
||||
------------------ |
||||
|
||||
- Include tests if your patch is supposed to solve a bug, and explain |
||||
clearly under which circumstances the bug happens. Make sure the test fails |
||||
without your patch. |
||||
- Try to follow `PEP8`_, but you may ignore the line length limit if following |
||||
it would make the code uglier. |
||||
|
||||
First time setup |
||||
~~~~~~~~~~~~~~~~ |
||||
|
||||
- Download and install the `latest version of git`_. |
||||
- Configure git with your `username`_ and `email`_:: |
||||
|
||||
git config --global user.name 'your name' |
||||
git config --global user.email 'your email' |
||||
|
||||
- Try to follow `PEP8 <http://legacy.python.org/dev/peps/pep-0008/>`_, but you |
||||
may ignore the line-length-limit if following it would make the code uglier. |
||||
- Make sure you have a `GitHub account`_. |
||||
- Fork Flask to your GitHub account by clicking the `Fork`_ button. |
||||
- `Clone`_ your GitHub fork locally:: |
||||
|
||||
git clone https://github.com/{username}/flask |
||||
cd flask |
||||
|
||||
Running the testsuite |
||||
--------------------- |
||||
- Add the main repository as a remote to update later:: |
||||
|
||||
You probably want to set up a `virtualenv |
||||
<https://virtualenv.readthedocs.io/en/latest/index.html>`_. |
||||
git remote add pallets https://github.com/pallets/flask |
||||
git fetch pallets |
||||
|
||||
The minimal requirement for running the testsuite is ``py.test``. You can |
||||
install it with:: |
||||
- Create a virtualenv:: |
||||
|
||||
pip install pytest |
||||
python3 -m venv env |
||||
. env/bin/activate |
||||
# or "env\Scripts\activate" on Windows |
||||
|
||||
Clone this repository:: |
||||
- Install Flask in editable mode with development dependencies:: |
||||
|
||||
git clone https://github.com/pallets/flask.git |
||||
pip install -e ".[dev]" |
||||
|
||||
Install Flask as an editable package using the current source:: |
||||
.. _GitHub account: https://github.com/join |
||||
.. _latest version of git: https://git-scm.com/downloads |
||||
.. _username: https://help.github.com/articles/setting-your-username-in-git/ |
||||
.. _email: https://help.github.com/articles/setting-your-email-in-git/ |
||||
.. _Fork: https://github.com/pallets/flask/pull/2305#fork-destination-box |
||||
.. _Clone: https://help.github.com/articles/fork-a-repo/#step-2-create-a-local-clone-of-your-fork |
||||
|
||||
cd flask |
||||
pip install --editable . |
||||
Start coding |
||||
~~~~~~~~~~~~ |
||||
|
||||
Then you can run the testsuite with:: |
||||
- Create a branch to identify the issue you would like to work on (e.g. |
||||
``2287-dry-test-suite``) |
||||
- Using your favorite editor, make your changes, `committing as you go`_. |
||||
- Try to follow `PEP8`_, but you may ignore the line length limit if following |
||||
it would make the code uglier. |
||||
- Include tests that cover any code changes you make. Make sure the test fails |
||||
without your patch. `Run the tests. <contributing-testsuite_>`_. |
||||
- Push your commits to GitHub and `create a pull request`_. |
||||
- Celebrate 🎉 |
||||
|
||||
py.test |
||||
.. _committing as you go: http://dont-be-afraid-to-commit.readthedocs.io/en/latest/git/commandlinegit.html#commit-your-changes |
||||
.. _PEP8: https://pep8.org/ |
||||
.. _create a pull request: https://help.github.com/articles/creating-a-pull-request/ |
||||
|
||||
With only py.test installed, a large part of the testsuite will get skipped |
||||
though. Whether this is relevant depends on which part of Flask you're working |
||||
on. Travis is set up to run the full testsuite when you submit your pull |
||||
request anyways. |
||||
.. _contributing-testsuite: |
||||
|
||||
If you really want to test everything, you will have to install ``tox`` instead |
||||
of ``pytest``. You can install it with:: |
||||
Running the tests |
||||
~~~~~~~~~~~~~~~~~ |
||||
|
||||
pip install tox |
||||
Run the basic test suite with:: |
||||
|
||||
The ``tox`` command will then run all tests against multiple combinations |
||||
Python versions and dependency versions. |
||||
pytest |
||||
|
||||
This only runs the tests for the current environment. Whether this is relevant |
||||
depends on which part of Flask you're working on. Travis-CI will run the full |
||||
suite when you submit your pull request. |
||||
|
||||
The full test suite takes a long time to run because it tests multiple |
||||
combinations of Python and dependencies. You need to have Python 2.7, 3.4, |
||||
3.5 3.6, and PyPy 2.7 installed to run all of the environments. Then run:: |
||||
|
||||
tox |
||||
|
||||
Running test coverage |
||||
--------------------- |
||||
Generating a report of lines that do not have unit test coverage can indicate where |
||||
to start contributing. ``pytest`` integrates with ``coverage.py``, using the ``pytest-cov`` |
||||
plugin. This assumes you have already run the testsuite (see previous section):: |
||||
~~~~~~~~~~~~~~~~~~~~~ |
||||
|
||||
pip install pytest-cov |
||||
Generating a report of lines that do not have test coverage can indicate |
||||
where to start contributing. Run ``pytest`` using ``coverage`` and generate a |
||||
report on the terminal and as an interactive HTML document:: |
||||
|
||||
After this has been installed, you can output a report to the command line using this command:: |
||||
coverage run -m pytest |
||||
coverage report |
||||
coverage html |
||||
# then open htmlcov/index.html |
||||
|
||||
py.test --cov=flask tests/ |
||||
Read more about `coverage <https://coverage.readthedocs.io>`_. |
||||
|
||||
Generate a HTML report can be done using this command:: |
||||
Running the full test suite with ``tox`` will combine the coverage reports |
||||
from all runs. |
||||
|
||||
py.test --cov-report html --cov=flask tests/ |
||||
``make`` targets |
||||
~~~~~~~~~~~~~~~~ |
||||
|
||||
Full docs on ``coverage.py`` are here: https://coverage.readthedocs.io |
||||
Flask provides a ``Makefile`` with various shortcuts. They will ensure that |
||||
all dependencies are installed. |
||||
|
||||
Caution |
||||
======= |
||||
pushing |
||||
------- |
||||
This repository contains several zero-padded file modes that may cause issues when pushing this repository to git hosts other than github. Fixing this is destructive to the commit history, so we suggest ignoring these warnings. If it fails to push and you're using a self-hosted git service like Gitlab, you can turn off repository checks in the admin panel. |
||||
- ``make test`` runs the basic test suite with ``pytest`` |
||||
- ``make cov`` runs the basic test suite with ``coverage`` |
||||
- ``make test-all`` runs the full test suite with ``tox`` |
||||
- ``make docs`` builds the HTML documentation |
||||
|
||||
Caution: zero-padded file modes |
||||
------------------------------- |
||||
|
||||
cloning |
||||
------- |
||||
The zero-padded file modes files above can cause issues while cloning, too. If you have |
||||
This repository contains several zero-padded file modes that may cause issues |
||||
when pushing this repository to git hosts other than GitHub. Fixing this is |
||||
destructive to the commit history, so we suggest ignoring these warnings. If it |
||||
fails to push and you're using a self-hosted git service like GitLab, you can |
||||
turn off repository checks in the admin panel. |
||||
|
||||
:: |
||||
These files can also cause issues while cloning. If you have :: |
||||
|
||||
[fetch] |
||||
fsckobjects = true |
||||
|
||||
or |
||||
|
||||
:: |
||||
or :: |
||||
|
||||
[receive] |
||||
fsckObjects = true |
||||
|
||||
|
||||
set in your git configuration file, cloning this repository will fail. The only solution is to set both of the above settings to false while cloning, and then setting them back to true after the cloning is finished. |
||||
set in your git configuration file, cloning this repository will fail. The only |
||||
solution is to set both of the above settings to false while cloning, and then |
||||
setting them back to true after the cloning is finished. |
||||
|
Before Width: | Height: | Size: 121 KiB After Width: | Height: | Size: 203 KiB |
Before Width: | Height: | Size: 9.7 KiB After Width: | Height: | Size: 6.8 KiB |
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 65 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 317 B After Width: | Height: | Size: 259 B |
After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 277 B After Width: | Height: | Size: 241 B |
@ -1 +1 @@
|
||||
.. include:: ../CHANGES |
||||
.. include:: ../CHANGES.rst |
||||
|
@ -1,86 +0,0 @@
|
||||
# flasky extensions. flasky pygments style based on tango style |
||||
from pygments.style import Style |
||||
from pygments.token import Keyword, Name, Comment, String, Error, \ |
||||
Number, Operator, Generic, Whitespace, Punctuation, Other, Literal |
||||
|
||||
|
||||
class FlaskyStyle(Style): |
||||
background_color = "#f8f8f8" |
||||
default_style = "" |
||||
|
||||
styles = { |
||||
# No corresponding class for the following: |
||||
#Text: "", # class: '' |
||||
Whitespace: "underline #f8f8f8", # class: 'w' |
||||
Error: "#a40000 border:#ef2929", # class: 'err' |
||||
Other: "#000000", # class 'x' |
||||
|
||||
Comment: "italic #8f5902", # class: 'c' |
||||
Comment.Preproc: "noitalic", # class: 'cp' |
||||
|
||||
Keyword: "bold #004461", # class: 'k' |
||||
Keyword.Constant: "bold #004461", # class: 'kc' |
||||
Keyword.Declaration: "bold #004461", # class: 'kd' |
||||
Keyword.Namespace: "bold #004461", # class: 'kn' |
||||
Keyword.Pseudo: "bold #004461", # class: 'kp' |
||||
Keyword.Reserved: "bold #004461", # class: 'kr' |
||||
Keyword.Type: "bold #004461", # class: 'kt' |
||||
|
||||
Operator: "#582800", # class: 'o' |
||||
Operator.Word: "bold #004461", # class: 'ow' - like keywords |
||||
|
||||
Punctuation: "bold #000000", # class: 'p' |
||||
|
||||
# because special names such as Name.Class, Name.Function, etc. |
||||
# are not recognized as such later in the parsing, we choose them |
||||
# to look the same as ordinary variables. |
||||
Name: "#000000", # class: 'n' |
||||
Name.Attribute: "#c4a000", # class: 'na' - to be revised |
||||
Name.Builtin: "#004461", # class: 'nb' |
||||
Name.Builtin.Pseudo: "#3465a4", # class: 'bp' |
||||
Name.Class: "#000000", # class: 'nc' - to be revised |
||||
Name.Constant: "#000000", # class: 'no' - to be revised |
||||
Name.Decorator: "#888", # class: 'nd' - to be revised |
||||
Name.Entity: "#ce5c00", # class: 'ni' |
||||
Name.Exception: "bold #cc0000", # class: 'ne' |
||||
Name.Function: "#000000", # class: 'nf' |
||||
Name.Property: "#000000", # class: 'py' |
||||
Name.Label: "#f57900", # class: 'nl' |
||||
Name.Namespace: "#000000", # class: 'nn' - to be revised |
||||
Name.Other: "#000000", # class: 'nx' |
||||
Name.Tag: "bold #004461", # class: 'nt' - like a keyword |
||||
Name.Variable: "#000000", # class: 'nv' - to be revised |
||||
Name.Variable.Class: "#000000", # class: 'vc' - to be revised |
||||
Name.Variable.Global: "#000000", # class: 'vg' - to be revised |
||||
Name.Variable.Instance: "#000000", # class: 'vi' - to be revised |
||||
|
||||
Number: "#990000", # class: 'm' |
||||
|
||||
Literal: "#000000", # class: 'l' |
||||
Literal.Date: "#000000", # class: 'ld' |
||||
|
||||
String: "#4e9a06", # class: 's' |
||||
String.Backtick: "#4e9a06", # class: 'sb' |
||||
String.Char: "#4e9a06", # class: 'sc' |
||||
String.Doc: "italic #8f5902", # class: 'sd' - like a comment |
||||
String.Double: "#4e9a06", # class: 's2' |
||||
String.Escape: "#4e9a06", # class: 'se' |
||||
String.Heredoc: "#4e9a06", # class: 'sh' |
||||
String.Interpol: "#4e9a06", # class: 'si' |
||||
String.Other: "#4e9a06", # class: 'sx' |
||||
String.Regex: "#4e9a06", # class: 'sr' |
||||
String.Single: "#4e9a06", # class: 's1' |
||||
String.Symbol: "#4e9a06", # class: 'ss' |
||||
|
||||
Generic: "#000000", # class: 'g' |
||||
Generic.Deleted: "#a40000", # class: 'gd' |
||||
Generic.Emph: "italic #000000", # class: 'ge' |
||||
Generic.Error: "#ef2929", # class: 'gr' |
||||
Generic.Heading: "bold #000080", # class: 'gh' |
||||
Generic.Inserted: "#00A000", # class: 'gi' |
||||
Generic.Output: "#888", # class: 'go' |
||||
Generic.Prompt: "#745334", # class: 'gp' |
||||
Generic.Strong: "bold #000000", # class: 'gs' |
||||
Generic.Subheading: "bold #800080", # class: 'gu' |
||||
Generic.Traceback: "bold #a40000", # class: 'gt' |
||||
} |
@ -0,0 +1,175 @@
|
||||
.. _logging: |
||||
|
||||
Logging |
||||
======= |
||||
|
||||
Flask uses standard Python :mod:`logging`. All Flask-related messages are |
||||
logged under the ``'flask'`` logger namespace. |
||||
:meth:`Flask.logger <flask.Flask.logger>` returns the logger named |
||||
``'flask.app'``, and can be used to log messages for your application. :: |
||||
|
||||
@app.route('/login', methods=['POST']) |
||||
def login(): |
||||
user = get_user(request.form['username']) |
||||
|
||||
if user.check_password(request.form['password']): |
||||
login_user(user) |
||||
app.logger.info('%s logged in successfully', user.username) |
||||
return redirect(url_for('index')) |
||||
else: |
||||
app.logger.info('%s failed to log in', user.username) |
||||
abort(401) |
||||
|
||||
|
||||
Basic Configuration |
||||
------------------- |
||||
|
||||
When you want to configure logging for your project, you should do it as soon |
||||
as possible when the program starts. If :meth:`app.logger <flask.Flask.logger>` |
||||
is accessed before logging is configured, it will add a default handler. If |
||||
possible, configure logging before creating the application object. |
||||
|
||||
This example uses :func:`~logging.config.dictConfig` to create a logging |
||||
configuration similar to Flask's default, except for all logs:: |
||||
|
||||
from logging.config import dictConfig |
||||
|
||||
dictConfig({ |
||||
'version': 1, |
||||
'formatters': {'default': { |
||||
'format': '[%(asctime)s] %(levelname)s in %(module)s: %(message)s', |
||||
}}, |
||||
'handlers': {'wsgi': { |
||||
'class': 'logging.StreamHandler', |
||||
'stream': 'ext://flask.logging.wsgi_errors_stream', |
||||
'formatter': 'default' |
||||
}}, |
||||
'root': { |
||||
'level': 'INFO', |
||||
'handlers': ['wsgi'] |
||||
} |
||||
}) |
||||
|
||||
app = Flask(__name__) |
||||
|
||||
|
||||
Default Configuration |
||||
````````````````````` |
||||
|
||||
If you do not configure logging yourself, Flask will add a |
||||
:class:`~logging.StreamHandler` to :meth:`app.logger <flask.Flask.logger>` |
||||
automatically. During requests, it will write to the stream specified by the |
||||
WSGI server in ``environ['wsgi.errors']`` (which is usually |
||||
:data:`sys.stderr`). Outside a request, it will log to :data:`sys.stderr`. |
||||
|
||||
|
||||
Removing the Default Handler |
||||
```````````````````````````` |
||||
|
||||
If you configured logging after accessing |
||||
:meth:`app.logger <flask.Flask.logger>`, and need to remove the default |
||||
handler, you can import and remove it:: |
||||
|
||||
from flask.logging import default_handler |
||||
|
||||
app.logger.removeHandler(default_handler) |
||||
|
||||
|
||||
Email Errors to Admins |
||||
---------------------- |
||||
|
||||
When running the application on a remote server for production, you probably |
||||
won't be looking at the log messages very often. The WSGI server will probably |
||||
send log messages to a file, and you'll only check that file if a user tells |
||||
you something went wrong. |
||||
|
||||
To be proactive about discovering and fixing bugs, you can configure a |
||||
:class:`logging.handlers.SMTPHandler` to send an email when errors and higher |
||||
are logged. :: |
||||
|
||||
import logging |
||||
from logging.handlers import SMTPHandler |
||||
|
||||
mail_handler = SMTPHandler( |
||||
mailhost='127.0.0.1', |
||||
fromaddr='server-error@example.com', |
||||
toaddrs=['admin@example.com'], |
||||
subject='Application Error' |
||||
) |
||||
mail_handler.setLevel(logging.ERROR) |
||||
mail_handler.setFormatter(logging.Formatter( |
||||
'[%(asctime)s] %(levelname)s in %(module)s: %(message)s' |
||||
)) |
||||
|
||||
if not app.debug: |
||||
app.logger.addHandler(mail_handler) |
||||
|
||||
This requires that you have an SMTP server set up on the same server. See the |
||||
Python docs for more information about configuring the handler. |
||||
|
||||
|
||||
Injecting Request Information |
||||
----------------------------- |
||||
|
||||
Seeing more information about the request, such as the IP address, may help |
||||
debugging some errors. You can subclass :class:`logging.Formatter` to inject |
||||
your own fields that can be used in messages. You can change the formatter for |
||||
Flask's default handler, the mail handler defined above, or any other |
||||
handler. :: |
||||
|
||||
from flask import request |
||||
from flask.logging import default_handler |
||||
|
||||
class RequestFormatter(logging.Formatter): |
||||
def format(self, record): |
||||
record.url = request.url |
||||
record.remote_addr = request.remote_addr |
||||
return super().format(record) |
||||
|
||||
formatter = RequestFormatter( |
||||
'[%(asctime)s] %(remote_addr)s requested %(url)s\n' |
||||
'%(levelname)s in %(module)s: %(message)s' |
||||
) |
||||
default_handler.setFormatter(formatter) |
||||
mail_handler.setFormatter(formatter) |
||||
|
||||
|
||||
Other Libraries |
||||
--------------- |
||||
|
||||
Other libraries may use logging extensively, and you want to see relevant |
||||
messages from those logs too. The simplest way to do this is to add handlers |
||||
to the root logger instead of only the app logger. :: |
||||
|
||||
from flask.logging import default_handler |
||||
|
||||
root = logging.getLogger() |
||||
root.addHandler(default_handler) |
||||
root.addHandler(mail_handler) |
||||
|
||||
Depending on your project, it may be more useful to configure each logger you |
||||
care about separately, instead of configuring only the root logger. :: |
||||
|
||||
for logger in ( |
||||
app.logger, |
||||
logging.getLogger('sqlalchemy'), |
||||
logging.getLogger('other_package'), |
||||
): |
||||
logger.addHandler(default_handler) |
||||
logger.addHandler(mail_handler) |
||||
|
||||
|
||||
Werkzeug |
||||
```````` |
||||
|
||||
Werkzeug logs basic request/response information to the ``'werkzeug'`` logger. |
||||
If the root logger has no handlers configured, Werkzeug adds a |
||||
:class:`~logging.StreamHandler` to its logger. |
||||
|
||||
|
||||
Flask Extensions |
||||
```````````````` |
||||
|
||||
Depending on the situation, an extension may choose to log to |
||||
:meth:`app.logger <flask.Flask.logger>` or its own named logger. Consult each |
||||
extension's documentation for details. |
@ -1,23 +0,0 @@
|
||||
.. _python3-support: |
||||
|
||||
Python 3 Support |
||||
================ |
||||
|
||||
Flask, its dependencies, and most Flask extensions support Python 3. |
||||
You should start using Python 3 for your next project, |
||||
but there are a few things to be aware of. |
||||
|
||||
You need to use Python 3.3 or higher. 3.2 and older are *not* supported. |
||||
|
||||
You should use the latest versions of all Flask-related packages. |
||||
Flask 0.10 and Werkzeug 0.9 were the first versions to introduce Python 3 support. |
||||
|
||||
Python 3 changed how unicode and bytes are handled, which complicates how low |
||||
level code handles HTTP data. This mainly affects WSGI middleware interacting |
||||
with the WSGI ``environ`` data. Werkzeug wraps that information in high-level |
||||
helpers, so encoding issues should not affect you. |
||||
|
||||
The majority of the upgrade work is in the lower-level libraries like |
||||
Flask and Werkzeug, not the high-level application code. |
||||
For example, all of the examples in the Flask repository work on both Python 2 and 3 |
||||
and did not require a single line of code changed. |
@ -0,0 +1,64 @@
|
||||
# -*- coding: utf-8 -*- |
||||
""" |
||||
Flaskr |
||||
~~~~~~ |
||||
|
||||
A microblog example application written as Flask tutorial with |
||||
Flask and sqlite3. |
||||
|
||||
:copyright: (c) 2015 by Armin Ronacher. |
||||
:license: BSD, see LICENSE for more details. |
||||
""" |
||||
|
||||
import os |
||||
from flask import Flask, g |
||||
from werkzeug.utils import find_modules, import_string |
||||
from flaskr.blueprints.flaskr import init_db |
||||
|
||||
|
||||
def create_app(config=None): |
||||
app = Flask('flaskr') |
||||
|
||||
app.config.update(dict( |
||||
DATABASE=os.path.join(app.root_path, 'flaskr.db'), |
||||
DEBUG=True, |
||||
SECRET_KEY=b'_5#y2L"F4Q8z\n\xec]/', |
||||
USERNAME='admin', |
||||
PASSWORD='default' |
||||
)) |
||||
app.config.update(config or {}) |
||||
app.config.from_envvar('FLASKR_SETTINGS', silent=True) |
||||
|
||||
register_blueprints(app) |
||||
register_cli(app) |
||||
register_teardowns(app) |
||||
|
||||
return app |
||||
|
||||
|
||||
def register_blueprints(app): |
||||
"""Register all blueprint modules |
||||
|
||||
Reference: Armin Ronacher, "Flask for Fun and for Profit" PyBay 2016. |
||||
""" |
||||
for name in find_modules('flaskr.blueprints'): |
||||
mod = import_string(name) |
||||
if hasattr(mod, 'bp'): |
||||
app.register_blueprint(mod.bp) |
||||
return None |
||||
|
||||
|
||||
def register_cli(app): |
||||
@app.cli.command('initdb') |
||||
def initdb_command(): |
||||
"""Creates the database tables.""" |
||||
init_db() |
||||
print('Initialized the database.') |
||||
|
||||
|
||||
def register_teardowns(app): |
||||
@app.teardown_appcontext |
||||
def close_db(error): |
||||
"""Closes the database again at the end of the request.""" |
||||
if hasattr(g, 'sqlite_db'): |
||||
g.sqlite_db.close() |
@ -1 +1 @@
|
||||
from minitwit import app |
||||
from .minitwit import app |
||||
|
@ -0,0 +1,10 @@
|
||||
from setuptools import setup |
||||
|
||||
setup( |
||||
name='yourapplication', |
||||
packages=['yourapplication'], |
||||
include_package_data=True, |
||||
install_requires=[ |
||||
'flask', |
||||
], |
||||
) |
@ -0,0 +1,12 @@
|
||||
from yourapplication import app |
||||
import pytest |
||||
|
||||
@pytest.fixture |
||||
def client(): |
||||
app.config['TESTING'] = True |
||||
client = app.test_client() |
||||
return client |
||||
|
||||
def test_index(client): |
||||
rv = client.get('/') |
||||
assert b"Hello World!" in rv.data |
@ -0,0 +1,4 @@
|
||||
from flask import Flask |
||||
app = Flask('yourapplication') |
||||
|
||||
import yourapplication.views |
@ -0,0 +1,5 @@
|
||||
from yourapplication import app |
||||
|
||||
@app.route('/') |
||||
def index(): |
||||
return 'Hello World!' |