107 Commits

Author SHA1 Message Date
Mac Newbold
bf21647c4b Bump to 0.15.0 (#251) 2024-04-24 14:38:33 -06:00
Jeff Widman
818e5f2d62 Bump to 0.15.0
We've merged a number of deprecation fixes, let's get them live to our users via a new release.
2024-04-24 07:59:07 -07:00
Jeff Widman
c65c6b94e5 Add .readthedocs.yaml file (#246)
Add `.readthedocs.yaml` file.

This config file is now required by RTD in order to build the docs.
2024-04-24 14:46:37 +00:00
Jeff Widman
0ca1f6b241 Install custom Sphinx theme via extras_require (#250)
Previously the custom theme was vendored in via a `git` submodule...

Now this theme is available via a python package, so install it using `extras_require` instead.

This also unlocks letting other tooling such as ReadTheDocs install the custom theme without having to do custom git incantations.

I also removed the `index_logo` config as Sphinx warns that it's not a supported option by the theme. I grep'd the theme package, and it makes no mention of this option, besides we were leaving it blank already, so there's no point in having it.
2024-04-24 07:40:27 -07:00
Mac Newbold
48de4e4a3c Prevent LookupError when accessing debug_toolbars_var (#245) 2024-04-18 10:59:27 -06:00
Mac Newbold
b139c60a60 Merge branch 'master' into master 2024-04-18 10:58:04 -06:00
Marc Aymerich Gunern
05f23436ac Prevent LookupError when accessing debug_toolbars_var when toolbar is being disabled in the middle of a request 2024-04-18 12:16:43 +01:00
Jeff Widman
7012193220 Replace deprecated pkg_resources with stdlib (#239)
`pkg_resources` has been deprecated by `setuptools` for quite a while: https://setuptools.pypa.io/en/latest/pkg_resources.html

It's got some bugs/warts:

* https://github.com/pypa/setuptools/issues/2531
* https://discuss.python.org/t/will-setuptools-remove-pkg-resource-module-in-the-future/27182

So switch to using `importlib` functions which are part of the Python standard library as of `3.8`.

This is less error-prone, and also removes the need for `setuptools` to be installed in order for this panel to work.

I realize we technically still support `3.7`, but I thought it was fine to change this particular panel to require `3.8`, as `3.7` support is best effort given that it's now EOL'd by the core Python team.

I also removed the relative path location for specific libraries as it was simply blank for me on Python 3.12... I think showing the location of the site packages directory should suffice. If someone later wants to build this out further, they're more than welcome to.

Note that `importlib.metadata.distributions()` does have an outstanding issue that it reports a local editable install twice, but they plan to eventually fix that:
* https://github.com/pypa/setuptools/issues/4170
2024-04-13 13:54:46 +00:00
Jeff Widman
7f3defff7c Fix some jquery deprecation warnings (#242)
Ths is a follow-on PR to
https://github.com/pallets-eco/flask-debugtoolbar/pull/241 in order to fix the deprecation warnings:
* `bind()` replaced by `on()`
* `click(handler)` replaced by `on('click', handler)`

Three deprecation warnings remain, but they are caused by the `jquery.tablesorter.js` plugin, so need to be handled upstream:
* https://github.com/Mottie/tablesorter/issues/1787
* https://github.com/Mottie/tablesorter/pull/1786

Related:
* https://github.com/pallets-eco/flask-debugtoolbar/issues/166
2024-04-13 13:48:56 +00:00
Jeff Widman
969cce532d Bump jquery to 3.7.1 and jquery-migrate to 3.4.1 (#241)
Bump to the latest versions of `jquery` and `jquery-migrate`.

I popped open the browser console and I see five deprecation warnings, but 3 out of the 5 are triggered by `jquery.tablesorter.js` which we vendor, so nothing we can do there.

The other two we should address, but we can do so in a follow-on PR as they are merely deprecations at this point, not fatal errors.

So getting onto the `3.x` series, even with deprecation warnings, is a nice step forward.

Previously we shipped the minified version of `jquery`, and we could
continue to do so, but given this is a dev tool and we still have
warnings we need to fix, I opted for the non-minified version for now.

Additionally, they offer a `slim` varient that is stripped down... we
could probably use that too, but I didn't take the time to investigate.

Fix: https://github.com/pallets-eco/flask-debugtoolbar/issues/166
2024-04-13 13:42:23 +00:00
Jeff Widman
c2804c4917 Bump jquery to 1.12.4 (#236)
This will allow us to migrate to the latest version of jquery 1.x series.

After we're on 1.9.x we can upgrade to the 3.x series.

I bumped this, and then checked the developer console while clicking
through the various panels offered in FDBT... Everything worked as
expected and I got zero warnings from `jquery-migrate`. So I think it's
safe to pull this in.

This is a pre-requesite to upgrading to the latest version of `jquery`,
as per their docs we have to first bump to `1.9+`, then bump the version
of `jquery-migrate`, then can bump to latest `jquery` version.

While I could do this in a single PR, I thought simpler to do it as a
series of PRs for easier reversion if we later run into problems.

Related:
* https://github.com/pallets-eco/flask-debugtoolbar/issues/166
2024-04-13 13:39:41 +00:00
Jeff Widman
56beb35c36 Update jquery.tablesorter.js plugin (#235)
Update to the latest `v2.31.3` version of this `jquery` plugin, which
unblocks upgrading to `jquery` >= `1.9.x`.

Using a fork because:

1. The original repo hasn't been updated in seven years: https://github.com/christianbach/tablesorter
2. The most recent committer to the original repo ☝️  now maintains the fork.
3. The fork was updated just a few months ago.
4. The fork supports the latest versions of `jquery`:
     > Works with jQuery 1.9+ (`$.browser.msie` was removed; needed in the original version)

As far as I can tell, no other changes are needed.

This is a straight copy/paste of the non-minized code from: https://github.com/Mottie/tablesorter

I used non-minimized for simplicity, since this is a dev-only tool, the
perf impacts of minimization don't really matter.

I tested this manually by:

```shell
$ cd flask-debugtoolbar/test
$ flask --app basic_app run --debug
```

Then loading `http://127.0.0.1:5000/` in a recent version of Chrome and
finding a FDBT panel that uses the sorter. In this case, the SQLAlchemy
panel. I visually compared behavior pre/past upgrade and it appeared
identical.

Related:
* https://github.com/pallets-eco/flask-debugtoolbar/issues/166
2024-04-13 06:37:37 -07:00
Jeff Widman
98bf17aa58 Fix trailing whitespace (#237)
I noticed some trailing whitespace has crept into these files. It wasn't caught by `pycodestyle` because that only checks Python files.

Ideally we'd add a linter that catches these, but I didn't want to take the time to configure one right now, I just want my editor to stop flagging these while I'm working on trying to upgrade `jquery` versions.

Long term, we'll probably want a meta-linter like `prettier` or whatever the newest kid on the block is.
2024-04-12 16:27:04 +00:00
Grey Li
716f05d953 Remove deprecated Flask version attribute (#243)
The `flask.__version__` attr is deprecated and will be removed in the Flask 3.1 version. This PR replaced this attr to `importlib.metadata.version`.

We could remove the use of `pkg_resources` when we drop the Python 3.7 support.
2024-04-12 09:20:53 -07:00
Jeff Widman
fb28aa9d61 Fix missing distutils error on Python 3.12 (#238)
Running on Python 3.12 I see:

```shell
[2024-04-11 11:01:12,915] WARNING in toolbar: Disabled flask_debugtoolbar.panels.versions.VersionDebugPanel due to ImportError: import_string() failed for 'flask_debugtoolbar.panels.versions.VersionDebugPanel'. Possible reasons are:

- missing __init__.py in a package;
- package or module path not included in sys.path;
- duplicated package or module name taking precedence in sys.path;
- missing module, class, function or variable;

Debugged import:

- 'flask_debugtoolbar' found in '/Users/jeffwidman/Code/open-source/flask-debugtoolbar/src/flask_debugtoolbar/__init__.py'.
- 'flask_debugtoolbar.panels' found in '/Users/jeffwidman/Code/open-source/flask-debugtoolbar/src/flask_debugtoolbar/panels/__init__.py'.
- 'flask_debugtoolbar.panels.versions' not found.

Original exception:

ModuleNotFoundError: No module named 'distutils'
```

This is because Python 3.12 removed `distutils`.

Fix pulled from https://bugs.python.org/issue41282#msg393018.

This will not work on Python `3.6`, but we've already dropped support for that.

After the fix, the error is gone and the Versions panel re-appears.
2024-04-11 18:18:04 -07:00
Mac Newbold
efe447fb5f Fix SQLAlchemy recording warning for versions >= 3 (#233) 2024-03-20 09:28:47 -06:00
Jonty Wareing
9656a2cf33 Fix SQLAlchemy recording warning for versions >= 3
Since SQLAlchemy 3.0 `SQLALCHEMY_RECORD_QUERIES` is no longer
automatically enabled when Flask is running in debug or testing mode so
the debug toolbar warning will never be shown.

https://flask-sqlalchemy.palletsprojects.com/en/3.0.x/config/#flask_sqlalchemy.config.SQLALCHEMY_RECORD_QUERIES
2024-03-20 14:25:36 +00:00
Mac Newbold
9b63ad1837 Support applications using flask.copy_current_request_context (#231) 2024-01-17 09:40:50 -07:00
Marc Aymerich Gunern
765f22126e Handle cases when debug toolbar has not been installed 2024-01-11 18:06:28 +00:00
Marc Aymerich Gunern
d4a8cc963e Support applications using flask.copy_current_request_context 2024-01-09 13:50:02 +00:00
Mac Newbold
b7f5a725cd Add init_app() method to DebugPanel base class (#95) 2023-12-20 09:35:17 -07:00
Malthe Jørgensen
5bf5e093bb [Add] init_app()-method to DebugPanel base class
Adds a method `DebugPanel.init_app()` that gets called from
`DebugToolbar.init_app()`.

This allows DebugPanels to register their own routes, and do setup work
that should go across requests (as opposed to per-request setup) and
needs access to the Flask `app`-object.
2023-12-15 10:14:33 +01:00
Mac Newbold
719fe02df5 Add option to dump profiler stats (#204) 2023-12-13 10:49:10 -07:00
Dosenpfand
f18bcc708a Remove trailing whitespaces 2023-12-13 10:47:24 -07:00
Dosenpfand
95c2b86bcd Add profile dump stats option 2023-12-13 10:47:24 -07:00
Mac Newbold
b03a2e6fb3 Require Flask >= 2.2.0 (#224) 2023-12-11 11:27:45 -07:00
Jeff Widman
1c39a9ce47 Require Flask >= 2.2.0, Python >= 3.7
Require Flask >= `2.2.0`.

I'm comfortable going up to requiring `3.x`, but when I grep'd for
places we use older Flask constructs, this was all I found.

So for now no need to jump further.

Flask `2.2.0` requires Python >= `3.7`, so also dropped older pythons.
2023-12-11 11:25:52 -07:00
Mac Newbold
8c8b2bb35c Add minimal test without extra deps (#230) 2023-12-10 20:18:10 -07:00
Grey Li
a2e773124f Add minimal test without extra deps
To prevent issues like https://github.com/pallets-eco/flask-debugtoolbar/pull/225,
This PR add a minimal test that no extra deps are involved, it only install
the package, then try to import the extension class.

fixes #226
2023-12-10 12:54:29 +08:00
Jeff Widman
2f8ec9027b Bump to version 0.14.1 (#227) 2023-12-07 09:31:28 -08:00
Grey Li
ab9a41df6a Add the missing install requirement packaging (#225)
The `packaging` lib is not listed in the `install_requires` list.

https://github.com/greyli/flask-extension-status/actions/runs/7129071225/job/19412328108

```
Run python -c "from flask import Flask; app = Flask(__name__); from flask_debugtoolbar import DebugToolbarExtension; DebugToolbarExtension(app)"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/opt/hostedtoolcache/Python/3.12.0/x64/lib/python3.12/site-packages/flask_debugtoolbar/__init__.py", line 6, in <module>
    from packaging import version as version_builder
ModuleNotFoundError: No module named 'packaging'
Error: Process completed with exit code 1.
```
2023-12-07 08:32:29 -08:00
Jeff Widman
2b1e7d9907 Bump version to 0.14.0 (#223)
We need this to land before we can push a release...
2023-12-06 16:48:19 -08:00
Mac Newbold
d0360218fd Drop CHANGES.rst in favor of GitHub Releases (#198) 2023-11-21 08:26:28 -07:00
Mac Newbold
e9fd3072a9 Merge branch 'master' into switch-to-using-github-auto-generated-releases 2023-11-21 08:24:53 -07:00
Grey Li
1aedfb0e2e Use standard Python gitignore file (#220)
Created from https://github.com/github/gitignore/blob/main/Python.gitignore
2023-11-20 18:29:03 -08:00
Grey Li
e6ae9d0288 Fix the test for basic app (#221)
1. Update the test app

If I understand correctly, the debug toolbar will only be enabled if `app.debug` is `True`. So I added the `DEBUG=True` to the test app.

Related code: 2b8bf9cc44/src/flask_debugtoolbar/__init__.py (L114)

2. Update the `src/flask_debugtoolbar/__init__.py`

Fix the two if statements to prevent the following errors:

```
>       if 'gzip' in response.headers.get('Content-Encoding'):
E       TypeError: argument of type 'NoneType' is not iterable
```

Since the `response.headers.get('Content-Encoding')` could be None.

With this PR, all the tests will be passed. The failed style checker will be fixed in #219
2023-11-20 18:21:38 -08:00
Grey Li
62ce443f8b Fix lint issues and lint config (#219)
For the two ignored rules:

- E731: It's OK to use lambda
- W504: W503 and W504 are conflicts with each other, we need to disable one of them.
2023-11-20 10:59:24 -08:00
Grey Li
2b8bf9cc44 Remove the use of before_first_request (#218) 2023-11-17 22:12:44 +08:00
Grey Li
42d859534a Remove the use of before_first_request 2023-11-17 22:09:25 +08:00
Grey Li
f959951185 Fix tox and GitHub actions settings (#217)
* Remove the branch constraint for pull request triggering
* Use Python 3.12 for main tests
* Use `ubuntu-20.04` for Python 3.6 since it's been removed in `ubuntu-latest`
* Remove Python 2.7 since it's not supported by GitHub Actions anymore (https://github.com/actions/setup-python/issues/672)
* Add the missing `setup-python` step
* Merge the `pip install` commands
2023-11-16 14:41:30 -08:00
dadavec
e1c8704444 Remove deprecated charset property from process_response content crafting (#211)
The `Request.charset` property is deprecated since Werkzeug version 2.3. It was removed in Werkzeug 3.0. Request data must always be UTF-8.

https://werkzeug.palletsprojects.com/en/2.3.x/wrappers/#werkzeug.wrappers.Request.charset
2023-11-15 19:53:02 -08:00
Mac Newbold
8a4cfa5e3c No need to specify custom default value if key not found (#210) 2023-11-15 17:30:39 -07:00
Grey Li
51d105afad Set up GitHub actions to replace Travis (#215) 2023-11-16 02:10:00 +08:00
Grey Li
15192f19e0 Set up github actions 2023-11-15 22:28:43 +08:00
Jeff Widman
5712e57869 No need to specify custom default value if key not found
The `''` arg specifies a custom default value if the key isn't found. However, the default of `None` works fine for boolean testing:

```python
>>> 'gzip' in [None]
False
```

I missed this when I originally reviewed https://github.com/pallets-eco/flask-debugtoolbar/pull/154.
2023-10-13 13:39:35 +00:00
Hiromasa Ihara
9571d06df5 fix: drop response.charset because charset deprecated (#206)
I took a quick peek at upstream to see if this has any backwards-breaking issues whereby we'd need to check the `werkzeug` version, but from my reading it looks it should be fine most of the time.

Also, this was deprecated back in April's `2.3.0` release and then removed in the recent `3.0.0` release, so I suspect most of our userbase will have already migrated to those versions.

Given this lib is a dev-tooling library not typically used in production, I'm not too worried about ensuring we support the 0.01% case where someone is using an old version of `werkzeug` + a custom charset.

More context:
* https://github.com/pallets/werkzeug/issues/2602
* https://github.com/pallets/werkzeug/pull/2641
* https://github.com/pallets/werkzeug/pull/2768
2023-10-13 06:35:25 -07:00
Nick Janetakis
3b25e114e9 fix: use urllib.parse.quote_plus and drop werkzeug.urls.url_quote_plus (#207) 2023-10-06 18:19:51 -04:00
Hiromasa Ihara
f7ae3fd591 fix: use urllib.parse.quote_plus and drop werkzeug.urls.url_quote_plus 2023-10-01 16:03:15 +09:00
Hiromasa Ihara
ce02d2da3c fix: migrate from deprecated flask.Markup to markupsafe.Markup (#203) 2023-05-24 10:22:56 -07:00
Jeff Widman
bd346a0fc1 Drop CHANGES.rst in favor of GitHub Releases
I started to cut a new release but realized it's a bit painful that we
are currently maintaining both a `CHANGES.rst` file and also tagging
releases in GitHub releases UI.

For a busy project, maintaining a dedicated changelog makes sense... but
the reality is this project is in maintenance mode, and we the
maintainers are more likely to cut releases when they're easy/low
friction. Since GitHub very nicely has the "Auto-generate-release-notes"
button, let's just use that.

I considered copy/pasting the results from that to `CHANGES.rst`, but
even that feels like a waste of time.
2023-01-17 20:05:25 +00:00
Jeff Widman
ed8243e17e Point URLs at pallets-eco/flask-debugtoolbar (#197) 2023-01-17 08:16:30 -08:00
Nick Janetakis
02c99a7b64 Fix Flask SQLAlchemy quickstart link (#196) 2022-12-27 08:10:52 -05:00
Francesco Frassinelli
96514793e4 Update sqlalchemy_error.html 2022-12-27 13:10:16 +01:00
Francesco Frassinelli
ec8cc3a0ba Fix Flask SQLAlchemy quickstart link 2022-12-27 10:54:53 +01:00
Jeff Widman
e3c8ab0ca2 Point at new location of django-debug-toolbar (#189) 2022-11-02 12:53:49 -07:00
Jeff Widman
fefb32b04d Fix outdated docs links (#187) 2022-11-02 12:51:06 -07:00
Nick Janetakis
b5a7c032ab Merge pull request #186 from Dosenpfand/flask-sqlalchemy-v3
Flask-SQLAlchemy 3 compatibility
2022-10-28 11:41:38 -04:00
Dosenpfand
6af24f5f44 Do not explicitly set SQLALCHEMY_TRACK_MODIFICATIONS for test/example 2022-10-28 11:28:50 +02:00
Dosenpfand
b4a197f87f Enable query recording if debug is active, remove warning 2022-10-26 14:31:14 +02:00
Dosenpfand
15b6fee933 Fix typo 2022-10-24 21:29:59 +02:00
Dosenpfand
9e03576c94 Keep config for flask_sqlalchemy < 3 2022-10-24 19:35:47 +02:00
Dosenpfand
bfa48c5a2c Add support for flask_sqlalchemy >= 3.0.0 2022-10-24 18:59:28 +02:00
sur.la.route
890fd9c7fb updated to work with flask 2.2+ (#183)
Replaced `_request_ctx_stack.top` with `request_ctx` per https://github.com/pallets/flask/pull/4682

This checks the version of `flask` and only does the switcheroo on newer versions of flask...
2022-10-04 16:20:14 -07:00
Hugo van Kemenade
42a9651950 Replace deprecated threading.currentThread with threading.current_thread (#179) 2022-09-18 14:08:43 -07:00
Nick Janetakis
ff01910f6a Merge pull request #182 from caffeinatedMike/master
Fixed scrollbar issues
2022-08-18 11:20:45 -04:00
Michael Hill
9cdb04edcb Make flDebugToolbar vertically scrollable
When on small screens where the debug toolbar is longer than the screen there was no way to access the items listed at the bottom of the toolbar. Adding `overflow-y: auto` allows a scrollbar to be used when this is the case.
2022-08-02 09:41:44 -04:00
Michael Hill
f546d4633b Fixed classname and bottom padding for scrollbar 2022-07-26 19:08:25 -04:00
Michael Hill
db07028aa0 Update scroll classname to make base.html template 2022-07-26 19:07:03 -04:00
Nick Janetakis
d44ab40729 Merge pull request #180 from timgates42/bugfix_typos
docs: Fix a few typos
2022-07-13 17:03:28 -04:00
Tim Gates
0d409f54f5 docs: Fix a few typos
There are small typos in:
- src/flask_debugtoolbar/panels/profiler.py
- src/flask_debugtoolbar/static/codemirror/mode/rst/rst.js
- src/flask_debugtoolbar/static/codemirror/mode/xquery/xquery.js
- src/flask_debugtoolbar/static/js/jquery.tablesorter.js

Fixes:
- Should read `second` rather than `secound`.
- Should read `preceded` rather than `preceeded`.
- Should read `initial` rather than `inital`.
- Should read `divided` rather than `divded`.
- Should read `debugging` rather than `debuging`.
- Should read `convenience` rather than `conveinence`.
- Should read `capabilities` rather than `capabilitys`.
2022-07-14 06:34:03 +10:00
Nate Collins
708df1c07a Expand HTTP codes on which the toolbar will be displayed (#176)
Change to expand what HTTP codes the toolbar displays on. Currently it only displays on 200 (or redirects when DEBUG_TB_INTERCEPT_REDIRECTS is enabled). However, debugging or verifying non-200 pages is commonly necessary. This change would enable display of the toolbar on other pages that may serve HTML, specifically: 201, 400, 401, 403, 404, 405, 500, 501, 502, 503, 504
2022-04-01 13:32:48 -07:00
Nathan Collins
10186a4202 Permit scrolling for content panels 2022-04-01 13:30:42 -07:00
Nate Collins
3cd2dceace Add ARIA role to toolbar for accessibility improvement (#174)
Change to improve accessibility compliance, for example useful when a developer is using a screen reader. Using the ARIA role attribute is a HTML4 compatible way of accomplishing this.

For reference: https://dequeuniversity.com/rules/axe/4.3/region

Co-authored-by: Megan Schanz <schanzme@msu.edu>
2022-04-01 13:30:16 -07:00
Megan Schanz
376c3deab3 Submodule to use https protocol after unencrypted git proto deprecated
Ref: https://github.blog/2021-09-01-improving-git-protocol-security-github/
2022-04-01 13:29:24 -07:00
Nick Janetakis
45d3588bb6 Release 0.13.1 2022-03-29 18:39:20 -04:00
Nick Janetakis
15e8d77a49 Fix changelog formatting for 0.12.X 2022-03-29 18:10:40 -04:00
Nick Janetakis
4d84f262ae Merge pull request #172 from flask-debugtoolbar/fix-setupcfg
Move library into src/ directory
2022-03-29 18:08:01 -04:00
Nick Janetakis
db64ce632c Move library into src/ directory
After building this locally I noticed all of the expected files were in
the wheel where as before this patch it was missing a lot of files.

This idea of using a src/ directory is mentioned in the official Python
documentation for packaging files at:

https://packaging.python.org/en/latest/tutorials/packaging-projects/

It's also used in Flask and other large Python projects.
2022-03-29 08:18:21 -04:00
Jeff Widman
956d7501ec Bump version for development 2022-03-28 01:19:17 -07:00
Jeff Widman
a758a9df7a Release 0.12.1 2022-03-28 01:16:17 -07:00
Jeff Widman
5eea25882c Fix changelog / docs link
I fat-fingered this in
https://github.com/flask-debugtoolbar/flask-debugtoolbar/pull/164 so
correcting it.
2022-03-28 01:14:12 -07:00
Jeff Widman
e954cd9fae Bump version for development 2022-03-27 23:48:24 -07:00
Jeff Widman
03d79be02c Release 0.12.0 2022-03-27 23:48:08 -07:00
Jeff Widman
7f17d2ce57 Update PyPI metadata files: add setup.cfg etc (#164)
Update to the newer PyPI / python packaging metadata file structure.

A lot of this was cribbed from how [`Flask`](https://github.com/pallets/flask) itself
exposes its metadata.
2022-03-26 21:51:54 -07:00
Nick Janetakis
30fba11f36 Remove with_ extension for Jinja 3.0 (#157)
Jinja 3.0 throws a deprecation warning that this will be removed in 3.1
because it's built into Jinja now without needing an extension.

However since folks might want to use Jinja 2 for a while this supports
both versions by only using the extension with Jinja 2.
2022-03-25 21:26:26 -07:00
jnnkB
d474a6a689 prefixed css classes, fixes #152 (#153) 2020-08-14 11:39:15 -07:00
zaw007
83d398d9d5 Support gzip response (#154)
* add gzip compress and decompress

* support gzip response
2020-08-14 11:37:37 -07:00
Jeff Widman
3929742d9c Cleanup version handling slightly (#149)
Some improvements I saw over on
https://github.com/FactoryBoy/factory_boy/pull/676/files that looked
useful here as well.
2020-03-09 13:10:02 -07:00
Jeff Widman
70abd78e55 Setup DB properly
When I switched over to `flask run` entrypoint in b92391d177,
I forgot that the `if name==__main__` code no longer triggers.
So the SQLite in-memory database wasn't getting created for the example
app.

This moves the DB creation to a werkzeug/Flask hook that runs before the
first request to the app, so that the DB table is created when we query
it.

Also updated the test which worked fine previously, but this is more
idiomatic.
2020-03-09 10:01:59 -07:00
Jeff Widman
dbea74b626 Update README.rst 2020-03-09 09:46:05 -07:00
Jeff Widman
c6102aeb14 Change docs to pull version from setup.py 2020-03-02 09:37:37 -08:00
Jeff Widman
10c9c1ae5d Update Flask-SQLAlchemy links 2020-02-22 20:39:21 -08:00
Yaser Amiri
9e600c6e13 Add flask.g section to show g object content. 2020-02-22 09:47:21 -08:00
Matthew Swabey
9b8a8afa97 Fix SQLAlchemy SELECT/EXPLAIN to use url_for to respect app prefixes. Provide url_for to all toolbar templates 2020-02-22 09:24:23 -08:00
Jeff Widman
39ac97a7e0 pycodestyle fixes 2020-02-18 01:21:40 -08:00
Jeff Widman
a5cb5a709f Bump version for development 2020-02-18 01:19:49 -08:00
Jeff Widman
02064c76ed Release 0.11.0 2020-02-18 01:11:19 -08:00
Jeff Widman
d713732807 Cleanup tox/travis
* Switch to python 3.8 in Travis. I tried to add 3.8 while keeping 3.7
and 3.6, but ran into issues with Travis config, so instead just bumped
straight to 3.8. Long term I'd like to explore moving to Azure
Pipelines, but don't have the time to figure that out just yet.
* `flake8` was renamed to `pycodestyle`
* `py.test` was deprecated in favor of `pytest`
2020-02-18 00:42:39 -08:00
Jeff Widman
b92391d177 Switch to Flask's native CLI
Drop `flask_script` in favor of Flask's native CLI:
* https://flask.palletsprojects.com/en/master/cli/

This also requires changing the tests so that `pytest` mocks the env var
`FLASK_ENV` so that the test app starts in development mode. Unlike
normal test apps, we _do_ want development/debug mode, in addition to
testing mode.
2020-02-17 23:57:04 -08:00
Florian
4964ae261f RoutesList: Do not show debugtoolbar routes 2020-02-17 22:30:10 -08:00
Pierre GIRAUD
ad847299c4 Add doc for SQL syntax highlighting 2020-02-17 21:57:01 -08:00
Jeff Widman
7ce099c3d0 Remove deprecated request.is_xhr
This was removed from `werkzeug` `1.0.0`.

Details:
* https://github.com/pallets/werkzeug/issues/1077
* https://github.com/pallets/werkzeug/issues/1714 (search for `is_xhr`)

Fix #144.
2020-02-17 21:50:56 -08:00
Jeff Widman
9c7db48362 Explicitly disable SQLALCHEMY_TRACK_MODIFICATIONS
This silences deprecation warnings.
Background: https://stackoverflow.com/a/33790196/770425

Note: This code can be removed once `flask_sqlalchemy` 3.0 ships, or any
release that includes
https://github.com/pallets/flask-sqlalchemy/pull/727.
2020-02-17 21:36:01 -08:00
Tim Gates
88f15cba35 Fix simple typo: exapanded -> expanded
Closes #141
2020-02-06 14:03:36 -08:00
Matt Good
d852042ccb Merge pull request #119 from davidism/json-available
don't use flask.json_available
2018-02-07 09:52:11 -08:00
David Lord
5bd2e8a423 flask.json_available is a no-op
it is removed in Flask 1.0
2018-02-07 07:13:21 -08:00
Jeff Widman
c27256c00a Bump dev version 2017-02-12 03:33:05 -08:00
204 changed files with 15369 additions and 1551 deletions

41
.github/workflows/tests.yml vendored Normal file
View File

@@ -0,0 +1,41 @@
name: Tests
on:
push:
branches:
- master
paths-ignore:
- 'docs/**'
- '*.rst'
pull_request:
paths-ignore:
- 'docs/**'
- '*.rst'
jobs:
tests:
name: ${{ matrix.name }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- {name: Linux, python: '3.12', os: ubuntu-latest, tox: py312}
- {name: Windows, python: '3.12', os: windows-latest, tox: py312}
- {name: Mac, python: '3.12', os: macos-latest, tox: py312}
- {name: Minimal, python: '3.12', os: ubuntu-latest, tox: minimal}
- {name: '3.11', python: '3.11', os: ubuntu-latest, tox: py311}
- {name: '3.10', python: '3.10', os: ubuntu-latest, tox: py310}
- {name: '3.9', python: '3.9', os: ubuntu-latest, tox: py39}
- {name: '3.8', python: '3.8', os: ubuntu-latest, tox: py38}
- {name: '3.7', python: '3.7', os: ubuntu-latest, tox: py37}
- {name: Style, python: '3.10', os: ubuntu-latest, tox: stylecheck}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python }}
- name: update pip
run: |
pip install -U setuptools wheel
python -m pip install -U pip
- run: pip install tox
- run: tox -e ${{ matrix.tox }}

162
.gitignore vendored
View File

@@ -1,6 +1,160 @@
*.egg-info
*.pyc
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
docs/_build
.tox
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/

3
.gitmodules vendored
View File

@@ -1,3 +0,0 @@
[submodule "docs/_themes"]
path = docs/_themes
url = git://github.com/mitsuhiko/flask-sphinx-themes.git

37
.readthedocs.yaml Normal file
View File

@@ -0,0 +1,37 @@
# Read the Docs configuration file for Sphinx projects
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
# Set the OS, Python version and other tools you might need
build:
os: ubuntu-lts-latest
tools:
python: "latest"
# You can also specify other tool versions:
# nodejs: "20"
# rust: "1.70"
# golang: "1.20"
# Build documentation in the "docs/" directory with Sphinx
sphinx:
configuration: docs/conf.py
# You can configure Sphinx to use a different builder, for instance use the dirhtml builder for simpler URLs
# builder: "dirhtml"
# Fail on all warnings to avoid broken references
fail_on_warning: true
# Optionally build your docs in additional formats such as PDF and ePub
# formats:
# - pdf
# - epub
# Optional but recommended, declare the Python requirements required
# to build your documentation
# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
python:
install:
- path: .
extra_requirements:
- docs

View File

@@ -1,9 +0,0 @@
sudo: false
language: python
python: "3.6"
env:
- TOXENV=py27
- TOXENV=py36
install:
- pip install tox
script: tox

View File

@@ -1,157 +0,0 @@
Changes
=======
0.10.1 (2017-02-12)
-------------------
Enhancements:
- Add support for Python wheels
Fixes:
- Switch imports from deprecated flask.ext.* to flask_* syntax (#94, thanks
Michael Lenzen & #97 thanks Iuri de Silvio)
0.10.0 (2015-04-17)
-------------------
Enhancements:
- Added new "Routes" panel displaying URL routing rules (#69, thanks Justin McKay)
- "Versions" panel displays versions of all installed packages (#49, thanks Lucas Taylor)
- SQLAlchemy displays necessary setup steps to set up query recording
- Support reformatting SQL queries if ``sqlparse`` library is available (#48, thanks Hyunjun Kim)
- Enable sorting SQLAlchemy queries (#81, thanks Eric Workman)
- Support inserting toolbar on HTML5 pages without ``</body>`` tag
- Log a warning if unable to insert the toolbar (#20, thanks Rune Halvorsen)
Fixes:
- Ensure numeric sorting of profiler "Calls" column
0.9.2 (2014-12-05)
------------------
Fixes:
- HTML escape SQL queries when syntax highlighting is not available
- Use case-insensitive comparison to normalize filenames on Windows
- Fix exception when SQL query contained non-ASCII characters
0.9.1 (2014-11-24)
------------------
Fixes:
- Fix SQL queries with byte strings on Python 3
- Fix displaying values whose `repr()` contains unprintable characters
0.9.0 (2014-01-03)
------------------
Enhancements:
- Python 3 compatibility (#54, thanks justinmayer and jmagnusson)
- Support .init_app() (#38)
- New "Config" panel displaying Flask config values (#51, thanks Alexey Diyan)
- Better PEP8-style formatting (#63, thanks Ivan Ivaschenko)
Fixes:
- Fix template editor with non-ASCII templates (#46)
0.8 (2013-02-21)
----------------
Enhancements:
- Use `itsdangerous <http://pythonhosted.org/itsdangerous/>`_ to sign SQL queries
- Expose the jQuery object as ``fldt.$`` so extensions can use the toolbar's
copy of jQuery (#42)
Fixes:
- Don't intercept redirects on XHR requests (#41)
- Fix SQL query time display as milliseconds (#36)
- Fix ``functools.partial`` error (#35)
- Fix werkzeug request logging with logging panel (#33)
- Fix SQL panel unicode encoding error (#31)
0.7.1 (2012-05-18)
------------------
Fixes:
- loading template editor in-place over current page
0.7 (2012-05-18)
----------------
Enhancements:
- Add an in-browser template editor to the template panel
- ``DEBUG_TB_PROFILER_ENABLED`` config option to enable the profiler on all
requests (normally it is user-enabled by clicking the checkmark)
0.6.3.1 (2012-04-16)
--------------------
New release to add missing changelog for 0.6.3
0.6.3 (2012-04-16)
------------------
Fixes:
- Compatibility with Flask-SQLAlchemy 0.16 package name
0.6.2 (2012-02-18)
------------------
Fixes:
- Installation issue on Windows with trailing slashes in MANIFEST.in
- JavaScript error when using conditional comments for ``<html>`` tag
(like in HTML5 Boilerplate)
0.6.1 (2012-02-15)
------------------
Fixes:
- Memory leak when toolbar was enabled
- UnicodeDecodeError when request data contained binary data (e.g. session values)
Enhancements:
- ``DEBUG_TB_ENABLED`` config setting to explicitly enable or disable the toolbar
- ``DEBUG_TB_HOSTS`` config setting to enable toolbar only for specific remote hosts
- New logo for Flask instead of Django
- Monospaced font on table data
Thanks to kennethreitz and joeshaw for their contributions.
0.6 (2012-01-04)
----------------
Flask 0.8 or higher is required
Enhancements:
- Flask 0.8 compatibility
Thanks to mvantellingen

View File

@@ -4,10 +4,10 @@ All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
2. 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.

View File

@@ -1,3 +1,3 @@
include LICENSE
recursive-include flask_debugtoolbar/templates *.html
recursive-include flask_debugtoolbar/static *
recursive-include src/flask_debugtoolbar/templates *.html
recursive-include src/flask_debugtoolbar/static *

View File

@@ -1,11 +1,11 @@
Flask Debug-toolbar
===================
This is a port of the excellent `django-debug-toolbar <https://github.com/django-debug-toolbar/django-debug-toolbar>`_
This is a port of the excellent `django-debug-toolbar <https://github.com/jazzband/django-debug-toolbar>`_
for Flask applications.
.. image:: https://travis-ci.org/mgood/flask-debugtoolbar.png?branch=master
:target: https://travis-ci.org/mgood/flask-debugtoolbar
.. image:: https://github.com/pallets-eco/flask-debugtoolbar/actions/workflows/tests.yml/badge.svg
:target: https://github.com/pallets-eco/flask-debugtoolbar/actions
Installation

View File

@@ -13,9 +13,12 @@
import datetime
import os
import pkg_resources
import sys
import time
import flask_debugtoolbar
BUILD_DATE = datetime.datetime.utcfromtimestamp(int(os.environ.get('SOURCE_DATE_EPOCH', time.time())))
@@ -34,6 +37,7 @@ BUILD_DATE = datetime.datetime.utcfromtimestamp(int(os.environ.get('SOURCE_DATE_
extensions = [
'sphinx.ext.viewcode',
'sphinx.ext.intersphinx',
'pallets_sphinx_themes',
]
# Add any paths that contain templates here, relative to this directory.
@@ -56,10 +60,10 @@ copyright = u'2012-{0}'.format(BUILD_DATE.year)
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '0.10'
# The full version, including alpha/beta/rc tags.
release = '0.10.1'
release = flask_debugtoolbar.__version__
# The short X.Y version.
version = '.'.join(release.split('.')[:2])
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@@ -96,7 +100,7 @@ pygments_style = 'sphinx'
#modindex_common_prefix = []
intersphinx_mapping = {
'flasksqlalchemy': ('http://flask-sqlalchemy.pocoo.org/latest/', None)
'flasksqlalchemy': ('https://flask-sqlalchemy.palletsprojects.com/', None)
}
@@ -109,9 +113,7 @@ html_theme = 'flask'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
html_theme_options = {
'index_logo': None,
}
html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
sys.path.append(os.path.abspath('_themes'))

View File

@@ -59,6 +59,8 @@ Name Description De
``DEBUG_TB_PANELS`` List of module/class names of panels enable all built-in panels
``DEBUG_TB_PROFILER_ENABLED`` Enable the profiler on all requests ``False``, user-enabled
``DEBUG_TB_TEMPLATE_EDITOR_ENABLED`` Enable the template editor ``False``
``DEBUG_TB_PROFILER_DUMP_FILENAME`` Filename of the profiler stats dump, ``None``, no dump will be written
can be a ``str`` or a ``callable``
==================================== ===================================== ==========================
To change one of the config options, set it in the Flask app's config like::
@@ -76,16 +78,16 @@ Panels
Contributing
------------
Fork us `on GitHub <https://github.com/mgood/flask-debugtoolbar>`_
Fork us `on GitHub <https://github.com/pallets-eco/flask-debugtoolbar>`_
Thanks
------
This was based on the original `django-debug-toolbar`_. Thanks to `Michael van Tellingen`_ for the original development of this Flask extension, and to all the `individual contributors`_.
.. _django-debug-toolbar: https://github.com/django-debug-toolbar/django-debug-toolbar
.. _django-debug-toolbar: https://github.com/jazzband/django-debug-toolbar
.. _Michael van Tellingen: https://github.com/mvantellingen
.. _individual contributors: https://github.com/mgood/flask-debugtoolbar/graphs/contributors
.. _individual contributors: https://github.com/pallets-eco/flask-debugtoolbar/graphs/contributors
Indices and tables
==================

View File

@@ -13,7 +13,7 @@ Time
flask_debugtoolbar.panels.timer.TimerDebugPanel
Shows the time taken to process the current request. The exapanded view includes the breakdown of CPU time, by user and system, wall clock time, and context switches.
Shows the time taken to process the current request. The expanded view includes the breakdown of CPU time, by user and system, wall clock time, and context switches.
.. image:: _static/screenshot-time-panel.png
@@ -72,9 +72,13 @@ Shows SQL queries run during the current request.
For additional details on query recording see the
:py:func:`~flask_sqlalchemy.get_debug_queries` documentation.
.. note:: SQL syntax highlighting requires `Pygments`_ to be installed.
.. image:: _static/screenshot-sqlalchemy-panel.png
.. _Flask-SQLAlchemy: http://flask-sqlalchemy.pocoo.org/
.. _Flask-SQLAlchemy: https://flask-sqlalchemy.palletsprojects.com/
.. _Pygments: https://pygments.org/
Logging

View File

@@ -1,8 +1,6 @@
import sys
sys.path.insert(0, '.')
# Run using: `FLASK_DEBUG=True flask run`
from flask import Flask, render_template, redirect, url_for
from flask_script import Manager
from flask_sqlalchemy import SQLAlchemy
from flask_debugtoolbar import DebugToolbarExtension
@@ -16,10 +14,12 @@ app.config['DEBUG_TB_INTERCEPT_REDIRECTS'] = True
#)
#app.config['DEBUG_TB_HOSTS'] = ('127.0.0.1', '::1' )
app.config['SECRET_KEY'] = 'asd'
app.config['DEBUG'] = True
app.config['SQLALCHEMY_RECORD_QUERIES'] = True
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
db = SQLAlchemy(app)
# This is no longer needed for Flask-SQLAlchemy 3.0+, if you're using 2.X you'll want to define this:
# app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
toolbar = DebugToolbarExtension(app)
@@ -37,13 +37,10 @@ def index():
@app.route('/redirect')
def redirect_example():
response = redirect(url_for('index'))
response.set_cookie('test_cookie', '1')
return response
if __name__ == "__main__":
db.create_all()
manager = Manager(app)
manager.run()
with app.app_context():
db.create_all()

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -1,33 +0,0 @@
<h4>Installed Packages</h4>
<p>
Installation paths relative to:
</p>
<pre>
{{ python_lib }}
</pre>
<table>
<thead>
<tr>
<th>Package</th>
<th>Version</th>
<th>Installed Path</th>
</tr>
</thead>
<tbody>
{% for package in packages %}
<tr class="{{ loop.cycle('flDebugOdd', 'flDebugEven') }}">
<td>{{ package.project_name }}</td>
<td>{{ package.version }}</td>
<td>{{ relpath(package.location, python_lib) }}</td>
</tr>
{% else %}
<tr>
<td>setuptools</td>
<td>NOT INSTALLED</td>
<td>Install setuptools to display installed packages and version information</td>
</tr>
{% endfor %}
</tbody>
</table>

6
pyproject.toml Normal file
View File

@@ -0,0 +1,6 @@
[build-system]
requires = [
"setuptools>=42",
"wheel"
]
build-backend = "setuptools.build_meta"

View File

@@ -1,2 +1,36 @@
[bdist_wheel]
universal=1
[metadata]
name = Flask-DebugToolbar
version = 0.15.0
author = Michael van Tellingen
author_email = michaelvantellingen@gmail.com
maintainer = Matt Good
maintainer_email = matt@matt-good.net
description = A toolbar overlay for debugging Flask applications.
long_description = file: README.rst
long_description_content_type = text/x-rst
keywords = flask, debug, toolbar
url = https://github.com/pallets-eco/flask-debugtoolbar
project_urls =
Changelog = https://github.com/pallets-eco/flask-debugtoolbar/releases
Documentation = https://flask-debugtoolbar.readthedocs.io/
classifiers =
Development Status :: 4 - Beta
Environment :: Web Environment
Framework :: Flask
Intended Audience :: Developers
License :: OSI Approved :: BSD License
Operating System :: OS Independent
Programming Language :: Python
Topic :: Internet :: WWW/HTTP :: Dynamic Content
Topic :: Software Development :: Libraries :: Python Modules
[options]
package_dir =
= src
packages = find:
include_package_data = True
python_requires = >=3.7
[options.packages.find]
where = src

View File

@@ -1,48 +1,20 @@
import os
from setuptools import setup
here = os.path.abspath(os.path.dirname(__file__))
try:
README = open(os.path.join(here, 'README.rst')).read()
CHANGES = open(os.path.join(here, 'CHANGES.rst')).read()
except:
README = ''
CHANGES = ''
# Metadata goes in setup.cfg. These are here for GitHub's dependency graph.
setup(
name='Flask-DebugToolbar',
version='0.10.1',
url='https://flask-debugtoolbar.readthedocs.io/',
license='BSD',
author='Michael van Tellingen',
author_email='michaelvantellingen@gmail.com',
maintainer='Matt Good',
maintainer_email='matt@matt-good.net',
description='A toolbar overlay for debugging Flask applications.',
long_description=README + '\n\n' + CHANGES,
zip_safe=False,
platforms='any',
include_package_data=True,
packages=['flask_debugtoolbar',
'flask_debugtoolbar.panels'
],
name="Flask-DebugToolbar",
install_requires=[
'Flask>=0.8',
'Flask>=2.2.0',
'Blinker',
'itsdangerous',
'werkzeug',
'MarkupSafe',
'packaging',
],
classifiers=[
'Development Status :: 4 - Beta',
'Environment :: Web Environment',
'Intended Audience :: Developers',
'License :: OSI Approved :: BSD License',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
'Topic :: Software Development :: Libraries :: Python Modules'
]
extras_require={
"docs": [
'Sphinx>=1.2.2',
'Pallets-Sphinx-Themes',
],
}
)

View File

@@ -1,14 +1,28 @@
import contextvars
import os
import urllib.parse
import warnings
from flask import Blueprint, current_app, request, g, send_from_directory
from flask.globals import _request_ctx_stack
import flask
from flask import Blueprint, current_app, request, g, send_from_directory, url_for
from flask.globals import request_ctx
from jinja2 import __version__ as __jinja_version__
from jinja2 import Environment, PackageLoader
from werkzeug.urls import url_quote_plus
from flask_debugtoolbar.compat import iteritems
from flask_debugtoolbar.toolbar import DebugToolbar
from flask_debugtoolbar.utils import decode_text
from flask_debugtoolbar.utils import decode_text, gzip_compress, gzip_decompress
try:
# Python 3.8+
from importlib.metadata import version
__version__ = version("Flask-DebugToolbar")
except ImportError:
import pkg_resources
__version__ = pkg_resources.get_distribution("Flask-DebugToolbar").version
module = Blueprint('debugtoolbar', __name__)
@@ -39,20 +53,28 @@ class DebugToolbarExtension(object):
_static_dir = os.path.realpath(
os.path.join(os.path.dirname(__file__), 'static'))
_toolbar_codes = [200, 201, 400, 401, 403, 404, 405, 500, 501, 502, 503, 504]
_redirect_codes = [301, 302, 303, 304]
def __init__(self, app=None):
self.app = app
self.debug_toolbars = {}
# Support threads running `flask.copy_current_request_context` without
# poping toolbar during `teardown_request`
self.debug_toolbars_var = contextvars.ContextVar('debug_toolbars')
jinja_extensions = ['jinja2.ext.i18n']
if __jinja_version__[0] == '2':
jinja_extensions.append('jinja2.ext.with_')
# Configure jinja for the internal templates and add url rules
# for static data
self.jinja_env = Environment(
autoescape=True,
extensions=['jinja2.ext.i18n', 'jinja2.ext.with_'],
extensions=jinja_extensions,
loader=PackageLoader(__name__, 'templates'))
self.jinja_env.filters['urlencode'] = url_quote_plus
self.jinja_env.filters['urlencode'] = urllib.parse.quote_plus
self.jinja_env.filters['printable'] = _printable
self.jinja_env.globals['url_for'] = url_for
if app is not None:
self.init_app(app)
@@ -99,12 +121,14 @@ class DebugToolbarExtension(object):
'flask_debugtoolbar.panels.logger.LoggingPanel',
'flask_debugtoolbar.panels.route_list.RouteListDebugPanel',
'flask_debugtoolbar.panels.profiler.ProfilerDebugPanel',
'flask_debugtoolbar.panels.g.GDebugPanel',
),
'SQLALCHEMY_RECORD_QUERIES': app.debug,
}
def dispatch_request(self):
"""Modified version of Flask.dispatch_request to call process_view."""
req = _request_ctx_stack.top.request
req = request_ctx.request
app = current_app
if req.routing_exception is not None:
@@ -146,11 +170,11 @@ class DebugToolbarExtension(object):
return
real_request = request._get_current_object()
self.debug_toolbars[real_request] = (
self.debug_toolbars_var.set({})
self.debug_toolbars_var.get()[real_request] = (
DebugToolbar(real_request, self.jinja_env))
for panel in self.debug_toolbars[real_request].panels:
for panel in self.debug_toolbars_var.get()[real_request].panels:
panel.process_request(real_request)
def process_view(self, app, view_func, view_kwargs):
@@ -159,7 +183,7 @@ class DebugToolbarExtension(object):
"""
real_request = request._get_current_object()
try:
toolbar = self.debug_toolbars[real_request]
toolbar = self.debug_toolbars_var.get({})[real_request]
except KeyError:
return view_func
@@ -172,14 +196,13 @@ class DebugToolbarExtension(object):
def process_response(self, response):
real_request = request._get_current_object()
if real_request not in self.debug_toolbars:
if real_request not in self.debug_toolbars_var.get({}):
return response
# Intercept http redirect codes and display an html page with a
# link to the target.
if current_app.config['DEBUG_TB_INTERCEPT_REDIRECTS']:
if (response.status_code in self._redirect_codes and
not real_request.is_xhr):
if response.status_code in self._redirect_codes:
redirect_to = response.location
redirect_code = response.status_code
if redirect_to:
@@ -192,14 +215,18 @@ class DebugToolbarExtension(object):
response.response = [content]
response.status_code = 200
# If the http response code is 200 then we process to add the
# If the http response code is an allowed code then we process to add the
# toolbar to the returned html response.
if not (response.status_code == 200 and
if not (response.status_code in self._toolbar_codes and
response.is_sequence and
response.headers['content-type'].startswith('text/html')):
return response
response_html = response.data.decode(response.charset)
content_encoding = response.headers.get('Content-Encoding')
if content_encoding and 'gzip' in content_encoding:
response_html = gzip_decompress(response.data).decode()
else:
response_html = response.get_data(as_text=True)
no_case = response_html.lower()
body_end = no_case.rfind('</body>')
@@ -215,7 +242,7 @@ class DebugToolbarExtension(object):
' </body> tag not found in response.')
return response
toolbar = self.debug_toolbars[real_request]
toolbar = self.debug_toolbars_var.get()[real_request]
for panel in toolbar.panels:
panel.process_response(real_request, response)
@@ -223,14 +250,17 @@ class DebugToolbarExtension(object):
toolbar_html = toolbar.render_toolbar()
content = ''.join((before, toolbar_html, after))
content = content.encode(response.charset)
content = content.encode('utf-8')
if content_encoding and 'gzip' in content_encoding:
content = gzip_compress(content)
response.response = [content]
response.content_length = len(content)
return response
def teardown_request(self, exc):
self.debug_toolbars.pop(request._get_current_object(), None)
# debug_toolbars_var won't be set under `flask.copy_current_request_context`
self.debug_toolbars_var.get({}).pop(request._get_current_object(), None)
def render(self, template_name, context):
template = self.jinja_env.get_template(template_name)

View File

@@ -25,6 +25,29 @@ class DebugPanel(object):
# If the client enabled the panel
self.is_active = False
@classmethod
def init_app(cls, app):
"""Method that can be overridden by child classes.
Can be used for setting up additional URL-rules/routes.
Example::
class UMLDiagramPanel(DebugPanel):
@classmethod
def init_app(cls, app):
app.add_url_rule(
'/_flask_debugtoolbar_umldiagram/<path:filename>',
'_flask_debugtoolbar_umldiagram.serve_generated_image',
cls.serve_generated_image
)
@classmethod
def serve_generated_image(cls, app):
return Response(...)
"""
pass
def render(self, template_name, context):
template = self.jinja_env.get_template(template_name)
return template.render(**context)

View File

@@ -0,0 +1,28 @@
from flask import g
from flask_debugtoolbar.panels import DebugPanel
_ = lambda x: x
class GDebugPanel(DebugPanel):
"""
A panel to display flask.g content.
"""
name = 'g'
has_content = True
def nav_title(self):
return _('flask.g')
def title(self):
return _('flask.g content')
def url(self):
return ''
def content(self):
context = self.context.copy()
context.update({
'g_content': g.__dict__
})
return self.render('panels/g.html', context)

View File

@@ -30,14 +30,14 @@ class ThreadTrackingHandler(logging.Handler):
provided, returns a list for the current thread.
"""
if thread is None:
thread = threading.currentThread()
thread = threading.current_thread()
if thread not in self.records:
self.records[thread] = []
return self.records[thread]
def clear_records(self, thread=None):
if thread is None:
thread = threading.currentThread()
thread = threading.current_thread()
if thread in self.records:
del self.records[thread]

View File

@@ -14,6 +14,7 @@ class ProfilerDebugPanel(DebugPanel):
"""
Panel that displays the time a response took with cProfile output.
"""
name = 'Profiler'
user_activate = True
@@ -22,6 +23,9 @@ class ProfilerDebugPanel(DebugPanel):
DebugPanel.__init__(self, jinja_env, context=context)
if current_app.config.get('DEBUG_TB_PROFILER_ENABLED'):
self.is_active = True
self.dump_filename = current_app.config.get(
"DEBUG_TB_PROFILER_DUMP_FILENAME"
)
def has_content(self):
return bool(self.profiler)
@@ -73,7 +77,7 @@ class ProfilerDebugPanel(DebugPanel):
# Cumulative time
current['cumtime'] = info[3] * 1000
# Quotient of the cumulative time divded by the number of
# Quotient of the cumulative time divided by the number of
# primitive calls.
if info[0]:
current['percall_cum'] = info[3] * 1000 / info[0]
@@ -88,13 +92,20 @@ class ProfilerDebugPanel(DebugPanel):
self.stats = stats
self.function_calls = function_calls
# destroy the profiler just in case
if self.dump_filename:
if callable(self.dump_filename):
filename = self.dump_filename()
else:
filename = self.dump_filename
self.profiler.dump_stats(filename)
return response
def title(self):
if not self.is_active:
return "Profiler not active"
return 'View: %.2fms' % (float(self.stats.total_tt)*1000,)
return 'View: %.2fms' % (float(self.stats.total_tt) * 1000,)
def nav_title(self):
return 'Profiler'
@@ -102,7 +113,7 @@ class ProfilerDebugPanel(DebugPanel):
def nav_subtitle(self):
if not self.is_active:
return "in-active"
return 'View: %.2fms' % (float(self.stats.total_tt)*1000,)
return 'View: %.2fms' % (float(self.stats.total_tt) * 1000,)
def url(self):
return ''

View File

@@ -26,7 +26,11 @@ class RouteListDebugPanel(DebugPanel):
return '%s %s' % (count, 'route' if count == 1 else 'routes')
def process_request(self, request):
self.routes = list(current_app.url_map.iter_rules())
self.routes = [
rule
for rule in current_app.url_map.iter_rules()
if not rule.rule.startswith('/_debug_toolbar')
]
def content(self):
return self.render('panels/route_list.html', {

View File

@@ -1,18 +1,31 @@
try:
from flask_sqlalchemy import get_debug_queries, SQLAlchemy
from flask_sqlalchemy import SQLAlchemy
except ImportError:
sqlalchemy_available = False
get_debug_queries = SQLAlchemy = None
get_recorded_queries = SQLAlchemy = None
else:
try:
from flask_sqlalchemy.record_queries import get_recorded_queries
debug_enables_record_queries = False
except ImportError:
# For flask_sqlalchemy < 3.0.0
from flask_sqlalchemy import get_debug_queries as get_recorded_queries
# flask_sqlalchemy < 3.0.0 automatically enabled
# SQLALCHEMY_RECORD_QUERIES in debug or test mode
debug_enables_record_queries = True
location_property = 'context'
else:
location_property = 'location'
sqlalchemy_available = True
from flask import request, current_app, abort, json_available, g
from flask import request, current_app, abort, g
from flask_debugtoolbar import module
from flask_debugtoolbar.panels import DebugPanel
from flask_debugtoolbar.utils import format_fname, format_sql
import itsdangerous
_ = lambda x: x
@@ -54,18 +67,19 @@ def extension_used():
def recording_enabled():
return (current_app.debug
or current_app.config.get('SQLALCHEMY_RECORD_QUERIES'))
return (
(debug_enables_record_queries and current_app.debug) or
current_app.config.get('SQLALCHEMY_RECORD_QUERIES')
)
def is_available():
return (json_available and sqlalchemy_available
and extension_used() and recording_enabled())
return sqlalchemy_available and extension_used() and recording_enabled()
def get_queries():
if get_debug_queries:
return get_debug_queries()
if get_recorded_queries:
return get_recorded_queries()
else:
return []
@@ -108,7 +122,6 @@ class SQLAlchemyDebugPanel(DebugPanel):
if not queries and not is_available():
return self.render('panels/sqlalchemy_error.html', {
'json_available': json_available,
'sqlalchemy_available': sqlalchemy_available,
'extension_used': extension_used(),
'recording_enabled': recording_enabled(),
@@ -120,11 +133,12 @@ class SQLAlchemyDebugPanel(DebugPanel):
'duration': query.duration,
'sql': format_sql(query.statement, query.parameters),
'signed_query': dump_query(query.statement, query.parameters),
'context_long': query.context,
'context': format_fname(query.context)
'location_long': getattr(query, location_property),
'location': format_fname(getattr(query, location_property))
})
return self.render('panels/sqlalchemy.html', {'queries': data})
# Panel views

View File

@@ -52,8 +52,7 @@ class TimerDebugPanel(DebugPanel):
return ''
def _elapsed_ru(self, name):
return (getattr(self._end_rusage, name)
- getattr(self._start_rusage, name))
return (getattr(self._end_rusage, name) - getattr(self._start_rusage, name))
def content(self):

View File

@@ -1,22 +1,22 @@
import os
from distutils.sysconfig import get_python_lib
from sysconfig import get_path
from flask import __version__ as flask_version
from flask_debugtoolbar.panels import DebugPanel
try:
# Python 3.8+
from importlib.metadata import version
flask_version = version('flask')
except ImportError:
import pkg_resources
flask_version = pkg_resources.get_distribution('flask').version
_ = lambda x: x
def relpath(location, python_lib):
location = os.path.normpath(location)
relative = os.path.relpath(location, python_lib)
if relative == os.path.curdir:
return ''
elif relative.startswith(os.path.pardir):
return location
return relative
class VersionDebugPanel(DebugPanel):
"""
Panel that displays the Flask version.
@@ -38,15 +38,14 @@ class VersionDebugPanel(DebugPanel):
def content(self):
try:
import pkg_resources
import importlib.metadata
except ImportError:
packages = []
else:
packages = sorted(pkg_resources.working_set,
key=lambda p: p.project_name.lower())
packages_metadata = [p.metadata for p in importlib.metadata.distributions()]
packages = sorted(packages_metadata, key=lambda p: p['Name'].lower())
return self.render('panels/versions.html', {
'packages': packages,
'python_lib': os.path.normpath(get_python_lib()),
'relpath': relpath,
'python_lib_dir': os.path.normpath(get_path('platlib')),
})

View File

@@ -183,7 +183,7 @@ CodeMirror.defineMode('rst', function(config, options) {
setState(state, inline, {
ch: orig, // inline() has to know what to search for
wide: wide, // are we looking for `ch` or `chch`
prev: null, // terminator must not be preceeded with whitespace
prev: null, // terminator must not be preceded with whitespace
token: token // I don't want to recompute this all the time
});

Some files were not shown because too many files have changed in this diff Show More