This is page 83 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/sansio/blueprints.py:
--------------------------------------------------------------------------------
```python
1 | from __future__ import annotations
2 |
3 | import os
4 | import typing as t
5 | from collections import defaultdict
6 | from functools import update_wrapper
7 |
8 | from .. import typing as ft
9 | from .scaffold import _endpoint_from_view_func
10 | from .scaffold import _sentinel
11 | from .scaffold import Scaffold
12 | from .scaffold import setupmethod
13 |
14 | if t.TYPE_CHECKING: # pragma: no cover
15 | from .app import App
16 |
17 | DeferredSetupFunction = t.Callable[["BlueprintSetupState"], None]
18 | T_after_request = t.TypeVar("T_after_request", bound=ft.AfterRequestCallable[t.Any])
19 | T_before_request = t.TypeVar("T_before_request", bound=ft.BeforeRequestCallable)
20 | T_error_handler = t.TypeVar("T_error_handler", bound=ft.ErrorHandlerCallable)
21 | T_teardown = t.TypeVar("T_teardown", bound=ft.TeardownCallable)
22 | T_template_context_processor = t.TypeVar(
23 | "T_template_context_processor", bound=ft.TemplateContextProcessorCallable
24 | )
25 | T_template_filter = t.TypeVar("T_template_filter", bound=ft.TemplateFilterCallable)
26 | T_template_global = t.TypeVar("T_template_global", bound=ft.TemplateGlobalCallable)
27 | T_template_test = t.TypeVar("T_template_test", bound=ft.TemplateTestCallable)
28 | T_url_defaults = t.TypeVar("T_url_defaults", bound=ft.URLDefaultCallable)
29 | T_url_value_preprocessor = t.TypeVar(
30 | "T_url_value_preprocessor", bound=ft.URLValuePreprocessorCallable
31 | )
32 |
33 |
34 | class BlueprintSetupState:
35 | """Temporary holder object for registering a blueprint with the
36 | application. An instance of this class is created by the
37 | :meth:`~flask.Blueprint.make_setup_state` method and later passed
38 | to all register callback functions.
39 | """
40 |
41 | def __init__(
42 | self,
43 | blueprint: Blueprint,
44 | app: App,
45 | options: t.Any,
46 | first_registration: bool,
47 | ) -> None:
48 | #: a reference to the current application
49 | self.app = app
50 |
51 | #: a reference to the blueprint that created this setup state.
52 | self.blueprint = blueprint
53 |
54 | #: a dictionary with all options that were passed to the
55 | #: :meth:`~flask.Flask.register_blueprint` method.
56 | self.options = options
57 |
58 | #: as blueprints can be registered multiple times with the
59 | #: application and not everything wants to be registered
60 | #: multiple times on it, this attribute can be used to figure
61 | #: out if the blueprint was registered in the past already.
62 | self.first_registration = first_registration
63 |
64 | subdomain = self.options.get("subdomain")
65 | if subdomain is None:
66 | subdomain = self.blueprint.subdomain
67 |
68 | #: The subdomain that the blueprint should be active for, ``None``
69 | #: otherwise.
70 | self.subdomain = subdomain
71 |
72 | url_prefix = self.options.get("url_prefix")
73 | if url_prefix is None:
74 | url_prefix = self.blueprint.url_prefix
75 | #: The prefix that should be used for all URLs defined on the
76 | #: blueprint.
77 | self.url_prefix = url_prefix
78 |
79 | self.name = self.options.get("name", blueprint.name)
80 | self.name_prefix = self.options.get("name_prefix", "")
81 |
82 | #: A dictionary with URL defaults that is added to each and every
83 | #: URL that was defined with the blueprint.
84 | self.url_defaults = dict(self.blueprint.url_values_defaults)
85 | self.url_defaults.update(self.options.get("url_defaults", ()))
86 |
87 | def add_url_rule(
88 | self,
89 | rule: str,
90 | endpoint: str | None = None,
91 | view_func: ft.RouteCallable | None = None,
92 | **options: t.Any,
93 | ) -> None:
94 | """A helper method to register a rule (and optionally a view function)
95 | to the application. The endpoint is automatically prefixed with the
96 | blueprint's name.
97 | """
98 | if self.url_prefix is not None:
99 | if rule:
100 | rule = "/".join((self.url_prefix.rstrip("/"), rule.lstrip("/")))
101 | else:
102 | rule = self.url_prefix
103 | options.setdefault("subdomain", self.subdomain)
104 | if endpoint is None:
105 | endpoint = _endpoint_from_view_func(view_func) # type: ignore
106 | defaults = self.url_defaults
107 | if "defaults" in options:
108 | defaults = dict(defaults, **options.pop("defaults"))
109 |
110 | self.app.add_url_rule(
111 | rule,
112 | f"{self.name_prefix}.{self.name}.{endpoint}".lstrip("."),
113 | view_func,
114 | defaults=defaults,
115 | **options,
116 | )
117 |
118 |
119 | class Blueprint(Scaffold):
120 | """Represents a blueprint, a collection of routes and other
121 | app-related functions that can be registered on a real application
122 | later.
123 |
124 | A blueprint is an object that allows defining application functions
125 | without requiring an application object ahead of time. It uses the
126 | same decorators as :class:`~flask.Flask`, but defers the need for an
127 | application by recording them for later registration.
128 |
129 | Decorating a function with a blueprint creates a deferred function
130 | that is called with :class:`~flask.blueprints.BlueprintSetupState`
131 | when the blueprint is registered on an application.
132 |
133 | See :doc:`/blueprints` for more information.
134 |
135 | :param name: The name of the blueprint. Will be prepended to each
136 | endpoint name.
137 | :param import_name: The name of the blueprint package, usually
138 | ``__name__``. This helps locate the ``root_path`` for the
139 | blueprint.
140 | :param static_folder: A folder with static files that should be
141 | served by the blueprint's static route. The path is relative to
142 | the blueprint's root path. Blueprint static files are disabled
143 | by default.
144 | :param static_url_path: The url to serve static files from.
145 | Defaults to ``static_folder``. If the blueprint does not have
146 | a ``url_prefix``, the app's static route will take precedence,
147 | and the blueprint's static files won't be accessible.
148 | :param template_folder: A folder with templates that should be added
149 | to the app's template search path. The path is relative to the
150 | blueprint's root path. Blueprint templates are disabled by
151 | default. Blueprint templates have a lower precedence than those
152 | in the app's templates folder.
153 | :param url_prefix: A path to prepend to all of the blueprint's URLs,
154 | to make them distinct from the rest of the app's routes.
155 | :param subdomain: A subdomain that blueprint routes will match on by
156 | default.
157 | :param url_defaults: A dict of default values that blueprint routes
158 | will receive by default.
159 | :param root_path: By default, the blueprint will automatically set
160 | this based on ``import_name``. In certain situations this
161 | automatic detection can fail, so the path can be specified
162 | manually instead.
163 |
164 | .. versionchanged:: 1.1.0
165 | Blueprints have a ``cli`` group to register nested CLI commands.
166 | The ``cli_group`` parameter controls the name of the group under
167 | the ``flask`` command.
168 |
169 | .. versionadded:: 0.7
170 | """
171 |
172 | _got_registered_once = False
173 |
174 | def __init__(
175 | self,
176 | name: str,
177 | import_name: str,
178 | static_folder: str | os.PathLike[str] | None = None,
179 | static_url_path: str | None = None,
180 | template_folder: str | os.PathLike[str] | None = None,
181 | url_prefix: str | None = None,
182 | subdomain: str | None = None,
183 | url_defaults: dict[str, t.Any] | None = None,
184 | root_path: str | None = None,
185 | cli_group: str | None = _sentinel, # type: ignore[assignment]
186 | ):
187 | super().__init__(
188 | import_name=import_name,
189 | static_folder=static_folder,
190 | static_url_path=static_url_path,
191 | template_folder=template_folder,
192 | root_path=root_path,
193 | )
194 |
195 | if not name:
196 | raise ValueError("'name' may not be empty.")
197 |
198 | if "." in name:
199 | raise ValueError("'name' may not contain a dot '.' character.")
200 |
201 | self.name = name
202 | self.url_prefix = url_prefix
203 | self.subdomain = subdomain
204 | self.deferred_functions: list[DeferredSetupFunction] = []
205 |
206 | if url_defaults is None:
207 | url_defaults = {}
208 |
209 | self.url_values_defaults = url_defaults
210 | self.cli_group = cli_group
211 | self._blueprints: list[tuple[Blueprint, dict[str, t.Any]]] = []
212 |
213 | def _check_setup_finished(self, f_name: str) -> None:
214 | if self._got_registered_once:
215 | raise AssertionError(
216 | f"The setup method '{f_name}' can no longer be called on the blueprint"
217 | f" '{self.name}'. It has already been registered at least once, any"
218 | " changes will not be applied consistently.\n"
219 | "Make sure all imports, decorators, functions, etc. needed to set up"
220 | " the blueprint are done before registering it."
221 | )
222 |
223 | @setupmethod
224 | def record(self, func: DeferredSetupFunction) -> None:
225 | """Registers a function that is called when the blueprint is
226 | registered on the application. This function is called with the
227 | state as argument as returned by the :meth:`make_setup_state`
228 | method.
229 | """
230 | self.deferred_functions.append(func)
231 |
232 | @setupmethod
233 | def record_once(self, func: DeferredSetupFunction) -> None:
234 | """Works like :meth:`record` but wraps the function in another
235 | function that will ensure the function is only called once. If the
236 | blueprint is registered a second time on the application, the
237 | function passed is not called.
238 | """
239 |
240 | def wrapper(state: BlueprintSetupState) -> None:
241 | if state.first_registration:
242 | func(state)
243 |
244 | self.record(update_wrapper(wrapper, func))
245 |
246 | def make_setup_state(
247 | self, app: App, options: dict[str, t.Any], first_registration: bool = False
248 | ) -> BlueprintSetupState:
249 | """Creates an instance of :meth:`~flask.blueprints.BlueprintSetupState`
250 | object that is later passed to the register callback functions.
251 | Subclasses can override this to return a subclass of the setup state.
252 | """
253 | return BlueprintSetupState(self, app, options, first_registration)
254 |
255 | @setupmethod
256 | def register_blueprint(self, blueprint: Blueprint, **options: t.Any) -> None:
257 | """Register a :class:`~flask.Blueprint` on this blueprint. Keyword
258 | arguments passed to this method will override the defaults set
259 | on the blueprint.
260 |
261 | .. versionchanged:: 2.0.1
262 | The ``name`` option can be used to change the (pre-dotted)
263 | name the blueprint is registered with. This allows the same
264 | blueprint to be registered multiple times with unique names
265 | for ``url_for``.
266 |
267 | .. versionadded:: 2.0
268 | """
269 | if blueprint is self:
270 | raise ValueError("Cannot register a blueprint on itself")
271 | self._blueprints.append((blueprint, options))
272 |
273 | def register(self, app: App, options: dict[str, t.Any]) -> None:
274 | """Called by :meth:`Flask.register_blueprint` to register all
275 | views and callbacks registered on the blueprint with the
276 | application. Creates a :class:`.BlueprintSetupState` and calls
277 | each :meth:`record` callback with it.
278 |
279 | :param app: The application this blueprint is being registered
280 | with.
281 | :param options: Keyword arguments forwarded from
282 | :meth:`~Flask.register_blueprint`.
283 |
284 | .. versionchanged:: 2.3
285 | Nested blueprints now correctly apply subdomains.
286 |
287 | .. versionchanged:: 2.1
288 | Registering the same blueprint with the same name multiple
289 | times is an error.
290 |
291 | .. versionchanged:: 2.0.1
292 | Nested blueprints are registered with their dotted name.
293 | This allows different blueprints with the same name to be
294 | nested at different locations.
295 |
296 | .. versionchanged:: 2.0.1
297 | The ``name`` option can be used to change the (pre-dotted)
298 | name the blueprint is registered with. This allows the same
299 | blueprint to be registered multiple times with unique names
300 | for ``url_for``.
301 | """
302 | name_prefix = options.get("name_prefix", "")
303 | self_name = options.get("name", self.name)
304 | name = f"{name_prefix}.{self_name}".lstrip(".")
305 |
306 | if name in app.blueprints:
307 | bp_desc = "this" if app.blueprints[name] is self else "a different"
308 | existing_at = f" '{name}'" if self_name != name else ""
309 |
310 | raise ValueError(
311 | f"The name '{self_name}' is already registered for"
312 | f" {bp_desc} blueprint{existing_at}. Use 'name=' to"
313 | f" provide a unique name."
314 | )
315 |
316 | first_bp_registration = not any(bp is self for bp in app.blueprints.values())
317 | first_name_registration = name not in app.blueprints
318 |
319 | app.blueprints[name] = self
320 | self._got_registered_once = True
321 | state = self.make_setup_state(app, options, first_bp_registration)
322 |
323 | if self.has_static_folder:
324 | state.add_url_rule(
325 | f"{self.static_url_path}/<path:filename>",
326 | view_func=self.send_static_file, # type: ignore[attr-defined]
327 | endpoint="static",
328 | )
329 |
330 | # Merge blueprint data into parent.
331 | if first_bp_registration or first_name_registration:
332 | self._merge_blueprint_funcs(app, name)
333 |
334 | for deferred in self.deferred_functions:
335 | deferred(state)
336 |
337 | cli_resolved_group = options.get("cli_group", self.cli_group)
338 |
339 | if self.cli.commands:
340 | if cli_resolved_group is None:
341 | app.cli.commands.update(self.cli.commands)
342 | elif cli_resolved_group is _sentinel:
343 | self.cli.name = name
344 | app.cli.add_command(self.cli)
345 | else:
346 | self.cli.name = cli_resolved_group
347 | app.cli.add_command(self.cli)
348 |
349 | for blueprint, bp_options in self._blueprints:
350 | bp_options = bp_options.copy()
351 | bp_url_prefix = bp_options.get("url_prefix")
352 | bp_subdomain = bp_options.get("subdomain")
353 |
354 | if bp_subdomain is None:
355 | bp_subdomain = blueprint.subdomain
356 |
357 | if state.subdomain is not None and bp_subdomain is not None:
358 | bp_options["subdomain"] = bp_subdomain + "." + state.subdomain
359 | elif bp_subdomain is not None:
360 | bp_options["subdomain"] = bp_subdomain
361 | elif state.subdomain is not None:
362 | bp_options["subdomain"] = state.subdomain
363 |
364 | if bp_url_prefix is None:
365 | bp_url_prefix = blueprint.url_prefix
366 |
367 | if state.url_prefix is not None and bp_url_prefix is not None:
368 | bp_options["url_prefix"] = (
369 | state.url_prefix.rstrip("/") + "/" + bp_url_prefix.lstrip("/")
370 | )
371 | elif bp_url_prefix is not None:
372 | bp_options["url_prefix"] = bp_url_prefix
373 | elif state.url_prefix is not None:
374 | bp_options["url_prefix"] = state.url_prefix
375 |
376 | bp_options["name_prefix"] = name
377 | blueprint.register(app, bp_options)
378 |
379 | def _merge_blueprint_funcs(self, app: App, name: str) -> None:
380 | def extend(
381 | bp_dict: dict[ft.AppOrBlueprintKey, list[t.Any]],
382 | parent_dict: dict[ft.AppOrBlueprintKey, list[t.Any]],
383 | ) -> None:
384 | for key, values in bp_dict.items():
385 | key = name if key is None else f"{name}.{key}"
386 | parent_dict[key].extend(values)
387 |
388 | for key, value in self.error_handler_spec.items():
389 | key = name if key is None else f"{name}.{key}"
390 | value = defaultdict(
391 | dict,
392 | {
393 | code: {exc_class: func for exc_class, func in code_values.items()}
394 | for code, code_values in value.items()
395 | },
396 | )
397 | app.error_handler_spec[key] = value
398 |
399 | for endpoint, func in self.view_functions.items():
400 | app.view_functions[endpoint] = func
401 |
402 | extend(self.before_request_funcs, app.before_request_funcs)
403 | extend(self.after_request_funcs, app.after_request_funcs)
404 | extend(
405 | self.teardown_request_funcs,
406 | app.teardown_request_funcs,
407 | )
408 | extend(self.url_default_functions, app.url_default_functions)
409 | extend(self.url_value_preprocessors, app.url_value_preprocessors)
410 | extend(self.template_context_processors, app.template_context_processors)
411 |
412 | @setupmethod
413 | def add_url_rule(
414 | self,
415 | rule: str,
416 | endpoint: str | None = None,
417 | view_func: ft.RouteCallable | None = None,
418 | provide_automatic_options: bool | None = None,
419 | **options: t.Any,
420 | ) -> None:
421 | """Register a URL rule with the blueprint. See :meth:`.Flask.add_url_rule` for
422 | full documentation.
423 |
424 | The URL rule is prefixed with the blueprint's URL prefix. The endpoint name,
425 | used with :func:`url_for`, is prefixed with the blueprint's name.
426 | """
427 | if endpoint and "." in endpoint:
428 | raise ValueError("'endpoint' may not contain a dot '.' character.")
429 |
430 | if view_func and hasattr(view_func, "__name__") and "." in view_func.__name__:
431 | raise ValueError("'view_func' name may not contain a dot '.' character.")
432 |
433 | self.record(
434 | lambda s: s.add_url_rule(
435 | rule,
436 | endpoint,
437 | view_func,
438 | provide_automatic_options=provide_automatic_options,
439 | **options,
440 | )
441 | )
442 |
443 | @setupmethod
444 | def app_template_filter(
445 | self, name: str | None = None
446 | ) -> t.Callable[[T_template_filter], T_template_filter]:
447 | """Register a template filter, available in any template rendered by the
448 | application. Equivalent to :meth:`.Flask.template_filter`.
449 |
450 | :param name: the optional name of the filter, otherwise the
451 | function name will be used.
452 | """
453 |
454 | def decorator(f: T_template_filter) -> T_template_filter:
455 | self.add_app_template_filter(f, name=name)
456 | return f
457 |
458 | return decorator
459 |
460 | @setupmethod
461 | def add_app_template_filter(
462 | self, f: ft.TemplateFilterCallable, name: str | None = None
463 | ) -> None:
464 | """Register a template filter, available in any template rendered by the
465 | application. Works like the :meth:`app_template_filter` decorator. Equivalent to
466 | :meth:`.Flask.add_template_filter`.
467 |
468 | :param name: the optional name of the filter, otherwise the
469 | function name will be used.
470 | """
471 |
472 | def register_template(state: BlueprintSetupState) -> None:
473 | state.app.jinja_env.filters[name or f.__name__] = f
474 |
475 | self.record_once(register_template)
476 |
477 | @setupmethod
478 | def app_template_test(
479 | self, name: str | None = None
480 | ) -> t.Callable[[T_template_test], T_template_test]:
481 | """Register a template test, available in any template rendered by the
482 | application. Equivalent to :meth:`.Flask.template_test`.
483 |
484 | .. versionadded:: 0.10
485 |
486 | :param name: the optional name of the test, otherwise the
487 | function name will be used.
488 | """
489 |
490 | def decorator(f: T_template_test) -> T_template_test:
491 | self.add_app_template_test(f, name=name)
492 | return f
493 |
494 | return decorator
495 |
496 | @setupmethod
497 | def add_app_template_test(
498 | self, f: ft.TemplateTestCallable, name: str | None = None
499 | ) -> None:
500 | """Register a template test, available in any template rendered by the
501 | application. Works like the :meth:`app_template_test` decorator. Equivalent to
502 | :meth:`.Flask.add_template_test`.
503 |
504 | .. versionadded:: 0.10
505 |
506 | :param name: the optional name of the test, otherwise the
507 | function name will be used.
508 | """
509 |
510 | def register_template(state: BlueprintSetupState) -> None:
511 | state.app.jinja_env.tests[name or f.__name__] = f
512 |
513 | self.record_once(register_template)
514 |
515 | @setupmethod
516 | def app_template_global(
517 | self, name: str | None = None
518 | ) -> t.Callable[[T_template_global], T_template_global]:
519 | """Register a template global, available in any template rendered by the
520 | application. Equivalent to :meth:`.Flask.template_global`.
521 |
522 | .. versionadded:: 0.10
523 |
524 | :param name: the optional name of the global, otherwise the
525 | function name will be used.
526 | """
527 |
528 | def decorator(f: T_template_global) -> T_template_global:
529 | self.add_app_template_global(f, name=name)
530 | return f
531 |
532 | return decorator
533 |
534 | @setupmethod
535 | def add_app_template_global(
536 | self, f: ft.TemplateGlobalCallable, name: str | None = None
537 | ) -> None:
538 | """Register a template global, available in any template rendered by the
539 | application. Works like the :meth:`app_template_global` decorator. Equivalent to
540 | :meth:`.Flask.add_template_global`.
541 |
542 | .. versionadded:: 0.10
543 |
544 | :param name: the optional name of the global, otherwise the
545 | function name will be used.
546 | """
547 |
548 | def register_template(state: BlueprintSetupState) -> None:
549 | state.app.jinja_env.globals[name or f.__name__] = f
550 |
551 | self.record_once(register_template)
552 |
553 | @setupmethod
554 | def before_app_request(self, f: T_before_request) -> T_before_request:
555 | """Like :meth:`before_request`, but before every request, not only those handled
556 | by the blueprint. Equivalent to :meth:`.Flask.before_request`.
557 | """
558 | self.record_once(
559 | lambda s: s.app.before_request_funcs.setdefault(None, []).append(f)
560 | )
561 | return f
562 |
563 | @setupmethod
564 | def after_app_request(self, f: T_after_request) -> T_after_request:
565 | """Like :meth:`after_request`, but after every request, not only those handled
566 | by the blueprint. Equivalent to :meth:`.Flask.after_request`.
567 | """
568 | self.record_once(
569 | lambda s: s.app.after_request_funcs.setdefault(None, []).append(f)
570 | )
571 | return f
572 |
573 | @setupmethod
574 | def teardown_app_request(self, f: T_teardown) -> T_teardown:
575 | """Like :meth:`teardown_request`, but after every request, not only those
576 | handled by the blueprint. Equivalent to :meth:`.Flask.teardown_request`.
577 | """
578 | self.record_once(
579 | lambda s: s.app.teardown_request_funcs.setdefault(None, []).append(f)
580 | )
581 | return f
582 |
583 | @setupmethod
584 | def app_context_processor(
585 | self, f: T_template_context_processor
586 | ) -> T_template_context_processor:
587 | """Like :meth:`context_processor`, but for templates rendered by every view, not
588 | only by the blueprint. Equivalent to :meth:`.Flask.context_processor`.
589 | """
590 | self.record_once(
591 | lambda s: s.app.template_context_processors.setdefault(None, []).append(f)
592 | )
593 | return f
594 |
595 | @setupmethod
596 | def app_errorhandler(
597 | self, code: type[Exception] | int
598 | ) -> t.Callable[[T_error_handler], T_error_handler]:
599 | """Like :meth:`errorhandler`, but for every request, not only those handled by
600 | the blueprint. Equivalent to :meth:`.Flask.errorhandler`.
601 | """
602 |
603 | def decorator(f: T_error_handler) -> T_error_handler:
604 | def from_blueprint(state: BlueprintSetupState) -> None:
605 | state.app.errorhandler(code)(f)
606 |
607 | self.record_once(from_blueprint)
608 | return f
609 |
610 | return decorator
611 |
612 | @setupmethod
613 | def app_url_value_preprocessor(
614 | self, f: T_url_value_preprocessor
615 | ) -> T_url_value_preprocessor:
616 | """Like :meth:`url_value_preprocessor`, but for every request, not only those
617 | handled by the blueprint. Equivalent to :meth:`.Flask.url_value_preprocessor`.
618 | """
619 | self.record_once(
620 | lambda s: s.app.url_value_preprocessors.setdefault(None, []).append(f)
621 | )
622 | return f
623 |
624 | @setupmethod
625 | def app_url_defaults(self, f: T_url_defaults) -> T_url_defaults:
626 | """Like :meth:`url_defaults`, but for every request, not only those handled by
627 | the blueprint. Equivalent to :meth:`.Flask.url_defaults`.
628 | """
629 | self.record_once(
630 | lambda s: s.app.url_default_functions.setdefault(None, []).append(f)
631 | )
632 | return f
633 |
```
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/werkzeug/wrappers/request.py:
--------------------------------------------------------------------------------
```python
1 | from __future__ import annotations
2 |
3 | import collections.abc as cabc
4 | import functools
5 | import json
6 | import typing as t
7 | from io import BytesIO
8 |
9 | from .._internal import _wsgi_decoding_dance
10 | from ..datastructures import CombinedMultiDict
11 | from ..datastructures import EnvironHeaders
12 | from ..datastructures import FileStorage
13 | from ..datastructures import ImmutableMultiDict
14 | from ..datastructures import iter_multi_items
15 | from ..datastructures import MultiDict
16 | from ..exceptions import BadRequest
17 | from ..exceptions import UnsupportedMediaType
18 | from ..formparser import default_stream_factory
19 | from ..formparser import FormDataParser
20 | from ..sansio.request import Request as _SansIORequest
21 | from ..utils import cached_property
22 | from ..utils import environ_property
23 | from ..wsgi import _get_server
24 | from ..wsgi import get_input_stream
25 |
26 | if t.TYPE_CHECKING:
27 | from _typeshed.wsgi import WSGIApplication
28 | from _typeshed.wsgi import WSGIEnvironment
29 |
30 |
31 | class Request(_SansIORequest):
32 | """Represents an incoming WSGI HTTP request, with headers and body
33 | taken from the WSGI environment. Has properties and methods for
34 | using the functionality defined by various HTTP specs. The data in
35 | requests object is read-only.
36 |
37 | Text data is assumed to use UTF-8 encoding, which should be true for
38 | the vast majority of modern clients. Using an encoding set by the
39 | client is unsafe in Python due to extra encodings it provides, such
40 | as ``zip``. To change the assumed encoding, subclass and replace
41 | :attr:`charset`.
42 |
43 | :param environ: The WSGI environ is generated by the WSGI server and
44 | contains information about the server configuration and client
45 | request.
46 | :param populate_request: Add this request object to the WSGI environ
47 | as ``environ['werkzeug.request']``. Can be useful when
48 | debugging.
49 | :param shallow: Makes reading from :attr:`stream` (and any method
50 | that would read from it) raise a :exc:`RuntimeError`. Useful to
51 | prevent consuming the form data in middleware, which would make
52 | it unavailable to the final application.
53 |
54 | .. versionchanged:: 3.0
55 | The ``charset``, ``url_charset``, and ``encoding_errors`` parameters
56 | were removed.
57 |
58 | .. versionchanged:: 2.1
59 | Old ``BaseRequest`` and mixin classes were removed.
60 |
61 | .. versionchanged:: 2.1
62 | Remove the ``disable_data_descriptor`` attribute.
63 |
64 | .. versionchanged:: 2.0
65 | Combine ``BaseRequest`` and mixins into a single ``Request``
66 | class.
67 |
68 | .. versionchanged:: 0.5
69 | Read-only mode is enforced with immutable classes for all data.
70 | """
71 |
72 | #: the maximum content length. This is forwarded to the form data
73 | #: parsing function (:func:`parse_form_data`). When set and the
74 | #: :attr:`form` or :attr:`files` attribute is accessed and the
75 | #: parsing fails because more than the specified value is transmitted
76 | #: a :exc:`~werkzeug.exceptions.RequestEntityTooLarge` exception is raised.
77 | #:
78 | #: .. versionadded:: 0.5
79 | max_content_length: int | None = None
80 |
81 | #: the maximum form field size. This is forwarded to the form data
82 | #: parsing function (:func:`parse_form_data`). When set and the
83 | #: :attr:`form` or :attr:`files` attribute is accessed and the
84 | #: data in memory for post data is longer than the specified value a
85 | #: :exc:`~werkzeug.exceptions.RequestEntityTooLarge` exception is raised.
86 | #:
87 | #: .. versionadded:: 0.5
88 | max_form_memory_size: int | None = None
89 |
90 | #: The maximum number of multipart parts to parse, passed to
91 | #: :attr:`form_data_parser_class`. Parsing form data with more than this
92 | #: many parts will raise :exc:`~.RequestEntityTooLarge`.
93 | #:
94 | #: .. versionadded:: 2.2.3
95 | max_form_parts = 1000
96 |
97 | #: The form data parser that should be used. Can be replaced to customize
98 | #: the form date parsing.
99 | form_data_parser_class: type[FormDataParser] = FormDataParser
100 |
101 | #: The WSGI environment containing HTTP headers and information from
102 | #: the WSGI server.
103 | environ: WSGIEnvironment
104 |
105 | #: Set when creating the request object. If ``True``, reading from
106 | #: the request body will cause a ``RuntimeException``. Useful to
107 | #: prevent modifying the stream from middleware.
108 | shallow: bool
109 |
110 | def __init__(
111 | self,
112 | environ: WSGIEnvironment,
113 | populate_request: bool = True,
114 | shallow: bool = False,
115 | ) -> None:
116 | super().__init__(
117 | method=environ.get("REQUEST_METHOD", "GET"),
118 | scheme=environ.get("wsgi.url_scheme", "http"),
119 | server=_get_server(environ),
120 | root_path=_wsgi_decoding_dance(environ.get("SCRIPT_NAME") or ""),
121 | path=_wsgi_decoding_dance(environ.get("PATH_INFO") or ""),
122 | query_string=environ.get("QUERY_STRING", "").encode("latin1"),
123 | headers=EnvironHeaders(environ),
124 | remote_addr=environ.get("REMOTE_ADDR"),
125 | )
126 | self.environ = environ
127 | self.shallow = shallow
128 |
129 | if populate_request and not shallow:
130 | self.environ["werkzeug.request"] = self
131 |
132 | @classmethod
133 | def from_values(cls, *args: t.Any, **kwargs: t.Any) -> Request:
134 | """Create a new request object based on the values provided. If
135 | environ is given missing values are filled from there. This method is
136 | useful for small scripts when you need to simulate a request from an URL.
137 | Do not use this method for unittesting, there is a full featured client
138 | object (:class:`Client`) that allows to create multipart requests,
139 | support for cookies etc.
140 |
141 | This accepts the same options as the
142 | :class:`~werkzeug.test.EnvironBuilder`.
143 |
144 | .. versionchanged:: 0.5
145 | This method now accepts the same arguments as
146 | :class:`~werkzeug.test.EnvironBuilder`. Because of this the
147 | `environ` parameter is now called `environ_overrides`.
148 |
149 | :return: request object
150 | """
151 | from ..test import EnvironBuilder
152 |
153 | builder = EnvironBuilder(*args, **kwargs)
154 | try:
155 | return builder.get_request(cls)
156 | finally:
157 | builder.close()
158 |
159 | @classmethod
160 | def application(cls, f: t.Callable[[Request], WSGIApplication]) -> WSGIApplication:
161 | """Decorate a function as responder that accepts the request as
162 | the last argument. This works like the :func:`responder`
163 | decorator but the function is passed the request object as the
164 | last argument and the request object will be closed
165 | automatically::
166 |
167 | @Request.application
168 | def my_wsgi_app(request):
169 | return Response('Hello World!')
170 |
171 | As of Werkzeug 0.14 HTTP exceptions are automatically caught and
172 | converted to responses instead of failing.
173 |
174 | :param f: the WSGI callable to decorate
175 | :return: a new WSGI callable
176 | """
177 | #: return a callable that wraps the -2nd argument with the request
178 | #: and calls the function with all the arguments up to that one and
179 | #: the request. The return value is then called with the latest
180 | #: two arguments. This makes it possible to use this decorator for
181 | #: both standalone WSGI functions as well as bound methods and
182 | #: partially applied functions.
183 | from ..exceptions import HTTPException
184 |
185 | @functools.wraps(f)
186 | def application(*args: t.Any) -> cabc.Iterable[bytes]:
187 | request = cls(args[-2])
188 | with request:
189 | try:
190 | resp = f(*args[:-2] + (request,))
191 | except HTTPException as e:
192 | resp = t.cast("WSGIApplication", e.get_response(args[-2]))
193 | return resp(*args[-2:])
194 |
195 | return t.cast("WSGIApplication", application)
196 |
197 | def _get_file_stream(
198 | self,
199 | total_content_length: int | None,
200 | content_type: str | None,
201 | filename: str | None = None,
202 | content_length: int | None = None,
203 | ) -> t.IO[bytes]:
204 | """Called to get a stream for the file upload.
205 |
206 | This must provide a file-like class with `read()`, `readline()`
207 | and `seek()` methods that is both writeable and readable.
208 |
209 | The default implementation returns a temporary file if the total
210 | content length is higher than 500KB. Because many browsers do not
211 | provide a content length for the files only the total content
212 | length matters.
213 |
214 | :param total_content_length: the total content length of all the
215 | data in the request combined. This value
216 | is guaranteed to be there.
217 | :param content_type: the mimetype of the uploaded file.
218 | :param filename: the filename of the uploaded file. May be `None`.
219 | :param content_length: the length of this file. This value is usually
220 | not provided because webbrowsers do not provide
221 | this value.
222 | """
223 | return default_stream_factory(
224 | total_content_length=total_content_length,
225 | filename=filename,
226 | content_type=content_type,
227 | content_length=content_length,
228 | )
229 |
230 | @property
231 | def want_form_data_parsed(self) -> bool:
232 | """``True`` if the request method carries content. By default
233 | this is true if a ``Content-Type`` is sent.
234 |
235 | .. versionadded:: 0.8
236 | """
237 | return bool(self.environ.get("CONTENT_TYPE"))
238 |
239 | def make_form_data_parser(self) -> FormDataParser:
240 | """Creates the form data parser. Instantiates the
241 | :attr:`form_data_parser_class` with some parameters.
242 |
243 | .. versionadded:: 0.8
244 | """
245 | return self.form_data_parser_class(
246 | stream_factory=self._get_file_stream,
247 | max_form_memory_size=self.max_form_memory_size,
248 | max_content_length=self.max_content_length,
249 | max_form_parts=self.max_form_parts,
250 | cls=self.parameter_storage_class,
251 | )
252 |
253 | def _load_form_data(self) -> None:
254 | """Method used internally to retrieve submitted data. After calling
255 | this sets `form` and `files` on the request object to multi dicts
256 | filled with the incoming form data. As a matter of fact the input
257 | stream will be empty afterwards. You can also call this method to
258 | force the parsing of the form data.
259 |
260 | .. versionadded:: 0.8
261 | """
262 | # abort early if we have already consumed the stream
263 | if "form" in self.__dict__:
264 | return
265 |
266 | if self.want_form_data_parsed:
267 | parser = self.make_form_data_parser()
268 | data = parser.parse(
269 | self._get_stream_for_parsing(),
270 | self.mimetype,
271 | self.content_length,
272 | self.mimetype_params,
273 | )
274 | else:
275 | data = (
276 | self.stream,
277 | self.parameter_storage_class(),
278 | self.parameter_storage_class(),
279 | )
280 |
281 | # inject the values into the instance dict so that we bypass
282 | # our cached_property non-data descriptor.
283 | d = self.__dict__
284 | d["stream"], d["form"], d["files"] = data
285 |
286 | def _get_stream_for_parsing(self) -> t.IO[bytes]:
287 | """This is the same as accessing :attr:`stream` with the difference
288 | that if it finds cached data from calling :meth:`get_data` first it
289 | will create a new stream out of the cached data.
290 |
291 | .. versionadded:: 0.9.3
292 | """
293 | cached_data = getattr(self, "_cached_data", None)
294 | if cached_data is not None:
295 | return BytesIO(cached_data)
296 | return self.stream
297 |
298 | def close(self) -> None:
299 | """Closes associated resources of this request object. This
300 | closes all file handles explicitly. You can also use the request
301 | object in a with statement which will automatically close it.
302 |
303 | .. versionadded:: 0.9
304 | """
305 | files = self.__dict__.get("files")
306 | for _key, value in iter_multi_items(files or ()):
307 | value.close()
308 |
309 | def __enter__(self) -> Request:
310 | return self
311 |
312 | def __exit__(self, exc_type, exc_value, tb) -> None: # type: ignore
313 | self.close()
314 |
315 | @cached_property
316 | def stream(self) -> t.IO[bytes]:
317 | """The WSGI input stream, with safety checks. This stream can only be consumed
318 | once.
319 |
320 | Use :meth:`get_data` to get the full data as bytes or text. The :attr:`data`
321 | attribute will contain the full bytes only if they do not represent form data.
322 | The :attr:`form` attribute will contain the parsed form data in that case.
323 |
324 | Unlike :attr:`input_stream`, this stream guards against infinite streams or
325 | reading past :attr:`content_length` or :attr:`max_content_length`.
326 |
327 | If ``max_content_length`` is set, it can be enforced on streams if
328 | ``wsgi.input_terminated`` is set. Otherwise, an empty stream is returned.
329 |
330 | If the limit is reached before the underlying stream is exhausted (such as a
331 | file that is too large, or an infinite stream), the remaining contents of the
332 | stream cannot be read safely. Depending on how the server handles this, clients
333 | may show a "connection reset" failure instead of seeing the 413 response.
334 |
335 | .. versionchanged:: 2.3
336 | Check ``max_content_length`` preemptively and while reading.
337 |
338 | .. versionchanged:: 0.9
339 | The stream is always set (but may be consumed) even if form parsing was
340 | accessed first.
341 | """
342 | if self.shallow:
343 | raise RuntimeError(
344 | "This request was created with 'shallow=True', reading"
345 | " from the input stream is disabled."
346 | )
347 |
348 | return get_input_stream(
349 | self.environ, max_content_length=self.max_content_length
350 | )
351 |
352 | input_stream = environ_property[t.IO[bytes]](
353 | "wsgi.input",
354 | doc="""The raw WSGI input stream, without any safety checks.
355 |
356 | This is dangerous to use. It does not guard against infinite streams or reading
357 | past :attr:`content_length` or :attr:`max_content_length`.
358 |
359 | Use :attr:`stream` instead.
360 | """,
361 | )
362 |
363 | @cached_property
364 | def data(self) -> bytes:
365 | """The raw data read from :attr:`stream`. Will be empty if the request
366 | represents form data.
367 |
368 | To get the raw data even if it represents form data, use :meth:`get_data`.
369 | """
370 | return self.get_data(parse_form_data=True)
371 |
372 | @t.overload
373 | def get_data(
374 | self,
375 | cache: bool = True,
376 | as_text: t.Literal[False] = False,
377 | parse_form_data: bool = False,
378 | ) -> bytes: ...
379 |
380 | @t.overload
381 | def get_data(
382 | self,
383 | cache: bool = True,
384 | as_text: t.Literal[True] = ...,
385 | parse_form_data: bool = False,
386 | ) -> str: ...
387 |
388 | def get_data(
389 | self, cache: bool = True, as_text: bool = False, parse_form_data: bool = False
390 | ) -> bytes | str:
391 | """This reads the buffered incoming data from the client into one
392 | bytes object. By default this is cached but that behavior can be
393 | changed by setting `cache` to `False`.
394 |
395 | Usually it's a bad idea to call this method without checking the
396 | content length first as a client could send dozens of megabytes or more
397 | to cause memory problems on the server.
398 |
399 | Note that if the form data was already parsed this method will not
400 | return anything as form data parsing does not cache the data like
401 | this method does. To implicitly invoke form data parsing function
402 | set `parse_form_data` to `True`. When this is done the return value
403 | of this method will be an empty string if the form parser handles
404 | the data. This generally is not necessary as if the whole data is
405 | cached (which is the default) the form parser will used the cached
406 | data to parse the form data. Please be generally aware of checking
407 | the content length first in any case before calling this method
408 | to avoid exhausting server memory.
409 |
410 | If `as_text` is set to `True` the return value will be a decoded
411 | string.
412 |
413 | .. versionadded:: 0.9
414 | """
415 | rv = getattr(self, "_cached_data", None)
416 | if rv is None:
417 | if parse_form_data:
418 | self._load_form_data()
419 | rv = self.stream.read()
420 | if cache:
421 | self._cached_data = rv
422 | if as_text:
423 | rv = rv.decode(errors="replace")
424 | return rv
425 |
426 | @cached_property
427 | def form(self) -> ImmutableMultiDict[str, str]:
428 | """The form parameters. By default an
429 | :class:`~werkzeug.datastructures.ImmutableMultiDict`
430 | is returned from this function. This can be changed by setting
431 | :attr:`parameter_storage_class` to a different type. This might
432 | be necessary if the order of the form data is important.
433 |
434 | Please keep in mind that file uploads will not end up here, but instead
435 | in the :attr:`files` attribute.
436 |
437 | .. versionchanged:: 0.9
438 |
439 | Previous to Werkzeug 0.9 this would only contain form data for POST
440 | and PUT requests.
441 | """
442 | self._load_form_data()
443 | return self.form
444 |
445 | @cached_property
446 | def values(self) -> CombinedMultiDict[str, str]:
447 | """A :class:`werkzeug.datastructures.CombinedMultiDict` that
448 | combines :attr:`args` and :attr:`form`.
449 |
450 | For GET requests, only ``args`` are present, not ``form``.
451 |
452 | .. versionchanged:: 2.0
453 | For GET requests, only ``args`` are present, not ``form``.
454 | """
455 | sources = [self.args]
456 |
457 | if self.method != "GET":
458 | # GET requests can have a body, and some caching proxies
459 | # might not treat that differently than a normal GET
460 | # request, allowing form data to "invisibly" affect the
461 | # cache without indication in the query string / URL.
462 | sources.append(self.form)
463 |
464 | args = []
465 |
466 | for d in sources:
467 | if not isinstance(d, MultiDict):
468 | d = MultiDict(d)
469 |
470 | args.append(d)
471 |
472 | return CombinedMultiDict(args)
473 |
474 | @cached_property
475 | def files(self) -> ImmutableMultiDict[str, FileStorage]:
476 | """:class:`~werkzeug.datastructures.MultiDict` object containing
477 | all uploaded files. Each key in :attr:`files` is the name from the
478 | ``<input type="file" name="">``. Each value in :attr:`files` is a
479 | Werkzeug :class:`~werkzeug.datastructures.FileStorage` object.
480 |
481 | It basically behaves like a standard file object you know from Python,
482 | with the difference that it also has a
483 | :meth:`~werkzeug.datastructures.FileStorage.save` function that can
484 | store the file on the filesystem.
485 |
486 | Note that :attr:`files` will only contain data if the request method was
487 | POST, PUT or PATCH and the ``<form>`` that posted to the request had
488 | ``enctype="multipart/form-data"``. It will be empty otherwise.
489 |
490 | See the :class:`~werkzeug.datastructures.MultiDict` /
491 | :class:`~werkzeug.datastructures.FileStorage` documentation for
492 | more details about the used data structure.
493 | """
494 | self._load_form_data()
495 | return self.files
496 |
497 | @property
498 | def script_root(self) -> str:
499 | """Alias for :attr:`self.root_path`. ``environ["SCRIPT_ROOT"]``
500 | without a trailing slash.
501 | """
502 | return self.root_path
503 |
504 | @cached_property
505 | def url_root(self) -> str:
506 | """Alias for :attr:`root_url`. The URL with scheme, host, and
507 | root path. For example, ``https://example.com/app/``.
508 | """
509 | return self.root_url
510 |
511 | remote_user = environ_property[str](
512 | "REMOTE_USER",
513 | doc="""If the server supports user authentication, and the
514 | script is protected, this attribute contains the username the
515 | user has authenticated as.""",
516 | )
517 | is_multithread = environ_property[bool](
518 | "wsgi.multithread",
519 | doc="""boolean that is `True` if the application is served by a
520 | multithreaded WSGI server.""",
521 | )
522 | is_multiprocess = environ_property[bool](
523 | "wsgi.multiprocess",
524 | doc="""boolean that is `True` if the application is served by a
525 | WSGI server that spawns multiple processes.""",
526 | )
527 | is_run_once = environ_property[bool](
528 | "wsgi.run_once",
529 | doc="""boolean that is `True` if the application will be
530 | executed only once in a process lifetime. This is the case for
531 | CGI for example, but it's not guaranteed that the execution only
532 | happens one time.""",
533 | )
534 |
535 | # JSON
536 |
537 | #: A module or other object that has ``dumps`` and ``loads``
538 | #: functions that match the API of the built-in :mod:`json` module.
539 | json_module = json
540 |
541 | @property
542 | def json(self) -> t.Any | None:
543 | """The parsed JSON data if :attr:`mimetype` indicates JSON
544 | (:mimetype:`application/json`, see :attr:`is_json`).
545 |
546 | Calls :meth:`get_json` with default arguments.
547 |
548 | If the request content type is not ``application/json``, this
549 | will raise a 415 Unsupported Media Type error.
550 |
551 | .. versionchanged:: 2.3
552 | Raise a 415 error instead of 400.
553 |
554 | .. versionchanged:: 2.1
555 | Raise a 400 error if the content type is incorrect.
556 | """
557 | return self.get_json()
558 |
559 | # Cached values for ``(silent=False, silent=True)``. Initialized
560 | # with sentinel values.
561 | _cached_json: tuple[t.Any, t.Any] = (Ellipsis, Ellipsis)
562 |
563 | @t.overload
564 | def get_json(
565 | self, force: bool = ..., silent: t.Literal[False] = ..., cache: bool = ...
566 | ) -> t.Any: ...
567 |
568 | @t.overload
569 | def get_json(
570 | self, force: bool = ..., silent: bool = ..., cache: bool = ...
571 | ) -> t.Any | None: ...
572 |
573 | def get_json(
574 | self, force: bool = False, silent: bool = False, cache: bool = True
575 | ) -> t.Any | None:
576 | """Parse :attr:`data` as JSON.
577 |
578 | If the mimetype does not indicate JSON
579 | (:mimetype:`application/json`, see :attr:`is_json`), or parsing
580 | fails, :meth:`on_json_loading_failed` is called and
581 | its return value is used as the return value. By default this
582 | raises a 415 Unsupported Media Type resp.
583 |
584 | :param force: Ignore the mimetype and always try to parse JSON.
585 | :param silent: Silence mimetype and parsing errors, and
586 | return ``None`` instead.
587 | :param cache: Store the parsed JSON to return for subsequent
588 | calls.
589 |
590 | .. versionchanged:: 2.3
591 | Raise a 415 error instead of 400.
592 |
593 | .. versionchanged:: 2.1
594 | Raise a 400 error if the content type is incorrect.
595 | """
596 | if cache and self._cached_json[silent] is not Ellipsis:
597 | return self._cached_json[silent]
598 |
599 | if not (force or self.is_json):
600 | if not silent:
601 | return self.on_json_loading_failed(None)
602 | else:
603 | return None
604 |
605 | data = self.get_data(cache=cache)
606 |
607 | try:
608 | rv = self.json_module.loads(data)
609 | except ValueError as e:
610 | if silent:
611 | rv = None
612 |
613 | if cache:
614 | normal_rv, _ = self._cached_json
615 | self._cached_json = (normal_rv, rv)
616 | else:
617 | rv = self.on_json_loading_failed(e)
618 |
619 | if cache:
620 | _, silent_rv = self._cached_json
621 | self._cached_json = (rv, silent_rv)
622 | else:
623 | if cache:
624 | self._cached_json = (rv, rv)
625 |
626 | return rv
627 |
628 | def on_json_loading_failed(self, e: ValueError | None) -> t.Any:
629 | """Called if :meth:`get_json` fails and isn't silenced.
630 |
631 | If this method returns a value, it is used as the return value
632 | for :meth:`get_json`. The default implementation raises
633 | :exc:`~werkzeug.exceptions.BadRequest`.
634 |
635 | :param e: If parsing failed, this is the exception. It will be
636 | ``None`` if the content type wasn't ``application/json``.
637 |
638 | .. versionchanged:: 2.3
639 | Raise a 415 error instead of 400.
640 | """
641 | if e is not None:
642 | raise BadRequest(f"Failed to decode JSON object: {e}")
643 |
644 | raise UnsupportedMediaType(
645 | "Did not attempt to load JSON data because the request"
646 | " Content-Type was not 'application/json'."
647 | )
648 |
```