#
tokens: 48517/50000 3/808 files (page 68/168)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 68 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/werkzeug/debug/__init__.py:
--------------------------------------------------------------------------------

```python
  1 | from __future__ import annotations
  2 | 
  3 | import getpass
  4 | import hashlib
  5 | import json
  6 | import os
  7 | import pkgutil
  8 | import re
  9 | import sys
 10 | import time
 11 | import typing as t
 12 | import uuid
 13 | from contextlib import ExitStack
 14 | from io import BytesIO
 15 | from itertools import chain
 16 | from multiprocessing import Value
 17 | from os.path import basename
 18 | from os.path import join
 19 | from zlib import adler32
 20 | 
 21 | from .._internal import _log
 22 | from ..exceptions import NotFound
 23 | from ..exceptions import SecurityError
 24 | from ..http import parse_cookie
 25 | from ..sansio.utils import host_is_trusted
 26 | from ..security import gen_salt
 27 | from ..utils import send_file
 28 | from ..wrappers.request import Request
 29 | from ..wrappers.response import Response
 30 | from .console import Console
 31 | from .tbtools import DebugFrameSummary
 32 | from .tbtools import DebugTraceback
 33 | from .tbtools import render_console_html
 34 | 
 35 | if t.TYPE_CHECKING:
 36 |     from _typeshed.wsgi import StartResponse
 37 |     from _typeshed.wsgi import WSGIApplication
 38 |     from _typeshed.wsgi import WSGIEnvironment
 39 | 
 40 | # A week
 41 | PIN_TIME = 60 * 60 * 24 * 7
 42 | 
 43 | 
 44 | def hash_pin(pin: str) -> str:
 45 |     return hashlib.sha1(f"{pin} added salt".encode("utf-8", "replace")).hexdigest()[:12]
 46 | 
 47 | 
 48 | _machine_id: str | bytes | None = None
 49 | 
 50 | 
 51 | def get_machine_id() -> str | bytes | None:
 52 |     global _machine_id
 53 | 
 54 |     if _machine_id is not None:
 55 |         return _machine_id
 56 | 
 57 |     def _generate() -> str | bytes | None:
 58 |         linux = b""
 59 | 
 60 |         # machine-id is stable across boots, boot_id is not.
 61 |         for filename in "/etc/machine-id", "/proc/sys/kernel/random/boot_id":
 62 |             try:
 63 |                 with open(filename, "rb") as f:
 64 |                     value = f.readline().strip()
 65 |             except OSError:
 66 |                 continue
 67 | 
 68 |             if value:
 69 |                 linux += value
 70 |                 break
 71 | 
 72 |         # Containers share the same machine id, add some cgroup
 73 |         # information. This is used outside containers too but should be
 74 |         # relatively stable across boots.
 75 |         try:
 76 |             with open("/proc/self/cgroup", "rb") as f:
 77 |                 linux += f.readline().strip().rpartition(b"/")[2]
 78 |         except OSError:
 79 |             pass
 80 | 
 81 |         if linux:
 82 |             return linux
 83 | 
 84 |         # On OS X, use ioreg to get the computer's serial number.
 85 |         try:
 86 |             # subprocess may not be available, e.g. Google App Engine
 87 |             # https://github.com/pallets/werkzeug/issues/925
 88 |             from subprocess import PIPE
 89 |             from subprocess import Popen
 90 | 
 91 |             dump = Popen(
 92 |                 ["ioreg", "-c", "IOPlatformExpertDevice", "-d", "2"], stdout=PIPE
 93 |             ).communicate()[0]
 94 |             match = re.search(b'"serial-number" = <([^>]+)', dump)
 95 | 
 96 |             if match is not None:
 97 |                 return match.group(1)
 98 |         except (OSError, ImportError):
 99 |             pass
100 | 
101 |         # On Windows, use winreg to get the machine guid.
102 |         if sys.platform == "win32":
103 |             import winreg
104 | 
105 |             try:
106 |                 with winreg.OpenKey(
107 |                     winreg.HKEY_LOCAL_MACHINE,
108 |                     "SOFTWARE\\Microsoft\\Cryptography",
109 |                     0,
110 |                     winreg.KEY_READ | winreg.KEY_WOW64_64KEY,
111 |                 ) as rk:
112 |                     guid: str | bytes
113 |                     guid_type: int
114 |                     guid, guid_type = winreg.QueryValueEx(rk, "MachineGuid")
115 | 
116 |                     if guid_type == winreg.REG_SZ:
117 |                         return guid.encode()
118 | 
119 |                     return guid
120 |             except OSError:
121 |                 pass
122 | 
123 |         return None
124 | 
125 |     _machine_id = _generate()
126 |     return _machine_id
127 | 
128 | 
129 | class _ConsoleFrame:
130 |     """Helper class so that we can reuse the frame console code for the
131 |     standalone console.
132 |     """
133 | 
134 |     def __init__(self, namespace: dict[str, t.Any]):
135 |         self.console = Console(namespace)
136 |         self.id = 0
137 | 
138 |     def eval(self, code: str) -> t.Any:
139 |         return self.console.eval(code)
140 | 
141 | 
142 | def get_pin_and_cookie_name(
143 |     app: WSGIApplication,
144 | ) -> tuple[str, str] | tuple[None, None]:
145 |     """Given an application object this returns a semi-stable 9 digit pin
146 |     code and a random key.  The hope is that this is stable between
147 |     restarts to not make debugging particularly frustrating.  If the pin
148 |     was forcefully disabled this returns `None`.
149 | 
150 |     Second item in the resulting tuple is the cookie name for remembering.
151 |     """
152 |     pin = os.environ.get("WERKZEUG_DEBUG_PIN")
153 |     rv = None
154 |     num = None
155 | 
156 |     # Pin was explicitly disabled
157 |     if pin == "off":
158 |         return None, None
159 | 
160 |     # Pin was provided explicitly
161 |     if pin is not None and pin.replace("-", "").isdecimal():
162 |         # If there are separators in the pin, return it directly
163 |         if "-" in pin:
164 |             rv = pin
165 |         else:
166 |             num = pin
167 | 
168 |     modname = getattr(app, "__module__", t.cast(object, app).__class__.__module__)
169 |     username: str | None
170 | 
171 |     try:
172 |         # getuser imports the pwd module, which does not exist in Google
173 |         # App Engine. It may also raise a KeyError if the UID does not
174 |         # have a username, such as in Docker.
175 |         username = getpass.getuser()
176 |     except (ImportError, KeyError):
177 |         username = None
178 | 
179 |     mod = sys.modules.get(modname)
180 | 
181 |     # This information only exists to make the cookie unique on the
182 |     # computer, not as a security feature.
183 |     probably_public_bits = [
184 |         username,
185 |         modname,
186 |         getattr(app, "__name__", type(app).__name__),
187 |         getattr(mod, "__file__", None),
188 |     ]
189 | 
190 |     # This information is here to make it harder for an attacker to
191 |     # guess the cookie name.  They are unlikely to be contained anywhere
192 |     # within the unauthenticated debug page.
193 |     private_bits = [str(uuid.getnode()), get_machine_id()]
194 | 
195 |     h = hashlib.sha1()
196 |     for bit in chain(probably_public_bits, private_bits):
197 |         if not bit:
198 |             continue
199 |         if isinstance(bit, str):
200 |             bit = bit.encode()
201 |         h.update(bit)
202 |     h.update(b"cookiesalt")
203 | 
204 |     cookie_name = f"__wzd{h.hexdigest()[:20]}"
205 | 
206 |     # If we need to generate a pin we salt it a bit more so that we don't
207 |     # end up with the same value and generate out 9 digits
208 |     if num is None:
209 |         h.update(b"pinsalt")
210 |         num = f"{int(h.hexdigest(), 16):09d}"[:9]
211 | 
212 |     # Format the pincode in groups of digits for easier remembering if
213 |     # we don't have a result yet.
214 |     if rv is None:
215 |         for group_size in 5, 4, 3:
216 |             if len(num) % group_size == 0:
217 |                 rv = "-".join(
218 |                     num[x : x + group_size].rjust(group_size, "0")
219 |                     for x in range(0, len(num), group_size)
220 |                 )
221 |                 break
222 |         else:
223 |             rv = num
224 | 
225 |     return rv, cookie_name
226 | 
227 | 
228 | class DebuggedApplication:
229 |     """Enables debugging support for a given application::
230 | 
231 |         from werkzeug.debug import DebuggedApplication
232 |         from myapp import app
233 |         app = DebuggedApplication(app, evalex=True)
234 | 
235 |     The ``evalex`` argument allows evaluating expressions in any frame
236 |     of a traceback. This works by preserving each frame with its local
237 |     state. Some state, such as context globals, cannot be restored with
238 |     the frame by default. When ``evalex`` is enabled,
239 |     ``environ["werkzeug.debug.preserve_context"]`` will be a callable
240 |     that takes a context manager, and can be called multiple times.
241 |     Each context manager will be entered before evaluating code in the
242 |     frame, then exited again, so they can perform setup and cleanup for
243 |     each call.
244 | 
245 |     :param app: the WSGI application to run debugged.
246 |     :param evalex: enable exception evaluation feature (interactive
247 |                    debugging).  This requires a non-forking server.
248 |     :param request_key: The key that points to the request object in this
249 |                         environment.  This parameter is ignored in current
250 |                         versions.
251 |     :param console_path: the URL for a general purpose console.
252 |     :param console_init_func: the function that is executed before starting
253 |                               the general purpose console.  The return value
254 |                               is used as initial namespace.
255 |     :param show_hidden_frames: by default hidden traceback frames are skipped.
256 |                                You can show them by setting this parameter
257 |                                to `True`.
258 |     :param pin_security: can be used to disable the pin based security system.
259 |     :param pin_logging: enables the logging of the pin system.
260 | 
261 |     .. versionchanged:: 2.2
262 |         Added the ``werkzeug.debug.preserve_context`` environ key.
263 |     """
264 | 
265 |     _pin: str
266 |     _pin_cookie: str
267 | 
268 |     def __init__(
269 |         self,
270 |         app: WSGIApplication,
271 |         evalex: bool = False,
272 |         request_key: str = "werkzeug.request",
273 |         console_path: str = "/console",
274 |         console_init_func: t.Callable[[], dict[str, t.Any]] | None = None,
275 |         show_hidden_frames: bool = False,
276 |         pin_security: bool = True,
277 |         pin_logging: bool = True,
278 |     ) -> None:
279 |         if not console_init_func:
280 |             console_init_func = None
281 |         self.app = app
282 |         self.evalex = evalex
283 |         self.frames: dict[int, DebugFrameSummary | _ConsoleFrame] = {}
284 |         self.frame_contexts: dict[int, list[t.ContextManager[None]]] = {}
285 |         self.request_key = request_key
286 |         self.console_path = console_path
287 |         self.console_init_func = console_init_func
288 |         self.show_hidden_frames = show_hidden_frames
289 |         self.secret = gen_salt(20)
290 |         self._failed_pin_auth = Value("B")
291 | 
292 |         self.pin_logging = pin_logging
293 |         if pin_security:
294 |             # Print out the pin for the debugger on standard out.
295 |             if os.environ.get("WERKZEUG_RUN_MAIN") == "true" and pin_logging:
296 |                 _log("warning", " * Debugger is active!")
297 |                 if self.pin is None:
298 |                     _log("warning", " * Debugger PIN disabled. DEBUGGER UNSECURED!")
299 |                 else:
300 |                     _log("info", " * Debugger PIN: %s", self.pin)
301 |         else:
302 |             self.pin = None
303 | 
304 |         self.trusted_hosts: list[str] = [".localhost", "127.0.0.1"]
305 |         """List of domains to allow requests to the debugger from. A leading dot
306 |         allows all subdomains. This only allows ``".localhost"`` domains by
307 |         default.
308 | 
309 |         .. versionadded:: 3.0.3
310 |         """
311 | 
312 |     @property
313 |     def pin(self) -> str | None:
314 |         if not hasattr(self, "_pin"):
315 |             pin_cookie = get_pin_and_cookie_name(self.app)
316 |             self._pin, self._pin_cookie = pin_cookie  # type: ignore
317 |         return self._pin
318 | 
319 |     @pin.setter
320 |     def pin(self, value: str) -> None:
321 |         self._pin = value
322 | 
323 |     @property
324 |     def pin_cookie_name(self) -> str:
325 |         """The name of the pin cookie."""
326 |         if not hasattr(self, "_pin_cookie"):
327 |             pin_cookie = get_pin_and_cookie_name(self.app)
328 |             self._pin, self._pin_cookie = pin_cookie  # type: ignore
329 |         return self._pin_cookie
330 | 
331 |     def debug_application(
332 |         self, environ: WSGIEnvironment, start_response: StartResponse
333 |     ) -> t.Iterator[bytes]:
334 |         """Run the application and conserve the traceback frames."""
335 |         contexts: list[t.ContextManager[t.Any]] = []
336 | 
337 |         if self.evalex:
338 |             environ["werkzeug.debug.preserve_context"] = contexts.append
339 | 
340 |         app_iter = None
341 |         try:
342 |             app_iter = self.app(environ, start_response)
343 |             yield from app_iter
344 |             if hasattr(app_iter, "close"):
345 |                 app_iter.close()
346 |         except Exception as e:
347 |             if hasattr(app_iter, "close"):
348 |                 app_iter.close()  # type: ignore
349 | 
350 |             tb = DebugTraceback(e, skip=1, hide=not self.show_hidden_frames)
351 | 
352 |             for frame in tb.all_frames:
353 |                 self.frames[id(frame)] = frame
354 |                 self.frame_contexts[id(frame)] = contexts
355 | 
356 |             is_trusted = bool(self.check_pin_trust(environ))
357 |             html = tb.render_debugger_html(
358 |                 evalex=self.evalex and self.check_host_trust(environ),
359 |                 secret=self.secret,
360 |                 evalex_trusted=is_trusted,
361 |             )
362 |             response = Response(html, status=500, mimetype="text/html")
363 | 
364 |             try:
365 |                 yield from response(environ, start_response)
366 |             except Exception:
367 |                 # if we end up here there has been output but an error
368 |                 # occurred.  in that situation we can do nothing fancy any
369 |                 # more, better log something into the error log and fall
370 |                 # back gracefully.
371 |                 environ["wsgi.errors"].write(
372 |                     "Debugging middleware caught exception in streamed "
373 |                     "response at a point where response headers were already "
374 |                     "sent.\n"
375 |                 )
376 | 
377 |             environ["wsgi.errors"].write("".join(tb.render_traceback_text()))
378 | 
379 |     def execute_command(
380 |         self,
381 |         request: Request,
382 |         command: str,
383 |         frame: DebugFrameSummary | _ConsoleFrame,
384 |     ) -> Response:
385 |         """Execute a command in a console."""
386 |         if not self.check_host_trust(request.environ):
387 |             return SecurityError()  # type: ignore[return-value]
388 | 
389 |         contexts = self.frame_contexts.get(id(frame), [])
390 | 
391 |         with ExitStack() as exit_stack:
392 |             for cm in contexts:
393 |                 exit_stack.enter_context(cm)
394 | 
395 |             return Response(frame.eval(command), mimetype="text/html")
396 | 
397 |     def display_console(self, request: Request) -> Response:
398 |         """Display a standalone shell."""
399 |         if not self.check_host_trust(request.environ):
400 |             return SecurityError()  # type: ignore[return-value]
401 | 
402 |         if 0 not in self.frames:
403 |             if self.console_init_func is None:
404 |                 ns = {}
405 |             else:
406 |                 ns = dict(self.console_init_func())
407 |             ns.setdefault("app", self.app)
408 |             self.frames[0] = _ConsoleFrame(ns)
409 |         is_trusted = bool(self.check_pin_trust(request.environ))
410 |         return Response(
411 |             render_console_html(secret=self.secret, evalex_trusted=is_trusted),
412 |             mimetype="text/html",
413 |         )
414 | 
415 |     def get_resource(self, request: Request, filename: str) -> Response:
416 |         """Return a static resource from the shared folder."""
417 |         path = join("shared", basename(filename))
418 | 
419 |         try:
420 |             data = pkgutil.get_data(__package__, path)
421 |         except OSError:
422 |             return NotFound()  # type: ignore[return-value]
423 |         else:
424 |             if data is None:
425 |                 return NotFound()  # type: ignore[return-value]
426 | 
427 |             etag = str(adler32(data) & 0xFFFFFFFF)
428 |             return send_file(
429 |                 BytesIO(data), request.environ, download_name=filename, etag=etag
430 |             )
431 | 
432 |     def check_pin_trust(self, environ: WSGIEnvironment) -> bool | None:
433 |         """Checks if the request passed the pin test.  This returns `True` if the
434 |         request is trusted on a pin/cookie basis and returns `False` if not.
435 |         Additionally if the cookie's stored pin hash is wrong it will return
436 |         `None` so that appropriate action can be taken.
437 |         """
438 |         if self.pin is None:
439 |             return True
440 |         val = parse_cookie(environ).get(self.pin_cookie_name)
441 |         if not val or "|" not in val:
442 |             return False
443 |         ts_str, pin_hash = val.split("|", 1)
444 | 
445 |         try:
446 |             ts = int(ts_str)
447 |         except ValueError:
448 |             return False
449 | 
450 |         if pin_hash != hash_pin(self.pin):
451 |             return None
452 |         return (time.time() - PIN_TIME) < ts
453 | 
454 |     def check_host_trust(self, environ: WSGIEnvironment) -> bool:
455 |         return host_is_trusted(environ.get("HTTP_HOST"), self.trusted_hosts)
456 | 
457 |     def _fail_pin_auth(self) -> None:
458 |         with self._failed_pin_auth.get_lock():
459 |             count = self._failed_pin_auth.value
460 |             self._failed_pin_auth.value = count + 1
461 | 
462 |         time.sleep(5.0 if count > 5 else 0.5)
463 | 
464 |     def pin_auth(self, request: Request) -> Response:
465 |         """Authenticates with the pin."""
466 |         if not self.check_host_trust(request.environ):
467 |             return SecurityError()  # type: ignore[return-value]
468 | 
469 |         exhausted = False
470 |         auth = False
471 |         trust = self.check_pin_trust(request.environ)
472 |         pin = t.cast(str, self.pin)
473 | 
474 |         # If the trust return value is `None` it means that the cookie is
475 |         # set but the stored pin hash value is bad.  This means that the
476 |         # pin was changed.  In this case we count a bad auth and unset the
477 |         # cookie.  This way it becomes harder to guess the cookie name
478 |         # instead of the pin as we still count up failures.
479 |         bad_cookie = False
480 |         if trust is None:
481 |             self._fail_pin_auth()
482 |             bad_cookie = True
483 | 
484 |         # If we're trusted, we're authenticated.
485 |         elif trust:
486 |             auth = True
487 | 
488 |         # If we failed too many times, then we're locked out.
489 |         elif self._failed_pin_auth.value > 10:
490 |             exhausted = True
491 | 
492 |         # Otherwise go through pin based authentication
493 |         else:
494 |             entered_pin = request.args["pin"]
495 | 
496 |             if entered_pin.strip().replace("-", "") == pin.replace("-", ""):
497 |                 self._failed_pin_auth.value = 0
498 |                 auth = True
499 |             else:
500 |                 self._fail_pin_auth()
501 | 
502 |         rv = Response(
503 |             json.dumps({"auth": auth, "exhausted": exhausted}),
504 |             mimetype="application/json",
505 |         )
506 |         if auth:
507 |             rv.set_cookie(
508 |                 self.pin_cookie_name,
509 |                 f"{int(time.time())}|{hash_pin(pin)}",
510 |                 httponly=True,
511 |                 samesite="Strict",
512 |                 secure=request.is_secure,
513 |             )
514 |         elif bad_cookie:
515 |             rv.delete_cookie(self.pin_cookie_name)
516 |         return rv
517 | 
518 |     def log_pin_request(self, request: Request) -> Response:
519 |         """Log the pin if needed."""
520 |         if not self.check_host_trust(request.environ):
521 |             return SecurityError()  # type: ignore[return-value]
522 | 
523 |         if self.pin_logging and self.pin is not None:
524 |             _log(
525 |                 "info", " * To enable the debugger you need to enter the security pin:"
526 |             )
527 |             _log("info", " * Debugger pin code: %s", self.pin)
528 |         return Response("")
529 | 
530 |     def __call__(
531 |         self, environ: WSGIEnvironment, start_response: StartResponse
532 |     ) -> t.Iterable[bytes]:
533 |         """Dispatch the requests."""
534 |         # important: don't ever access a function here that reads the incoming
535 |         # form data!  Otherwise the application won't have access to that data
536 |         # any more!
537 |         request = Request(environ)
538 |         response = self.debug_application
539 |         if request.args.get("__debugger__") == "yes":
540 |             cmd = request.args.get("cmd")
541 |             arg = request.args.get("f")
542 |             secret = request.args.get("s")
543 |             frame = self.frames.get(request.args.get("frm", type=int))  # type: ignore
544 |             if cmd == "resource" and arg:
545 |                 response = self.get_resource(request, arg)  # type: ignore
546 |             elif cmd == "pinauth" and secret == self.secret:
547 |                 response = self.pin_auth(request)  # type: ignore
548 |             elif cmd == "printpin" and secret == self.secret:
549 |                 response = self.log_pin_request(request)  # type: ignore
550 |             elif (
551 |                 self.evalex
552 |                 and cmd is not None
553 |                 and frame is not None
554 |                 and self.secret == secret
555 |                 and self.check_pin_trust(environ)
556 |             ):
557 |                 response = self.execute_command(request, cmd, frame)  # type: ignore
558 |         elif (
559 |             self.evalex
560 |             and self.console_path is not None
561 |             and request.path == self.console_path
562 |         ):
563 |             response = self.display_console(request)  # type: ignore
564 |         return response(environ, start_response)
565 | 
```

