This is page 152 of 168. Use http://codebase.md/romanshablio/mcp_server?lines=true&page={x} to view the full context.
# Directory Structure
```
├── .DS_Store
├── .venv
│ ├── __pycache__
│ │ └── hello.cpython-312.pyc
│ ├── bin
│ │ ├── activate
│ │ ├── activate.csh
│ │ ├── activate.fish
│ │ ├── Activate.ps1
│ │ ├── flask
│ │ ├── normalizer
│ │ ├── pip
│ │ ├── pip3
│ │ ├── pip3.12
│ │ ├── python
│ │ ├── python3
│ │ └── python3.12
│ ├── hello.py
│ ├── lib
│ │ └── python3.12
│ │ └── site-packages
│ │ ├── beautifulsoup4-4.12.3.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── licenses
│ │ │ │ ├── AUTHORS
│ │ │ │ └── LICENSE
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── REQUESTED
│ │ │ └── WHEEL
│ │ ├── blinker
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── _utilities.cpython-312.pyc
│ │ │ │ └── base.cpython-312.pyc
│ │ │ ├── _utilities.py
│ │ │ ├── base.py
│ │ │ └── py.typed
│ │ ├── blinker-1.8.2.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ └── WHEEL
│ │ ├── bs4
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── css.cpython-312.pyc
│ │ │ │ ├── dammit.cpython-312.pyc
│ │ │ │ ├── diagnose.cpython-312.pyc
│ │ │ │ ├── element.cpython-312.pyc
│ │ │ │ └── formatter.cpython-312.pyc
│ │ │ ├── builder
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── _html5lib.cpython-312.pyc
│ │ │ │ │ ├── _htmlparser.cpython-312.pyc
│ │ │ │ │ └── _lxml.cpython-312.pyc
│ │ │ │ ├── _html5lib.py
│ │ │ │ ├── _htmlparser.py
│ │ │ │ └── _lxml.py
│ │ │ ├── css.py
│ │ │ ├── dammit.py
│ │ │ ├── diagnose.py
│ │ │ ├── element.py
│ │ │ ├── formatter.py
│ │ │ └── tests
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── test_builder_registry.cpython-312.pyc
│ │ │ │ ├── test_builder.cpython-312.pyc
│ │ │ │ ├── test_css.cpython-312.pyc
│ │ │ │ ├── test_dammit.cpython-312.pyc
│ │ │ │ ├── test_docs.cpython-312.pyc
│ │ │ │ ├── test_element.cpython-312.pyc
│ │ │ │ ├── test_formatter.cpython-312.pyc
│ │ │ │ ├── test_fuzz.cpython-312.pyc
│ │ │ │ ├── test_html5lib.cpython-312.pyc
│ │ │ │ ├── test_htmlparser.cpython-312.pyc
│ │ │ │ ├── test_lxml.cpython-312.pyc
│ │ │ │ ├── test_navigablestring.cpython-312.pyc
│ │ │ │ ├── test_pageelement.cpython-312.pyc
│ │ │ │ ├── test_soup.cpython-312.pyc
│ │ │ │ ├── test_tag.cpython-312.pyc
│ │ │ │ └── test_tree.cpython-312.pyc
│ │ │ ├── fuzz
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-4670634698080256.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-4818336571064320.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-4999465949331456.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5000587759190016.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5167584867909632.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5270998950477824.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5375146639360000.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5492400320282624.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5703933063462912.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5843991618256896.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5984173902397440.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6124268085182464.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6241471367348224.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6306874195312640.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6450958476902400.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6600557255327744.testcase
│ │ │ │ ├── crash-0d306a50c8ed8bcd0785b67000fcd5dea1d33f08.testcase
│ │ │ │ └── crash-ffbdfa8a2b26f13537b68d3794b0478a4090ee4a.testcase
│ │ │ ├── test_builder_registry.py
│ │ │ ├── test_builder.py
│ │ │ ├── test_css.py
│ │ │ ├── test_dammit.py
│ │ │ ├── test_docs.py
│ │ │ ├── test_element.py
│ │ │ ├── test_formatter.py
│ │ │ ├── test_fuzz.py
│ │ │ ├── test_html5lib.py
│ │ │ ├── test_htmlparser.py
│ │ │ ├── test_lxml.py
│ │ │ ├── test_navigablestring.py
│ │ │ ├── test_pageelement.py
│ │ │ ├── test_soup.py
│ │ │ ├── test_tag.py
│ │ │ └── test_tree.py
│ │ ├── certifi
│ │ │ ├── __init__.py
│ │ │ ├── __main__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ └── core.cpython-312.pyc
│ │ │ ├── cacert.pem
│ │ │ ├── core.py
│ │ │ └── py.typed
│ │ ├── certifi-2024.8.30.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── charset_normalizer
│ │ │ ├── __init__.py
│ │ │ ├── __main__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ ├── api.cpython-312.pyc
│ │ │ │ ├── cd.cpython-312.pyc
│ │ │ │ ├── constant.cpython-312.pyc
│ │ │ │ ├── legacy.cpython-312.pyc
│ │ │ │ ├── md.cpython-312.pyc
│ │ │ │ ├── models.cpython-312.pyc
│ │ │ │ ├── utils.cpython-312.pyc
│ │ │ │ └── version.cpython-312.pyc
│ │ │ ├── api.py
│ │ │ ├── cd.py
│ │ │ ├── cli
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __main__.py
│ │ │ │ └── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ └── __main__.cpython-312.pyc
│ │ │ ├── constant.py
│ │ │ ├── legacy.py
│ │ │ ├── md__mypyc.cpython-312-darwin.so
│ │ │ ├── md.cpython-312-darwin.so
│ │ │ ├── md.py
│ │ │ ├── models.py
│ │ │ ├── py.typed
│ │ │ ├── utils.py
│ │ │ └── version.py
│ │ ├── charset_normalizer-3.4.0.dist-info
│ │ │ ├── entry_points.txt
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── click
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── _compat.cpython-312.pyc
│ │ │ │ ├── _termui_impl.cpython-312.pyc
│ │ │ │ ├── _textwrap.cpython-312.pyc
│ │ │ │ ├── _winconsole.cpython-312.pyc
│ │ │ │ ├── core.cpython-312.pyc
│ │ │ │ ├── decorators.cpython-312.pyc
│ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ ├── formatting.cpython-312.pyc
│ │ │ │ ├── globals.cpython-312.pyc
│ │ │ │ ├── parser.cpython-312.pyc
│ │ │ │ ├── shell_completion.cpython-312.pyc
│ │ │ │ ├── termui.cpython-312.pyc
│ │ │ │ ├── testing.cpython-312.pyc
│ │ │ │ ├── types.cpython-312.pyc
│ │ │ │ └── utils.cpython-312.pyc
│ │ │ ├── _compat.py
│ │ │ ├── _termui_impl.py
│ │ │ ├── _textwrap.py
│ │ │ ├── _winconsole.py
│ │ │ ├── core.py
│ │ │ ├── decorators.py
│ │ │ ├── exceptions.py
│ │ │ ├── formatting.py
│ │ │ ├── globals.py
│ │ │ ├── parser.py
│ │ │ ├── py.typed
│ │ │ ├── shell_completion.py
│ │ │ ├── termui.py
│ │ │ ├── testing.py
│ │ │ ├── types.py
│ │ │ └── utils.py
│ │ ├── click-8.1.7.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.rst
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── fake_useragent
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── errors.cpython-312.pyc
│ │ │ │ ├── fake.cpython-312.pyc
│ │ │ │ ├── log.cpython-312.pyc
│ │ │ │ ├── settings.cpython-312.pyc
│ │ │ │ └── utils.cpython-312.pyc
│ │ │ ├── data
│ │ │ │ └── browsers.json
│ │ │ ├── errors.py
│ │ │ ├── fake.py
│ │ │ ├── log.py
│ │ │ ├── settings.py
│ │ │ └── utils.py
│ │ ├── fake_useragent-1.5.1.dist-info
│ │ │ ├── AUTHORS
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── REQUESTED
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── flask
│ │ │ ├── __init__.py
│ │ │ ├── __main__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ ├── app.cpython-312.pyc
│ │ │ │ ├── blueprints.cpython-312.pyc
│ │ │ │ ├── cli.cpython-312.pyc
│ │ │ │ ├── config.cpython-312.pyc
│ │ │ │ ├── ctx.cpython-312.pyc
│ │ │ │ ├── debughelpers.cpython-312.pyc
│ │ │ │ ├── globals.cpython-312.pyc
│ │ │ │ ├── helpers.cpython-312.pyc
│ │ │ │ ├── logging.cpython-312.pyc
│ │ │ │ ├── sessions.cpython-312.pyc
│ │ │ │ ├── signals.cpython-312.pyc
│ │ │ │ ├── templating.cpython-312.pyc
│ │ │ │ ├── testing.cpython-312.pyc
│ │ │ │ ├── typing.cpython-312.pyc
│ │ │ │ ├── views.cpython-312.pyc
│ │ │ │ └── wrappers.cpython-312.pyc
│ │ │ ├── app.py
│ │ │ ├── blueprints.py
│ │ │ ├── cli.py
│ │ │ ├── config.py
│ │ │ ├── ctx.py
│ │ │ ├── debughelpers.py
│ │ │ ├── globals.py
│ │ │ ├── helpers.py
│ │ │ ├── json
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── provider.cpython-312.pyc
│ │ │ │ │ └── tag.cpython-312.pyc
│ │ │ │ ├── provider.py
│ │ │ │ └── tag.py
│ │ │ ├── logging.py
│ │ │ ├── py.typed
│ │ │ ├── sansio
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── app.cpython-312.pyc
│ │ │ │ │ ├── blueprints.cpython-312.pyc
│ │ │ │ │ └── scaffold.cpython-312.pyc
│ │ │ │ ├── app.py
│ │ │ │ ├── blueprints.py
│ │ │ │ ├── README.md
│ │ │ │ └── scaffold.py
│ │ │ ├── sessions.py
│ │ │ ├── signals.py
│ │ │ ├── templating.py
│ │ │ ├── testing.py
│ │ │ ├── typing.py
│ │ │ ├── views.py
│ │ │ └── wrappers.py
│ │ ├── flask-3.0.3.dist-info
│ │ │ ├── entry_points.txt
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── REQUESTED
│ │ │ └── WHEEL
│ │ ├── idna
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── codec.cpython-312.pyc
│ │ │ │ ├── compat.cpython-312.pyc
│ │ │ │ ├── core.cpython-312.pyc
│ │ │ │ ├── idnadata.cpython-312.pyc
│ │ │ │ ├── intranges.cpython-312.pyc
│ │ │ │ ├── package_data.cpython-312.pyc
│ │ │ │ └── uts46data.cpython-312.pyc
│ │ │ ├── codec.py
│ │ │ ├── compat.py
│ │ │ ├── core.py
│ │ │ ├── idnadata.py
│ │ │ ├── intranges.py
│ │ │ ├── package_data.py
│ │ │ ├── py.typed
│ │ │ └── uts46data.py
│ │ ├── idna-3.10.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.md
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ └── WHEEL
│ │ ├── itsdangerous
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── _json.cpython-312.pyc
│ │ │ │ ├── encoding.cpython-312.pyc
│ │ │ │ ├── exc.cpython-312.pyc
│ │ │ │ ├── serializer.cpython-312.pyc
│ │ │ │ ├── signer.cpython-312.pyc
│ │ │ │ ├── timed.cpython-312.pyc
│ │ │ │ └── url_safe.cpython-312.pyc
│ │ │ ├── _json.py
│ │ │ ├── encoding.py
│ │ │ ├── exc.py
│ │ │ ├── py.typed
│ │ │ ├── serializer.py
│ │ │ ├── signer.py
│ │ │ ├── timed.py
│ │ │ └── url_safe.py
│ │ ├── itsdangerous-2.2.0.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ └── WHEEL
│ │ ├── jinja2
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── _identifier.cpython-312.pyc
│ │ │ │ ├── async_utils.cpython-312.pyc
│ │ │ │ ├── bccache.cpython-312.pyc
│ │ │ │ ├── compiler.cpython-312.pyc
│ │ │ │ ├── constants.cpython-312.pyc
│ │ │ │ ├── debug.cpython-312.pyc
│ │ │ │ ├── defaults.cpython-312.pyc
│ │ │ │ ├── environment.cpython-312.pyc
│ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ ├── ext.cpython-312.pyc
│ │ │ │ ├── filters.cpython-312.pyc
│ │ │ │ ├── idtracking.cpython-312.pyc
│ │ │ │ ├── lexer.cpython-312.pyc
│ │ │ │ ├── loaders.cpython-312.pyc
│ │ │ │ ├── meta.cpython-312.pyc
│ │ │ │ ├── nativetypes.cpython-312.pyc
│ │ │ │ ├── nodes.cpython-312.pyc
│ │ │ │ ├── optimizer.cpython-312.pyc
│ │ │ │ ├── parser.cpython-312.pyc
│ │ │ │ ├── runtime.cpython-312.pyc
│ │ │ │ ├── sandbox.cpython-312.pyc
│ │ │ │ ├── tests.cpython-312.pyc
│ │ │ │ ├── utils.cpython-312.pyc
│ │ │ │ └── visitor.cpython-312.pyc
│ │ │ ├── _identifier.py
│ │ │ ├── async_utils.py
│ │ │ ├── bccache.py
│ │ │ ├── compiler.py
│ │ │ ├── constants.py
│ │ │ ├── debug.py
│ │ │ ├── defaults.py
│ │ │ ├── environment.py
│ │ │ ├── exceptions.py
│ │ │ ├── ext.py
│ │ │ ├── filters.py
│ │ │ ├── idtracking.py
│ │ │ ├── lexer.py
│ │ │ ├── loaders.py
│ │ │ ├── meta.py
│ │ │ ├── nativetypes.py
│ │ │ ├── nodes.py
│ │ │ ├── optimizer.py
│ │ │ ├── parser.py
│ │ │ ├── py.typed
│ │ │ ├── runtime.py
│ │ │ ├── sandbox.py
│ │ │ ├── tests.py
│ │ │ ├── utils.py
│ │ │ └── visitor.py
│ │ ├── jinja2-3.1.4.dist-info
│ │ │ ├── entry_points.txt
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ └── WHEEL
│ │ ├── lxml
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── _elementpath.cpython-312.pyc
│ │ │ │ ├── builder.cpython-312.pyc
│ │ │ │ ├── cssselect.cpython-312.pyc
│ │ │ │ ├── doctestcompare.cpython-312.pyc
│ │ │ │ ├── ElementInclude.cpython-312.pyc
│ │ │ │ ├── pyclasslookup.cpython-312.pyc
│ │ │ │ ├── sax.cpython-312.pyc
│ │ │ │ └── usedoctest.cpython-312.pyc
│ │ │ ├── _elementpath.cpython-312-darwin.so
│ │ │ ├── _elementpath.py
│ │ │ ├── apihelpers.pxi
│ │ │ ├── builder.cpython-312-darwin.so
│ │ │ ├── builder.py
│ │ │ ├── classlookup.pxi
│ │ │ ├── cleanup.pxi
│ │ │ ├── cssselect.py
│ │ │ ├── debug.pxi
│ │ │ ├── docloader.pxi
│ │ │ ├── doctestcompare.py
│ │ │ ├── dtd.pxi
│ │ │ ├── ElementInclude.py
│ │ │ ├── etree_api.h
│ │ │ ├── etree.cpython-312-darwin.so
│ │ │ ├── etree.h
│ │ │ ├── etree.pyx
│ │ │ ├── extensions.pxi
│ │ │ ├── html
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── _diffcommand.cpython-312.pyc
│ │ │ │ │ ├── _html5builder.cpython-312.pyc
│ │ │ │ │ ├── _setmixin.cpython-312.pyc
│ │ │ │ │ ├── builder.cpython-312.pyc
│ │ │ │ │ ├── clean.cpython-312.pyc
│ │ │ │ │ ├── defs.cpython-312.pyc
│ │ │ │ │ ├── diff.cpython-312.pyc
│ │ │ │ │ ├── ElementSoup.cpython-312.pyc
│ │ │ │ │ ├── formfill.cpython-312.pyc
│ │ │ │ │ ├── html5parser.cpython-312.pyc
│ │ │ │ │ ├── soupparser.cpython-312.pyc
│ │ │ │ │ └── usedoctest.cpython-312.pyc
│ │ │ │ ├── _diffcommand.py
│ │ │ │ ├── _html5builder.py
│ │ │ │ ├── _setmixin.py
│ │ │ │ ├── builder.py
│ │ │ │ ├── clean.py
│ │ │ │ ├── defs.py
│ │ │ │ ├── diff.cpython-312-darwin.so
│ │ │ │ ├── diff.py
│ │ │ │ ├── ElementSoup.py
│ │ │ │ ├── formfill.py
│ │ │ │ ├── html5parser.py
│ │ │ │ ├── soupparser.py
│ │ │ │ └── usedoctest.py
│ │ │ ├── includes
│ │ │ │ ├── __init__.pxd
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ ├── c14n.pxd
│ │ │ │ ├── config.pxd
│ │ │ │ ├── dtdvalid.pxd
│ │ │ │ ├── etree_defs.h
│ │ │ │ ├── etreepublic.pxd
│ │ │ │ ├── extlibs
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ │ ├── libcharset.h
│ │ │ │ │ ├── localcharset.h
│ │ │ │ │ ├── zconf.h
│ │ │ │ │ └── zlib.h
│ │ │ │ ├── htmlparser.pxd
│ │ │ │ ├── libexslt
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ │ ├── exslt.h
│ │ │ │ │ ├── exsltconfig.h
│ │ │ │ │ └── exsltexports.h
│ │ │ │ ├── libxml
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ │ ├── c14n.h
│ │ │ │ │ ├── catalog.h
│ │ │ │ │ ├── chvalid.h
│ │ │ │ │ ├── debugXML.h
│ │ │ │ │ ├── dict.h
│ │ │ │ │ ├── encoding.h
│ │ │ │ │ ├── entities.h
│ │ │ │ │ ├── globals.h
│ │ │ │ │ ├── hash.h
│ │ │ │ │ ├── HTMLparser.h
│ │ │ │ │ ├── HTMLtree.h
│ │ │ │ │ ├── list.h
│ │ │ │ │ ├── nanoftp.h
│ │ │ │ │ ├── nanohttp.h
│ │ │ │ │ ├── parser.h
│ │ │ │ │ ├── parserInternals.h
│ │ │ │ │ ├── relaxng.h
│ │ │ │ │ ├── SAX.h
│ │ │ │ │ ├── SAX2.h
│ │ │ │ │ ├── schemasInternals.h
│ │ │ │ │ ├── schematron.h
│ │ │ │ │ ├── threads.h
│ │ │ │ │ ├── tree.h
│ │ │ │ │ ├── uri.h
│ │ │ │ │ ├── valid.h
│ │ │ │ │ ├── xinclude.h
│ │ │ │ │ ├── xlink.h
│ │ │ │ │ ├── xmlautomata.h
│ │ │ │ │ ├── xmlerror.h
│ │ │ │ │ ├── xmlexports.h
│ │ │ │ │ ├── xmlIO.h
│ │ │ │ │ ├── xmlmemory.h
│ │ │ │ │ ├── xmlmodule.h
│ │ │ │ │ ├── xmlreader.h
│ │ │ │ │ ├── xmlregexp.h
│ │ │ │ │ ├── xmlsave.h
│ │ │ │ │ ├── xmlschemas.h
│ │ │ │ │ ├── xmlschemastypes.h
│ │ │ │ │ ├── xmlstring.h
│ │ │ │ │ ├── xmlunicode.h
│ │ │ │ │ ├── xmlversion.h
│ │ │ │ │ ├── xmlwriter.h
│ │ │ │ │ ├── xpath.h
│ │ │ │ │ ├── xpathInternals.h
│ │ │ │ │ └── xpointer.h
│ │ │ │ ├── libxslt
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ │ ├── attributes.h
│ │ │ │ │ ├── documents.h
│ │ │ │ │ ├── extensions.h
│ │ │ │ │ ├── extra.h
│ │ │ │ │ ├── functions.h
│ │ │ │ │ ├── imports.h
│ │ │ │ │ ├── keys.h
│ │ │ │ │ ├── namespaces.h
│ │ │ │ │ ├── numbersInternals.h
│ │ │ │ │ ├── pattern.h
│ │ │ │ │ ├── preproc.h
│ │ │ │ │ ├── security.h
│ │ │ │ │ ├── templates.h
│ │ │ │ │ ├── transform.h
│ │ │ │ │ ├── variables.h
│ │ │ │ │ ├── xslt.h
│ │ │ │ │ ├── xsltconfig.h
│ │ │ │ │ ├── xsltexports.h
│ │ │ │ │ ├── xsltInternals.h
│ │ │ │ │ ├── xsltlocale.h
│ │ │ │ │ └── xsltutils.h
│ │ │ │ ├── lxml-version.h
│ │ │ │ ├── relaxng.pxd
│ │ │ │ ├── schematron.pxd
│ │ │ │ ├── tree.pxd
│ │ │ │ ├── uri.pxd
│ │ │ │ ├── xinclude.pxd
│ │ │ │ ├── xmlerror.pxd
│ │ │ │ ├── xmlparser.pxd
│ │ │ │ ├── xmlschema.pxd
│ │ │ │ ├── xpath.pxd
│ │ │ │ └── xslt.pxd
│ │ │ ├── isoschematron
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ └── resources
│ │ │ │ ├── rng
│ │ │ │ │ └── iso-schematron.rng
│ │ │ │ └── xsl
│ │ │ │ ├── iso-schematron-xslt1
│ │ │ │ │ ├── iso_abstract_expand.xsl
│ │ │ │ │ ├── iso_dsdl_include.xsl
│ │ │ │ │ ├── iso_schematron_message.xsl
│ │ │ │ │ ├── iso_schematron_skeleton_for_xslt1.xsl
│ │ │ │ │ ├── iso_svrl_for_xslt1.xsl
│ │ │ │ │ └── readme.txt
│ │ │ │ ├── RNG2Schtrn.xsl
│ │ │ │ └── XSD2Schtrn.xsl
│ │ │ ├── iterparse.pxi
│ │ │ ├── lxml.etree_api.h
│ │ │ ├── lxml.etree.h
│ │ │ ├── nsclasses.pxi
│ │ │ ├── objectify.cpython-312-darwin.so
│ │ │ ├── objectify.pyx
│ │ │ ├── objectpath.pxi
│ │ │ ├── parser.pxi
│ │ │ ├── parsertarget.pxi
│ │ │ ├── proxy.pxi
│ │ │ ├── public-api.pxi
│ │ │ ├── pyclasslookup.py
│ │ │ ├── readonlytree.pxi
│ │ │ ├── relaxng.pxi
│ │ │ ├── sax.cpython-312-darwin.so
│ │ │ ├── sax.py
│ │ │ ├── saxparser.pxi
│ │ │ ├── schematron.pxi
│ │ │ ├── serializer.pxi
│ │ │ ├── usedoctest.py
│ │ │ ├── xinclude.pxi
│ │ │ ├── xmlerror.pxi
│ │ │ ├── xmlid.pxi
│ │ │ ├── xmlschema.pxi
│ │ │ ├── xpath.pxi
│ │ │ ├── xslt.pxi
│ │ │ └── xsltext.pxi
│ │ ├── lxml-5.3.0.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── LICENSES.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── REQUESTED
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── markupsafe
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ └── _native.cpython-312.pyc
│ │ │ ├── _native.py
│ │ │ ├── _speedups.c
│ │ │ ├── _speedups.cpython-312-darwin.so
│ │ │ ├── _speedups.pyi
│ │ │ └── py.typed
│ │ ├── MarkupSafe-3.0.1.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── pip
│ │ │ ├── __init__.py
│ │ │ ├── __main__.py
│ │ │ ├── __pip-runner__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ └── __pip-runner__.cpython-312.pyc
│ │ │ ├── _internal
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── build_env.cpython-312.pyc
│ │ │ │ │ ├── cache.cpython-312.pyc
│ │ │ │ │ ├── configuration.cpython-312.pyc
│ │ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ │ ├── main.cpython-312.pyc
│ │ │ │ │ ├── pyproject.cpython-312.pyc
│ │ │ │ │ ├── self_outdated_check.cpython-312.pyc
│ │ │ │ │ └── wheel_builder.cpython-312.pyc
│ │ │ │ ├── build_env.py
│ │ │ │ ├── cache.py
│ │ │ │ ├── cli
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── autocompletion.cpython-312.pyc
│ │ │ │ │ │ ├── base_command.cpython-312.pyc
│ │ │ │ │ │ ├── cmdoptions.cpython-312.pyc
│ │ │ │ │ │ ├── command_context.cpython-312.pyc
│ │ │ │ │ │ ├── index_command.cpython-312.pyc
│ │ │ │ │ │ ├── main_parser.cpython-312.pyc
│ │ │ │ │ │ ├── main.cpython-312.pyc
│ │ │ │ │ │ ├── parser.cpython-312.pyc
│ │ │ │ │ │ ├── progress_bars.cpython-312.pyc
│ │ │ │ │ │ ├── req_command.cpython-312.pyc
│ │ │ │ │ │ ├── spinners.cpython-312.pyc
│ │ │ │ │ │ └── status_codes.cpython-312.pyc
│ │ │ │ │ ├── autocompletion.py
│ │ │ │ │ ├── base_command.py
│ │ │ │ │ ├── cmdoptions.py
│ │ │ │ │ ├── command_context.py
│ │ │ │ │ ├── index_command.py
│ │ │ │ │ ├── main_parser.py
│ │ │ │ │ ├── main.py
│ │ │ │ │ ├── parser.py
│ │ │ │ │ ├── progress_bars.py
│ │ │ │ │ ├── req_command.py
│ │ │ │ │ ├── spinners.py
│ │ │ │ │ └── status_codes.py
│ │ │ │ ├── commands
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── cache.cpython-312.pyc
│ │ │ │ │ │ ├── check.cpython-312.pyc
│ │ │ │ │ │ ├── completion.cpython-312.pyc
│ │ │ │ │ │ ├── configuration.cpython-312.pyc
│ │ │ │ │ │ ├── debug.cpython-312.pyc
│ │ │ │ │ │ ├── download.cpython-312.pyc
│ │ │ │ │ │ ├── freeze.cpython-312.pyc
│ │ │ │ │ │ ├── hash.cpython-312.pyc
│ │ │ │ │ │ ├── help.cpython-312.pyc
│ │ │ │ │ │ ├── index.cpython-312.pyc
│ │ │ │ │ │ ├── inspect.cpython-312.pyc
│ │ │ │ │ │ ├── install.cpython-312.pyc
│ │ │ │ │ │ ├── list.cpython-312.pyc
│ │ │ │ │ │ ├── search.cpython-312.pyc
│ │ │ │ │ │ ├── show.cpython-312.pyc
│ │ │ │ │ │ ├── uninstall.cpython-312.pyc
│ │ │ │ │ │ └── wheel.cpython-312.pyc
│ │ │ │ │ ├── cache.py
│ │ │ │ │ ├── check.py
│ │ │ │ │ ├── completion.py
│ │ │ │ │ ├── configuration.py
│ │ │ │ │ ├── debug.py
│ │ │ │ │ ├── download.py
│ │ │ │ │ ├── freeze.py
│ │ │ │ │ ├── hash.py
│ │ │ │ │ ├── help.py
│ │ │ │ │ ├── index.py
│ │ │ │ │ ├── inspect.py
│ │ │ │ │ ├── install.py
│ │ │ │ │ ├── list.py
│ │ │ │ │ ├── search.py
│ │ │ │ │ ├── show.py
│ │ │ │ │ ├── uninstall.py
│ │ │ │ │ └── wheel.py
│ │ │ │ ├── configuration.py
│ │ │ │ ├── distributions
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── base.cpython-312.pyc
│ │ │ │ │ │ ├── installed.cpython-312.pyc
│ │ │ │ │ │ ├── sdist.cpython-312.pyc
│ │ │ │ │ │ └── wheel.cpython-312.pyc
│ │ │ │ │ ├── base.py
│ │ │ │ │ ├── installed.py
│ │ │ │ │ ├── sdist.py
│ │ │ │ │ └── wheel.py
│ │ │ │ ├── exceptions.py
│ │ │ │ ├── index
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── collector.cpython-312.pyc
│ │ │ │ │ │ ├── package_finder.cpython-312.pyc
│ │ │ │ │ │ └── sources.cpython-312.pyc
│ │ │ │ │ ├── collector.py
│ │ │ │ │ ├── package_finder.py
│ │ │ │ │ └── sources.py
│ │ │ │ ├── locations
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _distutils.cpython-312.pyc
│ │ │ │ │ │ ├── _sysconfig.cpython-312.pyc
│ │ │ │ │ │ └── base.cpython-312.pyc
│ │ │ │ │ ├── _distutils.py
│ │ │ │ │ ├── _sysconfig.py
│ │ │ │ │ └── base.py
│ │ │ │ ├── main.py
│ │ │ │ ├── metadata
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _json.cpython-312.pyc
│ │ │ │ │ │ ├── base.cpython-312.pyc
│ │ │ │ │ │ └── pkg_resources.cpython-312.pyc
│ │ │ │ │ ├── _json.py
│ │ │ │ │ ├── base.py
│ │ │ │ │ ├── importlib
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ ├── _compat.cpython-312.pyc
│ │ │ │ │ │ │ ├── _dists.cpython-312.pyc
│ │ │ │ │ │ │ └── _envs.cpython-312.pyc
│ │ │ │ │ │ ├── _compat.py
│ │ │ │ │ │ ├── _dists.py
│ │ │ │ │ │ └── _envs.py
│ │ │ │ │ └── pkg_resources.py
│ │ │ │ ├── models
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── candidate.cpython-312.pyc
│ │ │ │ │ │ ├── direct_url.cpython-312.pyc
│ │ │ │ │ │ ├── format_control.cpython-312.pyc
│ │ │ │ │ │ ├── index.cpython-312.pyc
│ │ │ │ │ │ ├── installation_report.cpython-312.pyc
│ │ │ │ │ │ ├── link.cpython-312.pyc
│ │ │ │ │ │ ├── scheme.cpython-312.pyc
│ │ │ │ │ │ ├── search_scope.cpython-312.pyc
│ │ │ │ │ │ ├── selection_prefs.cpython-312.pyc
│ │ │ │ │ │ ├── target_python.cpython-312.pyc
│ │ │ │ │ │ └── wheel.cpython-312.pyc
│ │ │ │ │ ├── candidate.py
│ │ │ │ │ ├── direct_url.py
│ │ │ │ │ ├── format_control.py
│ │ │ │ │ ├── index.py
│ │ │ │ │ ├── installation_report.py
│ │ │ │ │ ├── link.py
│ │ │ │ │ ├── scheme.py
│ │ │ │ │ ├── search_scope.py
│ │ │ │ │ ├── selection_prefs.py
│ │ │ │ │ ├── target_python.py
│ │ │ │ │ └── wheel.py
│ │ │ │ ├── network
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── auth.cpython-312.pyc
│ │ │ │ │ │ ├── cache.cpython-312.pyc
│ │ │ │ │ │ ├── download.cpython-312.pyc
│ │ │ │ │ │ ├── lazy_wheel.cpython-312.pyc
│ │ │ │ │ │ ├── session.cpython-312.pyc
│ │ │ │ │ │ ├── utils.cpython-312.pyc
│ │ │ │ │ │ └── xmlrpc.cpython-312.pyc
│ │ │ │ │ ├── auth.py
│ │ │ │ │ ├── cache.py
│ │ │ │ │ ├── download.py
│ │ │ │ │ ├── lazy_wheel.py
│ │ │ │ │ ├── session.py
│ │ │ │ │ ├── utils.py
│ │ │ │ │ └── xmlrpc.py
│ │ │ │ ├── operations
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── check.cpython-312.pyc
│ │ │ │ │ │ ├── freeze.cpython-312.pyc
│ │ │ │ │ │ └── prepare.cpython-312.pyc
│ │ │ │ │ ├── build
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ ├── build_tracker.cpython-312.pyc
│ │ │ │ │ │ │ ├── metadata_editable.cpython-312.pyc
│ │ │ │ │ │ │ ├── metadata_legacy.cpython-312.pyc
│ │ │ │ │ │ │ ├── metadata.cpython-312.pyc
│ │ │ │ │ │ │ ├── wheel_editable.cpython-312.pyc
│ │ │ │ │ │ │ ├── wheel_legacy.cpython-312.pyc
│ │ │ │ │ │ │ └── wheel.cpython-312.pyc
│ │ │ │ │ │ ├── build_tracker.py
│ │ │ │ │ │ ├── metadata_editable.py
│ │ │ │ │ │ ├── metadata_legacy.py
│ │ │ │ │ │ ├── metadata.py
│ │ │ │ │ │ ├── wheel_editable.py
│ │ │ │ │ │ ├── wheel_legacy.py
│ │ │ │ │ │ └── wheel.py
│ │ │ │ │ ├── check.py
│ │ │ │ │ ├── freeze.py
│ │ │ │ │ ├── install
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ ├── editable_legacy.cpython-312.pyc
│ │ │ │ │ │ │ └── wheel.cpython-312.pyc
│ │ │ │ │ │ ├── editable_legacy.py
│ │ │ │ │ │ └── wheel.py
│ │ │ │ │ └── prepare.py
│ │ │ │ ├── pyproject.py
│ │ │ │ ├── req
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── constructors.cpython-312.pyc
│ │ │ │ │ │ ├── req_file.cpython-312.pyc
│ │ │ │ │ │ ├── req_install.cpython-312.pyc
│ │ │ │ │ │ ├── req_set.cpython-312.pyc
│ │ │ │ │ │ └── req_uninstall.cpython-312.pyc
│ │ │ │ │ ├── constructors.py
│ │ │ │ │ ├── req_file.py
│ │ │ │ │ ├── req_install.py
│ │ │ │ │ ├── req_set.py
│ │ │ │ │ └── req_uninstall.py
│ │ │ │ ├── resolution
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ └── base.cpython-312.pyc
│ │ │ │ │ ├── base.py
│ │ │ │ │ ├── legacy
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ └── resolver.cpython-312.pyc
│ │ │ │ │ │ └── resolver.py
│ │ │ │ │ └── resolvelib
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── base.cpython-312.pyc
│ │ │ │ │ │ ├── candidates.cpython-312.pyc
│ │ │ │ │ │ ├── factory.cpython-312.pyc
│ │ │ │ │ │ ├── found_candidates.cpython-312.pyc
│ │ │ │ │ │ ├── provider.cpython-312.pyc
│ │ │ │ │ │ ├── reporter.cpython-312.pyc
│ │ │ │ │ │ ├── requirements.cpython-312.pyc
│ │ │ │ │ │ └── resolver.cpython-312.pyc
│ │ │ │ │ ├── base.py
│ │ │ │ │ ├── candidates.py
│ │ │ │ │ ├── factory.py
│ │ │ │ │ ├── found_candidates.py
│ │ │ │ │ ├── provider.py
│ │ │ │ │ ├── reporter.py
│ │ │ │ │ ├── requirements.py
│ │ │ │ │ └── resolver.py
│ │ │ │ ├── self_outdated_check.py
│ │ │ │ ├── utils
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _jaraco_text.cpython-312.pyc
│ │ │ │ │ │ ├── _log.cpython-312.pyc
│ │ │ │ │ │ ├── appdirs.cpython-312.pyc
│ │ │ │ │ │ ├── compat.cpython-312.pyc
│ │ │ │ │ │ ├── compatibility_tags.cpython-312.pyc
│ │ │ │ │ │ ├── datetime.cpython-312.pyc
│ │ │ │ │ │ ├── deprecation.cpython-312.pyc
│ │ │ │ │ │ ├── direct_url_helpers.cpython-312.pyc
│ │ │ │ │ │ ├── egg_link.cpython-312.pyc
│ │ │ │ │ │ ├── encoding.cpython-312.pyc
│ │ │ │ │ │ ├── entrypoints.cpython-312.pyc
│ │ │ │ │ │ ├── filesystem.cpython-312.pyc
│ │ │ │ │ │ ├── filetypes.cpython-312.pyc
│ │ │ │ │ │ ├── glibc.cpython-312.pyc
│ │ │ │ │ │ ├── hashes.cpython-312.pyc
│ │ │ │ │ │ ├── logging.cpython-312.pyc
│ │ │ │ │ │ ├── misc.cpython-312.pyc
│ │ │ │ │ │ ├── packaging.cpython-312.pyc
│ │ │ │ │ │ ├── retry.cpython-312.pyc
│ │ │ │ │ │ ├── setuptools_build.cpython-312.pyc
│ │ │ │ │ │ ├── subprocess.cpython-312.pyc
│ │ │ │ │ │ ├── temp_dir.cpython-312.pyc
│ │ │ │ │ │ ├── unpacking.cpython-312.pyc
│ │ │ │ │ │ ├── urls.cpython-312.pyc
│ │ │ │ │ │ ├── virtualenv.cpython-312.pyc
│ │ │ │ │ │ └── wheel.cpython-312.pyc
│ │ │ │ │ ├── _jaraco_text.py
│ │ │ │ │ ├── _log.py
│ │ │ │ │ ├── appdirs.py
│ │ │ │ │ ├── compat.py
│ │ │ │ │ ├── compatibility_tags.py
│ │ │ │ │ ├── datetime.py
│ │ │ │ │ ├── deprecation.py
│ │ │ │ │ ├── direct_url_helpers.py
│ │ │ │ │ ├── egg_link.py
│ │ │ │ │ ├── encoding.py
│ │ │ │ │ ├── entrypoints.py
│ │ │ │ │ ├── filesystem.py
│ │ │ │ │ ├── filetypes.py
│ │ │ │ │ ├── glibc.py
│ │ │ │ │ ├── hashes.py
│ │ │ │ │ ├── logging.py
│ │ │ │ │ ├── misc.py
│ │ │ │ │ ├── packaging.py
│ │ │ │ │ ├── retry.py
│ │ │ │ │ ├── setuptools_build.py
│ │ │ │ │ ├── subprocess.py
│ │ │ │ │ ├── temp_dir.py
│ │ │ │ │ ├── unpacking.py
│ │ │ │ │ ├── urls.py
│ │ │ │ │ ├── virtualenv.py
│ │ │ │ │ └── wheel.py
│ │ │ │ ├── vcs
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── bazaar.cpython-312.pyc
│ │ │ │ │ │ ├── git.cpython-312.pyc
│ │ │ │ │ │ ├── mercurial.cpython-312.pyc
│ │ │ │ │ │ ├── subversion.cpython-312.pyc
│ │ │ │ │ │ └── versioncontrol.cpython-312.pyc
│ │ │ │ │ ├── bazaar.py
│ │ │ │ │ ├── git.py
│ │ │ │ │ ├── mercurial.py
│ │ │ │ │ ├── subversion.py
│ │ │ │ │ └── versioncontrol.py
│ │ │ │ └── wheel_builder.py
│ │ │ ├── _vendor
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ └── typing_extensions.cpython-312.pyc
│ │ │ │ ├── cachecontrol
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _cmd.cpython-312.pyc
│ │ │ │ │ │ ├── adapter.cpython-312.pyc
│ │ │ │ │ │ ├── cache.cpython-312.pyc
│ │ │ │ │ │ ├── controller.cpython-312.pyc
│ │ │ │ │ │ ├── filewrapper.cpython-312.pyc
│ │ │ │ │ │ ├── heuristics.cpython-312.pyc
│ │ │ │ │ │ ├── serialize.cpython-312.pyc
│ │ │ │ │ │ └── wrapper.cpython-312.pyc
│ │ │ │ │ ├── _cmd.py
│ │ │ │ │ ├── adapter.py
│ │ │ │ │ ├── cache.py
│ │ │ │ │ ├── caches
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ ├── file_cache.cpython-312.pyc
│ │ │ │ │ │ │ └── redis_cache.cpython-312.pyc
│ │ │ │ │ │ ├── file_cache.py
│ │ │ │ │ │ └── redis_cache.py
│ │ │ │ │ ├── controller.py
│ │ │ │ │ ├── filewrapper.py
│ │ │ │ │ ├── heuristics.py
│ │ │ │ │ ├── py.typed
│ │ │ │ │ ├── serialize.py
│ │ │ │ │ └── wrapper.py
│ │ │ │ ├── certifi
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __main__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ │ │ └── core.cpython-312.pyc
│ │ │ │ │ ├── cacert.pem
│ │ │ │ │ ├── core.py
│ │ │ │ │ └── py.typed
│ │ │ │ ├── distlib
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── compat.cpython-312.pyc
│ │ │ │ │ │ ├── database.cpython-312.pyc
│ │ │ │ │ │ ├── index.cpython-312.pyc
│ │ │ │ │ │ ├── locators.cpython-312.pyc
│ │ │ │ │ │ ├── manifest.cpython-312.pyc
│ │ │ │ │ │ ├── markers.cpython-312.pyc
│ │ │ │ │ │ ├── metadata.cpython-312.pyc
│ │ │ │ │ │ ├── resources.cpython-312.pyc
│ │ │ │ │ │ ├── scripts.cpython-312.pyc
│ │ │ │ │ │ ├── util.cpython-312.pyc
│ │ │ │ │ │ ├── version.cpython-312.pyc
│ │ │ │ │ │ └── wheel.cpython-312.pyc
│ │ │ │ │ ├── compat.py
│ │ │ │ │ ├── database.py
│ │ │ │ │ ├── index.py
│ │ │ │ │ ├── locators.py
│ │ │ │ │ ├── manifest.py
│ │ │ │ │ ├── markers.py
│ │ │ │ │ ├── metadata.py
│ │ │ │ │ ├── resources.py
│ │ │ │ │ ├── scripts.py
│ │ │ │ │ ├── t32.exe
│ │ │ │ │ ├── t64-arm.exe
│ │ │ │ │ ├── t64.exe
│ │ │ │ │ ├── util.py
│ │ │ │ │ ├── version.py
│ │ │ │ │ ├── w32.exe
│ │ │ │ │ ├── w64-arm.exe
│ │ │ │ │ ├── w64.exe
│ │ │ │ │ └── wheel.py
│ │ │ │ ├── distro
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __main__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ │ │ └── distro.cpython-312.pyc
│ │ │ │ │ ├── distro.py
│ │ │ │ │ └── py.typed
│ │ │ │ ├── idna
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── codec.cpython-312.pyc
│ │ │ │ │ │ ├── compat.cpython-312.pyc
│ │ │ │ │ │ ├── core.cpython-312.pyc
│ │ │ │ │ │ ├── idnadata.cpython-312.pyc
│ │ │ │ │ │ ├── intranges.cpython-312.pyc
│ │ │ │ │ │ ├── package_data.cpython-312.pyc
│ │ │ │ │ │ └── uts46data.cpython-312.pyc
│ │ │ │ │ ├── codec.py
│ │ │ │ │ ├── compat.py
│ │ │ │ │ ├── core.py
│ │ │ │ │ ├── idnadata.py
│ │ │ │ │ ├── intranges.py
│ │ │ │ │ ├── package_data.py
│ │ │ │ │ ├── py.typed
│ │ │ │ │ └── uts46data.py
│ │ │ │ ├── msgpack
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ │ │ ├── ext.cpython-312.pyc
│ │ │ │ │ │ └── fallback.cpython-312.pyc
│ │ │ │ │ ├── exceptions.py
│ │ │ │ │ ├── ext.py
│ │ │ │ │ └── fallback.py
│ │ │ │ ├── packaging
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _elffile.cpython-312.pyc
│ │ │ │ │ │ ├── _manylinux.cpython-312.pyc
│ │ │ │ │ │ ├── _musllinux.cpython-312.pyc
│ │ │ │ │ │ ├── _parser.cpython-312.pyc
│ │ │ │ │ │ ├── _structures.cpython-312.pyc
│ │ │ │ │ │ ├── _tokenizer.cpython-312.pyc
│ │ │ │ │ │ ├── markers.cpython-312.pyc
│ │ │ │ │ │ ├── metadata.cpython-312.pyc
│ │ │ │ │ │ ├── requirements.cpython-312.pyc
│ │ │ │ │ │ ├── specifiers.cpython-312.pyc
│ │ │ │ │ │ ├── tags.cpython-312.pyc
│ │ │ │ │ │ ├── utils.cpython-312.pyc
│ │ │ │ │ │ └── version.cpython-312.pyc
│ │ │ │ │ ├── _elffile.py
│ │ │ │ │ ├── _manylinux.py
│ │ │ │ │ ├── _musllinux.py
│ │ │ │ │ ├── _parser.py
│ │ │ │ │ ├── _structures.py
│ │ │ │ │ ├── _tokenizer.py
│ │ │ │ │ ├── markers.py
│ │ │ │ │ ├── metadata.py
│ │ │ │ │ ├── py.typed
│ │ │ │ │ ├── requirements.py
│ │ │ │ │ ├── specifiers.py
│ │ │ │ │ ├── tags.py
│ │ │ │ │ ├── utils.py
│ │ │ │ │ └── version.py
│ │ │ │ ├── pkg_resources
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ └── __pycache__
│ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ ├── platformdirs
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __main__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ │ │ ├── android.cpython-312.pyc
│ │ │ │ │ │ ├── api.cpython-312.pyc
│ │ │ │ │ │ ├── macos.cpython-312.pyc
│ │ │ │ │ │ ├── unix.cpython-312.pyc
│ │ │ │ │ │ ├── version.cpython-312.pyc
│ │ │ │ │ │ └── windows.cpython-312.pyc
│ │ │ │ │ ├── android.py
│ │ │ │ │ ├── api.py
│ │ │ │ │ ├── macos.py
│ │ │ │ │ ├── py.typed
│ │ │ │ │ ├── unix.py
│ │ │ │ │ ├── version.py
│ │ │ │ │ └── windows.py
│ │ │ │ ├── pygments
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __main__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ │ │ ├── cmdline.cpython-312.pyc
│ │ │ │ │ │ ├── console.cpython-312.pyc
│ │ │ │ │ │ ├── filter.cpython-312.pyc
│ │ │ │ │ │ ├── formatter.cpython-312.pyc
│ │ │ │ │ │ ├── lexer.cpython-312.pyc
│ │ │ │ │ │ ├── modeline.cpython-312.pyc
│ │ │ │ │ │ ├── plugin.cpython-312.pyc
│ │ │ │ │ │ ├── regexopt.cpython-312.pyc
│ │ │ │ │ │ ├── scanner.cpython-312.pyc
│ │ │ │ │ │ ├── sphinxext.cpython-312.pyc
│ │ │ │ │ │ ├── style.cpython-312.pyc
│ │ │ │ │ │ ├── token.cpython-312.pyc
│ │ │ │ │ │ ├── unistring.cpython-312.pyc
│ │ │ │ │ │ └── util.cpython-312.pyc
│ │ │ │ │ ├── cmdline.py
│ │ │ │ │ ├── console.py
│ │ │ │ │ ├── filter.py
│ │ │ │ │ ├── filters
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ └── __pycache__
│ │ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ │ ├── formatter.py
│ │ │ │ │ ├── formatters
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ ├── _mapping.cpython-312.pyc
│ │ │ │ │ │ │ ├── bbcode.cpython-312.pyc
│ │ │ │ │ │ │ ├── groff.cpython-312.pyc
│ │ │ │ │ │ │ ├── html.cpython-312.pyc
│ │ │ │ │ │ │ ├── img.cpython-312.pyc
│ │ │ │ │ │ │ ├── irc.cpython-312.pyc
│ │ │ │ │ │ │ ├── latex.cpython-312.pyc
│ │ │ │ │ │ │ ├── other.cpython-312.pyc
│ │ │ │ │ │ │ ├── pangomarkup.cpython-312.pyc
│ │ │ │ │ │ │ ├── rtf.cpython-312.pyc
│ │ │ │ │ │ │ ├── svg.cpython-312.pyc
│ │ │ │ │ │ │ ├── terminal.cpython-312.pyc
│ │ │ │ │ │ │ └── terminal256.cpython-312.pyc
│ │ │ │ │ │ ├── _mapping.py
│ │ │ │ │ │ ├── bbcode.py
│ │ │ │ │ │ ├── groff.py
│ │ │ │ │ │ ├── html.py
│ │ │ │ │ │ ├── img.py
│ │ │ │ │ │ ├── irc.py
│ │ │ │ │ │ ├── latex.py
│ │ │ │ │ │ ├── other.py
│ │ │ │ │ │ ├── pangomarkup.py
│ │ │ │ │ │ ├── rtf.py
│ │ │ │ │ │ ├── svg.py
│ │ │ │ │ │ ├── terminal.py
│ │ │ │ │ │ └── terminal256.py
│ │ │ │ │ ├── lexer.py
│ │ │ │ │ ├── lexers
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ ├── _mapping.cpython-312.pyc
│ │ │ │ │ │ │ └── python.cpython-312.pyc
│ │ │ │ │ │ ├── _mapping.py
│ │ │ │ │ │ └── python.py
│ │ │ │ │ ├── modeline.py
│ │ │ │ │ ├── plugin.py
│ │ │ │ │ ├── regexopt.py
│ │ │ │ │ ├── scanner.py
│ │ │ │ │ ├── sphinxext.py
│ │ │ │ │ ├── style.py
│ │ │ │ │ ├── styles
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ └── _mapping.cpython-312.pyc
│ │ │ │ │ │ └── _mapping.py
│ │ │ │ │ ├── token.py
│ │ │ │ │ ├── unistring.py
│ │ │ │ │ └── util.py
│ │ │ │ ├── pyproject_hooks
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _compat.cpython-312.pyc
│ │ │ │ │ │ └── _impl.cpython-312.pyc
│ │ │ │ │ ├── _compat.py
│ │ │ │ │ ├── _impl.py
│ │ │ │ │ └── _in_process
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ └── _in_process.cpython-312.pyc
│ │ │ │ │ └── _in_process.py
│ │ │ │ ├── requests
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── __version__.cpython-312.pyc
│ │ │ │ │ │ ├── _internal_utils.cpython-312.pyc
│ │ │ │ │ │ ├── adapters.cpython-312.pyc
│ │ │ │ │ │ ├── api.cpython-312.pyc
│ │ │ │ │ │ ├── auth.cpython-312.pyc
│ │ │ │ │ │ ├── certs.cpython-312.pyc
│ │ │ │ │ │ ├── compat.cpython-312.pyc
│ │ │ │ │ │ ├── cookies.cpython-312.pyc
│ │ │ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ │ │ ├── help.cpython-312.pyc
│ │ │ │ │ │ ├── hooks.cpython-312.pyc
│ │ │ │ │ │ ├── models.cpython-312.pyc
│ │ │ │ │ │ ├── packages.cpython-312.pyc
│ │ │ │ │ │ ├── sessions.cpython-312.pyc
│ │ │ │ │ │ ├── status_codes.cpython-312.pyc
│ │ │ │ │ │ ├── structures.cpython-312.pyc
│ │ │ │ │ │ └── utils.cpython-312.pyc
│ │ │ │ │ ├── __version__.py
│ │ │ │ │ ├── _internal_utils.py
│ │ │ │ │ ├── adapters.py
│ │ │ │ │ ├── api.py
│ │ │ │ │ ├── auth.py
│ │ │ │ │ ├── certs.py
│ │ │ │ │ ├── compat.py
│ │ │ │ │ ├── cookies.py
│ │ │ │ │ ├── exceptions.py
│ │ │ │ │ ├── help.py
│ │ │ │ │ ├── hooks.py
│ │ │ │ │ ├── models.py
│ │ │ │ │ ├── packages.py
│ │ │ │ │ ├── sessions.py
│ │ │ │ │ ├── status_codes.py
│ │ │ │ │ ├── structures.py
│ │ │ │ │ └── utils.py
│ │ │ │ ├── resolvelib
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── providers.cpython-312.pyc
│ │ │ │ │ │ ├── reporters.cpython-312.pyc
│ │ │ │ │ │ ├── resolvers.cpython-312.pyc
│ │ │ │ │ │ └── structs.cpython-312.pyc
│ │ │ │ │ ├── compat
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ └── collections_abc.cpython-312.pyc
│ │ │ │ │ │ └── collections_abc.py
│ │ │ │ │ ├── providers.py
│ │ │ │ │ ├── py.typed
│ │ │ │ │ ├── reporters.py
│ │ │ │ │ ├── resolvers.py
│ │ │ │ │ └── structs.py
│ │ │ │ ├── rich
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __main__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ │ │ ├── _cell_widths.cpython-312.pyc
│ │ │ │ │ │ ├── _emoji_codes.cpython-312.pyc
│ │ │ │ │ │ ├── _emoji_replace.cpython-312.pyc
│ │ │ │ │ │ ├── _export_format.cpython-312.pyc
│ │ │ │ │ │ ├── _extension.cpython-312.pyc
│ │ │ │ │ │ ├── _fileno.cpython-312.pyc
│ │ │ │ │ │ ├── _inspect.cpython-312.pyc
│ │ │ │ │ │ ├── _log_render.cpython-312.pyc
│ │ │ │ │ │ ├── _loop.cpython-312.pyc
│ │ │ │ │ │ ├── _null_file.cpython-312.pyc
│ │ │ │ │ │ ├── _palettes.cpython-312.pyc
│ │ │ │ │ │ ├── _pick.cpython-312.pyc
│ │ │ │ │ │ ├── _ratio.cpython-312.pyc
│ │ │ │ │ │ ├── _spinners.cpython-312.pyc
│ │ │ │ │ │ ├── _stack.cpython-312.pyc
│ │ │ │ │ │ ├── _timer.cpython-312.pyc
│ │ │ │ │ │ ├── _win32_console.cpython-312.pyc
│ │ │ │ │ │ ├── _windows_renderer.cpython-312.pyc
│ │ │ │ │ │ ├── _windows.cpython-312.pyc
│ │ │ │ │ │ ├── _wrap.cpython-312.pyc
│ │ │ │ │ │ ├── abc.cpython-312.pyc
│ │ │ │ │ │ ├── align.cpython-312.pyc
│ │ │ │ │ │ ├── ansi.cpython-312.pyc
│ │ │ │ │ │ ├── bar.cpython-312.pyc
│ │ │ │ │ │ ├── box.cpython-312.pyc
│ │ │ │ │ │ ├── cells.cpython-312.pyc
│ │ │ │ │ │ ├── color_triplet.cpython-312.pyc
│ │ │ │ │ │ ├── color.cpython-312.pyc
│ │ │ │ │ │ ├── columns.cpython-312.pyc
│ │ │ │ │ │ ├── console.cpython-312.pyc
│ │ │ │ │ │ ├── constrain.cpython-312.pyc
│ │ │ │ │ │ ├── containers.cpython-312.pyc
│ │ │ │ │ │ ├── control.cpython-312.pyc
│ │ │ │ │ │ ├── default_styles.cpython-312.pyc
│ │ │ │ │ │ ├── diagnose.cpython-312.pyc
│ │ │ │ │ │ ├── emoji.cpython-312.pyc
│ │ │ │ │ │ ├── errors.cpython-312.pyc
│ │ │ │ │ │ ├── file_proxy.cpython-312.pyc
│ │ │ │ │ │ ├── filesize.cpython-312.pyc
│ │ │ │ │ │ ├── highlighter.cpython-312.pyc
│ │ │ │ │ │ ├── json.cpython-312.pyc
│ │ │ │ │ │ ├── jupyter.cpython-312.pyc
│ │ │ │ │ │ ├── layout.cpython-312.pyc
│ │ │ │ │ │ ├── live_render.cpython-312.pyc
│ │ │ │ │ │ ├── live.cpython-312.pyc
│ │ │ │ │ │ ├── logging.cpython-312.pyc
│ │ │ │ │ │ ├── markup.cpython-312.pyc
│ │ │ │ │ │ ├── measure.cpython-312.pyc
│ │ │ │ │ │ ├── padding.cpython-312.pyc
│ │ │ │ │ │ ├── pager.cpython-312.pyc
│ │ │ │ │ │ ├── palette.cpython-312.pyc
│ │ │ │ │ │ ├── panel.cpython-312.pyc
│ │ │ │ │ │ ├── pretty.cpython-312.pyc
│ │ │ │ │ │ ├── progress_bar.cpython-312.pyc
│ │ │ │ │ │ ├── progress.cpython-312.pyc
│ │ │ │ │ │ ├── prompt.cpython-312.pyc
│ │ │ │ │ │ ├── protocol.cpython-312.pyc
│ │ │ │ │ │ ├── region.cpython-312.pyc
│ │ │ │ │ │ ├── repr.cpython-312.pyc
│ │ │ │ │ │ ├── rule.cpython-312.pyc
│ │ │ │ │ │ ├── scope.cpython-312.pyc
│ │ │ │ │ │ ├── screen.cpython-312.pyc
│ │ │ │ │ │ ├── segment.cpython-312.pyc
│ │ │ │ │ │ ├── spinner.cpython-312.pyc
│ │ │ │ │ │ ├── status.cpython-312.pyc
│ │ │ │ │ │ ├── style.cpython-312.pyc
│ │ │ │ │ │ ├── styled.cpython-312.pyc
│ │ │ │ │ │ ├── syntax.cpython-312.pyc
│ │ │ │ │ │ ├── table.cpython-312.pyc
│ │ │ │ │ │ ├── terminal_theme.cpython-312.pyc
│ │ │ │ │ │ ├── text.cpython-312.pyc
│ │ │ │ │ │ ├── theme.cpython-312.pyc
│ │ │ │ │ │ ├── themes.cpython-312.pyc
│ │ │ │ │ │ ├── traceback.cpython-312.pyc
│ │ │ │ │ │ └── tree.cpython-312.pyc
│ │ │ │ │ ├── _cell_widths.py
│ │ │ │ │ ├── _emoji_codes.py
│ │ │ │ │ ├── _emoji_replace.py
│ │ │ │ │ ├── _export_format.py
│ │ │ │ │ ├── _extension.py
│ │ │ │ │ ├── _fileno.py
│ │ │ │ │ ├── _inspect.py
│ │ │ │ │ ├── _log_render.py
│ │ │ │ │ ├── _loop.py
│ │ │ │ │ ├── _null_file.py
│ │ │ │ │ ├── _palettes.py
│ │ │ │ │ ├── _pick.py
│ │ │ │ │ ├── _ratio.py
│ │ │ │ │ ├── _spinners.py
│ │ │ │ │ ├── _stack.py
│ │ │ │ │ ├── _timer.py
│ │ │ │ │ ├── _win32_console.py
│ │ │ │ │ ├── _windows_renderer.py
│ │ │ │ │ ├── _windows.py
│ │ │ │ │ ├── _wrap.py
│ │ │ │ │ ├── abc.py
│ │ │ │ │ ├── align.py
│ │ │ │ │ ├── ansi.py
│ │ │ │ │ ├── bar.py
│ │ │ │ │ ├── box.py
│ │ │ │ │ ├── cells.py
│ │ │ │ │ ├── color_triplet.py
│ │ │ │ │ ├── color.py
│ │ │ │ │ ├── columns.py
│ │ │ │ │ ├── console.py
│ │ │ │ │ ├── constrain.py
│ │ │ │ │ ├── containers.py
│ │ │ │ │ ├── control.py
│ │ │ │ │ ├── default_styles.py
│ │ │ │ │ ├── diagnose.py
│ │ │ │ │ ├── emoji.py
│ │ │ │ │ ├── errors.py
│ │ │ │ │ ├── file_proxy.py
│ │ │ │ │ ├── filesize.py
│ │ │ │ │ ├── highlighter.py
│ │ │ │ │ ├── json.py
│ │ │ │ │ ├── jupyter.py
│ │ │ │ │ ├── layout.py
│ │ │ │ │ ├── live_render.py
│ │ │ │ │ ├── live.py
│ │ │ │ │ ├── logging.py
│ │ │ │ │ ├── markup.py
│ │ │ │ │ ├── measure.py
│ │ │ │ │ ├── padding.py
│ │ │ │ │ ├── pager.py
│ │ │ │ │ ├── palette.py
│ │ │ │ │ ├── panel.py
│ │ │ │ │ ├── pretty.py
│ │ │ │ │ ├── progress_bar.py
│ │ │ │ │ ├── progress.py
│ │ │ │ │ ├── prompt.py
│ │ │ │ │ ├── protocol.py
│ │ │ │ │ ├── py.typed
│ │ │ │ │ ├── region.py
│ │ │ │ │ ├── repr.py
│ │ │ │ │ ├── rule.py
│ │ │ │ │ ├── scope.py
│ │ │ │ │ ├── screen.py
│ │ │ │ │ ├── segment.py
│ │ │ │ │ ├── spinner.py
│ │ │ │ │ ├── status.py
│ │ │ │ │ ├── style.py
│ │ │ │ │ ├── styled.py
│ │ │ │ │ ├── syntax.py
│ │ │ │ │ ├── table.py
│ │ │ │ │ ├── terminal_theme.py
│ │ │ │ │ ├── text.py
│ │ │ │ │ ├── theme.py
│ │ │ │ │ ├── themes.py
│ │ │ │ │ ├── traceback.py
│ │ │ │ │ └── tree.py
│ │ │ │ ├── tomli
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _parser.cpython-312.pyc
│ │ │ │ │ │ ├── _re.cpython-312.pyc
│ │ │ │ │ │ └── _types.cpython-312.pyc
│ │ │ │ │ ├── _parser.py
│ │ │ │ │ ├── _re.py
│ │ │ │ │ ├── _types.py
│ │ │ │ │ └── py.typed
│ │ │ │ ├── truststore
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _api.cpython-312.pyc
│ │ │ │ │ │ ├── _macos.cpython-312.pyc
│ │ │ │ │ │ ├── _openssl.cpython-312.pyc
│ │ │ │ │ │ ├── _ssl_constants.cpython-312.pyc
│ │ │ │ │ │ └── _windows.cpython-312.pyc
│ │ │ │ │ ├── _api.py
│ │ │ │ │ ├── _macos.py
│ │ │ │ │ ├── _openssl.py
│ │ │ │ │ ├── _ssl_constants.py
│ │ │ │ │ ├── _windows.py
│ │ │ │ │ └── py.typed
│ │ │ │ ├── typing_extensions.py
│ │ │ │ ├── urllib3
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _collections.cpython-312.pyc
│ │ │ │ │ │ ├── _version.cpython-312.pyc
│ │ │ │ │ │ ├── connection.cpython-312.pyc
│ │ │ │ │ │ ├── connectionpool.cpython-312.pyc
│ │ │ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ │ │ ├── fields.cpython-312.pyc
│ │ │ │ │ │ ├── filepost.cpython-312.pyc
│ │ │ │ │ │ ├── poolmanager.cpython-312.pyc
│ │ │ │ │ │ ├── request.cpython-312.pyc
│ │ │ │ │ │ └── response.cpython-312.pyc
│ │ │ │ │ ├── _collections.py
│ │ │ │ │ ├── _version.py
│ │ │ │ │ ├── connection.py
│ │ │ │ │ ├── connectionpool.py
│ │ │ │ │ ├── contrib
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ ├── _appengine_environ.cpython-312.pyc
│ │ │ │ │ │ │ ├── appengine.cpython-312.pyc
│ │ │ │ │ │ │ ├── ntlmpool.cpython-312.pyc
│ │ │ │ │ │ │ ├── pyopenssl.cpython-312.pyc
│ │ │ │ │ │ │ ├── securetransport.cpython-312.pyc
│ │ │ │ │ │ │ └── socks.cpython-312.pyc
│ │ │ │ │ │ ├── _appengine_environ.py
│ │ │ │ │ │ ├── _securetransport
│ │ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ │ ├── bindings.cpython-312.pyc
│ │ │ │ │ │ │ │ └── low_level.cpython-312.pyc
│ │ │ │ │ │ │ ├── bindings.py
│ │ │ │ │ │ │ └── low_level.py
│ │ │ │ │ │ ├── appengine.py
│ │ │ │ │ │ ├── ntlmpool.py
│ │ │ │ │ │ ├── pyopenssl.py
│ │ │ │ │ │ ├── securetransport.py
│ │ │ │ │ │ └── socks.py
│ │ │ │ │ ├── exceptions.py
│ │ │ │ │ ├── fields.py
│ │ │ │ │ ├── filepost.py
│ │ │ │ │ ├── packages
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ └── six.cpython-312.pyc
│ │ │ │ │ │ ├── backports
│ │ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ │ ├── makefile.cpython-312.pyc
│ │ │ │ │ │ │ │ └── weakref_finalize.cpython-312.pyc
│ │ │ │ │ │ │ ├── makefile.py
│ │ │ │ │ │ │ └── weakref_finalize.py
│ │ │ │ │ │ └── six.py
│ │ │ │ │ ├── poolmanager.py
│ │ │ │ │ ├── request.py
│ │ │ │ │ ├── response.py
│ │ │ │ │ └── util
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── connection.cpython-312.pyc
│ │ │ │ │ │ ├── proxy.cpython-312.pyc
│ │ │ │ │ │ ├── queue.cpython-312.pyc
│ │ │ │ │ │ ├── request.cpython-312.pyc
│ │ │ │ │ │ ├── response.cpython-312.pyc
│ │ │ │ │ │ ├── retry.cpython-312.pyc
│ │ │ │ │ │ ├── ssl_.cpython-312.pyc
│ │ │ │ │ │ ├── ssl_match_hostname.cpython-312.pyc
│ │ │ │ │ │ ├── ssltransport.cpython-312.pyc
│ │ │ │ │ │ ├── timeout.cpython-312.pyc
│ │ │ │ │ │ ├── url.cpython-312.pyc
│ │ │ │ │ │ └── wait.cpython-312.pyc
│ │ │ │ │ ├── connection.py
│ │ │ │ │ ├── proxy.py
│ │ │ │ │ ├── queue.py
│ │ │ │ │ ├── request.py
│ │ │ │ │ ├── response.py
│ │ │ │ │ ├── retry.py
│ │ │ │ │ ├── ssl_.py
│ │ │ │ │ ├── ssl_match_hostname.py
│ │ │ │ │ ├── ssltransport.py
│ │ │ │ │ ├── timeout.py
│ │ │ │ │ ├── url.py
│ │ │ │ │ └── wait.py
│ │ │ │ └── vendor.txt
│ │ │ └── py.typed
│ │ ├── pip-24.2.dist-info
│ │ │ ├── AUTHORS.txt
│ │ │ ├── entry_points.txt
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── REQUESTED
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── requests
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── __version__.cpython-312.pyc
│ │ │ │ ├── _internal_utils.cpython-312.pyc
│ │ │ │ ├── adapters.cpython-312.pyc
│ │ │ │ ├── api.cpython-312.pyc
│ │ │ │ ├── auth.cpython-312.pyc
│ │ │ │ ├── certs.cpython-312.pyc
│ │ │ │ ├── compat.cpython-312.pyc
│ │ │ │ ├── cookies.cpython-312.pyc
│ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ ├── help.cpython-312.pyc
│ │ │ │ ├── hooks.cpython-312.pyc
│ │ │ │ ├── models.cpython-312.pyc
│ │ │ │ ├── packages.cpython-312.pyc
│ │ │ │ ├── sessions.cpython-312.pyc
│ │ │ │ ├── status_codes.cpython-312.pyc
│ │ │ │ ├── structures.cpython-312.pyc
│ │ │ │ └── utils.cpython-312.pyc
│ │ │ ├── __version__.py
│ │ │ ├── _internal_utils.py
│ │ │ ├── adapters.py
│ │ │ ├── api.py
│ │ │ ├── auth.py
│ │ │ ├── certs.py
│ │ │ ├── compat.py
│ │ │ ├── cookies.py
│ │ │ ├── exceptions.py
│ │ │ ├── help.py
│ │ │ ├── hooks.py
│ │ │ ├── models.py
│ │ │ ├── packages.py
│ │ │ ├── sessions.py
│ │ │ ├── status_codes.py
│ │ │ ├── structures.py
│ │ │ └── utils.py
│ │ ├── requests-2.32.3.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── REQUESTED
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── soupsieve
│ │ │ ├── __init__.py
│ │ │ ├── __meta__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── __meta__.cpython-312.pyc
│ │ │ │ ├── css_match.cpython-312.pyc
│ │ │ │ ├── css_parser.cpython-312.pyc
│ │ │ │ ├── css_types.cpython-312.pyc
│ │ │ │ ├── pretty.cpython-312.pyc
│ │ │ │ └── util.cpython-312.pyc
│ │ │ ├── css_match.py
│ │ │ ├── css_parser.py
│ │ │ ├── css_types.py
│ │ │ ├── pretty.py
│ │ │ ├── py.typed
│ │ │ └── util.py
│ │ ├── soupsieve-2.6.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── licenses
│ │ │ │ └── LICENSE.md
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ └── WHEEL
│ │ ├── urllib3
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── _base_connection.cpython-312.pyc
│ │ │ │ ├── _collections.cpython-312.pyc
│ │ │ │ ├── _request_methods.cpython-312.pyc
│ │ │ │ ├── _version.cpython-312.pyc
│ │ │ │ ├── connection.cpython-312.pyc
│ │ │ │ ├── connectionpool.cpython-312.pyc
│ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ ├── fields.cpython-312.pyc
│ │ │ │ ├── filepost.cpython-312.pyc
│ │ │ │ ├── poolmanager.cpython-312.pyc
│ │ │ │ └── response.cpython-312.pyc
│ │ │ ├── _base_connection.py
│ │ │ ├── _collections.py
│ │ │ ├── _request_methods.py
│ │ │ ├── _version.py
│ │ │ ├── connection.py
│ │ │ ├── connectionpool.py
│ │ │ ├── contrib
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── pyopenssl.cpython-312.pyc
│ │ │ │ │ └── socks.cpython-312.pyc
│ │ │ │ ├── emscripten
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── connection.cpython-312.pyc
│ │ │ │ │ │ ├── fetch.cpython-312.pyc
│ │ │ │ │ │ ├── request.cpython-312.pyc
│ │ │ │ │ │ └── response.cpython-312.pyc
│ │ │ │ │ ├── connection.py
│ │ │ │ │ ├── emscripten_fetch_worker.js
│ │ │ │ │ ├── fetch.py
│ │ │ │ │ ├── request.py
│ │ │ │ │ └── response.py
│ │ │ │ ├── pyopenssl.py
│ │ │ │ └── socks.py
│ │ │ ├── exceptions.py
│ │ │ ├── fields.py
│ │ │ ├── filepost.py
│ │ │ ├── http2
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── connection.cpython-312.pyc
│ │ │ │ │ └── probe.cpython-312.pyc
│ │ │ │ ├── connection.py
│ │ │ │ └── probe.py
│ │ │ ├── poolmanager.py
│ │ │ ├── py.typed
│ │ │ ├── response.py
│ │ │ └── util
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── connection.cpython-312.pyc
│ │ │ │ ├── proxy.cpython-312.pyc
│ │ │ │ ├── request.cpython-312.pyc
│ │ │ │ ├── response.cpython-312.pyc
│ │ │ │ ├── retry.cpython-312.pyc
│ │ │ │ ├── ssl_.cpython-312.pyc
│ │ │ │ ├── ssl_match_hostname.cpython-312.pyc
│ │ │ │ ├── ssltransport.cpython-312.pyc
│ │ │ │ ├── timeout.cpython-312.pyc
│ │ │ │ ├── url.cpython-312.pyc
│ │ │ │ ├── util.cpython-312.pyc
│ │ │ │ └── wait.cpython-312.pyc
│ │ │ ├── connection.py
│ │ │ ├── proxy.py
│ │ │ ├── request.py
│ │ │ ├── response.py
│ │ │ ├── retry.py
│ │ │ ├── ssl_.py
│ │ │ ├── ssl_match_hostname.py
│ │ │ ├── ssltransport.py
│ │ │ ├── timeout.py
│ │ │ ├── url.py
│ │ │ ├── util.py
│ │ │ └── wait.py
│ │ ├── urllib3-2.2.3.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── licenses
│ │ │ │ └── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ └── WHEEL
│ │ ├── useragent
│ │ │ ├── __init__.py
│ │ │ ├── __init__.pyc
│ │ │ ├── __pycache__
│ │ │ │ └── __init__.cpython-312.pyc
│ │ │ ├── resources
│ │ │ │ └── user_agent_data.json
│ │ │ └── test
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ └── __init__.cpython-312.pyc
│ │ │ ├── test_additional_os.json
│ │ │ ├── test_browser.json
│ │ │ ├── test_device.json
│ │ │ ├── test_firefox.json
│ │ │ ├── test_os.json
│ │ │ └── test_pgts_browser.json
│ │ ├── useragent-0.1.1.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── REQUESTED
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── werkzeug
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── _internal.cpython-312.pyc
│ │ │ │ ├── _reloader.cpython-312.pyc
│ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ ├── formparser.cpython-312.pyc
│ │ │ │ ├── http.cpython-312.pyc
│ │ │ │ ├── local.cpython-312.pyc
│ │ │ │ ├── security.cpython-312.pyc
│ │ │ │ ├── serving.cpython-312.pyc
│ │ │ │ ├── test.cpython-312.pyc
│ │ │ │ ├── testapp.cpython-312.pyc
│ │ │ │ ├── urls.cpython-312.pyc
│ │ │ │ ├── user_agent.cpython-312.pyc
│ │ │ │ ├── utils.cpython-312.pyc
│ │ │ │ └── wsgi.cpython-312.pyc
│ │ │ ├── _internal.py
│ │ │ ├── _reloader.py
│ │ │ ├── datastructures
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── accept.cpython-312.pyc
│ │ │ │ │ ├── auth.cpython-312.pyc
│ │ │ │ │ ├── cache_control.cpython-312.pyc
│ │ │ │ │ ├── csp.cpython-312.pyc
│ │ │ │ │ ├── etag.cpython-312.pyc
│ │ │ │ │ ├── file_storage.cpython-312.pyc
│ │ │ │ │ ├── headers.cpython-312.pyc
│ │ │ │ │ ├── mixins.cpython-312.pyc
│ │ │ │ │ ├── range.cpython-312.pyc
│ │ │ │ │ └── structures.cpython-312.pyc
│ │ │ │ ├── accept.py
│ │ │ │ ├── accept.pyi
│ │ │ │ ├── auth.py
│ │ │ │ ├── cache_control.py
│ │ │ │ ├── cache_control.pyi
│ │ │ │ ├── csp.py
│ │ │ │ ├── csp.pyi
│ │ │ │ ├── etag.py
│ │ │ │ ├── etag.pyi
│ │ │ │ ├── file_storage.py
│ │ │ │ ├── file_storage.pyi
│ │ │ │ ├── headers.py
│ │ │ │ ├── headers.pyi
│ │ │ │ ├── mixins.py
│ │ │ │ ├── mixins.pyi
│ │ │ │ ├── range.py
│ │ │ │ ├── range.pyi
│ │ │ │ ├── structures.py
│ │ │ │ └── structures.pyi
│ │ │ ├── debug
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── console.cpython-312.pyc
│ │ │ │ │ ├── repr.cpython-312.pyc
│ │ │ │ │ └── tbtools.cpython-312.pyc
│ │ │ │ ├── console.py
│ │ │ │ ├── repr.py
│ │ │ │ ├── shared
│ │ │ │ │ ├── console.png
│ │ │ │ │ ├── debugger.js
│ │ │ │ │ ├── ICON_LICENSE.md
│ │ │ │ │ ├── less.png
│ │ │ │ │ ├── more.png
│ │ │ │ │ └── style.css
│ │ │ │ └── tbtools.py
│ │ │ ├── exceptions.py
│ │ │ ├── formparser.py
│ │ │ ├── http.py
│ │ │ ├── local.py
│ │ │ ├── middleware
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── dispatcher.cpython-312.pyc
│ │ │ │ │ ├── http_proxy.cpython-312.pyc
│ │ │ │ │ ├── lint.cpython-312.pyc
│ │ │ │ │ ├── profiler.cpython-312.pyc
│ │ │ │ │ ├── proxy_fix.cpython-312.pyc
│ │ │ │ │ └── shared_data.cpython-312.pyc
│ │ │ │ ├── dispatcher.py
│ │ │ │ ├── http_proxy.py
│ │ │ │ ├── lint.py
│ │ │ │ ├── profiler.py
│ │ │ │ ├── proxy_fix.py
│ │ │ │ └── shared_data.py
│ │ │ ├── py.typed
│ │ │ ├── routing
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── converters.cpython-312.pyc
│ │ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ │ ├── map.cpython-312.pyc
│ │ │ │ │ ├── matcher.cpython-312.pyc
│ │ │ │ │ └── rules.cpython-312.pyc
│ │ │ │ ├── converters.py
│ │ │ │ ├── exceptions.py
│ │ │ │ ├── map.py
│ │ │ │ ├── matcher.py
│ │ │ │ └── rules.py
│ │ │ ├── sansio
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── http.cpython-312.pyc
│ │ │ │ │ ├── multipart.cpython-312.pyc
│ │ │ │ │ ├── request.cpython-312.pyc
│ │ │ │ │ ├── response.cpython-312.pyc
│ │ │ │ │ └── utils.cpython-312.pyc
│ │ │ │ ├── http.py
│ │ │ │ ├── multipart.py
│ │ │ │ ├── request.py
│ │ │ │ ├── response.py
│ │ │ │ └── utils.py
│ │ │ ├── security.py
│ │ │ ├── serving.py
│ │ │ ├── test.py
│ │ │ ├── testapp.py
│ │ │ ├── urls.py
│ │ │ ├── user_agent.py
│ │ │ ├── utils.py
│ │ │ ├── wrappers
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── request.cpython-312.pyc
│ │ │ │ │ └── response.cpython-312.pyc
│ │ │ │ ├── request.py
│ │ │ │ └── response.py
│ │ │ └── wsgi.py
│ │ └── werkzeug-3.0.4.dist-info
│ │ ├── INSTALLER
│ │ ├── LICENSE.txt
│ │ ├── METADATA
│ │ ├── RECORD
│ │ └── WHEEL
│ ├── pyvenv.cfg
│ ├── static
│ │ └── styles.css
│ ├── templates
│ │ └── index.html
│ └── test.py
├── cline_config.json
├── mcp_server.py
├── README.md
├── search_results.json
├── settings.json
└── test_files
├── text1.txt
└── text2.txt
```
# Files
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/flask/app.py:
--------------------------------------------------------------------------------
```python
1 | from __future__ import annotations
2 |
3 | import collections.abc as cabc
4 | import os
5 | import sys
6 | import typing as t
7 | import weakref
8 | from datetime import timedelta
9 | from inspect import iscoroutinefunction
10 | from itertools import chain
11 | from types import TracebackType
12 | from urllib.parse import quote as _url_quote
13 |
14 | import click
15 | from werkzeug.datastructures import Headers
16 | from werkzeug.datastructures import ImmutableDict
17 | from werkzeug.exceptions import BadRequestKeyError
18 | from werkzeug.exceptions import HTTPException
19 | from werkzeug.exceptions import InternalServerError
20 | from werkzeug.routing import BuildError
21 | from werkzeug.routing import MapAdapter
22 | from werkzeug.routing import RequestRedirect
23 | from werkzeug.routing import RoutingException
24 | from werkzeug.routing import Rule
25 | from werkzeug.serving import is_running_from_reloader
26 | from werkzeug.wrappers import Response as BaseResponse
27 |
28 | from . import cli
29 | from . import typing as ft
30 | from .ctx import AppContext
31 | from .ctx import RequestContext
32 | from .globals import _cv_app
33 | from .globals import _cv_request
34 | from .globals import current_app
35 | from .globals import g
36 | from .globals import request
37 | from .globals import request_ctx
38 | from .globals import session
39 | from .helpers import get_debug_flag
40 | from .helpers import get_flashed_messages
41 | from .helpers import get_load_dotenv
42 | from .helpers import send_from_directory
43 | from .sansio.app import App
44 | from .sansio.scaffold import _sentinel
45 | from .sessions import SecureCookieSessionInterface
46 | from .sessions import SessionInterface
47 | from .signals import appcontext_tearing_down
48 | from .signals import got_request_exception
49 | from .signals import request_finished
50 | from .signals import request_started
51 | from .signals import request_tearing_down
52 | from .templating import Environment
53 | from .wrappers import Request
54 | from .wrappers import Response
55 |
56 | if t.TYPE_CHECKING: # pragma: no cover
57 | from _typeshed.wsgi import StartResponse
58 | from _typeshed.wsgi import WSGIEnvironment
59 |
60 | from .testing import FlaskClient
61 | from .testing import FlaskCliRunner
62 |
63 | T_shell_context_processor = t.TypeVar(
64 | "T_shell_context_processor", bound=ft.ShellContextProcessorCallable
65 | )
66 | T_teardown = t.TypeVar("T_teardown", bound=ft.TeardownCallable)
67 | T_template_filter = t.TypeVar("T_template_filter", bound=ft.TemplateFilterCallable)
68 | T_template_global = t.TypeVar("T_template_global", bound=ft.TemplateGlobalCallable)
69 | T_template_test = t.TypeVar("T_template_test", bound=ft.TemplateTestCallable)
70 |
71 |
72 | def _make_timedelta(value: timedelta | int | None) -> timedelta | None:
73 | if value is None or isinstance(value, timedelta):
74 | return value
75 |
76 | return timedelta(seconds=value)
77 |
78 |
79 | class Flask(App):
80 | """The flask object implements a WSGI application and acts as the central
81 | object. It is passed the name of the module or package of the
82 | application. Once it is created it will act as a central registry for
83 | the view functions, the URL rules, template configuration and much more.
84 |
85 | The name of the package is used to resolve resources from inside the
86 | package or the folder the module is contained in depending on if the
87 | package parameter resolves to an actual python package (a folder with
88 | an :file:`__init__.py` file inside) or a standard module (just a ``.py`` file).
89 |
90 | For more information about resource loading, see :func:`open_resource`.
91 |
92 | Usually you create a :class:`Flask` instance in your main module or
93 | in the :file:`__init__.py` file of your package like this::
94 |
95 | from flask import Flask
96 | app = Flask(__name__)
97 |
98 | .. admonition:: About the First Parameter
99 |
100 | The idea of the first parameter is to give Flask an idea of what
101 | belongs to your application. This name is used to find resources
102 | on the filesystem, can be used by extensions to improve debugging
103 | information and a lot more.
104 |
105 | So it's important what you provide there. If you are using a single
106 | module, `__name__` is always the correct value. If you however are
107 | using a package, it's usually recommended to hardcode the name of
108 | your package there.
109 |
110 | For example if your application is defined in :file:`yourapplication/app.py`
111 | you should create it with one of the two versions below::
112 |
113 | app = Flask('yourapplication')
114 | app = Flask(__name__.split('.')[0])
115 |
116 | Why is that? The application will work even with `__name__`, thanks
117 | to how resources are looked up. However it will make debugging more
118 | painful. Certain extensions can make assumptions based on the
119 | import name of your application. For example the Flask-SQLAlchemy
120 | extension will look for the code in your application that triggered
121 | an SQL query in debug mode. If the import name is not properly set
122 | up, that debugging information is lost. (For example it would only
123 | pick up SQL queries in `yourapplication.app` and not
124 | `yourapplication.views.frontend`)
125 |
126 | .. versionadded:: 0.7
127 | The `static_url_path`, `static_folder`, and `template_folder`
128 | parameters were added.
129 |
130 | .. versionadded:: 0.8
131 | The `instance_path` and `instance_relative_config` parameters were
132 | added.
133 |
134 | .. versionadded:: 0.11
135 | The `root_path` parameter was added.
136 |
137 | .. versionadded:: 1.0
138 | The ``host_matching`` and ``static_host`` parameters were added.
139 |
140 | .. versionadded:: 1.0
141 | The ``subdomain_matching`` parameter was added. Subdomain
142 | matching needs to be enabled manually now. Setting
143 | :data:`SERVER_NAME` does not implicitly enable it.
144 |
145 | :param import_name: the name of the application package
146 | :param static_url_path: can be used to specify a different path for the
147 | static files on the web. Defaults to the name
148 | of the `static_folder` folder.
149 | :param static_folder: The folder with static files that is served at
150 | ``static_url_path``. Relative to the application ``root_path``
151 | or an absolute path. Defaults to ``'static'``.
152 | :param static_host: the host to use when adding the static route.
153 | Defaults to None. Required when using ``host_matching=True``
154 | with a ``static_folder`` configured.
155 | :param host_matching: set ``url_map.host_matching`` attribute.
156 | Defaults to False.
157 | :param subdomain_matching: consider the subdomain relative to
158 | :data:`SERVER_NAME` when matching routes. Defaults to False.
159 | :param template_folder: the folder that contains the templates that should
160 | be used by the application. Defaults to
161 | ``'templates'`` folder in the root path of the
162 | application.
163 | :param instance_path: An alternative instance path for the application.
164 | By default the folder ``'instance'`` next to the
165 | package or module is assumed to be the instance
166 | path.
167 | :param instance_relative_config: if set to ``True`` relative filenames
168 | for loading the config are assumed to
169 | be relative to the instance path instead
170 | of the application root.
171 | :param root_path: The path to the root of the application files.
172 | This should only be set manually when it can't be detected
173 | automatically, such as for namespace packages.
174 | """
175 |
176 | default_config = ImmutableDict(
177 | {
178 | "DEBUG": None,
179 | "TESTING": False,
180 | "PROPAGATE_EXCEPTIONS": None,
181 | "SECRET_KEY": None,
182 | "PERMANENT_SESSION_LIFETIME": timedelta(days=31),
183 | "USE_X_SENDFILE": False,
184 | "SERVER_NAME": None,
185 | "APPLICATION_ROOT": "/",
186 | "SESSION_COOKIE_NAME": "session",
187 | "SESSION_COOKIE_DOMAIN": None,
188 | "SESSION_COOKIE_PATH": None,
189 | "SESSION_COOKIE_HTTPONLY": True,
190 | "SESSION_COOKIE_SECURE": False,
191 | "SESSION_COOKIE_SAMESITE": None,
192 | "SESSION_REFRESH_EACH_REQUEST": True,
193 | "MAX_CONTENT_LENGTH": None,
194 | "SEND_FILE_MAX_AGE_DEFAULT": None,
195 | "TRAP_BAD_REQUEST_ERRORS": None,
196 | "TRAP_HTTP_EXCEPTIONS": False,
197 | "EXPLAIN_TEMPLATE_LOADING": False,
198 | "PREFERRED_URL_SCHEME": "http",
199 | "TEMPLATES_AUTO_RELOAD": None,
200 | "MAX_COOKIE_SIZE": 4093,
201 | }
202 | )
203 |
204 | #: The class that is used for request objects. See :class:`~flask.Request`
205 | #: for more information.
206 | request_class: type[Request] = Request
207 |
208 | #: The class that is used for response objects. See
209 | #: :class:`~flask.Response` for more information.
210 | response_class: type[Response] = Response
211 |
212 | #: the session interface to use. By default an instance of
213 | #: :class:`~flask.sessions.SecureCookieSessionInterface` is used here.
214 | #:
215 | #: .. versionadded:: 0.8
216 | session_interface: SessionInterface = SecureCookieSessionInterface()
217 |
218 | def __init__(
219 | self,
220 | import_name: str,
221 | static_url_path: str | None = None,
222 | static_folder: str | os.PathLike[str] | None = "static",
223 | static_host: str | None = None,
224 | host_matching: bool = False,
225 | subdomain_matching: bool = False,
226 | template_folder: str | os.PathLike[str] | None = "templates",
227 | instance_path: str | None = None,
228 | instance_relative_config: bool = False,
229 | root_path: str | None = None,
230 | ):
231 | super().__init__(
232 | import_name=import_name,
233 | static_url_path=static_url_path,
234 | static_folder=static_folder,
235 | static_host=static_host,
236 | host_matching=host_matching,
237 | subdomain_matching=subdomain_matching,
238 | template_folder=template_folder,
239 | instance_path=instance_path,
240 | instance_relative_config=instance_relative_config,
241 | root_path=root_path,
242 | )
243 |
244 | #: The Click command group for registering CLI commands for this
245 | #: object. The commands are available from the ``flask`` command
246 | #: once the application has been discovered and blueprints have
247 | #: been registered.
248 | self.cli = cli.AppGroup()
249 |
250 | # Set the name of the Click group in case someone wants to add
251 | # the app's commands to another CLI tool.
252 | self.cli.name = self.name
253 |
254 | # Add a static route using the provided static_url_path, static_host,
255 | # and static_folder if there is a configured static_folder.
256 | # Note we do this without checking if static_folder exists.
257 | # For one, it might be created while the server is running (e.g. during
258 | # development). Also, Google App Engine stores static files somewhere
259 | if self.has_static_folder:
260 | assert (
261 | bool(static_host) == host_matching
262 | ), "Invalid static_host/host_matching combination"
263 | # Use a weakref to avoid creating a reference cycle between the app
264 | # and the view function (see #3761).
265 | self_ref = weakref.ref(self)
266 | self.add_url_rule(
267 | f"{self.static_url_path}/<path:filename>",
268 | endpoint="static",
269 | host=static_host,
270 | view_func=lambda **kw: self_ref().send_static_file(**kw), # type: ignore # noqa: B950
271 | )
272 |
273 | def get_send_file_max_age(self, filename: str | None) -> int | None:
274 | """Used by :func:`send_file` to determine the ``max_age`` cache
275 | value for a given file path if it wasn't passed.
276 |
277 | By default, this returns :data:`SEND_FILE_MAX_AGE_DEFAULT` from
278 | the configuration of :data:`~flask.current_app`. This defaults
279 | to ``None``, which tells the browser to use conditional requests
280 | instead of a timed cache, which is usually preferable.
281 |
282 | Note this is a duplicate of the same method in the Flask
283 | class.
284 |
285 | .. versionchanged:: 2.0
286 | The default configuration is ``None`` instead of 12 hours.
287 |
288 | .. versionadded:: 0.9
289 | """
290 | value = current_app.config["SEND_FILE_MAX_AGE_DEFAULT"]
291 |
292 | if value is None:
293 | return None
294 |
295 | if isinstance(value, timedelta):
296 | return int(value.total_seconds())
297 |
298 | return value # type: ignore[no-any-return]
299 |
300 | def send_static_file(self, filename: str) -> Response:
301 | """The view function used to serve files from
302 | :attr:`static_folder`. A route is automatically registered for
303 | this view at :attr:`static_url_path` if :attr:`static_folder` is
304 | set.
305 |
306 | Note this is a duplicate of the same method in the Flask
307 | class.
308 |
309 | .. versionadded:: 0.5
310 |
311 | """
312 | if not self.has_static_folder:
313 | raise RuntimeError("'static_folder' must be set to serve static_files.")
314 |
315 | # send_file only knows to call get_send_file_max_age on the app,
316 | # call it here so it works for blueprints too.
317 | max_age = self.get_send_file_max_age(filename)
318 | return send_from_directory(
319 | t.cast(str, self.static_folder), filename, max_age=max_age
320 | )
321 |
322 | def open_resource(self, resource: str, mode: str = "rb") -> t.IO[t.AnyStr]:
323 | """Open a resource file relative to :attr:`root_path` for
324 | reading.
325 |
326 | For example, if the file ``schema.sql`` is next to the file
327 | ``app.py`` where the ``Flask`` app is defined, it can be opened
328 | with:
329 |
330 | .. code-block:: python
331 |
332 | with app.open_resource("schema.sql") as f:
333 | conn.executescript(f.read())
334 |
335 | :param resource: Path to the resource relative to
336 | :attr:`root_path`.
337 | :param mode: Open the file in this mode. Only reading is
338 | supported, valid values are "r" (or "rt") and "rb".
339 |
340 | Note this is a duplicate of the same method in the Flask
341 | class.
342 |
343 | """
344 | if mode not in {"r", "rt", "rb"}:
345 | raise ValueError("Resources can only be opened for reading.")
346 |
347 | return open(os.path.join(self.root_path, resource), mode)
348 |
349 | def open_instance_resource(self, resource: str, mode: str = "rb") -> t.IO[t.AnyStr]:
350 | """Opens a resource from the application's instance folder
351 | (:attr:`instance_path`). Otherwise works like
352 | :meth:`open_resource`. Instance resources can also be opened for
353 | writing.
354 |
355 | :param resource: the name of the resource. To access resources within
356 | subfolders use forward slashes as separator.
357 | :param mode: resource file opening mode, default is 'rb'.
358 | """
359 | return open(os.path.join(self.instance_path, resource), mode)
360 |
361 | def create_jinja_environment(self) -> Environment:
362 | """Create the Jinja environment based on :attr:`jinja_options`
363 | and the various Jinja-related methods of the app. Changing
364 | :attr:`jinja_options` after this will have no effect. Also adds
365 | Flask-related globals and filters to the environment.
366 |
367 | .. versionchanged:: 0.11
368 | ``Environment.auto_reload`` set in accordance with
369 | ``TEMPLATES_AUTO_RELOAD`` configuration option.
370 |
371 | .. versionadded:: 0.5
372 | """
373 | options = dict(self.jinja_options)
374 |
375 | if "autoescape" not in options:
376 | options["autoescape"] = self.select_jinja_autoescape
377 |
378 | if "auto_reload" not in options:
379 | auto_reload = self.config["TEMPLATES_AUTO_RELOAD"]
380 |
381 | if auto_reload is None:
382 | auto_reload = self.debug
383 |
384 | options["auto_reload"] = auto_reload
385 |
386 | rv = self.jinja_environment(self, **options)
387 | rv.globals.update(
388 | url_for=self.url_for,
389 | get_flashed_messages=get_flashed_messages,
390 | config=self.config,
391 | # request, session and g are normally added with the
392 | # context processor for efficiency reasons but for imported
393 | # templates we also want the proxies in there.
394 | request=request,
395 | session=session,
396 | g=g,
397 | )
398 | rv.policies["json.dumps_function"] = self.json.dumps
399 | return rv
400 |
401 | def create_url_adapter(self, request: Request | None) -> MapAdapter | None:
402 | """Creates a URL adapter for the given request. The URL adapter
403 | is created at a point where the request context is not yet set
404 | up so the request is passed explicitly.
405 |
406 | .. versionadded:: 0.6
407 |
408 | .. versionchanged:: 0.9
409 | This can now also be called without a request object when the
410 | URL adapter is created for the application context.
411 |
412 | .. versionchanged:: 1.0
413 | :data:`SERVER_NAME` no longer implicitly enables subdomain
414 | matching. Use :attr:`subdomain_matching` instead.
415 | """
416 | if request is not None:
417 | # If subdomain matching is disabled (the default), use the
418 | # default subdomain in all cases. This should be the default
419 | # in Werkzeug but it currently does not have that feature.
420 | if not self.subdomain_matching:
421 | subdomain = self.url_map.default_subdomain or None
422 | else:
423 | subdomain = None
424 |
425 | return self.url_map.bind_to_environ(
426 | request.environ,
427 | server_name=self.config["SERVER_NAME"],
428 | subdomain=subdomain,
429 | )
430 | # We need at the very least the server name to be set for this
431 | # to work.
432 | if self.config["SERVER_NAME"] is not None:
433 | return self.url_map.bind(
434 | self.config["SERVER_NAME"],
435 | script_name=self.config["APPLICATION_ROOT"],
436 | url_scheme=self.config["PREFERRED_URL_SCHEME"],
437 | )
438 |
439 | return None
440 |
441 | def raise_routing_exception(self, request: Request) -> t.NoReturn:
442 | """Intercept routing exceptions and possibly do something else.
443 |
444 | In debug mode, intercept a routing redirect and replace it with
445 | an error if the body will be discarded.
446 |
447 | With modern Werkzeug this shouldn't occur, since it now uses a
448 | 308 status which tells the browser to resend the method and
449 | body.
450 |
451 | .. versionchanged:: 2.1
452 | Don't intercept 307 and 308 redirects.
453 |
454 | :meta private:
455 | :internal:
456 | """
457 | if (
458 | not self.debug
459 | or not isinstance(request.routing_exception, RequestRedirect)
460 | or request.routing_exception.code in {307, 308}
461 | or request.method in {"GET", "HEAD", "OPTIONS"}
462 | ):
463 | raise request.routing_exception # type: ignore[misc]
464 |
465 | from .debughelpers import FormDataRoutingRedirect
466 |
467 | raise FormDataRoutingRedirect(request)
468 |
469 | def update_template_context(self, context: dict[str, t.Any]) -> None:
470 | """Update the template context with some commonly used variables.
471 | This injects request, session, config and g into the template
472 | context as well as everything template context processors want
473 | to inject. Note that the as of Flask 0.6, the original values
474 | in the context will not be overridden if a context processor
475 | decides to return a value with the same key.
476 |
477 | :param context: the context as a dictionary that is updated in place
478 | to add extra variables.
479 | """
480 | names: t.Iterable[str | None] = (None,)
481 |
482 | # A template may be rendered outside a request context.
483 | if request:
484 | names = chain(names, reversed(request.blueprints))
485 |
486 | # The values passed to render_template take precedence. Keep a
487 | # copy to re-apply after all context functions.
488 | orig_ctx = context.copy()
489 |
490 | for name in names:
491 | if name in self.template_context_processors:
492 | for func in self.template_context_processors[name]:
493 | context.update(self.ensure_sync(func)())
494 |
495 | context.update(orig_ctx)
496 |
497 | def make_shell_context(self) -> dict[str, t.Any]:
498 | """Returns the shell context for an interactive shell for this
499 | application. This runs all the registered shell context
500 | processors.
501 |
502 | .. versionadded:: 0.11
503 | """
504 | rv = {"app": self, "g": g}
505 | for processor in self.shell_context_processors:
506 | rv.update(processor())
507 | return rv
508 |
509 | def run(
510 | self,
511 | host: str | None = None,
512 | port: int | None = None,
513 | debug: bool | None = None,
514 | load_dotenv: bool = True,
515 | **options: t.Any,
516 | ) -> None:
517 | """Runs the application on a local development server.
518 |
519 | Do not use ``run()`` in a production setting. It is not intended to
520 | meet security and performance requirements for a production server.
521 | Instead, see :doc:`/deploying/index` for WSGI server recommendations.
522 |
523 | If the :attr:`debug` flag is set the server will automatically reload
524 | for code changes and show a debugger in case an exception happened.
525 |
526 | If you want to run the application in debug mode, but disable the
527 | code execution on the interactive debugger, you can pass
528 | ``use_evalex=False`` as parameter. This will keep the debugger's
529 | traceback screen active, but disable code execution.
530 |
531 | It is not recommended to use this function for development with
532 | automatic reloading as this is badly supported. Instead you should
533 | be using the :command:`flask` command line script's ``run`` support.
534 |
535 | .. admonition:: Keep in Mind
536 |
537 | Flask will suppress any server error with a generic error page
538 | unless it is in debug mode. As such to enable just the
539 | interactive debugger without the code reloading, you have to
540 | invoke :meth:`run` with ``debug=True`` and ``use_reloader=False``.
541 | Setting ``use_debugger`` to ``True`` without being in debug mode
542 | won't catch any exceptions because there won't be any to
543 | catch.
544 |
545 | :param host: the hostname to listen on. Set this to ``'0.0.0.0'`` to
546 | have the server available externally as well. Defaults to
547 | ``'127.0.0.1'`` or the host in the ``SERVER_NAME`` config variable
548 | if present.
549 | :param port: the port of the webserver. Defaults to ``5000`` or the
550 | port defined in the ``SERVER_NAME`` config variable if present.
551 | :param debug: if given, enable or disable debug mode. See
552 | :attr:`debug`.
553 | :param load_dotenv: Load the nearest :file:`.env` and :file:`.flaskenv`
554 | files to set environment variables. Will also change the working
555 | directory to the directory containing the first file found.
556 | :param options: the options to be forwarded to the underlying Werkzeug
557 | server. See :func:`werkzeug.serving.run_simple` for more
558 | information.
559 |
560 | .. versionchanged:: 1.0
561 | If installed, python-dotenv will be used to load environment
562 | variables from :file:`.env` and :file:`.flaskenv` files.
563 |
564 | The :envvar:`FLASK_DEBUG` environment variable will override :attr:`debug`.
565 |
566 | Threaded mode is enabled by default.
567 |
568 | .. versionchanged:: 0.10
569 | The default port is now picked from the ``SERVER_NAME``
570 | variable.
571 | """
572 | # Ignore this call so that it doesn't start another server if
573 | # the 'flask run' command is used.
574 | if os.environ.get("FLASK_RUN_FROM_CLI") == "true":
575 | if not is_running_from_reloader():
576 | click.secho(
577 | " * Ignoring a call to 'app.run()' that would block"
578 | " the current 'flask' CLI command.\n"
579 | " Only call 'app.run()' in an 'if __name__ =="
580 | ' "__main__"\' guard.',
581 | fg="red",
582 | )
583 |
584 | return
585 |
586 | if get_load_dotenv(load_dotenv):
587 | cli.load_dotenv()
588 |
589 | # if set, env var overrides existing value
590 | if "FLASK_DEBUG" in os.environ:
591 | self.debug = get_debug_flag()
592 |
593 | # debug passed to method overrides all other sources
594 | if debug is not None:
595 | self.debug = bool(debug)
596 |
597 | server_name = self.config.get("SERVER_NAME")
598 | sn_host = sn_port = None
599 |
600 | if server_name:
601 | sn_host, _, sn_port = server_name.partition(":")
602 |
603 | if not host:
604 | if sn_host:
605 | host = sn_host
606 | else:
607 | host = "127.0.0.1"
608 |
609 | if port or port == 0:
610 | port = int(port)
611 | elif sn_port:
612 | port = int(sn_port)
613 | else:
614 | port = 5000
615 |
616 | options.setdefault("use_reloader", self.debug)
617 | options.setdefault("use_debugger", self.debug)
618 | options.setdefault("threaded", True)
619 |
620 | cli.show_server_banner(self.debug, self.name)
621 |
622 | from werkzeug.serving import run_simple
623 |
624 | try:
625 | run_simple(t.cast(str, host), port, self, **options)
626 | finally:
627 | # reset the first request information if the development server
628 | # reset normally. This makes it possible to restart the server
629 | # without reloader and that stuff from an interactive shell.
630 | self._got_first_request = False
631 |
632 | def test_client(self, use_cookies: bool = True, **kwargs: t.Any) -> FlaskClient:
633 | """Creates a test client for this application. For information
634 | about unit testing head over to :doc:`/testing`.
635 |
636 | Note that if you are testing for assertions or exceptions in your
637 | application code, you must set ``app.testing = True`` in order for the
638 | exceptions to propagate to the test client. Otherwise, the exception
639 | will be handled by the application (not visible to the test client) and
640 | the only indication of an AssertionError or other exception will be a
641 | 500 status code response to the test client. See the :attr:`testing`
642 | attribute. For example::
643 |
644 | app.testing = True
645 | client = app.test_client()
646 |
647 | The test client can be used in a ``with`` block to defer the closing down
648 | of the context until the end of the ``with`` block. This is useful if
649 | you want to access the context locals for testing::
650 |
651 | with app.test_client() as c:
652 | rv = c.get('/?vodka=42')
653 | assert request.args['vodka'] == '42'
654 |
655 | Additionally, you may pass optional keyword arguments that will then
656 | be passed to the application's :attr:`test_client_class` constructor.
657 | For example::
658 |
659 | from flask.testing import FlaskClient
660 |
661 | class CustomClient(FlaskClient):
662 | def __init__(self, *args, **kwargs):
663 | self._authentication = kwargs.pop("authentication")
664 | super(CustomClient,self).__init__( *args, **kwargs)
665 |
666 | app.test_client_class = CustomClient
667 | client = app.test_client(authentication='Basic ....')
668 |
669 | See :class:`~flask.testing.FlaskClient` for more information.
670 |
671 | .. versionchanged:: 0.4
672 | added support for ``with`` block usage for the client.
673 |
674 | .. versionadded:: 0.7
675 | The `use_cookies` parameter was added as well as the ability
676 | to override the client to be used by setting the
677 | :attr:`test_client_class` attribute.
678 |
679 | .. versionchanged:: 0.11
680 | Added `**kwargs` to support passing additional keyword arguments to
681 | the constructor of :attr:`test_client_class`.
682 | """
683 | cls = self.test_client_class
684 | if cls is None:
685 | from .testing import FlaskClient as cls
686 | return cls( # type: ignore
687 | self, self.response_class, use_cookies=use_cookies, **kwargs
688 | )
689 |
690 | def test_cli_runner(self, **kwargs: t.Any) -> FlaskCliRunner:
691 | """Create a CLI runner for testing CLI commands.
692 | See :ref:`testing-cli`.
693 |
694 | Returns an instance of :attr:`test_cli_runner_class`, by default
695 | :class:`~flask.testing.FlaskCliRunner`. The Flask app object is
696 | passed as the first argument.
697 |
698 | .. versionadded:: 1.0
699 | """
700 | cls = self.test_cli_runner_class
701 |
702 | if cls is None:
703 | from .testing import FlaskCliRunner as cls
704 |
705 | return cls(self, **kwargs) # type: ignore
706 |
707 | def handle_http_exception(
708 | self, e: HTTPException
709 | ) -> HTTPException | ft.ResponseReturnValue:
710 | """Handles an HTTP exception. By default this will invoke the
711 | registered error handlers and fall back to returning the
712 | exception as response.
713 |
714 | .. versionchanged:: 1.0.3
715 | ``RoutingException``, used internally for actions such as
716 | slash redirects during routing, is not passed to error
717 | handlers.
718 |
719 | .. versionchanged:: 1.0
720 | Exceptions are looked up by code *and* by MRO, so
721 | ``HTTPException`` subclasses can be handled with a catch-all
722 | handler for the base ``HTTPException``.
723 |
724 | .. versionadded:: 0.3
725 | """
726 | # Proxy exceptions don't have error codes. We want to always return
727 | # those unchanged as errors
728 | if e.code is None:
729 | return e
730 |
731 | # RoutingExceptions are used internally to trigger routing
732 | # actions, such as slash redirects raising RequestRedirect. They
733 | # are not raised or handled in user code.
734 | if isinstance(e, RoutingException):
735 | return e
736 |
737 | handler = self._find_error_handler(e, request.blueprints)
738 | if handler is None:
739 | return e
740 | return self.ensure_sync(handler)(e) # type: ignore[no-any-return]
741 |
742 | def handle_user_exception(
743 | self, e: Exception
744 | ) -> HTTPException | ft.ResponseReturnValue:
745 | """This method is called whenever an exception occurs that
746 | should be handled. A special case is :class:`~werkzeug
747 | .exceptions.HTTPException` which is forwarded to the
748 | :meth:`handle_http_exception` method. This function will either
749 | return a response value or reraise the exception with the same
750 | traceback.
751 |
752 | .. versionchanged:: 1.0
753 | Key errors raised from request data like ``form`` show the
754 | bad key in debug mode rather than a generic bad request
755 | message.
756 |
757 | .. versionadded:: 0.7
758 | """
759 | if isinstance(e, BadRequestKeyError) and (
760 | self.debug or self.config["TRAP_BAD_REQUEST_ERRORS"]
761 | ):
762 | e.show_exception = True
763 |
764 | if isinstance(e, HTTPException) and not self.trap_http_exception(e):
765 | return self.handle_http_exception(e)
766 |
767 | handler = self._find_error_handler(e, request.blueprints)
768 |
769 | if handler is None:
770 | raise
771 |
772 | return self.ensure_sync(handler)(e) # type: ignore[no-any-return]
773 |
774 | def handle_exception(self, e: Exception) -> Response:
775 | """Handle an exception that did not have an error handler
776 | associated with it, or that was raised from an error handler.
777 | This always causes a 500 ``InternalServerError``.
778 |
779 | Always sends the :data:`got_request_exception` signal.
780 |
781 | If :data:`PROPAGATE_EXCEPTIONS` is ``True``, such as in debug
782 | mode, the error will be re-raised so that the debugger can
783 | display it. Otherwise, the original exception is logged, and
784 | an :exc:`~werkzeug.exceptions.InternalServerError` is returned.
785 |
786 | If an error handler is registered for ``InternalServerError`` or
787 | ``500``, it will be used. For consistency, the handler will
788 | always receive the ``InternalServerError``. The original
789 | unhandled exception is available as ``e.original_exception``.
790 |
791 | .. versionchanged:: 1.1.0
792 | Always passes the ``InternalServerError`` instance to the
793 | handler, setting ``original_exception`` to the unhandled
794 | error.
795 |
796 | .. versionchanged:: 1.1.0
797 | ``after_request`` functions and other finalization is done
798 | even for the default 500 response when there is no handler.
799 |
800 | .. versionadded:: 0.3
801 | """
802 | exc_info = sys.exc_info()
803 | got_request_exception.send(self, _async_wrapper=self.ensure_sync, exception=e)
804 | propagate = self.config["PROPAGATE_EXCEPTIONS"]
805 |
806 | if propagate is None:
807 | propagate = self.testing or self.debug
808 |
809 | if propagate:
810 | # Re-raise if called with an active exception, otherwise
811 | # raise the passed in exception.
812 | if exc_info[1] is e:
813 | raise
814 |
815 | raise e
816 |
817 | self.log_exception(exc_info)
818 | server_error: InternalServerError | ft.ResponseReturnValue
819 | server_error = InternalServerError(original_exception=e)
820 | handler = self._find_error_handler(server_error, request.blueprints)
821 |
822 | if handler is not None:
823 | server_error = self.ensure_sync(handler)(server_error)
824 |
825 | return self.finalize_request(server_error, from_error_handler=True)
826 |
827 | def log_exception(
828 | self,
829 | exc_info: (tuple[type, BaseException, TracebackType] | tuple[None, None, None]),
830 | ) -> None:
831 | """Logs an exception. This is called by :meth:`handle_exception`
832 | if debugging is disabled and right before the handler is called.
833 | The default implementation logs the exception as error on the
834 | :attr:`logger`.
835 |
836 | .. versionadded:: 0.8
837 | """
838 | self.logger.error(
839 | f"Exception on {request.path} [{request.method}]", exc_info=exc_info
840 | )
841 |
842 | def dispatch_request(self) -> ft.ResponseReturnValue:
843 | """Does the request dispatching. Matches the URL and returns the
844 | return value of the view or error handler. This does not have to
845 | be a response object. In order to convert the return value to a
846 | proper response object, call :func:`make_response`.
847 |
848 | .. versionchanged:: 0.7
849 | This no longer does the exception handling, this code was
850 | moved to the new :meth:`full_dispatch_request`.
851 | """
852 | req = request_ctx.request
853 | if req.routing_exception is not None:
854 | self.raise_routing_exception(req)
855 | rule: Rule = req.url_rule # type: ignore[assignment]
856 | # if we provide automatic options for this URL and the
857 | # request came with the OPTIONS method, reply automatically
858 | if (
859 | getattr(rule, "provide_automatic_options", False)
860 | and req.method == "OPTIONS"
861 | ):
862 | return self.make_default_options_response()
863 | # otherwise dispatch to the handler for that endpoint
864 | view_args: dict[str, t.Any] = req.view_args # type: ignore[assignment]
865 | return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return]
866 |
867 | def full_dispatch_request(self) -> Response:
868 | """Dispatches the request and on top of that performs request
869 | pre and postprocessing as well as HTTP exception catching and
870 | error handling.
871 |
872 | .. versionadded:: 0.7
873 | """
874 | self._got_first_request = True
875 |
876 | try:
877 | request_started.send(self, _async_wrapper=self.ensure_sync)
878 | rv = self.preprocess_request()
879 | if rv is None:
880 | rv = self.dispatch_request()
881 | except Exception as e:
882 | rv = self.handle_user_exception(e)
883 | return self.finalize_request(rv)
884 |
885 | def finalize_request(
886 | self,
887 | rv: ft.ResponseReturnValue | HTTPException,
888 | from_error_handler: bool = False,
889 | ) -> Response:
890 | """Given the return value from a view function this finalizes
891 | the request by converting it into a response and invoking the
892 | postprocessing functions. This is invoked for both normal
893 | request dispatching as well as error handlers.
894 |
895 | Because this means that it might be called as a result of a
896 | failure a special safe mode is available which can be enabled
897 | with the `from_error_handler` flag. If enabled, failures in
898 | response processing will be logged and otherwise ignored.
899 |
900 | :internal:
901 | """
902 | response = self.make_response(rv)
903 | try:
904 | response = self.process_response(response)
905 | request_finished.send(
906 | self, _async_wrapper=self.ensure_sync, response=response
907 | )
908 | except Exception:
909 | if not from_error_handler:
910 | raise
911 | self.logger.exception(
912 | "Request finalizing failed with an error while handling an error"
913 | )
914 | return response
915 |
916 | def make_default_options_response(self) -> Response:
917 | """This method is called to create the default ``OPTIONS`` response.
918 | This can be changed through subclassing to change the default
919 | behavior of ``OPTIONS`` responses.
920 |
921 | .. versionadded:: 0.7
922 | """
923 | adapter = request_ctx.url_adapter
924 | methods = adapter.allowed_methods() # type: ignore[union-attr]
925 | rv = self.response_class()
926 | rv.allow.update(methods)
927 | return rv
928 |
929 | def ensure_sync(self, func: t.Callable[..., t.Any]) -> t.Callable[..., t.Any]:
930 | """Ensure that the function is synchronous for WSGI workers.
931 | Plain ``def`` functions are returned as-is. ``async def``
932 | functions are wrapped to run and wait for the response.
933 |
934 | Override this method to change how the app runs async views.
935 |
936 | .. versionadded:: 2.0
937 | """
938 | if iscoroutinefunction(func):
939 | return self.async_to_sync(func)
940 |
941 | return func
942 |
943 | def async_to_sync(
944 | self, func: t.Callable[..., t.Coroutine[t.Any, t.Any, t.Any]]
945 | ) -> t.Callable[..., t.Any]:
946 | """Return a sync function that will run the coroutine function.
947 |
948 | .. code-block:: python
949 |
950 | result = app.async_to_sync(func)(*args, **kwargs)
951 |
952 | Override this method to change how the app converts async code
953 | to be synchronously callable.
954 |
955 | .. versionadded:: 2.0
956 | """
957 | try:
958 | from asgiref.sync import async_to_sync as asgiref_async_to_sync
959 | except ImportError:
960 | raise RuntimeError(
961 | "Install Flask with the 'async' extra in order to use async views."
962 | ) from None
963 |
964 | return asgiref_async_to_sync(func)
965 |
966 | def url_for(
967 | self,
968 | /,
969 | endpoint: str,
970 | *,
971 | _anchor: str | None = None,
972 | _method: str | None = None,
973 | _scheme: str | None = None,
974 | _external: bool | None = None,
975 | **values: t.Any,
976 | ) -> str:
977 | """Generate a URL to the given endpoint with the given values.
978 |
979 | This is called by :func:`flask.url_for`, and can be called
980 | directly as well.
981 |
982 | An *endpoint* is the name of a URL rule, usually added with
983 | :meth:`@app.route() <route>`, and usually the same name as the
984 | view function. A route defined in a :class:`~flask.Blueprint`
985 | will prepend the blueprint's name separated by a ``.`` to the
986 | endpoint.
987 |
988 | In some cases, such as email messages, you want URLs to include
989 | the scheme and domain, like ``https://example.com/hello``. When
990 | not in an active request, URLs will be external by default, but
991 | this requires setting :data:`SERVER_NAME` so Flask knows what
992 | domain to use. :data:`APPLICATION_ROOT` and
993 | :data:`PREFERRED_URL_SCHEME` should also be configured as
994 | needed. This config is only used when not in an active request.
995 |
996 | Functions can be decorated with :meth:`url_defaults` to modify
997 | keyword arguments before the URL is built.
998 |
999 | If building fails for some reason, such as an unknown endpoint
1000 | or incorrect values, the app's :meth:`handle_url_build_error`
1001 | method is called. If that returns a string, that is returned,
1002 | otherwise a :exc:`~werkzeug.routing.BuildError` is raised.
1003 |
1004 | :param endpoint: The endpoint name associated with the URL to
1005 | generate. If this starts with a ``.``, the current blueprint
1006 | name (if any) will be used.
1007 | :param _anchor: If given, append this as ``#anchor`` to the URL.
1008 | :param _method: If given, generate the URL associated with this
1009 | method for the endpoint.
1010 | :param _scheme: If given, the URL will have this scheme if it
1011 | is external.
1012 | :param _external: If given, prefer the URL to be internal
1013 | (False) or require it to be external (True). External URLs
1014 | include the scheme and domain. When not in an active
1015 | request, URLs are external by default.
1016 | :param values: Values to use for the variable parts of the URL
1017 | rule. Unknown keys are appended as query string arguments,
1018 | like ``?a=b&c=d``.
1019 |
1020 | .. versionadded:: 2.2
1021 | Moved from ``flask.url_for``, which calls this method.
1022 | """
1023 | req_ctx = _cv_request.get(None)
1024 |
1025 | if req_ctx is not None:
1026 | url_adapter = req_ctx.url_adapter
1027 | blueprint_name = req_ctx.request.blueprint
1028 |
1029 | # If the endpoint starts with "." and the request matches a
1030 | # blueprint, the endpoint is relative to the blueprint.
1031 | if endpoint[:1] == ".":
1032 | if blueprint_name is not None:
1033 | endpoint = f"{blueprint_name}{endpoint}"
1034 | else:
1035 | endpoint = endpoint[1:]
1036 |
1037 | # When in a request, generate a URL without scheme and
1038 | # domain by default, unless a scheme is given.
1039 | if _external is None:
1040 | _external = _scheme is not None
1041 | else:
1042 | app_ctx = _cv_app.get(None)
1043 |
1044 | # If called by helpers.url_for, an app context is active,
1045 | # use its url_adapter. Otherwise, app.url_for was called
1046 | # directly, build an adapter.
1047 | if app_ctx is not None:
1048 | url_adapter = app_ctx.url_adapter
1049 | else:
1050 | url_adapter = self.create_url_adapter(None)
1051 |
1052 | if url_adapter is None:
1053 | raise RuntimeError(
1054 | "Unable to build URLs outside an active request"
1055 | " without 'SERVER_NAME' configured. Also configure"
1056 | " 'APPLICATION_ROOT' and 'PREFERRED_URL_SCHEME' as"
1057 | " needed."
1058 | )
1059 |
1060 | # When outside a request, generate a URL with scheme and
1061 | # domain by default.
1062 | if _external is None:
1063 | _external = True
1064 |
1065 | # It is an error to set _scheme when _external=False, in order
1066 | # to avoid accidental insecure URLs.
1067 | if _scheme is not None and not _external:
1068 | raise ValueError("When specifying '_scheme', '_external' must be True.")
1069 |
1070 | self.inject_url_defaults(endpoint, values)
1071 |
1072 | try:
1073 | rv = url_adapter.build( # type: ignore[union-attr]
1074 | endpoint,
1075 | values,
1076 | method=_method,
1077 | url_scheme=_scheme,
1078 | force_external=_external,
1079 | )
1080 | except BuildError as error:
1081 | values.update(
1082 | _anchor=_anchor, _method=_method, _scheme=_scheme, _external=_external
1083 | )
1084 | return self.handle_url_build_error(error, endpoint, values)
1085 |
1086 | if _anchor is not None:
1087 | _anchor = _url_quote(_anchor, safe="%!#$&'()*+,/:;=?@")
1088 | rv = f"{rv}#{_anchor}"
1089 |
1090 | return rv
1091 |
1092 | def make_response(self, rv: ft.ResponseReturnValue) -> Response:
1093 | """Convert the return value from a view function to an instance of
1094 | :attr:`response_class`.
1095 |
1096 | :param rv: the return value from the view function. The view function
1097 | must return a response. Returning ``None``, or the view ending
1098 | without returning, is not allowed. The following types are allowed
1099 | for ``view_rv``:
1100 |
1101 | ``str``
1102 | A response object is created with the string encoded to UTF-8
1103 | as the body.
1104 |
1105 | ``bytes``
1106 | A response object is created with the bytes as the body.
1107 |
1108 | ``dict``
1109 | A dictionary that will be jsonify'd before being returned.
1110 |
1111 | ``list``
1112 | A list that will be jsonify'd before being returned.
1113 |
1114 | ``generator`` or ``iterator``
1115 | A generator that returns ``str`` or ``bytes`` to be
1116 | streamed as the response.
1117 |
1118 | ``tuple``
1119 | Either ``(body, status, headers)``, ``(body, status)``, or
1120 | ``(body, headers)``, where ``body`` is any of the other types
1121 | allowed here, ``status`` is a string or an integer, and
1122 | ``headers`` is a dictionary or a list of ``(key, value)``
1123 | tuples. If ``body`` is a :attr:`response_class` instance,
1124 | ``status`` overwrites the exiting value and ``headers`` are
1125 | extended.
1126 |
1127 | :attr:`response_class`
1128 | The object is returned unchanged.
1129 |
1130 | other :class:`~werkzeug.wrappers.Response` class
1131 | The object is coerced to :attr:`response_class`.
1132 |
1133 | :func:`callable`
1134 | The function is called as a WSGI application. The result is
1135 | used to create a response object.
1136 |
1137 | .. versionchanged:: 2.2
1138 | A generator will be converted to a streaming response.
1139 | A list will be converted to a JSON response.
1140 |
1141 | .. versionchanged:: 1.1
1142 | A dict will be converted to a JSON response.
1143 |
1144 | .. versionchanged:: 0.9
1145 | Previously a tuple was interpreted as the arguments for the
1146 | response object.
1147 | """
1148 |
1149 | status = headers = None
1150 |
1151 | # unpack tuple returns
1152 | if isinstance(rv, tuple):
1153 | len_rv = len(rv)
1154 |
1155 | # a 3-tuple is unpacked directly
1156 | if len_rv == 3:
1157 | rv, status, headers = rv # type: ignore[misc]
1158 | # decide if a 2-tuple has status or headers
1159 | elif len_rv == 2:
1160 | if isinstance(rv[1], (Headers, dict, tuple, list)):
1161 | rv, headers = rv
1162 | else:
1163 | rv, status = rv # type: ignore[assignment,misc]
1164 | # other sized tuples are not allowed
1165 | else:
1166 | raise TypeError(
1167 | "The view function did not return a valid response tuple."
1168 | " The tuple must have the form (body, status, headers),"
1169 | " (body, status), or (body, headers)."
1170 | )
1171 |
1172 | # the body must not be None
1173 | if rv is None:
1174 | raise TypeError(
1175 | f"The view function for {request.endpoint!r} did not"
1176 | " return a valid response. The function either returned"
1177 | " None or ended without a return statement."
1178 | )
1179 |
1180 | # make sure the body is an instance of the response class
1181 | if not isinstance(rv, self.response_class):
1182 | if isinstance(rv, (str, bytes, bytearray)) or isinstance(rv, cabc.Iterator):
1183 | # let the response class set the status and headers instead of
1184 | # waiting to do it manually, so that the class can handle any
1185 | # special logic
1186 | rv = self.response_class(
1187 | rv,
1188 | status=status,
1189 | headers=headers, # type: ignore[arg-type]
1190 | )
1191 | status = headers = None
1192 | elif isinstance(rv, (dict, list)):
1193 | rv = self.json.response(rv)
1194 | elif isinstance(rv, BaseResponse) or callable(rv):
1195 | # evaluate a WSGI callable, or coerce a different response
1196 | # class to the correct type
1197 | try:
1198 | rv = self.response_class.force_type(
1199 | rv, # type: ignore[arg-type]
1200 | request.environ,
1201 | )
1202 | except TypeError as e:
1203 | raise TypeError(
1204 | f"{e}\nThe view function did not return a valid"
1205 | " response. The return type must be a string,"
1206 | " dict, list, tuple with headers or status,"
1207 | " Response instance, or WSGI callable, but it"
1208 | f" was a {type(rv).__name__}."
1209 | ).with_traceback(sys.exc_info()[2]) from None
1210 | else:
1211 | raise TypeError(
1212 | "The view function did not return a valid"
1213 | " response. The return type must be a string,"
1214 | " dict, list, tuple with headers or status,"
1215 | " Response instance, or WSGI callable, but it was a"
1216 | f" {type(rv).__name__}."
1217 | )
1218 |
1219 | rv = t.cast(Response, rv)
1220 | # prefer the status if it was provided
1221 | if status is not None:
1222 | if isinstance(status, (str, bytes, bytearray)):
1223 | rv.status = status
1224 | else:
1225 | rv.status_code = status
1226 |
1227 | # extend existing headers with provided headers
1228 | if headers:
1229 | rv.headers.update(headers) # type: ignore[arg-type]
1230 |
1231 | return rv
1232 |
1233 | def preprocess_request(self) -> ft.ResponseReturnValue | None:
1234 | """Called before the request is dispatched. Calls
1235 | :attr:`url_value_preprocessors` registered with the app and the
1236 | current blueprint (if any). Then calls :attr:`before_request_funcs`
1237 | registered with the app and the blueprint.
1238 |
1239 | If any :meth:`before_request` handler returns a non-None value, the
1240 | value is handled as if it was the return value from the view, and
1241 | further request handling is stopped.
1242 | """
1243 | names = (None, *reversed(request.blueprints))
1244 |
1245 | for name in names:
1246 | if name in self.url_value_preprocessors:
1247 | for url_func in self.url_value_preprocessors[name]:
1248 | url_func(request.endpoint, request.view_args)
1249 |
1250 | for name in names:
1251 | if name in self.before_request_funcs:
1252 | for before_func in self.before_request_funcs[name]:
1253 | rv = self.ensure_sync(before_func)()
1254 |
1255 | if rv is not None:
1256 | return rv # type: ignore[no-any-return]
1257 |
1258 | return None
1259 |
1260 | def process_response(self, response: Response) -> Response:
1261 | """Can be overridden in order to modify the response object
1262 | before it's sent to the WSGI server. By default this will
1263 | call all the :meth:`after_request` decorated functions.
1264 |
1265 | .. versionchanged:: 0.5
1266 | As of Flask 0.5 the functions registered for after request
1267 | execution are called in reverse order of registration.
1268 |
1269 | :param response: a :attr:`response_class` object.
1270 | :return: a new response object or the same, has to be an
1271 | instance of :attr:`response_class`.
1272 | """
1273 | ctx = request_ctx._get_current_object() # type: ignore[attr-defined]
1274 |
1275 | for func in ctx._after_request_functions:
1276 | response = self.ensure_sync(func)(response)
1277 |
1278 | for name in chain(request.blueprints, (None,)):
1279 | if name in self.after_request_funcs:
1280 | for func in reversed(self.after_request_funcs[name]):
1281 | response = self.ensure_sync(func)(response)
1282 |
1283 | if not self.session_interface.is_null_session(ctx.session):
1284 | self.session_interface.save_session(self, ctx.session, response)
1285 |
1286 | return response
1287 |
1288 | def do_teardown_request(
1289 | self,
1290 | exc: BaseException | None = _sentinel, # type: ignore[assignment]
1291 | ) -> None:
1292 | """Called after the request is dispatched and the response is
1293 | returned, right before the request context is popped.
1294 |
1295 | This calls all functions decorated with
1296 | :meth:`teardown_request`, and :meth:`Blueprint.teardown_request`
1297 | if a blueprint handled the request. Finally, the
1298 | :data:`request_tearing_down` signal is sent.
1299 |
1300 | This is called by
1301 | :meth:`RequestContext.pop() <flask.ctx.RequestContext.pop>`,
1302 | which may be delayed during testing to maintain access to
1303 | resources.
1304 |
1305 | :param exc: An unhandled exception raised while dispatching the
1306 | request. Detected from the current exception information if
1307 | not passed. Passed to each teardown function.
1308 |
1309 | .. versionchanged:: 0.9
1310 | Added the ``exc`` argument.
1311 | """
1312 | if exc is _sentinel:
1313 | exc = sys.exc_info()[1]
1314 |
1315 | for name in chain(request.blueprints, (None,)):
1316 | if name in self.teardown_request_funcs:
1317 | for func in reversed(self.teardown_request_funcs[name]):
1318 | self.ensure_sync(func)(exc)
1319 |
1320 | request_tearing_down.send(self, _async_wrapper=self.ensure_sync, exc=exc)
1321 |
1322 | def do_teardown_appcontext(
1323 | self,
1324 | exc: BaseException | None = _sentinel, # type: ignore[assignment]
1325 | ) -> None:
1326 | """Called right before the application context is popped.
1327 |
1328 | When handling a request, the application context is popped
1329 | after the request context. See :meth:`do_teardown_request`.
1330 |
1331 | This calls all functions decorated with
1332 | :meth:`teardown_appcontext`. Then the
1333 | :data:`appcontext_tearing_down` signal is sent.
1334 |
1335 | This is called by
1336 | :meth:`AppContext.pop() <flask.ctx.AppContext.pop>`.
1337 |
1338 | .. versionadded:: 0.9
1339 | """
1340 | if exc is _sentinel:
1341 | exc = sys.exc_info()[1]
1342 |
1343 | for func in reversed(self.teardown_appcontext_funcs):
1344 | self.ensure_sync(func)(exc)
1345 |
1346 | appcontext_tearing_down.send(self, _async_wrapper=self.ensure_sync, exc=exc)
1347 |
1348 | def app_context(self) -> AppContext:
1349 | """Create an :class:`~flask.ctx.AppContext`. Use as a ``with``
1350 | block to push the context, which will make :data:`current_app`
1351 | point at this application.
1352 |
1353 | An application context is automatically pushed by
1354 | :meth:`RequestContext.push() <flask.ctx.RequestContext.push>`
1355 | when handling a request, and when running a CLI command. Use
1356 | this to manually create a context outside of these situations.
1357 |
1358 | ::
1359 |
1360 | with app.app_context():
1361 | init_db()
1362 |
1363 | See :doc:`/appcontext`.
1364 |
1365 | .. versionadded:: 0.9
1366 | """
1367 | return AppContext(self)
1368 |
1369 | def request_context(self, environ: WSGIEnvironment) -> RequestContext:
1370 | """Create a :class:`~flask.ctx.RequestContext` representing a
1371 | WSGI environment. Use a ``with`` block to push the context,
1372 | which will make :data:`request` point at this request.
1373 |
1374 | See :doc:`/reqcontext`.
1375 |
1376 | Typically you should not call this from your own code. A request
1377 | context is automatically pushed by the :meth:`wsgi_app` when
1378 | handling a request. Use :meth:`test_request_context` to create
1379 | an environment and context instead of this method.
1380 |
1381 | :param environ: a WSGI environment
1382 | """
1383 | return RequestContext(self, environ)
1384 |
1385 | def test_request_context(self, *args: t.Any, **kwargs: t.Any) -> RequestContext:
1386 | """Create a :class:`~flask.ctx.RequestContext` for a WSGI
1387 | environment created from the given values. This is mostly useful
1388 | during testing, where you may want to run a function that uses
1389 | request data without dispatching a full request.
1390 |
1391 | See :doc:`/reqcontext`.
1392 |
1393 | Use a ``with`` block to push the context, which will make
1394 | :data:`request` point at the request for the created
1395 | environment. ::
1396 |
1397 | with app.test_request_context(...):
1398 | generate_report()
1399 |
1400 | When using the shell, it may be easier to push and pop the
1401 | context manually to avoid indentation. ::
1402 |
1403 | ctx = app.test_request_context(...)
1404 | ctx.push()
1405 | ...
1406 | ctx.pop()
1407 |
1408 | Takes the same arguments as Werkzeug's
1409 | :class:`~werkzeug.test.EnvironBuilder`, with some defaults from
1410 | the application. See the linked Werkzeug docs for most of the
1411 | available arguments. Flask-specific behavior is listed here.
1412 |
1413 | :param path: URL path being requested.
1414 | :param base_url: Base URL where the app is being served, which
1415 | ``path`` is relative to. If not given, built from
1416 | :data:`PREFERRED_URL_SCHEME`, ``subdomain``,
1417 | :data:`SERVER_NAME`, and :data:`APPLICATION_ROOT`.
1418 | :param subdomain: Subdomain name to append to
1419 | :data:`SERVER_NAME`.
1420 | :param url_scheme: Scheme to use instead of
1421 | :data:`PREFERRED_URL_SCHEME`.
1422 | :param data: The request body, either as a string or a dict of
1423 | form keys and values.
1424 | :param json: If given, this is serialized as JSON and passed as
1425 | ``data``. Also defaults ``content_type`` to
1426 | ``application/json``.
1427 | :param args: other positional arguments passed to
1428 | :class:`~werkzeug.test.EnvironBuilder`.
1429 | :param kwargs: other keyword arguments passed to
1430 | :class:`~werkzeug.test.EnvironBuilder`.
1431 | """
1432 | from .testing import EnvironBuilder
1433 |
1434 | builder = EnvironBuilder(self, *args, **kwargs)
1435 |
1436 | try:
1437 | return self.request_context(builder.get_environ())
1438 | finally:
1439 | builder.close()
1440 |
1441 | def wsgi_app(
1442 | self, environ: WSGIEnvironment, start_response: StartResponse
1443 | ) -> cabc.Iterable[bytes]:
1444 | """The actual WSGI application. This is not implemented in
1445 | :meth:`__call__` so that middlewares can be applied without
1446 | losing a reference to the app object. Instead of doing this::
1447 |
1448 | app = MyMiddleware(app)
1449 |
1450 | It's a better idea to do this instead::
1451 |
1452 | app.wsgi_app = MyMiddleware(app.wsgi_app)
1453 |
1454 | Then you still have the original application object around and
1455 | can continue to call methods on it.
1456 |
1457 | .. versionchanged:: 0.7
1458 | Teardown events for the request and app contexts are called
1459 | even if an unhandled error occurs. Other events may not be
1460 | called depending on when an error occurs during dispatch.
1461 | See :ref:`callbacks-and-errors`.
1462 |
1463 | :param environ: A WSGI environment.
1464 | :param start_response: A callable accepting a status code,
1465 | a list of headers, and an optional exception context to
1466 | start the response.
1467 | """
1468 | ctx = self.request_context(environ)
1469 | error: BaseException | None = None
1470 | try:
1471 | try:
1472 | ctx.push()
1473 | response = self.full_dispatch_request()
1474 | except Exception as e:
1475 | error = e
1476 | response = self.handle_exception(e)
1477 | except: # noqa: B001
1478 | error = sys.exc_info()[1]
1479 | raise
1480 | return response(environ, start_response)
1481 | finally:
1482 | if "werkzeug.debug.preserve_context" in environ:
1483 | environ["werkzeug.debug.preserve_context"](_cv_app.get())
1484 | environ["werkzeug.debug.preserve_context"](_cv_request.get())
1485 |
1486 | if error is not None and self.should_ignore_error(error):
1487 | error = None
1488 |
1489 | ctx.pop(error)
1490 |
1491 | def __call__(
1492 | self, environ: WSGIEnvironment, start_response: StartResponse
1493 | ) -> cabc.Iterable[bytes]:
1494 | """The WSGI server calls the Flask application object as the
1495 | WSGI application. This calls :meth:`wsgi_app`, which can be
1496 | wrapped to apply middleware.
1497 | """
1498 | return self.wsgi_app(environ, start_response)
1499 |
```