This is page 87 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/requests/adapters.py:
--------------------------------------------------------------------------------
```python
1 | """
2 | requests.adapters
3 | ~~~~~~~~~~~~~~~~~
4 |
5 | This module contains the transport adapters that Requests uses to define
6 | and maintain connections.
7 | """
8 |
9 | import os.path
10 | import socket # noqa: F401
11 | import typing
12 | import warnings
13 |
14 | from urllib3.exceptions import ClosedPoolError, ConnectTimeoutError
15 | from urllib3.exceptions import HTTPError as _HTTPError
16 | from urllib3.exceptions import InvalidHeader as _InvalidHeader
17 | from urllib3.exceptions import (
18 | LocationValueError,
19 | MaxRetryError,
20 | NewConnectionError,
21 | ProtocolError,
22 | )
23 | from urllib3.exceptions import ProxyError as _ProxyError
24 | from urllib3.exceptions import ReadTimeoutError, ResponseError
25 | from urllib3.exceptions import SSLError as _SSLError
26 | from urllib3.poolmanager import PoolManager, proxy_from_url
27 | from urllib3.util import Timeout as TimeoutSauce
28 | from urllib3.util import parse_url
29 | from urllib3.util.retry import Retry
30 | from urllib3.util.ssl_ import create_urllib3_context
31 |
32 | from .auth import _basic_auth_str
33 | from .compat import basestring, urlparse
34 | from .cookies import extract_cookies_to_jar
35 | from .exceptions import (
36 | ConnectionError,
37 | ConnectTimeout,
38 | InvalidHeader,
39 | InvalidProxyURL,
40 | InvalidSchema,
41 | InvalidURL,
42 | ProxyError,
43 | ReadTimeout,
44 | RetryError,
45 | SSLError,
46 | )
47 | from .models import Response
48 | from .structures import CaseInsensitiveDict
49 | from .utils import (
50 | DEFAULT_CA_BUNDLE_PATH,
51 | extract_zipped_paths,
52 | get_auth_from_url,
53 | get_encoding_from_headers,
54 | prepend_scheme_if_needed,
55 | select_proxy,
56 | urldefragauth,
57 | )
58 |
59 | try:
60 | from urllib3.contrib.socks import SOCKSProxyManager
61 | except ImportError:
62 |
63 | def SOCKSProxyManager(*args, **kwargs):
64 | raise InvalidSchema("Missing dependencies for SOCKS support.")
65 |
66 |
67 | if typing.TYPE_CHECKING:
68 | from .models import PreparedRequest
69 |
70 |
71 | DEFAULT_POOLBLOCK = False
72 | DEFAULT_POOLSIZE = 10
73 | DEFAULT_RETRIES = 0
74 | DEFAULT_POOL_TIMEOUT = None
75 |
76 |
77 | try:
78 | import ssl # noqa: F401
79 |
80 | _preloaded_ssl_context = create_urllib3_context()
81 | _preloaded_ssl_context.load_verify_locations(
82 | extract_zipped_paths(DEFAULT_CA_BUNDLE_PATH)
83 | )
84 | except ImportError:
85 | # Bypass default SSLContext creation when Python
86 | # interpreter isn't built with the ssl module.
87 | _preloaded_ssl_context = None
88 |
89 |
90 | def _urllib3_request_context(
91 | request: "PreparedRequest",
92 | verify: "bool | str | None",
93 | client_cert: "typing.Tuple[str, str] | str | None",
94 | poolmanager: "PoolManager",
95 | ) -> "(typing.Dict[str, typing.Any], typing.Dict[str, typing.Any])":
96 | host_params = {}
97 | pool_kwargs = {}
98 | parsed_request_url = urlparse(request.url)
99 | scheme = parsed_request_url.scheme.lower()
100 | port = parsed_request_url.port
101 |
102 | # Determine if we have and should use our default SSLContext
103 | # to optimize performance on standard requests.
104 | poolmanager_kwargs = getattr(poolmanager, "connection_pool_kw", {})
105 | has_poolmanager_ssl_context = poolmanager_kwargs.get("ssl_context")
106 | should_use_default_ssl_context = (
107 | _preloaded_ssl_context is not None and not has_poolmanager_ssl_context
108 | )
109 |
110 | cert_reqs = "CERT_REQUIRED"
111 | if verify is False:
112 | cert_reqs = "CERT_NONE"
113 | elif verify is True and should_use_default_ssl_context:
114 | pool_kwargs["ssl_context"] = _preloaded_ssl_context
115 | elif isinstance(verify, str):
116 | if not os.path.isdir(verify):
117 | pool_kwargs["ca_certs"] = verify
118 | else:
119 | pool_kwargs["ca_cert_dir"] = verify
120 | pool_kwargs["cert_reqs"] = cert_reqs
121 | if client_cert is not None:
122 | if isinstance(client_cert, tuple) and len(client_cert) == 2:
123 | pool_kwargs["cert_file"] = client_cert[0]
124 | pool_kwargs["key_file"] = client_cert[1]
125 | else:
126 | # According to our docs, we allow users to specify just the client
127 | # cert path
128 | pool_kwargs["cert_file"] = client_cert
129 | host_params = {
130 | "scheme": scheme,
131 | "host": parsed_request_url.hostname,
132 | "port": port,
133 | }
134 | return host_params, pool_kwargs
135 |
136 |
137 | class BaseAdapter:
138 | """The Base Transport Adapter"""
139 |
140 | def __init__(self):
141 | super().__init__()
142 |
143 | def send(
144 | self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None
145 | ):
146 | """Sends PreparedRequest object. Returns Response object.
147 |
148 | :param request: The :class:`PreparedRequest <PreparedRequest>` being sent.
149 | :param stream: (optional) Whether to stream the request content.
150 | :param timeout: (optional) How long to wait for the server to send
151 | data before giving up, as a float, or a :ref:`(connect timeout,
152 | read timeout) <timeouts>` tuple.
153 | :type timeout: float or tuple
154 | :param verify: (optional) Either a boolean, in which case it controls whether we verify
155 | the server's TLS certificate, or a string, in which case it must be a path
156 | to a CA bundle to use
157 | :param cert: (optional) Any user-provided SSL certificate to be trusted.
158 | :param proxies: (optional) The proxies dictionary to apply to the request.
159 | """
160 | raise NotImplementedError
161 |
162 | def close(self):
163 | """Cleans up adapter specific items."""
164 | raise NotImplementedError
165 |
166 |
167 | class HTTPAdapter(BaseAdapter):
168 | """The built-in HTTP Adapter for urllib3.
169 |
170 | Provides a general-case interface for Requests sessions to contact HTTP and
171 | HTTPS urls by implementing the Transport Adapter interface. This class will
172 | usually be created by the :class:`Session <Session>` class under the
173 | covers.
174 |
175 | :param pool_connections: The number of urllib3 connection pools to cache.
176 | :param pool_maxsize: The maximum number of connections to save in the pool.
177 | :param max_retries: The maximum number of retries each connection
178 | should attempt. Note, this applies only to failed DNS lookups, socket
179 | connections and connection timeouts, never to requests where data has
180 | made it to the server. By default, Requests does not retry failed
181 | connections. If you need granular control over the conditions under
182 | which we retry a request, import urllib3's ``Retry`` class and pass
183 | that instead.
184 | :param pool_block: Whether the connection pool should block for connections.
185 |
186 | Usage::
187 |
188 | >>> import requests
189 | >>> s = requests.Session()
190 | >>> a = requests.adapters.HTTPAdapter(max_retries=3)
191 | >>> s.mount('http://', a)
192 | """
193 |
194 | __attrs__ = [
195 | "max_retries",
196 | "config",
197 | "_pool_connections",
198 | "_pool_maxsize",
199 | "_pool_block",
200 | ]
201 |
202 | def __init__(
203 | self,
204 | pool_connections=DEFAULT_POOLSIZE,
205 | pool_maxsize=DEFAULT_POOLSIZE,
206 | max_retries=DEFAULT_RETRIES,
207 | pool_block=DEFAULT_POOLBLOCK,
208 | ):
209 | if max_retries == DEFAULT_RETRIES:
210 | self.max_retries = Retry(0, read=False)
211 | else:
212 | self.max_retries = Retry.from_int(max_retries)
213 | self.config = {}
214 | self.proxy_manager = {}
215 |
216 | super().__init__()
217 |
218 | self._pool_connections = pool_connections
219 | self._pool_maxsize = pool_maxsize
220 | self._pool_block = pool_block
221 |
222 | self.init_poolmanager(pool_connections, pool_maxsize, block=pool_block)
223 |
224 | def __getstate__(self):
225 | return {attr: getattr(self, attr, None) for attr in self.__attrs__}
226 |
227 | def __setstate__(self, state):
228 | # Can't handle by adding 'proxy_manager' to self.__attrs__ because
229 | # self.poolmanager uses a lambda function, which isn't pickleable.
230 | self.proxy_manager = {}
231 | self.config = {}
232 |
233 | for attr, value in state.items():
234 | setattr(self, attr, value)
235 |
236 | self.init_poolmanager(
237 | self._pool_connections, self._pool_maxsize, block=self._pool_block
238 | )
239 |
240 | def init_poolmanager(
241 | self, connections, maxsize, block=DEFAULT_POOLBLOCK, **pool_kwargs
242 | ):
243 | """Initializes a urllib3 PoolManager.
244 |
245 | This method should not be called from user code, and is only
246 | exposed for use when subclassing the
247 | :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
248 |
249 | :param connections: The number of urllib3 connection pools to cache.
250 | :param maxsize: The maximum number of connections to save in the pool.
251 | :param block: Block when no free connections are available.
252 | :param pool_kwargs: Extra keyword arguments used to initialize the Pool Manager.
253 | """
254 | # save these values for pickling
255 | self._pool_connections = connections
256 | self._pool_maxsize = maxsize
257 | self._pool_block = block
258 |
259 | self.poolmanager = PoolManager(
260 | num_pools=connections,
261 | maxsize=maxsize,
262 | block=block,
263 | **pool_kwargs,
264 | )
265 |
266 | def proxy_manager_for(self, proxy, **proxy_kwargs):
267 | """Return urllib3 ProxyManager for the given proxy.
268 |
269 | This method should not be called from user code, and is only
270 | exposed for use when subclassing the
271 | :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
272 |
273 | :param proxy: The proxy to return a urllib3 ProxyManager for.
274 | :param proxy_kwargs: Extra keyword arguments used to configure the Proxy Manager.
275 | :returns: ProxyManager
276 | :rtype: urllib3.ProxyManager
277 | """
278 | if proxy in self.proxy_manager:
279 | manager = self.proxy_manager[proxy]
280 | elif proxy.lower().startswith("socks"):
281 | username, password = get_auth_from_url(proxy)
282 | manager = self.proxy_manager[proxy] = SOCKSProxyManager(
283 | proxy,
284 | username=username,
285 | password=password,
286 | num_pools=self._pool_connections,
287 | maxsize=self._pool_maxsize,
288 | block=self._pool_block,
289 | **proxy_kwargs,
290 | )
291 | else:
292 | proxy_headers = self.proxy_headers(proxy)
293 | manager = self.proxy_manager[proxy] = proxy_from_url(
294 | proxy,
295 | proxy_headers=proxy_headers,
296 | num_pools=self._pool_connections,
297 | maxsize=self._pool_maxsize,
298 | block=self._pool_block,
299 | **proxy_kwargs,
300 | )
301 |
302 | return manager
303 |
304 | def cert_verify(self, conn, url, verify, cert):
305 | """Verify a SSL certificate. This method should not be called from user
306 | code, and is only exposed for use when subclassing the
307 | :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
308 |
309 | :param conn: The urllib3 connection object associated with the cert.
310 | :param url: The requested URL.
311 | :param verify: Either a boolean, in which case it controls whether we verify
312 | the server's TLS certificate, or a string, in which case it must be a path
313 | to a CA bundle to use
314 | :param cert: The SSL certificate to verify.
315 | """
316 | if url.lower().startswith("https") and verify:
317 | conn.cert_reqs = "CERT_REQUIRED"
318 |
319 | # Only load the CA certificates if 'verify' is a string indicating the CA bundle to use.
320 | # Otherwise, if verify is a boolean, we don't load anything since
321 | # the connection will be using a context with the default certificates already loaded,
322 | # and this avoids a call to the slow load_verify_locations()
323 | if verify is not True:
324 | # `verify` must be a str with a path then
325 | cert_loc = verify
326 |
327 | if not os.path.exists(cert_loc):
328 | raise OSError(
329 | f"Could not find a suitable TLS CA certificate bundle, "
330 | f"invalid path: {cert_loc}"
331 | )
332 |
333 | if not os.path.isdir(cert_loc):
334 | conn.ca_certs = cert_loc
335 | else:
336 | conn.ca_cert_dir = cert_loc
337 | else:
338 | conn.cert_reqs = "CERT_NONE"
339 | conn.ca_certs = None
340 | conn.ca_cert_dir = None
341 |
342 | if cert:
343 | if not isinstance(cert, basestring):
344 | conn.cert_file = cert[0]
345 | conn.key_file = cert[1]
346 | else:
347 | conn.cert_file = cert
348 | conn.key_file = None
349 | if conn.cert_file and not os.path.exists(conn.cert_file):
350 | raise OSError(
351 | f"Could not find the TLS certificate file, "
352 | f"invalid path: {conn.cert_file}"
353 | )
354 | if conn.key_file and not os.path.exists(conn.key_file):
355 | raise OSError(
356 | f"Could not find the TLS key file, invalid path: {conn.key_file}"
357 | )
358 |
359 | def build_response(self, req, resp):
360 | """Builds a :class:`Response <requests.Response>` object from a urllib3
361 | response. This should not be called from user code, and is only exposed
362 | for use when subclassing the
363 | :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`
364 |
365 | :param req: The :class:`PreparedRequest <PreparedRequest>` used to generate the response.
366 | :param resp: The urllib3 response object.
367 | :rtype: requests.Response
368 | """
369 | response = Response()
370 |
371 | # Fallback to None if there's no status_code, for whatever reason.
372 | response.status_code = getattr(resp, "status", None)
373 |
374 | # Make headers case-insensitive.
375 | response.headers = CaseInsensitiveDict(getattr(resp, "headers", {}))
376 |
377 | # Set encoding.
378 | response.encoding = get_encoding_from_headers(response.headers)
379 | response.raw = resp
380 | response.reason = response.raw.reason
381 |
382 | if isinstance(req.url, bytes):
383 | response.url = req.url.decode("utf-8")
384 | else:
385 | response.url = req.url
386 |
387 | # Add new cookies from the server.
388 | extract_cookies_to_jar(response.cookies, req, resp)
389 |
390 | # Give the Response some context.
391 | response.request = req
392 | response.connection = self
393 |
394 | return response
395 |
396 | def build_connection_pool_key_attributes(self, request, verify, cert=None):
397 | """Build the PoolKey attributes used by urllib3 to return a connection.
398 |
399 | This looks at the PreparedRequest, the user-specified verify value,
400 | and the value of the cert parameter to determine what PoolKey values
401 | to use to select a connection from a given urllib3 Connection Pool.
402 |
403 | The SSL related pool key arguments are not consistently set. As of
404 | this writing, use the following to determine what keys may be in that
405 | dictionary:
406 |
407 | * If ``verify`` is ``True``, ``"ssl_context"`` will be set and will be the
408 | default Requests SSL Context
409 | * If ``verify`` is ``False``, ``"ssl_context"`` will not be set but
410 | ``"cert_reqs"`` will be set
411 | * If ``verify`` is a string, (i.e., it is a user-specified trust bundle)
412 | ``"ca_certs"`` will be set if the string is not a directory recognized
413 | by :py:func:`os.path.isdir`, otherwise ``"ca_certs_dir"`` will be
414 | set.
415 | * If ``"cert"`` is specified, ``"cert_file"`` will always be set. If
416 | ``"cert"`` is a tuple with a second item, ``"key_file"`` will also
417 | be present
418 |
419 | To override these settings, one may subclass this class, call this
420 | method and use the above logic to change parameters as desired. For
421 | example, if one wishes to use a custom :py:class:`ssl.SSLContext` one
422 | must both set ``"ssl_context"`` and based on what else they require,
423 | alter the other keys to ensure the desired behaviour.
424 |
425 | :param request:
426 | The PreparedReqest being sent over the connection.
427 | :type request:
428 | :class:`~requests.models.PreparedRequest`
429 | :param verify:
430 | Either a boolean, in which case it controls whether
431 | we verify the server's TLS certificate, or a string, in which case it
432 | must be a path to a CA bundle to use.
433 | :param cert:
434 | (optional) Any user-provided SSL certificate for client
435 | authentication (a.k.a., mTLS). This may be a string (i.e., just
436 | the path to a file which holds both certificate and key) or a
437 | tuple of length 2 with the certificate file path and key file
438 | path.
439 | :returns:
440 | A tuple of two dictionaries. The first is the "host parameters"
441 | portion of the Pool Key including scheme, hostname, and port. The
442 | second is a dictionary of SSLContext related parameters.
443 | """
444 | return _urllib3_request_context(request, verify, cert, self.poolmanager)
445 |
446 | def get_connection_with_tls_context(self, request, verify, proxies=None, cert=None):
447 | """Returns a urllib3 connection for the given request and TLS settings.
448 | This should not be called from user code, and is only exposed for use
449 | when subclassing the :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
450 |
451 | :param request:
452 | The :class:`PreparedRequest <PreparedRequest>` object to be sent
453 | over the connection.
454 | :param verify:
455 | Either a boolean, in which case it controls whether we verify the
456 | server's TLS certificate, or a string, in which case it must be a
457 | path to a CA bundle to use.
458 | :param proxies:
459 | (optional) The proxies dictionary to apply to the request.
460 | :param cert:
461 | (optional) Any user-provided SSL certificate to be used for client
462 | authentication (a.k.a., mTLS).
463 | :rtype:
464 | urllib3.ConnectionPool
465 | """
466 | proxy = select_proxy(request.url, proxies)
467 | try:
468 | host_params, pool_kwargs = self.build_connection_pool_key_attributes(
469 | request,
470 | verify,
471 | cert,
472 | )
473 | except ValueError as e:
474 | raise InvalidURL(e, request=request)
475 | if proxy:
476 | proxy = prepend_scheme_if_needed(proxy, "http")
477 | proxy_url = parse_url(proxy)
478 | if not proxy_url.host:
479 | raise InvalidProxyURL(
480 | "Please check proxy URL. It is malformed "
481 | "and could be missing the host."
482 | )
483 | proxy_manager = self.proxy_manager_for(proxy)
484 | conn = proxy_manager.connection_from_host(
485 | **host_params, pool_kwargs=pool_kwargs
486 | )
487 | else:
488 | # Only scheme should be lower case
489 | conn = self.poolmanager.connection_from_host(
490 | **host_params, pool_kwargs=pool_kwargs
491 | )
492 |
493 | return conn
494 |
495 | def get_connection(self, url, proxies=None):
496 | """DEPRECATED: Users should move to `get_connection_with_tls_context`
497 | for all subclasses of HTTPAdapter using Requests>=2.32.2.
498 |
499 | Returns a urllib3 connection for the given URL. This should not be
500 | called from user code, and is only exposed for use when subclassing the
501 | :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
502 |
503 | :param url: The URL to connect to.
504 | :param proxies: (optional) A Requests-style dictionary of proxies used on this request.
505 | :rtype: urllib3.ConnectionPool
506 | """
507 | warnings.warn(
508 | (
509 | "`get_connection` has been deprecated in favor of "
510 | "`get_connection_with_tls_context`. Custom HTTPAdapter subclasses "
511 | "will need to migrate for Requests>=2.32.2. Please see "
512 | "https://github.com/psf/requests/pull/6710 for more details."
513 | ),
514 | DeprecationWarning,
515 | )
516 | proxy = select_proxy(url, proxies)
517 |
518 | if proxy:
519 | proxy = prepend_scheme_if_needed(proxy, "http")
520 | proxy_url = parse_url(proxy)
521 | if not proxy_url.host:
522 | raise InvalidProxyURL(
523 | "Please check proxy URL. It is malformed "
524 | "and could be missing the host."
525 | )
526 | proxy_manager = self.proxy_manager_for(proxy)
527 | conn = proxy_manager.connection_from_url(url)
528 | else:
529 | # Only scheme should be lower case
530 | parsed = urlparse(url)
531 | url = parsed.geturl()
532 | conn = self.poolmanager.connection_from_url(url)
533 |
534 | return conn
535 |
536 | def close(self):
537 | """Disposes of any internal state.
538 |
539 | Currently, this closes the PoolManager and any active ProxyManager,
540 | which closes any pooled connections.
541 | """
542 | self.poolmanager.clear()
543 | for proxy in self.proxy_manager.values():
544 | proxy.clear()
545 |
546 | def request_url(self, request, proxies):
547 | """Obtain the url to use when making the final request.
548 |
549 | If the message is being sent through a HTTP proxy, the full URL has to
550 | be used. Otherwise, we should only use the path portion of the URL.
551 |
552 | This should not be called from user code, and is only exposed for use
553 | when subclassing the
554 | :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
555 |
556 | :param request: The :class:`PreparedRequest <PreparedRequest>` being sent.
557 | :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs.
558 | :rtype: str
559 | """
560 | proxy = select_proxy(request.url, proxies)
561 | scheme = urlparse(request.url).scheme
562 |
563 | is_proxied_http_request = proxy and scheme != "https"
564 | using_socks_proxy = False
565 | if proxy:
566 | proxy_scheme = urlparse(proxy).scheme.lower()
567 | using_socks_proxy = proxy_scheme.startswith("socks")
568 |
569 | url = request.path_url
570 | if url.startswith("//"): # Don't confuse urllib3
571 | url = f"/{url.lstrip('/')}"
572 |
573 | if is_proxied_http_request and not using_socks_proxy:
574 | url = urldefragauth(request.url)
575 |
576 | return url
577 |
578 | def add_headers(self, request, **kwargs):
579 | """Add any headers needed by the connection. As of v2.0 this does
580 | nothing by default, but is left for overriding by users that subclass
581 | the :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
582 |
583 | This should not be called from user code, and is only exposed for use
584 | when subclassing the
585 | :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
586 |
587 | :param request: The :class:`PreparedRequest <PreparedRequest>` to add headers to.
588 | :param kwargs: The keyword arguments from the call to send().
589 | """
590 | pass
591 |
592 | def proxy_headers(self, proxy):
593 | """Returns a dictionary of the headers to add to any request sent
594 | through a proxy. This works with urllib3 magic to ensure that they are
595 | correctly sent to the proxy, rather than in a tunnelled request if
596 | CONNECT is being used.
597 |
598 | This should not be called from user code, and is only exposed for use
599 | when subclassing the
600 | :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
601 |
602 | :param proxy: The url of the proxy being used for this request.
603 | :rtype: dict
604 | """
605 | headers = {}
606 | username, password = get_auth_from_url(proxy)
607 |
608 | if username:
609 | headers["Proxy-Authorization"] = _basic_auth_str(username, password)
610 |
611 | return headers
612 |
613 | def send(
614 | self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None
615 | ):
616 | """Sends PreparedRequest object. Returns Response object.
617 |
618 | :param request: The :class:`PreparedRequest <PreparedRequest>` being sent.
619 | :param stream: (optional) Whether to stream the request content.
620 | :param timeout: (optional) How long to wait for the server to send
621 | data before giving up, as a float, or a :ref:`(connect timeout,
622 | read timeout) <timeouts>` tuple.
623 | :type timeout: float or tuple or urllib3 Timeout object
624 | :param verify: (optional) Either a boolean, in which case it controls whether
625 | we verify the server's TLS certificate, or a string, in which case it
626 | must be a path to a CA bundle to use
627 | :param cert: (optional) Any user-provided SSL certificate to be trusted.
628 | :param proxies: (optional) The proxies dictionary to apply to the request.
629 | :rtype: requests.Response
630 | """
631 |
632 | try:
633 | conn = self.get_connection_with_tls_context(
634 | request, verify, proxies=proxies, cert=cert
635 | )
636 | except LocationValueError as e:
637 | raise InvalidURL(e, request=request)
638 |
639 | self.cert_verify(conn, request.url, verify, cert)
640 | url = self.request_url(request, proxies)
641 | self.add_headers(
642 | request,
643 | stream=stream,
644 | timeout=timeout,
645 | verify=verify,
646 | cert=cert,
647 | proxies=proxies,
648 | )
649 |
650 | chunked = not (request.body is None or "Content-Length" in request.headers)
651 |
652 | if isinstance(timeout, tuple):
653 | try:
654 | connect, read = timeout
655 | timeout = TimeoutSauce(connect=connect, read=read)
656 | except ValueError:
657 | raise ValueError(
658 | f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, "
659 | f"or a single float to set both timeouts to the same value."
660 | )
661 | elif isinstance(timeout, TimeoutSauce):
662 | pass
663 | else:
664 | timeout = TimeoutSauce(connect=timeout, read=timeout)
665 |
666 | try:
667 | resp = conn.urlopen(
668 | method=request.method,
669 | url=url,
670 | body=request.body,
671 | headers=request.headers,
672 | redirect=False,
673 | assert_same_host=False,
674 | preload_content=False,
675 | decode_content=False,
676 | retries=self.max_retries,
677 | timeout=timeout,
678 | chunked=chunked,
679 | )
680 |
681 | except (ProtocolError, OSError) as err:
682 | raise ConnectionError(err, request=request)
683 |
684 | except MaxRetryError as e:
685 | if isinstance(e.reason, ConnectTimeoutError):
686 | # TODO: Remove this in 3.0.0: see #2811
687 | if not isinstance(e.reason, NewConnectionError):
688 | raise ConnectTimeout(e, request=request)
689 |
690 | if isinstance(e.reason, ResponseError):
691 | raise RetryError(e, request=request)
692 |
693 | if isinstance(e.reason, _ProxyError):
694 | raise ProxyError(e, request=request)
695 |
696 | if isinstance(e.reason, _SSLError):
697 | # This branch is for urllib3 v1.22 and later.
698 | raise SSLError(e, request=request)
699 |
700 | raise ConnectionError(e, request=request)
701 |
702 | except ClosedPoolError as e:
703 | raise ConnectionError(e, request=request)
704 |
705 | except _ProxyError as e:
706 | raise ProxyError(e)
707 |
708 | except (_SSLError, _HTTPError) as e:
709 | if isinstance(e, _SSLError):
710 | # This branch is for urllib3 versions earlier than v1.22
711 | raise SSLError(e, request=request)
712 | elif isinstance(e, ReadTimeoutError):
713 | raise ReadTimeout(e, request=request)
714 | elif isinstance(e, _InvalidHeader):
715 | raise InvalidHeader(e, request=request)
716 | else:
717 | raise
718 |
719 | return self.build_response(request, resp)
720 |
```
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/werkzeug/sansio/response.py:
--------------------------------------------------------------------------------
```python
1 | from __future__ import annotations
2 |
3 | import typing as t
4 | from datetime import datetime
5 | from datetime import timedelta
6 | from datetime import timezone
7 | from http import HTTPStatus
8 |
9 | from ..datastructures import CallbackDict
10 | from ..datastructures import ContentRange
11 | from ..datastructures import ContentSecurityPolicy
12 | from ..datastructures import Headers
13 | from ..datastructures import HeaderSet
14 | from ..datastructures import ResponseCacheControl
15 | from ..datastructures import WWWAuthenticate
16 | from ..http import COEP
17 | from ..http import COOP
18 | from ..http import dump_age
19 | from ..http import dump_cookie
20 | from ..http import dump_header
21 | from ..http import dump_options_header
22 | from ..http import http_date
23 | from ..http import HTTP_STATUS_CODES
24 | from ..http import parse_age
25 | from ..http import parse_cache_control_header
26 | from ..http import parse_content_range_header
27 | from ..http import parse_csp_header
28 | from ..http import parse_date
29 | from ..http import parse_options_header
30 | from ..http import parse_set_header
31 | from ..http import quote_etag
32 | from ..http import unquote_etag
33 | from ..utils import get_content_type
34 | from ..utils import header_property
35 |
36 | if t.TYPE_CHECKING:
37 | from ..datastructures.cache_control import _CacheControl
38 |
39 |
40 | def _set_property(name: str, doc: str | None = None) -> property:
41 | def fget(self: Response) -> HeaderSet:
42 | def on_update(header_set: HeaderSet) -> None:
43 | if not header_set and name in self.headers:
44 | del self.headers[name]
45 | elif header_set:
46 | self.headers[name] = header_set.to_header()
47 |
48 | return parse_set_header(self.headers.get(name), on_update)
49 |
50 | def fset(
51 | self: Response,
52 | value: None | (str | dict[str, str | int] | t.Iterable[str]),
53 | ) -> None:
54 | if not value:
55 | del self.headers[name]
56 | elif isinstance(value, str):
57 | self.headers[name] = value
58 | else:
59 | self.headers[name] = dump_header(value)
60 |
61 | return property(fget, fset, doc=doc)
62 |
63 |
64 | class Response:
65 | """Represents the non-IO parts of an HTTP response, specifically the
66 | status and headers but not the body.
67 |
68 | This class is not meant for general use. It should only be used when
69 | implementing WSGI, ASGI, or another HTTP application spec. Werkzeug
70 | provides a WSGI implementation at :cls:`werkzeug.wrappers.Response`.
71 |
72 | :param status: The status code for the response. Either an int, in
73 | which case the default status message is added, or a string in
74 | the form ``{code} {message}``, like ``404 Not Found``. Defaults
75 | to 200.
76 | :param headers: A :class:`~werkzeug.datastructures.Headers` object,
77 | or a list of ``(key, value)`` tuples that will be converted to a
78 | ``Headers`` object.
79 | :param mimetype: The mime type (content type without charset or
80 | other parameters) of the response. If the value starts with
81 | ``text/`` (or matches some other special cases), the charset
82 | will be added to create the ``content_type``.
83 | :param content_type: The full content type of the response.
84 | Overrides building the value from ``mimetype``.
85 |
86 | .. versionchanged:: 3.0
87 | The ``charset`` attribute was removed.
88 |
89 | .. versionadded:: 2.0
90 | """
91 |
92 | #: the default status if none is provided.
93 | default_status = 200
94 |
95 | #: the default mimetype if none is provided.
96 | default_mimetype: str | None = "text/plain"
97 |
98 | #: Warn if a cookie header exceeds this size. The default, 4093, should be
99 | #: safely `supported by most browsers <cookie_>`_. A cookie larger than
100 | #: this size will still be sent, but it may be ignored or handled
101 | #: incorrectly by some browsers. Set to 0 to disable this check.
102 | #:
103 | #: .. versionadded:: 0.13
104 | #:
105 | #: .. _`cookie`: http://browsercookielimits.squawky.net/
106 | max_cookie_size = 4093
107 |
108 | # A :class:`Headers` object representing the response headers.
109 | headers: Headers
110 |
111 | def __init__(
112 | self,
113 | status: int | str | HTTPStatus | None = None,
114 | headers: t.Mapping[str, str | t.Iterable[str]]
115 | | t.Iterable[tuple[str, str]]
116 | | None = None,
117 | mimetype: str | None = None,
118 | content_type: str | None = None,
119 | ) -> None:
120 | if isinstance(headers, Headers):
121 | self.headers = headers
122 | elif not headers:
123 | self.headers = Headers()
124 | else:
125 | self.headers = Headers(headers)
126 |
127 | if content_type is None:
128 | if mimetype is None and "content-type" not in self.headers:
129 | mimetype = self.default_mimetype
130 | if mimetype is not None:
131 | mimetype = get_content_type(mimetype, "utf-8")
132 | content_type = mimetype
133 | if content_type is not None:
134 | self.headers["Content-Type"] = content_type
135 | if status is None:
136 | status = self.default_status
137 | self.status = status # type: ignore
138 |
139 | def __repr__(self) -> str:
140 | return f"<{type(self).__name__} [{self.status}]>"
141 |
142 | @property
143 | def status_code(self) -> int:
144 | """The HTTP status code as a number."""
145 | return self._status_code
146 |
147 | @status_code.setter
148 | def status_code(self, code: int) -> None:
149 | self.status = code # type: ignore
150 |
151 | @property
152 | def status(self) -> str:
153 | """The HTTP status code as a string."""
154 | return self._status
155 |
156 | @status.setter
157 | def status(self, value: str | int | HTTPStatus) -> None:
158 | self._status, self._status_code = self._clean_status(value)
159 |
160 | def _clean_status(self, value: str | int | HTTPStatus) -> tuple[str, int]:
161 | if isinstance(value, (int, HTTPStatus)):
162 | status_code = int(value)
163 | else:
164 | value = value.strip()
165 |
166 | if not value:
167 | raise ValueError("Empty status argument")
168 |
169 | code_str, sep, _ = value.partition(" ")
170 |
171 | try:
172 | status_code = int(code_str)
173 | except ValueError:
174 | # only message
175 | return f"0 {value}", 0
176 |
177 | if sep:
178 | # code and message
179 | return value, status_code
180 |
181 | # only code, look up message
182 | try:
183 | status = f"{status_code} {HTTP_STATUS_CODES[status_code].upper()}"
184 | except KeyError:
185 | status = f"{status_code} UNKNOWN"
186 |
187 | return status, status_code
188 |
189 | def set_cookie(
190 | self,
191 | key: str,
192 | value: str = "",
193 | max_age: timedelta | int | None = None,
194 | expires: str | datetime | int | float | None = None,
195 | path: str | None = "/",
196 | domain: str | None = None,
197 | secure: bool = False,
198 | httponly: bool = False,
199 | samesite: str | None = None,
200 | ) -> None:
201 | """Sets a cookie.
202 |
203 | A warning is raised if the size of the cookie header exceeds
204 | :attr:`max_cookie_size`, but the header will still be set.
205 |
206 | :param key: the key (name) of the cookie to be set.
207 | :param value: the value of the cookie.
208 | :param max_age: should be a number of seconds, or `None` (default) if
209 | the cookie should last only as long as the client's
210 | browser session.
211 | :param expires: should be a `datetime` object or UNIX timestamp.
212 | :param path: limits the cookie to a given path, per default it will
213 | span the whole domain.
214 | :param domain: if you want to set a cross-domain cookie. For example,
215 | ``domain="example.com"`` will set a cookie that is
216 | readable by the domain ``www.example.com``,
217 | ``foo.example.com`` etc. Otherwise, a cookie will only
218 | be readable by the domain that set it.
219 | :param secure: If ``True``, the cookie will only be available
220 | via HTTPS.
221 | :param httponly: Disallow JavaScript access to the cookie.
222 | :param samesite: Limit the scope of the cookie to only be
223 | attached to requests that are "same-site".
224 | """
225 | self.headers.add(
226 | "Set-Cookie",
227 | dump_cookie(
228 | key,
229 | value=value,
230 | max_age=max_age,
231 | expires=expires,
232 | path=path,
233 | domain=domain,
234 | secure=secure,
235 | httponly=httponly,
236 | max_size=self.max_cookie_size,
237 | samesite=samesite,
238 | ),
239 | )
240 |
241 | def delete_cookie(
242 | self,
243 | key: str,
244 | path: str | None = "/",
245 | domain: str | None = None,
246 | secure: bool = False,
247 | httponly: bool = False,
248 | samesite: str | None = None,
249 | ) -> None:
250 | """Delete a cookie. Fails silently if key doesn't exist.
251 |
252 | :param key: the key (name) of the cookie to be deleted.
253 | :param path: if the cookie that should be deleted was limited to a
254 | path, the path has to be defined here.
255 | :param domain: if the cookie that should be deleted was limited to a
256 | domain, that domain has to be defined here.
257 | :param secure: If ``True``, the cookie will only be available
258 | via HTTPS.
259 | :param httponly: Disallow JavaScript access to the cookie.
260 | :param samesite: Limit the scope of the cookie to only be
261 | attached to requests that are "same-site".
262 | """
263 | self.set_cookie(
264 | key,
265 | expires=0,
266 | max_age=0,
267 | path=path,
268 | domain=domain,
269 | secure=secure,
270 | httponly=httponly,
271 | samesite=samesite,
272 | )
273 |
274 | @property
275 | def is_json(self) -> bool:
276 | """Check if the mimetype indicates JSON data, either
277 | :mimetype:`application/json` or :mimetype:`application/*+json`.
278 | """
279 | mt = self.mimetype
280 | return mt is not None and (
281 | mt == "application/json"
282 | or mt.startswith("application/")
283 | and mt.endswith("+json")
284 | )
285 |
286 | # Common Descriptors
287 |
288 | @property
289 | def mimetype(self) -> str | None:
290 | """The mimetype (content type without charset etc.)"""
291 | ct = self.headers.get("content-type")
292 |
293 | if ct:
294 | return ct.split(";")[0].strip()
295 | else:
296 | return None
297 |
298 | @mimetype.setter
299 | def mimetype(self, value: str) -> None:
300 | self.headers["Content-Type"] = get_content_type(value, "utf-8")
301 |
302 | @property
303 | def mimetype_params(self) -> dict[str, str]:
304 | """The mimetype parameters as dict. For example if the
305 | content type is ``text/html; charset=utf-8`` the params would be
306 | ``{'charset': 'utf-8'}``.
307 |
308 | .. versionadded:: 0.5
309 | """
310 |
311 | def on_update(d: CallbackDict[str, str]) -> None:
312 | self.headers["Content-Type"] = dump_options_header(self.mimetype, d)
313 |
314 | d = parse_options_header(self.headers.get("content-type", ""))[1]
315 | return CallbackDict(d, on_update)
316 |
317 | location = header_property[str](
318 | "Location",
319 | doc="""The Location response-header field is used to redirect
320 | the recipient to a location other than the Request-URI for
321 | completion of the request or identification of a new
322 | resource.""",
323 | )
324 | age = header_property(
325 | "Age",
326 | None,
327 | parse_age,
328 | dump_age, # type: ignore
329 | doc="""The Age response-header field conveys the sender's
330 | estimate of the amount of time since the response (or its
331 | revalidation) was generated at the origin server.
332 |
333 | Age values are non-negative decimal integers, representing time
334 | in seconds.""",
335 | )
336 | content_type = header_property[str](
337 | "Content-Type",
338 | doc="""The Content-Type entity-header field indicates the media
339 | type of the entity-body sent to the recipient or, in the case of
340 | the HEAD method, the media type that would have been sent had
341 | the request been a GET.""",
342 | )
343 | content_length = header_property(
344 | "Content-Length",
345 | None,
346 | int,
347 | str,
348 | doc="""The Content-Length entity-header field indicates the size
349 | of the entity-body, in decimal number of OCTETs, sent to the
350 | recipient or, in the case of the HEAD method, the size of the
351 | entity-body that would have been sent had the request been a
352 | GET.""",
353 | )
354 | content_location = header_property[str](
355 | "Content-Location",
356 | doc="""The Content-Location entity-header field MAY be used to
357 | supply the resource location for the entity enclosed in the
358 | message when that entity is accessible from a location separate
359 | from the requested resource's URI.""",
360 | )
361 | content_encoding = header_property[str](
362 | "Content-Encoding",
363 | doc="""The Content-Encoding entity-header field is used as a
364 | modifier to the media-type. When present, its value indicates
365 | what additional content codings have been applied to the
366 | entity-body, and thus what decoding mechanisms must be applied
367 | in order to obtain the media-type referenced by the Content-Type
368 | header field.""",
369 | )
370 | content_md5 = header_property[str](
371 | "Content-MD5",
372 | doc="""The Content-MD5 entity-header field, as defined in
373 | RFC 1864, is an MD5 digest of the entity-body for the purpose of
374 | providing an end-to-end message integrity check (MIC) of the
375 | entity-body. (Note: a MIC is good for detecting accidental
376 | modification of the entity-body in transit, but is not proof
377 | against malicious attacks.)""",
378 | )
379 | date = header_property(
380 | "Date",
381 | None,
382 | parse_date,
383 | http_date,
384 | doc="""The Date general-header field represents the date and
385 | time at which the message was originated, having the same
386 | semantics as orig-date in RFC 822.
387 |
388 | .. versionchanged:: 2.0
389 | The datetime object is timezone-aware.
390 | """,
391 | )
392 | expires = header_property(
393 | "Expires",
394 | None,
395 | parse_date,
396 | http_date,
397 | doc="""The Expires entity-header field gives the date/time after
398 | which the response is considered stale. A stale cache entry may
399 | not normally be returned by a cache.
400 |
401 | .. versionchanged:: 2.0
402 | The datetime object is timezone-aware.
403 | """,
404 | )
405 | last_modified = header_property(
406 | "Last-Modified",
407 | None,
408 | parse_date,
409 | http_date,
410 | doc="""The Last-Modified entity-header field indicates the date
411 | and time at which the origin server believes the variant was
412 | last modified.
413 |
414 | .. versionchanged:: 2.0
415 | The datetime object is timezone-aware.
416 | """,
417 | )
418 |
419 | @property
420 | def retry_after(self) -> datetime | None:
421 | """The Retry-After response-header field can be used with a
422 | 503 (Service Unavailable) response to indicate how long the
423 | service is expected to be unavailable to the requesting client.
424 |
425 | Time in seconds until expiration or date.
426 |
427 | .. versionchanged:: 2.0
428 | The datetime object is timezone-aware.
429 | """
430 | value = self.headers.get("retry-after")
431 | if value is None:
432 | return None
433 |
434 | try:
435 | seconds = int(value)
436 | except ValueError:
437 | return parse_date(value)
438 |
439 | return datetime.now(timezone.utc) + timedelta(seconds=seconds)
440 |
441 | @retry_after.setter
442 | def retry_after(self, value: datetime | int | str | None) -> None:
443 | if value is None:
444 | if "retry-after" in self.headers:
445 | del self.headers["retry-after"]
446 | return
447 | elif isinstance(value, datetime):
448 | value = http_date(value)
449 | else:
450 | value = str(value)
451 | self.headers["Retry-After"] = value
452 |
453 | vary = _set_property(
454 | "Vary",
455 | doc="""The Vary field value indicates the set of request-header
456 | fields that fully determines, while the response is fresh,
457 | whether a cache is permitted to use the response to reply to a
458 | subsequent request without revalidation.""",
459 | )
460 | content_language = _set_property(
461 | "Content-Language",
462 | doc="""The Content-Language entity-header field describes the
463 | natural language(s) of the intended audience for the enclosed
464 | entity. Note that this might not be equivalent to all the
465 | languages used within the entity-body.""",
466 | )
467 | allow = _set_property(
468 | "Allow",
469 | doc="""The Allow entity-header field lists the set of methods
470 | supported by the resource identified by the Request-URI. The
471 | purpose of this field is strictly to inform the recipient of
472 | valid methods associated with the resource. An Allow header
473 | field MUST be present in a 405 (Method Not Allowed)
474 | response.""",
475 | )
476 |
477 | # ETag
478 |
479 | @property
480 | def cache_control(self) -> ResponseCacheControl:
481 | """The Cache-Control general-header field is used to specify
482 | directives that MUST be obeyed by all caching mechanisms along the
483 | request/response chain.
484 | """
485 |
486 | def on_update(cache_control: _CacheControl) -> None:
487 | if not cache_control and "cache-control" in self.headers:
488 | del self.headers["cache-control"]
489 | elif cache_control:
490 | self.headers["Cache-Control"] = cache_control.to_header()
491 |
492 | return parse_cache_control_header(
493 | self.headers.get("cache-control"), on_update, ResponseCacheControl
494 | )
495 |
496 | def set_etag(self, etag: str, weak: bool = False) -> None:
497 | """Set the etag, and override the old one if there was one."""
498 | self.headers["ETag"] = quote_etag(etag, weak)
499 |
500 | def get_etag(self) -> tuple[str, bool] | tuple[None, None]:
501 | """Return a tuple in the form ``(etag, is_weak)``. If there is no
502 | ETag the return value is ``(None, None)``.
503 | """
504 | return unquote_etag(self.headers.get("ETag"))
505 |
506 | accept_ranges = header_property[str](
507 | "Accept-Ranges",
508 | doc="""The `Accept-Ranges` header. Even though the name would
509 | indicate that multiple values are supported, it must be one
510 | string token only.
511 |
512 | The values ``'bytes'`` and ``'none'`` are common.
513 |
514 | .. versionadded:: 0.7""",
515 | )
516 |
517 | @property
518 | def content_range(self) -> ContentRange:
519 | """The ``Content-Range`` header as a
520 | :class:`~werkzeug.datastructures.ContentRange` object. Available
521 | even if the header is not set.
522 |
523 | .. versionadded:: 0.7
524 | """
525 |
526 | def on_update(rng: ContentRange) -> None:
527 | if not rng:
528 | del self.headers["content-range"]
529 | else:
530 | self.headers["Content-Range"] = rng.to_header()
531 |
532 | rv = parse_content_range_header(self.headers.get("content-range"), on_update)
533 | # always provide a content range object to make the descriptor
534 | # more user friendly. It provides an unset() method that can be
535 | # used to remove the header quickly.
536 | if rv is None:
537 | rv = ContentRange(None, None, None, on_update=on_update)
538 | return rv
539 |
540 | @content_range.setter
541 | def content_range(self, value: ContentRange | str | None) -> None:
542 | if not value:
543 | del self.headers["content-range"]
544 | elif isinstance(value, str):
545 | self.headers["Content-Range"] = value
546 | else:
547 | self.headers["Content-Range"] = value.to_header()
548 |
549 | # Authorization
550 |
551 | @property
552 | def www_authenticate(self) -> WWWAuthenticate:
553 | """The ``WWW-Authenticate`` header parsed into a :class:`.WWWAuthenticate`
554 | object. Modifying the object will modify the header value.
555 |
556 | This header is not set by default. To set this header, assign an instance of
557 | :class:`.WWWAuthenticate` to this attribute.
558 |
559 | .. code-block:: python
560 |
561 | response.www_authenticate = WWWAuthenticate(
562 | "basic", {"realm": "Authentication Required"}
563 | )
564 |
565 | Multiple values for this header can be sent to give the client multiple options.
566 | Assign a list to set multiple headers. However, modifying the items in the list
567 | will not automatically update the header values, and accessing this attribute
568 | will only ever return the first value.
569 |
570 | To unset this header, assign ``None`` or use ``del``.
571 |
572 | .. versionchanged:: 2.3
573 | This attribute can be assigned to to set the header. A list can be assigned
574 | to set multiple header values. Use ``del`` to unset the header.
575 |
576 | .. versionchanged:: 2.3
577 | :class:`WWWAuthenticate` is no longer a ``dict``. The ``token`` attribute
578 | was added for auth challenges that use a token instead of parameters.
579 | """
580 | value = WWWAuthenticate.from_header(self.headers.get("WWW-Authenticate"))
581 |
582 | if value is None:
583 | value = WWWAuthenticate("basic")
584 |
585 | def on_update(value: WWWAuthenticate) -> None:
586 | self.www_authenticate = value
587 |
588 | value._on_update = on_update
589 | return value
590 |
591 | @www_authenticate.setter
592 | def www_authenticate(
593 | self, value: WWWAuthenticate | list[WWWAuthenticate] | None
594 | ) -> None:
595 | if not value: # None or empty list
596 | del self.www_authenticate
597 | elif isinstance(value, list):
598 | # Clear any existing header by setting the first item.
599 | self.headers.set("WWW-Authenticate", value[0].to_header())
600 |
601 | for item in value[1:]:
602 | # Add additional header lines for additional items.
603 | self.headers.add("WWW-Authenticate", item.to_header())
604 | else:
605 | self.headers.set("WWW-Authenticate", value.to_header())
606 |
607 | def on_update(value: WWWAuthenticate) -> None:
608 | self.www_authenticate = value
609 |
610 | # When setting a single value, allow updating it directly.
611 | value._on_update = on_update
612 |
613 | @www_authenticate.deleter
614 | def www_authenticate(self) -> None:
615 | if "WWW-Authenticate" in self.headers:
616 | del self.headers["WWW-Authenticate"]
617 |
618 | # CSP
619 |
620 | @property
621 | def content_security_policy(self) -> ContentSecurityPolicy:
622 | """The ``Content-Security-Policy`` header as a
623 | :class:`~werkzeug.datastructures.ContentSecurityPolicy` object. Available
624 | even if the header is not set.
625 |
626 | The Content-Security-Policy header adds an additional layer of
627 | security to help detect and mitigate certain types of attacks.
628 | """
629 |
630 | def on_update(csp: ContentSecurityPolicy) -> None:
631 | if not csp:
632 | del self.headers["content-security-policy"]
633 | else:
634 | self.headers["Content-Security-Policy"] = csp.to_header()
635 |
636 | rv = parse_csp_header(self.headers.get("content-security-policy"), on_update)
637 | if rv is None:
638 | rv = ContentSecurityPolicy(None, on_update=on_update)
639 | return rv
640 |
641 | @content_security_policy.setter
642 | def content_security_policy(
643 | self, value: ContentSecurityPolicy | str | None
644 | ) -> None:
645 | if not value:
646 | del self.headers["content-security-policy"]
647 | elif isinstance(value, str):
648 | self.headers["Content-Security-Policy"] = value
649 | else:
650 | self.headers["Content-Security-Policy"] = value.to_header()
651 |
652 | @property
653 | def content_security_policy_report_only(self) -> ContentSecurityPolicy:
654 | """The ``Content-Security-policy-report-only`` header as a
655 | :class:`~werkzeug.datastructures.ContentSecurityPolicy` object. Available
656 | even if the header is not set.
657 |
658 | The Content-Security-Policy-Report-Only header adds a csp policy
659 | that is not enforced but is reported thereby helping detect
660 | certain types of attacks.
661 | """
662 |
663 | def on_update(csp: ContentSecurityPolicy) -> None:
664 | if not csp:
665 | del self.headers["content-security-policy-report-only"]
666 | else:
667 | self.headers["Content-Security-policy-report-only"] = csp.to_header()
668 |
669 | rv = parse_csp_header(
670 | self.headers.get("content-security-policy-report-only"), on_update
671 | )
672 | if rv is None:
673 | rv = ContentSecurityPolicy(None, on_update=on_update)
674 | return rv
675 |
676 | @content_security_policy_report_only.setter
677 | def content_security_policy_report_only(
678 | self, value: ContentSecurityPolicy | str | None
679 | ) -> None:
680 | if not value:
681 | del self.headers["content-security-policy-report-only"]
682 | elif isinstance(value, str):
683 | self.headers["Content-Security-policy-report-only"] = value
684 | else:
685 | self.headers["Content-Security-policy-report-only"] = value.to_header()
686 |
687 | # CORS
688 |
689 | @property
690 | def access_control_allow_credentials(self) -> bool:
691 | """Whether credentials can be shared by the browser to
692 | JavaScript code. As part of the preflight request it indicates
693 | whether credentials can be used on the cross origin request.
694 | """
695 | return "Access-Control-Allow-Credentials" in self.headers
696 |
697 | @access_control_allow_credentials.setter
698 | def access_control_allow_credentials(self, value: bool | None) -> None:
699 | if value is True:
700 | self.headers["Access-Control-Allow-Credentials"] = "true"
701 | else:
702 | self.headers.pop("Access-Control-Allow-Credentials", None)
703 |
704 | access_control_allow_headers = header_property(
705 | "Access-Control-Allow-Headers",
706 | load_func=parse_set_header,
707 | dump_func=dump_header,
708 | doc="Which headers can be sent with the cross origin request.",
709 | )
710 |
711 | access_control_allow_methods = header_property(
712 | "Access-Control-Allow-Methods",
713 | load_func=parse_set_header,
714 | dump_func=dump_header,
715 | doc="Which methods can be used for the cross origin request.",
716 | )
717 |
718 | access_control_allow_origin = header_property[str](
719 | "Access-Control-Allow-Origin",
720 | doc="The origin or '*' for any origin that may make cross origin requests.",
721 | )
722 |
723 | access_control_expose_headers = header_property(
724 | "Access-Control-Expose-Headers",
725 | load_func=parse_set_header,
726 | dump_func=dump_header,
727 | doc="Which headers can be shared by the browser to JavaScript code.",
728 | )
729 |
730 | access_control_max_age = header_property(
731 | "Access-Control-Max-Age",
732 | load_func=int,
733 | dump_func=str,
734 | doc="The maximum age in seconds the access control settings can be cached for.",
735 | )
736 |
737 | cross_origin_opener_policy = header_property[COOP](
738 | "Cross-Origin-Opener-Policy",
739 | load_func=lambda value: COOP(value),
740 | dump_func=lambda value: value.value,
741 | default=COOP.UNSAFE_NONE,
742 | doc="""Allows control over sharing of browsing context group with cross-origin
743 | documents. Values must be a member of the :class:`werkzeug.http.COOP` enum.""",
744 | )
745 |
746 | cross_origin_embedder_policy = header_property[COEP](
747 | "Cross-Origin-Embedder-Policy",
748 | load_func=lambda value: COEP(value),
749 | dump_func=lambda value: value.value,
750 | default=COEP.UNSAFE_NONE,
751 | doc="""Prevents a document from loading any cross-origin resources that do not
752 | explicitly grant the document permission. Values must be a member of the
753 | :class:`werkzeug.http.COEP` enum.""",
754 | )
755 |
```