--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/werkzeug/sansio/request.py:
--------------------------------------------------------------------------------

```python
  1 | from __future__ import annotations
  2 | 
  3 | import typing as t
  4 | from datetime import datetime
  5 | from urllib.parse import parse_qsl
  6 | 
  7 | from ..datastructures import Accept
  8 | from ..datastructures import Authorization
  9 | from ..datastructures import CharsetAccept
 10 | from ..datastructures import ETags
 11 | from ..datastructures import Headers
 12 | from ..datastructures import HeaderSet
 13 | from ..datastructures import IfRange
 14 | from ..datastructures import ImmutableList
 15 | from ..datastructures import ImmutableMultiDict
 16 | from ..datastructures import LanguageAccept
 17 | from ..datastructures import MIMEAccept
 18 | from ..datastructures import MultiDict
 19 | from ..datastructures import Range
 20 | from ..datastructures import RequestCacheControl
 21 | from ..http import parse_accept_header
 22 | from ..http import parse_cache_control_header
 23 | from ..http import parse_date
 24 | from ..http import parse_etags
 25 | from ..http import parse_if_range_header
 26 | from ..http import parse_list_header
 27 | from ..http import parse_options_header
 28 | from ..http import parse_range_header
 29 | from ..http import parse_set_header
 30 | from ..user_agent import UserAgent
 31 | from ..utils import cached_property
 32 | from ..utils import header_property
 33 | from .http import parse_cookie
 34 | from .utils import get_content_length
 35 | from .utils import get_current_url
 36 | from .utils import get_host
 37 | 
 38 | 
 39 | class Request:
 40 |     """Represents the non-IO parts of a HTTP request, including the
 41 |     method, URL info, and headers.
 42 | 
 43 |     This class is not meant for general use. It should only be used when
 44 |     implementing WSGI, ASGI, or another HTTP application spec. Werkzeug
 45 |     provides a WSGI implementation at :cls:`werkzeug.wrappers.Request`.
 46 | 
 47 |     :param method: The method the request was made with, such as
 48 |         ``GET``.
 49 |     :param scheme: The URL scheme of the protocol the request used, such
 50 |         as ``https`` or ``wss``.
 51 |     :param server: The address of the server. ``(host, port)``,
 52 |         ``(path, None)`` for unix sockets, or ``None`` if not known.
 53 |     :param root_path: The prefix that the application is mounted under.
 54 |         This is prepended to generated URLs, but is not part of route
 55 |         matching.
 56 |     :param path: The path part of the URL after ``root_path``.
 57 |     :param query_string: The part of the URL after the "?".
 58 |     :param headers: The headers received with the request.
 59 |     :param remote_addr: The address of the client sending the request.
 60 | 
 61 |     .. versionchanged:: 3.0
 62 |         The ``charset``, ``url_charset``, and ``encoding_errors`` attributes
 63 |         were removed.
 64 | 
 65 |     .. versionadded:: 2.0
 66 |     """
 67 | 
 68 |     #: the class to use for `args` and `form`.  The default is an
 69 |     #: :class:`~werkzeug.datastructures.ImmutableMultiDict` which supports
 70 |     #: multiple values per key.  alternatively it makes sense to use an
 71 |     #: :class:`~werkzeug.datastructures.ImmutableOrderedMultiDict` which
 72 |     #: preserves order or a :class:`~werkzeug.datastructures.ImmutableDict`
 73 |     #: which is the fastest but only remembers the last key.  It is also
 74 |     #: possible to use mutable structures, but this is not recommended.
 75 |     #:
 76 |     #: .. versionadded:: 0.6
 77 |     parameter_storage_class: type[MultiDict[str, t.Any]] = ImmutableMultiDict
 78 | 
 79 |     #: The type to be used for dict values from the incoming WSGI
 80 |     #: environment. (For example for :attr:`cookies`.) By default an
 81 |     #: :class:`~werkzeug.datastructures.ImmutableMultiDict` is used.
 82 |     #:
 83 |     #: .. versionchanged:: 1.0.0
 84 |     #:     Changed to ``ImmutableMultiDict`` to support multiple values.
 85 |     #:
 86 |     #: .. versionadded:: 0.6
 87 |     dict_storage_class: type[MultiDict[str, t.Any]] = ImmutableMultiDict
 88 | 
 89 |     #: the type to be used for list values from the incoming WSGI environment.
 90 |     #: By default an :class:`~werkzeug.datastructures.ImmutableList` is used
 91 |     #: (for example for :attr:`access_list`).
 92 |     #:
 93 |     #: .. versionadded:: 0.6
 94 |     list_storage_class: type[list[t.Any]] = ImmutableList
 95 | 
 96 |     user_agent_class: type[UserAgent] = UserAgent
 97 |     """The class used and returned by the :attr:`user_agent` property to
 98 |     parse the header. Defaults to
 99 |     :class:`~werkzeug.user_agent.UserAgent`, which does no parsing. An
100 |     extension can provide a subclass that uses a parser to provide other
101 |     data.
102 | 
103 |     .. versionadded:: 2.0
104 |     """
105 | 
106 |     #: Valid host names when handling requests. By default all hosts are
107 |     #: trusted, which means that whatever the client says the host is
108 |     #: will be accepted.
109 |     #:
110 |     #: Because ``Host`` and ``X-Forwarded-Host`` headers can be set to
111 |     #: any value by a malicious client, it is recommended to either set
112 |     #: this property or implement similar validation in the proxy (if
113 |     #: the application is being run behind one).
114 |     #:
115 |     #: .. versionadded:: 0.9
116 |     trusted_hosts: list[str] | None = None
117 | 
118 |     def __init__(
119 |         self,
120 |         method: str,
121 |         scheme: str,
122 |         server: tuple[str, int | None] | None,
123 |         root_path: str,
124 |         path: str,
125 |         query_string: bytes,
126 |         headers: Headers,
127 |         remote_addr: str | None,
128 |     ) -> None:
129 |         #: The method the request was made with, such as ``GET``.
130 |         self.method = method.upper()
131 |         #: The URL scheme of the protocol the request used, such as
132 |         #: ``https`` or ``wss``.
133 |         self.scheme = scheme
134 |         #: The address of the server. ``(host, port)``, ``(path, None)``
135 |         #: for unix sockets, or ``None`` if not known.
136 |         self.server = server
137 |         #: The prefix that the application is mounted under, without a
138 |         #: trailing slash. :attr:`path` comes after this.
139 |         self.root_path = root_path.rstrip("/")
140 |         #: The path part of the URL after :attr:`root_path`. This is the
141 |         #: path used for routing within the application.
142 |         self.path = "/" + path.lstrip("/")
143 |         #: The part of the URL after the "?". This is the raw value, use
144 |         #: :attr:`args` for the parsed values.
145 |         self.query_string = query_string
146 |         #: The headers received with the request.
147 |         self.headers = headers
148 |         #: The address of the client sending the request.
149 |         self.remote_addr = remote_addr
150 | 
151 |     def __repr__(self) -> str:
152 |         try:
153 |             url = self.url
154 |         except Exception as e:
155 |             url = f"(invalid URL: {e})"
156 | 
157 |         return f"<{type(self).__name__} {url!r} [{self.method}]>"
158 | 
159 |     @cached_property
160 |     def args(self) -> MultiDict[str, str]:
161 |         """The parsed URL parameters (the part in the URL after the question
162 |         mark).
163 | 
164 |         By default an
165 |         :class:`~werkzeug.datastructures.ImmutableMultiDict`
166 |         is returned from this function.  This can be changed by setting
167 |         :attr:`parameter_storage_class` to a different type.  This might
168 |         be necessary if the order of the form data is important.
169 | 
170 |         .. versionchanged:: 2.3
171 |             Invalid bytes remain percent encoded.
172 |         """
173 |         return self.parameter_storage_class(
174 |             parse_qsl(
175 |                 self.query_string.decode(),
176 |                 keep_blank_values=True,
177 |                 errors="werkzeug.url_quote",
178 |             )
179 |         )
180 | 
181 |     @cached_property
182 |     def access_route(self) -> list[str]:
183 |         """If a forwarded header exists this is a list of all ip addresses
184 |         from the client ip to the last proxy server.
185 |         """
186 |         if "X-Forwarded-For" in self.headers:
187 |             return self.list_storage_class(
188 |                 parse_list_header(self.headers["X-Forwarded-For"])
189 |             )
190 |         elif self.remote_addr is not None:
191 |             return self.list_storage_class([self.remote_addr])
192 |         return self.list_storage_class()
193 | 
194 |     @cached_property
195 |     def full_path(self) -> str:
196 |         """Requested path, including the query string."""
197 |         return f"{self.path}?{self.query_string.decode()}"
198 | 
199 |     @property
200 |     def is_secure(self) -> bool:
201 |         """``True`` if the request was made with a secure protocol
202 |         (HTTPS or WSS).
203 |         """
204 |         return self.scheme in {"https", "wss"}
205 | 
206 |     @cached_property
207 |     def url(self) -> str:
208 |         """The full request URL with the scheme, host, root path, path,
209 |         and query string."""
210 |         return get_current_url(
211 |             self.scheme, self.host, self.root_path, self.path, self.query_string
212 |         )
213 | 
214 |     @cached_property
215 |     def base_url(self) -> str:
216 |         """Like :attr:`url` but without the query string."""
217 |         return get_current_url(self.scheme, self.host, self.root_path, self.path)
218 | 
219 |     @cached_property
220 |     def root_url(self) -> str:
221 |         """The request URL scheme, host, and root path. This is the root
222 |         that the application is accessed from.
223 |         """
224 |         return get_current_url(self.scheme, self.host, self.root_path)
225 | 
226 |     @cached_property
227 |     def host_url(self) -> str:
228 |         """The request URL scheme and host only."""
229 |         return get_current_url(self.scheme, self.host)
230 | 
231 |     @cached_property
232 |     def host(self) -> str:
233 |         """The host name the request was made to, including the port if
234 |         it's non-standard. Validated with :attr:`trusted_hosts`.
235 |         """
236 |         return get_host(
237 |             self.scheme, self.headers.get("host"), self.server, self.trusted_hosts
238 |         )
239 | 
240 |     @cached_property
241 |     def cookies(self) -> ImmutableMultiDict[str, str]:
242 |         """A :class:`dict` with the contents of all cookies transmitted with
243 |         the request."""
244 |         wsgi_combined_cookie = ";".join(self.headers.getlist("Cookie"))
245 |         return parse_cookie(  # type: ignore
246 |             wsgi_combined_cookie, cls=self.dict_storage_class
247 |         )
248 | 
249 |     # Common Descriptors
250 | 
251 |     content_type = header_property[str](
252 |         "Content-Type",
253 |         doc="""The Content-Type entity-header field indicates the media
254 |         type of the entity-body sent to the recipient or, in the case of
255 |         the HEAD method, the media type that would have been sent had
256 |         the request been a GET.""",
257 |         read_only=True,
258 |     )
259 | 
260 |     @cached_property
261 |     def content_length(self) -> int | None:
262 |         """The Content-Length entity-header field indicates the size of the
263 |         entity-body in bytes or, in the case of the HEAD method, the size of
264 |         the entity-body that would have been sent had the request been a
265 |         GET.
266 |         """
267 |         return get_content_length(
268 |             http_content_length=self.headers.get("Content-Length"),
269 |             http_transfer_encoding=self.headers.get("Transfer-Encoding"),
270 |         )
271 | 
272 |     content_encoding = header_property[str](
273 |         "Content-Encoding",
274 |         doc="""The Content-Encoding entity-header field is used as a
275 |         modifier to the media-type. When present, its value indicates
276 |         what additional content codings have been applied to the
277 |         entity-body, and thus what decoding mechanisms must be applied
278 |         in order to obtain the media-type referenced by the Content-Type
279 |         header field.
280 | 
281 |         .. versionadded:: 0.9""",
282 |         read_only=True,
283 |     )
284 |     content_md5 = header_property[str](
285 |         "Content-MD5",
286 |         doc="""The Content-MD5 entity-header field, as defined in
287 |         RFC 1864, is an MD5 digest of the entity-body for the purpose of
288 |         providing an end-to-end message integrity check (MIC) of the
289 |         entity-body. (Note: a MIC is good for detecting accidental
290 |         modification of the entity-body in transit, but is not proof
291 |         against malicious attacks.)
292 | 
293 |         .. versionadded:: 0.9""",
294 |         read_only=True,
295 |     )
296 |     referrer = header_property[str](
297 |         "Referer",
298 |         doc="""The Referer[sic] request-header field allows the client
299 |         to specify, for the server's benefit, the address (URI) of the
300 |         resource from which the Request-URI was obtained (the
301 |         "referrer", although the header field is misspelled).""",
302 |         read_only=True,
303 |     )
304 |     date = header_property(
305 |         "Date",
306 |         None,
307 |         parse_date,
308 |         doc="""The Date general-header field represents the date and
309 |         time at which the message was originated, having the same
310 |         semantics as orig-date in RFC 822.
311 | 
312 |         .. versionchanged:: 2.0
313 |             The datetime object is timezone-aware.
314 |         """,
315 |         read_only=True,
316 |     )
317 |     max_forwards = header_property(
318 |         "Max-Forwards",
319 |         None,
320 |         int,
321 |         doc="""The Max-Forwards request-header field provides a
322 |         mechanism with the TRACE and OPTIONS methods to limit the number
323 |         of proxies or gateways that can forward the request to the next
324 |         inbound server.""",
325 |         read_only=True,
326 |     )
327 | 
328 |     def _parse_content_type(self) -> None:
329 |         if not hasattr(self, "_parsed_content_type"):
330 |             self._parsed_content_type = parse_options_header(
331 |                 self.headers.get("Content-Type", "")
332 |             )
333 | 
334 |     @property
335 |     def mimetype(self) -> str:
336 |         """Like :attr:`content_type`, but without parameters (eg, without
337 |         charset, type etc.) and always lowercase.  For example if the content
338 |         type is ``text/HTML; charset=utf-8`` the mimetype would be
339 |         ``'text/html'``.
340 |         """
341 |         self._parse_content_type()
342 |         return self._parsed_content_type[0].lower()
343 | 
344 |     @property
345 |     def mimetype_params(self) -> dict[str, str]:
346 |         """The mimetype parameters as dict.  For example if the content
347 |         type is ``text/html; charset=utf-8`` the params would be
348 |         ``{'charset': 'utf-8'}``.
349 |         """
350 |         self._parse_content_type()
351 |         return self._parsed_content_type[1]
352 | 
353 |     @cached_property
354 |     def pragma(self) -> HeaderSet:
355 |         """The Pragma general-header field is used to include
356 |         implementation-specific directives that might apply to any recipient
357 |         along the request/response chain.  All pragma directives specify
358 |         optional behavior from the viewpoint of the protocol; however, some
359 |         systems MAY require that behavior be consistent with the directives.
360 |         """
361 |         return parse_set_header(self.headers.get("Pragma", ""))
362 | 
363 |     # Accept
364 | 
365 |     @cached_property
366 |     def accept_mimetypes(self) -> MIMEAccept:
367 |         """List of mimetypes this client supports as
368 |         :class:`~werkzeug.datastructures.MIMEAccept` object.
369 |         """
370 |         return parse_accept_header(self.headers.get("Accept"), MIMEAccept)
371 | 
372 |     @cached_property
373 |     def accept_charsets(self) -> CharsetAccept:
374 |         """List of charsets this client supports as
375 |         :class:`~werkzeug.datastructures.CharsetAccept` object.
376 |         """
377 |         return parse_accept_header(self.headers.get("Accept-Charset"), CharsetAccept)
378 | 
379 |     @cached_property
380 |     def accept_encodings(self) -> Accept:
381 |         """List of encodings this client accepts.  Encodings in a HTTP term
382 |         are compression encodings such as gzip.  For charsets have a look at
383 |         :attr:`accept_charset`.
384 |         """
385 |         return parse_accept_header(self.headers.get("Accept-Encoding"))
386 | 
387 |     @cached_property
388 |     def accept_languages(self) -> LanguageAccept:
389 |         """List of languages this client accepts as
390 |         :class:`~werkzeug.datastructures.LanguageAccept` object.
391 | 
392 |         .. versionchanged 0.5
393 |            In previous versions this was a regular
394 |            :class:`~werkzeug.datastructures.Accept` object.
395 |         """
396 |         return parse_accept_header(self.headers.get("Accept-Language"), LanguageAccept)
397 | 
398 |     # ETag
399 | 
400 |     @cached_property
401 |     def cache_control(self) -> RequestCacheControl:
402 |         """A :class:`~werkzeug.datastructures.RequestCacheControl` object
403 |         for the incoming cache control headers.
404 |         """
405 |         cache_control = self.headers.get("Cache-Control")
406 |         return parse_cache_control_header(cache_control, None, RequestCacheControl)
407 | 
408 |     @cached_property
409 |     def if_match(self) -> ETags:
410 |         """An object containing all the etags in the `If-Match` header.
411 | 
412 |         :rtype: :class:`~werkzeug.datastructures.ETags`
413 |         """
414 |         return parse_etags(self.headers.get("If-Match"))
415 | 
416 |     @cached_property
417 |     def if_none_match(self) -> ETags:
418 |         """An object containing all the etags in the `If-None-Match` header.
419 | 
420 |         :rtype: :class:`~werkzeug.datastructures.ETags`
421 |         """
422 |         return parse_etags(self.headers.get("If-None-Match"))
423 | 
424 |     @cached_property
425 |     def if_modified_since(self) -> datetime | None:
426 |         """The parsed `If-Modified-Since` header as a datetime object.
427 | 
428 |         .. versionchanged:: 2.0
429 |             The datetime object is timezone-aware.
430 |         """
431 |         return parse_date(self.headers.get("If-Modified-Since"))
432 | 
433 |     @cached_property
434 |     def if_unmodified_since(self) -> datetime | None:
435 |         """The parsed `If-Unmodified-Since` header as a datetime object.
436 | 
437 |         .. versionchanged:: 2.0
438 |             The datetime object is timezone-aware.
439 |         """
440 |         return parse_date(self.headers.get("If-Unmodified-Since"))
441 | 
442 |     @cached_property
443 |     def if_range(self) -> IfRange:
444 |         """The parsed ``If-Range`` header.
445 | 
446 |         .. versionchanged:: 2.0
447 |             ``IfRange.date`` is timezone-aware.
448 | 
449 |         .. versionadded:: 0.7
450 |         """
451 |         return parse_if_range_header(self.headers.get("If-Range"))
452 | 
453 |     @cached_property
454 |     def range(self) -> Range | None:
455 |         """The parsed `Range` header.
456 | 
457 |         .. versionadded:: 0.7
458 | 
459 |         :rtype: :class:`~werkzeug.datastructures.Range`
460 |         """
461 |         return parse_range_header(self.headers.get("Range"))
462 | 
463 |     # User Agent
464 | 
465 |     @cached_property
466 |     def user_agent(self) -> UserAgent:
467 |         """The user agent. Use ``user_agent.string`` to get the header
468 |         value. Set :attr:`user_agent_class` to a subclass of
469 |         :class:`~werkzeug.user_agent.UserAgent` to provide parsing for
470 |         the other properties or other extended data.
471 | 
472 |         .. versionchanged:: 2.1
473 |             The built-in parser was removed. Set ``user_agent_class`` to a ``UserAgent``
474 |             subclass to parse data from the string.
475 |         """
476 |         return self.user_agent_class(self.headers.get("User-Agent", ""))
477 | 
478 |     # Authorization
479 | 
480 |     @cached_property
481 |     def authorization(self) -> Authorization | None:
482 |         """The ``Authorization`` header parsed into an :class:`.Authorization` object.
483 |         ``None`` if the header is not present.
484 | 
485 |         .. versionchanged:: 2.3
486 |             :class:`Authorization` is no longer a ``dict``. The ``token`` attribute
487 |             was added for auth schemes that use a token instead of parameters.
488 |         """
489 |         return Authorization.from_header(self.headers.get("Authorization"))
490 | 
491 |     # CORS
492 | 
493 |     origin = header_property[str](
494 |         "Origin",
495 |         doc=(
496 |             "The host that the request originated from. Set"
497 |             " :attr:`~CORSResponseMixin.access_control_allow_origin` on"
498 |             " the response to indicate which origins are allowed."
499 |         ),
500 |         read_only=True,
501 |     )
502 | 
503 |     access_control_request_headers = header_property(
504 |         "Access-Control-Request-Headers",
505 |         load_func=parse_set_header,
506 |         doc=(
507 |             "Sent with a preflight request to indicate which headers"
508 |             " will be sent with the cross origin request. Set"
509 |             " :attr:`~CORSResponseMixin.access_control_allow_headers`"
510 |             " on the response to indicate which headers are allowed."
511 |         ),
512 |         read_only=True,
513 |     )
514 | 
515 |     access_control_request_method = header_property[str](
516 |         "Access-Control-Request-Method",
517 |         doc=(
518 |             "Sent with a preflight request to indicate which method"
519 |             " will be used for the cross origin request. Set"
520 |             " :attr:`~CORSResponseMixin.access_control_allow_methods`"
521 |             " on the response to indicate which methods are allowed."
522 |         ),
523 |         read_only=True,
524 |     )
525 | 
526 |     @property
527 |     def is_json(self) -> bool:
528 |         """Check if the mimetype indicates JSON data, either
529 |         :mimetype:`application/json` or :mimetype:`application/*+json`.
530 |         """
531 |         mt = self.mimetype
532 |         return (
533 |             mt == "application/json"
534 |             or mt.startswith("application/")
535 |             and mt.endswith("+json")
536 |         )
537 | 
```

--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/poolmanager.py:
--------------------------------------------------------------------------------

```python
  1 | from __future__ import absolute_import
  2 | 
  3 | import collections
  4 | import functools
  5 | import logging
  6 | 
  7 | from ._collections import HTTPHeaderDict, RecentlyUsedContainer
  8 | from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool, port_by_scheme
  9 | from .exceptions import (
 10 |     LocationValueError,
 11 |     MaxRetryError,
 12 |     ProxySchemeUnknown,
 13 |     ProxySchemeUnsupported,
 14 |     URLSchemeUnknown,
 15 | )
 16 | from .packages import six
 17 | from .packages.six.moves.urllib.parse import urljoin
 18 | from .request import RequestMethods
 19 | from .util.proxy import connection_requires_http_tunnel
 20 | from .util.retry import Retry
 21 | from .util.url import parse_url
 22 | 
 23 | __all__ = ["PoolManager", "ProxyManager", "proxy_from_url"]
 24 | 
 25 | 
 26 | log = logging.getLogger(__name__)
 27 | 
 28 | SSL_KEYWORDS = (
 29 |     "key_file",
 30 |     "cert_file",
 31 |     "cert_reqs",
 32 |     "ca_certs",
 33 |     "ssl_version",
 34 |     "ca_cert_dir",
 35 |     "ssl_context",
 36 |     "key_password",
 37 |     "server_hostname",
 38 | )
 39 | 
 40 | # All known keyword arguments that could be provided to the pool manager, its
 41 | # pools, or the underlying connections. This is used to construct a pool key.
 42 | _key_fields = (
 43 |     "key_scheme",  # str
 44 |     "key_host",  # str
 45 |     "key_port",  # int
 46 |     "key_timeout",  # int or float or Timeout
 47 |     "key_retries",  # int or Retry
 48 |     "key_strict",  # bool
 49 |     "key_block",  # bool
 50 |     "key_source_address",  # str
 51 |     "key_key_file",  # str
 52 |     "key_key_password",  # str
 53 |     "key_cert_file",  # str
 54 |     "key_cert_reqs",  # str
 55 |     "key_ca_certs",  # str
 56 |     "key_ssl_version",  # str
 57 |     "key_ca_cert_dir",  # str
 58 |     "key_ssl_context",  # instance of ssl.SSLContext or urllib3.util.ssl_.SSLContext
 59 |     "key_maxsize",  # int
 60 |     "key_headers",  # dict
 61 |     "key__proxy",  # parsed proxy url
 62 |     "key__proxy_headers",  # dict
 63 |     "key__proxy_config",  # class
 64 |     "key_socket_options",  # list of (level (int), optname (int), value (int or str)) tuples
 65 |     "key__socks_options",  # dict
 66 |     "key_assert_hostname",  # bool or string
 67 |     "key_assert_fingerprint",  # str
 68 |     "key_server_hostname",  # str
 69 | )
 70 | 
 71 | #: The namedtuple class used to construct keys for the connection pool.
 72 | #: All custom key schemes should include the fields in this key at a minimum.
 73 | PoolKey = collections.namedtuple("PoolKey", _key_fields)
 74 | 
 75 | _proxy_config_fields = ("ssl_context", "use_forwarding_for_https")
 76 | ProxyConfig = collections.namedtuple("ProxyConfig", _proxy_config_fields)
 77 | 
 78 | 
 79 | def _default_key_normalizer(key_class, request_context):
 80 |     """
 81 |     Create a pool key out of a request context dictionary.
 82 | 
 83 |     According to RFC 3986, both the scheme and host are case-insensitive.
 84 |     Therefore, this function normalizes both before constructing the pool
 85 |     key for an HTTPS request. If you wish to change this behaviour, provide
 86 |     alternate callables to ``key_fn_by_scheme``.
 87 | 
 88 |     :param key_class:
 89 |         The class to use when constructing the key. This should be a namedtuple
 90 |         with the ``scheme`` and ``host`` keys at a minimum.
 91 |     :type  key_class: namedtuple
 92 |     :param request_context:
 93 |         A dictionary-like object that contain the context for a request.
 94 |     :type  request_context: dict
 95 | 
 96 |     :return: A namedtuple that can be used as a connection pool key.
 97 |     :rtype:  PoolKey
 98 |     """
 99 |     # Since we mutate the dictionary, make a copy first
100 |     context = request_context.copy()
101 |     context["scheme"] = context["scheme"].lower()
102 |     context["host"] = context["host"].lower()
103 | 
104 |     # These are both dictionaries and need to be transformed into frozensets
105 |     for key in ("headers", "_proxy_headers", "_socks_options"):
106 |         if key in context and context[key] is not None:
107 |             context[key] = frozenset(context[key].items())
108 | 
109 |     # The socket_options key may be a list and needs to be transformed into a
110 |     # tuple.
111 |     socket_opts = context.get("socket_options")
112 |     if socket_opts is not None:
113 |         context["socket_options"] = tuple(socket_opts)
114 | 
115 |     # Map the kwargs to the names in the namedtuple - this is necessary since
116 |     # namedtuples can't have fields starting with '_'.
117 |     for key in list(context.keys()):
118 |         context["key_" + key] = context.pop(key)
119 | 
120 |     # Default to ``None`` for keys missing from the context
121 |     for field in key_class._fields:
122 |         if field not in context:
123 |             context[field] = None
124 | 
125 |     return key_class(**context)
126 | 
127 | 
128 | #: A dictionary that maps a scheme to a callable that creates a pool key.
129 | #: This can be used to alter the way pool keys are constructed, if desired.
130 | #: Each PoolManager makes a copy of this dictionary so they can be configured
131 | #: globally here, or individually on the instance.
132 | key_fn_by_scheme = {
133 |     "http": functools.partial(_default_key_normalizer, PoolKey),
134 |     "https": functools.partial(_default_key_normalizer, PoolKey),
135 | }
136 | 
137 | pool_classes_by_scheme = {"http": HTTPConnectionPool, "https": HTTPSConnectionPool}
138 | 
139 | 
140 | class PoolManager(RequestMethods):
141 |     """
142 |     Allows for arbitrary requests while transparently keeping track of
143 |     necessary connection pools for you.
144 | 
145 |     :param num_pools:
146 |         Number of connection pools to cache before discarding the least
147 |         recently used pool.
148 | 
149 |     :param headers:
150 |         Headers to include with all requests, unless other headers are given
151 |         explicitly.
152 | 
153 |     :param \\**connection_pool_kw:
154 |         Additional parameters are used to create fresh
155 |         :class:`urllib3.connectionpool.ConnectionPool` instances.
156 | 
157 |     Example::
158 | 
159 |         >>> manager = PoolManager(num_pools=2)
160 |         >>> r = manager.request('GET', 'http://google.com/')
161 |         >>> r = manager.request('GET', 'http://google.com/mail')
162 |         >>> r = manager.request('GET', 'http://yahoo.com/')
163 |         >>> len(manager.pools)
164 |         2
165 | 
166 |     """
167 | 
168 |     proxy = None
169 |     proxy_config = None
170 | 
171 |     def __init__(self, num_pools=10, headers=None, **connection_pool_kw):
172 |         RequestMethods.__init__(self, headers)
173 |         self.connection_pool_kw = connection_pool_kw
174 |         self.pools = RecentlyUsedContainer(num_pools)
175 | 
176 |         # Locally set the pool classes and keys so other PoolManagers can
177 |         # override them.
178 |         self.pool_classes_by_scheme = pool_classes_by_scheme
179 |         self.key_fn_by_scheme = key_fn_by_scheme.copy()
180 | 
181 |     def __enter__(self):
182 |         return self
183 | 
184 |     def __exit__(self, exc_type, exc_val, exc_tb):
185 |         self.clear()
186 |         # Return False to re-raise any potential exceptions
187 |         return False
188 | 
189 |     def _new_pool(self, scheme, host, port, request_context=None):
190 |         """
191 |         Create a new :class:`urllib3.connectionpool.ConnectionPool` based on host, port, scheme, and
192 |         any additional pool keyword arguments.
193 | 
194 |         If ``request_context`` is provided, it is provided as keyword arguments
195 |         to the pool class used. This method is used to actually create the
196 |         connection pools handed out by :meth:`connection_from_url` and
197 |         companion methods. It is intended to be overridden for customization.
198 |         """
199 |         pool_cls = self.pool_classes_by_scheme[scheme]
200 |         if request_context is None:
201 |             request_context = self.connection_pool_kw.copy()
202 | 
203 |         # Although the context has everything necessary to create the pool,
204 |         # this function has historically only used the scheme, host, and port
205 |         # in the positional args. When an API change is acceptable these can
206 |         # be removed.
207 |         for key in ("scheme", "host", "port"):
208 |             request_context.pop(key, None)
209 | 
210 |         if scheme == "http":
211 |             for kw in SSL_KEYWORDS:
212 |                 request_context.pop(kw, None)
213 | 
214 |         return pool_cls(host, port, **request_context)
215 | 
216 |     def clear(self):
217 |         """
218 |         Empty our store of pools and direct them all to close.
219 | 
220 |         This will not affect in-flight connections, but they will not be
221 |         re-used after completion.
222 |         """
223 |         self.pools.clear()
224 | 
225 |     def connection_from_host(self, host, port=None, scheme="http", pool_kwargs=None):
226 |         """
227 |         Get a :class:`urllib3.connectionpool.ConnectionPool` based on the host, port, and scheme.
228 | 
229 |         If ``port`` isn't given, it will be derived from the ``scheme`` using
230 |         ``urllib3.connectionpool.port_by_scheme``. If ``pool_kwargs`` is
231 |         provided, it is merged with the instance's ``connection_pool_kw``
232 |         variable and used to create the new connection pool, if one is
233 |         needed.
234 |         """
235 | 
236 |         if not host:
237 |             raise LocationValueError("No host specified.")
238 | 
239 |         request_context = self._merge_pool_kwargs(pool_kwargs)
240 |         request_context["scheme"] = scheme or "http"
241 |         if not port:
242 |             port = port_by_scheme.get(request_context["scheme"].lower(), 80)
243 |         request_context["port"] = port
244 |         request_context["host"] = host
245 | 
246 |         return self.connection_from_context(request_context)
247 | 
248 |     def connection_from_context(self, request_context):
249 |         """
250 |         Get a :class:`urllib3.connectionpool.ConnectionPool` based on the request context.
251 | 
252 |         ``request_context`` must at least contain the ``scheme`` key and its
253 |         value must be a key in ``key_fn_by_scheme`` instance variable.
254 |         """
255 |         scheme = request_context["scheme"].lower()
256 |         pool_key_constructor = self.key_fn_by_scheme.get(scheme)
257 |         if not pool_key_constructor:
258 |             raise URLSchemeUnknown(scheme)
259 |         pool_key = pool_key_constructor(request_context)
260 | 
261 |         return self.connection_from_pool_key(pool_key, request_context=request_context)
262 | 
263 |     def connection_from_pool_key(self, pool_key, request_context=None):
264 |         """
265 |         Get a :class:`urllib3.connectionpool.ConnectionPool` based on the provided pool key.
266 | 
267 |         ``pool_key`` should be a namedtuple that only contains immutable
268 |         objects. At a minimum it must have the ``scheme``, ``host``, and
269 |         ``port`` fields.
270 |         """
271 |         with self.pools.lock:
272 |             # If the scheme, host, or port doesn't match existing open
273 |             # connections, open a new ConnectionPool.
274 |             pool = self.pools.get(pool_key)
275 |             if pool:
276 |                 return pool
277 | 
278 |             # Make a fresh ConnectionPool of the desired type
279 |             scheme = request_context["scheme"]
280 |             host = request_context["host"]
281 |             port = request_context["port"]
282 |             pool = self._new_pool(scheme, host, port, request_context=request_context)
283 |             self.pools[pool_key] = pool
284 | 
285 |         return pool
286 | 
287 |     def connection_from_url(self, url, pool_kwargs=None):
288 |         """
289 |         Similar to :func:`urllib3.connectionpool.connection_from_url`.
290 | 
291 |         If ``pool_kwargs`` is not provided and a new pool needs to be
292 |         constructed, ``self.connection_pool_kw`` is used to initialize
293 |         the :class:`urllib3.connectionpool.ConnectionPool`. If ``pool_kwargs``
294 |         is provided, it is used instead. Note that if a new pool does not
295 |         need to be created for the request, the provided ``pool_kwargs`` are
296 |         not used.
297 |         """
298 |         u = parse_url(url)
299 |         return self.connection_from_host(
300 |             u.host, port=u.port, scheme=u.scheme, pool_kwargs=pool_kwargs
301 |         )
302 | 
303 |     def _merge_pool_kwargs(self, override):
304 |         """
305 |         Merge a dictionary of override values for self.connection_pool_kw.
306 | 
307 |         This does not modify self.connection_pool_kw and returns a new dict.
308 |         Any keys in the override dictionary with a value of ``None`` are
309 |         removed from the merged dictionary.
310 |         """
311 |         base_pool_kwargs = self.connection_pool_kw.copy()
312 |         if override:
313 |             for key, value in override.items():
314 |                 if value is None:
315 |                     try:
316 |                         del base_pool_kwargs[key]
317 |                     except KeyError:
318 |                         pass
319 |                 else:
320 |                     base_pool_kwargs[key] = value
321 |         return base_pool_kwargs
322 | 
323 |     def _proxy_requires_url_absolute_form(self, parsed_url):
324 |         """
325 |         Indicates if the proxy requires the complete destination URL in the
326 |         request.  Normally this is only needed when not using an HTTP CONNECT
327 |         tunnel.
328 |         """
329 |         if self.proxy is None:
330 |             return False
331 | 
332 |         return not connection_requires_http_tunnel(
333 |             self.proxy, self.proxy_config, parsed_url.scheme
334 |         )
335 | 
336 |     def _validate_proxy_scheme_url_selection(self, url_scheme):
337 |         """
338 |         Validates that were not attempting to do TLS in TLS connections on
339 |         Python2 or with unsupported SSL implementations.
340 |         """
341 |         if self.proxy is None or url_scheme != "https":
342 |             return
343 | 
344 |         if self.proxy.scheme != "https":
345 |             return
346 | 
347 |         if six.PY2 and not self.proxy_config.use_forwarding_for_https:
348 |             raise ProxySchemeUnsupported(
349 |                 "Contacting HTTPS destinations through HTTPS proxies "
350 |                 "'via CONNECT tunnels' is not supported in Python 2"
351 |             )
352 | 
353 |     def urlopen(self, method, url, redirect=True, **kw):
354 |         """
355 |         Same as :meth:`urllib3.HTTPConnectionPool.urlopen`
356 |         with custom cross-host redirect logic and only sends the request-uri
357 |         portion of the ``url``.
358 | 
359 |         The given ``url`` parameter must be absolute, such that an appropriate
360 |         :class:`urllib3.connectionpool.ConnectionPool` can be chosen for it.
361 |         """
362 |         u = parse_url(url)
363 |         self._validate_proxy_scheme_url_selection(u.scheme)
364 | 
365 |         conn = self.connection_from_host(u.host, port=u.port, scheme=u.scheme)
366 | 
367 |         kw["assert_same_host"] = False
368 |         kw["redirect"] = False
369 | 
370 |         if "headers" not in kw:
371 |             kw["headers"] = self.headers.copy()
372 | 
373 |         if self._proxy_requires_url_absolute_form(u):
374 |             response = conn.urlopen(method, url, **kw)
375 |         else:
376 |             response = conn.urlopen(method, u.request_uri, **kw)
377 | 
378 |         redirect_location = redirect and response.get_redirect_location()
379 |         if not redirect_location:
380 |             return response
381 | 
382 |         # Support relative URLs for redirecting.
383 |         redirect_location = urljoin(url, redirect_location)
384 | 
385 |         if response.status == 303:
386 |             # Change the method according to RFC 9110, Section 15.4.4.
387 |             method = "GET"
388 |             # And lose the body not to transfer anything sensitive.
389 |             kw["body"] = None
390 |             kw["headers"] = HTTPHeaderDict(kw["headers"])._prepare_for_method_change()
391 | 
392 |         retries = kw.get("retries")
393 |         if not isinstance(retries, Retry):
394 |             retries = Retry.from_int(retries, redirect=redirect)
395 | 
396 |         # Strip headers marked as unsafe to forward to the redirected location.
397 |         # Check remove_headers_on_redirect to avoid a potential network call within
398 |         # conn.is_same_host() which may use socket.gethostbyname() in the future.
399 |         if retries.remove_headers_on_redirect and not conn.is_same_host(
400 |             redirect_location
401 |         ):
402 |             headers = list(six.iterkeys(kw["headers"]))
403 |             for header in headers:
404 |                 if header.lower() in retries.remove_headers_on_redirect:
405 |                     kw["headers"].pop(header, None)
406 | 
407 |         try:
408 |             retries = retries.increment(method, url, response=response, _pool=conn)
409 |         except MaxRetryError:
410 |             if retries.raise_on_redirect:
411 |                 response.drain_conn()
412 |                 raise
413 |             return response
414 | 
415 |         kw["retries"] = retries
416 |         kw["redirect"] = redirect
417 | 
418 |         log.info("Redirecting %s -> %s", url, redirect_location)
419 | 
420 |         response.drain_conn()
421 |         return self.urlopen(method, redirect_location, **kw)
422 | 
423 | 
424 | class ProxyManager(PoolManager):
425 |     """
426 |     Behaves just like :class:`PoolManager`, but sends all requests through
427 |     the defined proxy, using the CONNECT method for HTTPS URLs.
428 | 
429 |     :param proxy_url:
430 |         The URL of the proxy to be used.
431 | 
432 |     :param proxy_headers:
433 |         A dictionary containing headers that will be sent to the proxy. In case
434 |         of HTTP they are being sent with each request, while in the
435 |         HTTPS/CONNECT case they are sent only once. Could be used for proxy
436 |         authentication.
437 | 
438 |     :param proxy_ssl_context:
439 |         The proxy SSL context is used to establish the TLS connection to the
440 |         proxy when using HTTPS proxies.
441 | 
442 |     :param use_forwarding_for_https:
443 |         (Defaults to False) If set to True will forward requests to the HTTPS
444 |         proxy to be made on behalf of the client instead of creating a TLS
445 |         tunnel via the CONNECT method. **Enabling this flag means that request
446 |         and response headers and content will be visible from the HTTPS proxy**
447 |         whereas tunneling keeps request and response headers and content
448 |         private.  IP address, target hostname, SNI, and port are always visible
449 |         to an HTTPS proxy even when this flag is disabled.
450 | 
451 |     Example:
452 |         >>> proxy = urllib3.ProxyManager('http://localhost:3128/')
453 |         >>> r1 = proxy.request('GET', 'http://google.com/')
454 |         >>> r2 = proxy.request('GET', 'http://httpbin.org/')
455 |         >>> len(proxy.pools)
456 |         1
457 |         >>> r3 = proxy.request('GET', 'https://httpbin.org/')
458 |         >>> r4 = proxy.request('GET', 'https://twitter.com/')
459 |         >>> len(proxy.pools)
460 |         3
461 | 
462 |     """
463 | 
464 |     def __init__(
465 |         self,
466 |         proxy_url,
467 |         num_pools=10,
468 |         headers=None,
469 |         proxy_headers=None,
470 |         proxy_ssl_context=None,
471 |         use_forwarding_for_https=False,
472 |         **connection_pool_kw
473 |     ):
474 | 
475 |         if isinstance(proxy_url, HTTPConnectionPool):
476 |             proxy_url = "%s://%s:%i" % (
477 |                 proxy_url.scheme,
478 |                 proxy_url.host,
479 |                 proxy_url.port,
480 |             )
481 |         proxy = parse_url(proxy_url)
482 | 
483 |         if proxy.scheme not in ("http", "https"):
484 |             raise ProxySchemeUnknown(proxy.scheme)
485 | 
486 |         if not proxy.port:
487 |             port = port_by_scheme.get(proxy.scheme, 80)
488 |             proxy = proxy._replace(port=port)
489 | 
490 |         self.proxy = proxy
491 |         self.proxy_headers = proxy_headers or {}
492 |         self.proxy_ssl_context = proxy_ssl_context
493 |         self.proxy_config = ProxyConfig(proxy_ssl_context, use_forwarding_for_https)
494 | 
495 |         connection_pool_kw["_proxy"] = self.proxy
496 |         connection_pool_kw["_proxy_headers"] = self.proxy_headers
497 |         connection_pool_kw["_proxy_config"] = self.proxy_config
498 | 
499 |         super(ProxyManager, self).__init__(num_pools, headers, **connection_pool_kw)
500 | 
501 |     def connection_from_host(self, host, port=None, scheme="http", pool_kwargs=None):
502 |         if scheme == "https":
503 |             return super(ProxyManager, self).connection_from_host(
504 |                 host, port, scheme, pool_kwargs=pool_kwargs
505 |             )
506 | 
507 |         return super(ProxyManager, self).connection_from_host(
508 |             self.proxy.host, self.proxy.port, self.proxy.scheme, pool_kwargs=pool_kwargs
509 |         )
510 | 
511 |     def _set_proxy_headers(self, url, headers=None):
512 |         """
513 |         Sets headers needed by proxies: specifically, the Accept and Host
514 |         headers. Only sets headers not provided by the user.
515 |         """
516 |         headers_ = {"Accept": "*/*"}
517 | 
518 |         netloc = parse_url(url).netloc
519 |         if netloc:
520 |             headers_["Host"] = netloc
521 | 
522 |         if headers:
523 |             headers_.update(headers)
524 |         return headers_
525 | 
526 |     def urlopen(self, method, url, redirect=True, **kw):
527 |         "Same as HTTP(S)ConnectionPool.urlopen, ``url`` must be absolute."
528 |         u = parse_url(url)
529 |         if not connection_requires_http_tunnel(self.proxy, self.proxy_config, u.scheme):
530 |             # For connections using HTTP CONNECT, httplib sets the necessary
531 |             # headers on the CONNECT to the proxy. If we're not using CONNECT,
532 |             # we'll definitely need to set 'Host' at the very least.
533 |             headers = kw.get("headers", self.headers)
534 |             kw["headers"] = self._set_proxy_headers(url, headers)
535 | 
536 |         return super(ProxyManager, self).urlopen(method, url, redirect=redirect, **kw)
537 | 
538 | 
539 | def proxy_from_url(url, **kw):
540 |     return ProxyManager(proxy_url=url, **kw)
541 | 
```
Page 68/168FirstPrevNextLast