+ In other language (unofficial port - by the community)
+
+
+
+
+
+> A library that helps you read text from an unknown charset encoding. Motivated by `chardet`,
+> I'm trying to resolve the issue by taking a new approach.
+> All IANA character set names for which the Python core library provides codecs are supported.
+
+
+
+---
+
+**Documentation**: https://fastapi.tiangolo.com
+
+**Source Code**: https://github.com/fastapi/fastapi
+
+---
+
+FastAPI is a modern, fast (high-performance), web framework for building APIs with Python based on standard Python type hints.
+
+The key features are:
+
+* **Fast**: Very high performance, on par with **NodeJS** and **Go** (thanks to Starlette and Pydantic). [One of the fastest Python frameworks available](#performance).
+* **Fast to code**: Increase the speed to develop features by about 200% to 300%. *
+* **Fewer bugs**: Reduce about 40% of human (developer) induced errors. *
+* **Intuitive**: Great editor support. Completion everywhere. Less time debugging.
+* **Easy**: Designed to be easy to use and learn. Less time reading docs.
+* **Short**: Minimize code duplication. Multiple features from each parameter declaration. Fewer bugs.
+* **Robust**: Get production-ready code. With automatic interactive documentation.
+* **Standards-based**: Based on (and fully compatible with) the open standards for APIs: OpenAPI (previously known as Swagger) and JSON Schema.
+
+* estimation based on tests on an internal development team, building production applications.
+
+## Sponsors
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Other sponsors
+
+## Opinions
+
+"_[...] I'm using **FastAPI** a ton these days. [...] I'm actually planning to use it for all of my team's **ML services at Microsoft**. Some of them are getting integrated into the core **Windows** product and some **Office** products._"
+
+
+
+---
+
+"_We adopted the **FastAPI** library to spawn a **REST** server that can be queried to obtain **predictions**. [for Ludwig]_"
+
+
Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - Uber(ref)
+
+---
+
+"_**Netflix** is pleased to announce the open-source release of our **crisis management** orchestration framework: **Dispatch**! [built with **FastAPI**]_"
+
+
Kevin Glisson, Marc Vilanova, Forest Monsen - Netflix(ref)
+
+---
+
+"_I’m over the moon excited about **FastAPI**. It’s so fun!_"
+
+
+
+---
+
+"_Honestly, what you've built looks super solid and polished. In many ways, it's what I wanted **Hug** to be - it's really inspiring to see someone build that._"
+
+
+
+---
+
+"_If you're looking to learn one **modern framework** for building REST APIs, check out **FastAPI** [...] It's fast, easy to use and easy to learn [...]_"
+
+"_We've switched over to **FastAPI** for our **APIs** [...] I think you'll like it [...]_"
+
+
+
+---
+
+"_If anyone is looking to build a production Python API, I would highly recommend **FastAPI**. It is **beautifully designed**, **simple to use** and **highly scalable**, it has become a **key component** in our API first development strategy and is driving many automations and services such as our Virtual TAC Engineer._"
+
+
+
+---
+
+## **Typer**, the FastAPI of CLIs
+
+
+
+If you are building a CLI app to be used in the terminal instead of a web API, check out **Typer**.
+
+**Typer** is FastAPI's little sibling. And it's intended to be the **FastAPI of CLIs**. ⌨️ 🚀
+
+## Requirements
+
+FastAPI stands on the shoulders of giants:
+
+* Starlette for the web parts.
+* Pydantic for the data parts.
+
+## Installation
+
+Create and activate a virtual environment and then install FastAPI:
+
+
+
+**Note**: Make sure you put `"fastapi[standard]"` in quotes to ensure it works in all terminals.
+
+## Example
+
+### Create it
+
+Create a file `main.py` with:
+
+```Python
+from typing import Union
+
+from fastapi import FastAPI
+
+app = FastAPI()
+
+
+@app.get("/")
+def read_root():
+ return {"Hello": "World"}
+
+
+@app.get("/items/{item_id}")
+def read_item(item_id: int, q: Union[str, None] = None):
+ return {"item_id": item_id, "q": q}
+```
+
+
+Or use async def...
+
+If your code uses `async` / `await`, use `async def`:
+
+```Python hl_lines="9 14"
+from typing import Union
+
+from fastapi import FastAPI
+
+app = FastAPI()
+
+
+@app.get("/")
+async def read_root():
+ return {"Hello": "World"}
+
+
+@app.get("/items/{item_id}")
+async def read_item(item_id: int, q: Union[str, None] = None):
+ return {"item_id": item_id, "q": q}
+```
+
+**Note**:
+
+If you don't know, check the _"In a hurry?"_ section about `async` and `await` in the docs.
+
+
+
+### Run it
+
+Run the server with:
+
+
+
+```console
+$ fastapi dev main.py
+
+ ╭────────── FastAPI CLI - Development mode ───────────╮
+ │ │
+ │ Serving at: http://127.0.0.1:8000 │
+ │ │
+ │ API docs: http://127.0.0.1:8000/docs │
+ │ │
+ │ Running in development mode, for production use: │
+ │ │
+ │ fastapi run │
+ │ │
+ ╰─────────────────────────────────────────────────────╯
+
+INFO: Will watch for changes in these directories: ['/home/user/code/awesomeapp']
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+INFO: Started reloader process [2248755] using WatchFiles
+INFO: Started server process [2248757]
+INFO: Waiting for application startup.
+INFO: Application startup complete.
+```
+
+
+
+
+About the command fastapi dev main.py...
+
+The command `fastapi dev` reads your `main.py` file, detects the **FastAPI** app in it, and starts a server using Uvicorn.
+
+By default, `fastapi dev` will start with auto-reload enabled for local development.
+
+You can read more about it in the FastAPI CLI docs.
+
+
+
+### Check it
+
+Open your browser at http://127.0.0.1:8000/items/5?q=somequery.
+
+You will see the JSON response as:
+
+```JSON
+{"item_id": 5, "q": "somequery"}
+```
+
+You already created an API that:
+
+* Receives HTTP requests in the _paths_ `/` and `/items/{item_id}`.
+* Both _paths_ take `GET` operations (also known as HTTP _methods_).
+* The _path_ `/items/{item_id}` has a _path parameter_ `item_id` that should be an `int`.
+* The _path_ `/items/{item_id}` has an optional `str` _query parameter_ `q`.
+
+### Interactive API docs
+
+Now go to http://127.0.0.1:8000/docs.
+
+You will see the automatic interactive API documentation (provided by Swagger UI):
+
+
+
+### Alternative API docs
+
+And now, go to http://127.0.0.1:8000/redoc.
+
+You will see the alternative automatic documentation (provided by ReDoc):
+
+
+
+## Example upgrade
+
+Now modify the file `main.py` to receive a body from a `PUT` request.
+
+Declare the body using standard Python types, thanks to Pydantic.
+
+```Python hl_lines="4 9-12 25-27"
+from typing import Union
+
+from fastapi import FastAPI
+from pydantic import BaseModel
+
+app = FastAPI()
+
+
+class Item(BaseModel):
+ name: str
+ price: float
+ is_offer: Union[bool, None] = None
+
+
+@app.get("/")
+def read_root():
+ return {"Hello": "World"}
+
+
+@app.get("/items/{item_id}")
+def read_item(item_id: int, q: Union[str, None] = None):
+ return {"item_id": item_id, "q": q}
+
+
+@app.put("/items/{item_id}")
+def update_item(item_id: int, item: Item):
+ return {"item_name": item.name, "item_id": item_id}
+```
+
+The `fastapi dev` server should reload automatically.
+
+### Interactive API docs upgrade
+
+Now go to http://127.0.0.1:8000/docs.
+
+* The interactive API documentation will be automatically updated, including the new body:
+
+
+
+* Click on the button "Try it out", it allows you to fill the parameters and directly interact with the API:
+
+
+
+* Then click on the "Execute" button, the user interface will communicate with your API, send the parameters, get the results and show them on the screen:
+
+
+
+### Alternative API docs upgrade
+
+And now, go to http://127.0.0.1:8000/redoc.
+
+* The alternative documentation will also reflect the new query parameter and body:
+
+
+
+### Recap
+
+In summary, you declare **once** the types of parameters, body, etc. as function parameters.
+
+You do that with standard modern Python types.
+
+You don't have to learn a new syntax, the methods or classes of a specific library, etc.
+
+Just standard **Python**.
+
+For example, for an `int`:
+
+```Python
+item_id: int
+```
+
+or for a more complex `Item` model:
+
+```Python
+item: Item
+```
+
+...and with that single declaration you get:
+
+* Editor support, including:
+ * Completion.
+ * Type checks.
+* Validation of data:
+ * Automatic and clear errors when the data is invalid.
+ * Validation even for deeply nested JSON objects.
+* Conversion of input data: coming from the network to Python data and types. Reading from:
+ * JSON.
+ * Path parameters.
+ * Query parameters.
+ * Cookies.
+ * Headers.
+ * Forms.
+ * Files.
+* Conversion of output data: converting from Python data and types to network data (as JSON):
+ * Convert Python types (`str`, `int`, `float`, `bool`, `list`, etc).
+ * `datetime` objects.
+ * `UUID` objects.
+ * Database models.
+ * ...and many more.
+* Automatic interactive API documentation, including 2 alternative user interfaces:
+ * Swagger UI.
+ * ReDoc.
+
+---
+
+Coming back to the previous code example, **FastAPI** will:
+
+* Validate that there is an `item_id` in the path for `GET` and `PUT` requests.
+* Validate that the `item_id` is of type `int` for `GET` and `PUT` requests.
+ * If it is not, the client will see a useful, clear error.
+* Check if there is an optional query parameter named `q` (as in `http://127.0.0.1:8000/items/foo?q=somequery`) for `GET` requests.
+ * As the `q` parameter is declared with `= None`, it is optional.
+ * Without the `None` it would be required (as is the body in the case with `PUT`).
+* For `PUT` requests to `/items/{item_id}`, read the body as JSON:
+ * Check that it has a required attribute `name` that should be a `str`.
+ * Check that it has a required attribute `price` that has to be a `float`.
+ * Check that it has an optional attribute `is_offer`, that should be a `bool`, if present.
+ * All this would also work for deeply nested JSON objects.
+* Convert from and to JSON automatically.
+* Document everything with OpenAPI, that can be used by:
+ * Interactive documentation systems.
+ * Automatic client code generation systems, for many languages.
+* Provide 2 interactive documentation web interfaces directly.
+
+---
+
+We just scratched the surface, but you already get the idea of how it all works.
+
+Try changing the line with:
+
+```Python
+ return {"item_name": item.name, "item_id": item_id}
+```
+
+...from:
+
+```Python
+ ... "item_name": item.name ...
+```
+
+...to:
+
+```Python
+ ... "item_price": item.price ...
+```
+
+...and see how your editor will auto-complete the attributes and know their types:
+
+
+
+For a more complete example including more features, see the Tutorial - User Guide.
+
+**Spoiler alert**: the tutorial - user guide includes:
+
+* Declaration of **parameters** from other different places as: **headers**, **cookies**, **form fields** and **files**.
+* How to set **validation constraints** as `maximum_length` or `regex`.
+* A very powerful and easy to use **Dependency Injection** system.
+* Security and authentication, including support for **OAuth2** with **JWT tokens** and **HTTP Basic** auth.
+* More advanced (but equally easy) techniques for declaring **deeply nested JSON models** (thanks to Pydantic).
+* **GraphQL** integration with Strawberry and other libraries.
+* Many extra features (thanks to Starlette) as:
+ * **WebSockets**
+ * extremely easy tests based on HTTPX and `pytest`
+ * **CORS**
+ * **Cookie Sessions**
+ * ...and more.
+
+## Performance
+
+Independent TechEmpower benchmarks show **FastAPI** applications running under Uvicorn as one of the fastest Python frameworks available, only below Starlette and Uvicorn themselves (used internally by FastAPI). (*)
+
+To understand more about it, see the section Benchmarks.
+
+## Dependencies
+
+FastAPI depends on Pydantic and Starlette.
+
+### `standard` Dependencies
+
+When you install FastAPI with `pip install "fastapi[standard]"` it comes with the `standard` group of optional dependencies:
+
+Used by Pydantic:
+
+* email-validator - for email validation.
+
+Used by Starlette:
+
+* httpx - Required if you want to use the `TestClient`.
+* jinja2 - Required if you want to use the default template configuration.
+* python-multipart - Required if you want to support form "parsing", with `request.form()`.
+
+Used by FastAPI / Starlette:
+
+* uvicorn - for the server that loads and serves your application. This includes `uvicorn[standard]`, which includes some dependencies (e.g. `uvloop`) needed for high performance serving.
+* `fastapi-cli` - to provide the `fastapi` command.
+
+### Without `standard` Dependencies
+
+If you don't want to include the `standard` optional dependencies, you can install with `pip install fastapi` instead of `pip install "fastapi[standard]"`.
+
+### Additional Optional Dependencies
+
+There are some additional dependencies you might want to install.
+
+Additional optional Pydantic dependencies:
+
+* pydantic-settings - for settings management.
+* pydantic-extra-types - for extra types to be used with Pydantic.
+
+Additional optional FastAPI dependencies:
+
+* orjson - Required if you want to use `ORJSONResponse`.
+* ujson - Required if you want to use `UJSONResponse`.
+
+## License
+
+This project is licensed under the terms of the MIT license.
diff --git a/venv/Lib/site-packages/fastapi-0.115.14.dist-info/RECORD b/venv/Lib/site-packages/fastapi-0.115.14.dist-info/RECORD
new file mode 100644
index 00000000..b14145eb
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi-0.115.14.dist-info/RECORD
@@ -0,0 +1,97 @@
+../../Scripts/fastapi.exe,sha256=HeMeOECE5j0VKhIfzIDfMnAA4LATyaoAegFr0AGuWKM,108404
+fastapi-0.115.14.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
+fastapi-0.115.14.dist-info/METADATA,sha256=BKQS5L_nvCHYJUCYQujjjM8dxMoJDV84thmsHYxZiI0,27180
+fastapi-0.115.14.dist-info/RECORD,,
+fastapi-0.115.14.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
+fastapi-0.115.14.dist-info/WHEEL,sha256=tSfRZzRHthuv7vxpI4aehrdN9scLjk-dCJkPLzkHxGg,90
+fastapi-0.115.14.dist-info/entry_points.txt,sha256=GCf-WbIZxyGT4MUmrPGj1cOHYZoGsNPHAvNkT6hnGeA,61
+fastapi-0.115.14.dist-info/licenses/LICENSE,sha256=Tsif_IFIW5f-xYSy1KlhAy7v_oNEU4lP2cEnSQbMdE4,1086
+fastapi/__init__.py,sha256=zto_Knb1xNkut8EXy4Q4enLzjY6UIFsGKNCJUQpgcwc,1082
+fastapi/__main__.py,sha256=bKePXLdO4SsVSM6r9SVoLickJDcR2c0cTOxZRKq26YQ,37
+fastapi/__pycache__/__init__.cpython-312.pyc,,
+fastapi/__pycache__/__main__.cpython-312.pyc,,
+fastapi/__pycache__/_compat.cpython-312.pyc,,
+fastapi/__pycache__/applications.cpython-312.pyc,,
+fastapi/__pycache__/background.cpython-312.pyc,,
+fastapi/__pycache__/cli.cpython-312.pyc,,
+fastapi/__pycache__/concurrency.cpython-312.pyc,,
+fastapi/__pycache__/datastructures.cpython-312.pyc,,
+fastapi/__pycache__/encoders.cpython-312.pyc,,
+fastapi/__pycache__/exception_handlers.cpython-312.pyc,,
+fastapi/__pycache__/exceptions.cpython-312.pyc,,
+fastapi/__pycache__/logger.cpython-312.pyc,,
+fastapi/__pycache__/param_functions.cpython-312.pyc,,
+fastapi/__pycache__/params.cpython-312.pyc,,
+fastapi/__pycache__/requests.cpython-312.pyc,,
+fastapi/__pycache__/responses.cpython-312.pyc,,
+fastapi/__pycache__/routing.cpython-312.pyc,,
+fastapi/__pycache__/staticfiles.cpython-312.pyc,,
+fastapi/__pycache__/templating.cpython-312.pyc,,
+fastapi/__pycache__/testclient.cpython-312.pyc,,
+fastapi/__pycache__/types.cpython-312.pyc,,
+fastapi/__pycache__/utils.cpython-312.pyc,,
+fastapi/__pycache__/websockets.cpython-312.pyc,,
+fastapi/_compat.py,sha256=PwGTZd6d-u2o6YF9M8pQahuBtD_3q3Kpj7vU5-ngChc,24228
+fastapi/applications.py,sha256=rZTr0Ix-vdMwh6MQGCI_NC-Ir9lpfIGHHBY-JnNWZ_E,176550
+fastapi/background.py,sha256=rouLirxUANrcYC824MSMypXL_Qb2HYg2YZqaiEqbEKI,1768
+fastapi/cli.py,sha256=OYhZb0NR_deuT5ofyPF2NoNBzZDNOP8Salef2nk-HqA,418
+fastapi/concurrency.py,sha256=MirfowoSpkMQZ8j_g0ZxaQKpV6eB3G-dB5TgcXCrgEA,1424
+fastapi/datastructures.py,sha256=b2PEz77XGq-u3Ur1Inwk0AGjOsQZO49yF9C7IPJ15cY,5766
+fastapi/dependencies/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
+fastapi/dependencies/__pycache__/__init__.cpython-312.pyc,,
+fastapi/dependencies/__pycache__/models.cpython-312.pyc,,
+fastapi/dependencies/__pycache__/utils.cpython-312.pyc,,
+fastapi/dependencies/models.py,sha256=Pjl6vx-4nZ5Tta9kJa3-RfQKkXtCpS09-FhMgs9eWNs,1507
+fastapi/dependencies/utils.py,sha256=wGN-BAb0NpG-89nA_OllS0F4wYwGfhHgb8IuT3MTqck,36619
+fastapi/encoders.py,sha256=LvwYmFeOz4tVwvgBoC5rvZnbr7hZr73KGrU8O7zSptU,11068
+fastapi/exception_handlers.py,sha256=MBrIOA-ugjJDivIi4rSsUJBdTsjuzN76q4yh0q1COKw,1332
+fastapi/exceptions.py,sha256=taNixuFEXb67lI1bnX1ubq8y8TseJ4yoPlWjyP0fTzk,4969
+fastapi/logger.py,sha256=I9NNi3ov8AcqbsbC9wl1X-hdItKgYt2XTrx1f99Zpl4,54
+fastapi/middleware/__init__.py,sha256=oQDxiFVcc1fYJUOIFvphnK7pTT5kktmfL32QXpBFvvo,58
+fastapi/middleware/__pycache__/__init__.cpython-312.pyc,,
+fastapi/middleware/__pycache__/cors.cpython-312.pyc,,
+fastapi/middleware/__pycache__/gzip.cpython-312.pyc,,
+fastapi/middleware/__pycache__/httpsredirect.cpython-312.pyc,,
+fastapi/middleware/__pycache__/trustedhost.cpython-312.pyc,,
+fastapi/middleware/__pycache__/wsgi.cpython-312.pyc,,
+fastapi/middleware/cors.py,sha256=ynwjWQZoc_vbhzZ3_ZXceoaSrslHFHPdoM52rXr0WUU,79
+fastapi/middleware/gzip.py,sha256=xM5PcsH8QlAimZw4VDvcmTnqQamslThsfe3CVN2voa0,79
+fastapi/middleware/httpsredirect.py,sha256=rL8eXMnmLijwVkH7_400zHri1AekfeBd6D6qs8ix950,115
+fastapi/middleware/trustedhost.py,sha256=eE5XGRxGa7c5zPnMJDGp3BxaL25k5iVQlhnv-Pk0Pss,109
+fastapi/middleware/wsgi.py,sha256=Z3Ue-7wni4lUZMvH3G9ek__acgYdJstbnpZX_HQAboY,79
+fastapi/openapi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
+fastapi/openapi/__pycache__/__init__.cpython-312.pyc,,
+fastapi/openapi/__pycache__/constants.cpython-312.pyc,,
+fastapi/openapi/__pycache__/docs.cpython-312.pyc,,
+fastapi/openapi/__pycache__/models.cpython-312.pyc,,
+fastapi/openapi/__pycache__/utils.cpython-312.pyc,,
+fastapi/openapi/constants.py,sha256=adGzmis1L1HJRTE3kJ5fmHS_Noq6tIY6pWv_SFzoFDU,153
+fastapi/openapi/docs.py,sha256=zSDv4xY6XHcKsaG4zyk1HqSnrZtfZFBB0J7ZBk5YHPE,10345
+fastapi/openapi/models.py,sha256=PqkxQiqcEgjKuhfUIWPZPQcyTcubtUCB3vcObLsB7VE,15397
+fastapi/openapi/utils.py,sha256=e00G_p0IdpiffBUaq31BUyiloXbpld8RryKYnYKisdY,23964
+fastapi/param_functions.py,sha256=JHNPLIYvoAwdnZZavIVsxOat8x23fX_Kl33reh7HKl8,64019
+fastapi/params.py,sha256=g450axUBQgQJODdtM7WBxZbQj9Z64inFvadrgHikBbU,28237
+fastapi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
+fastapi/requests.py,sha256=zayepKFcienBllv3snmWI20Gk0oHNVLU4DDhqXBb4LU,142
+fastapi/responses.py,sha256=QNQQlwpKhQoIPZTTWkpc9d_QGeGZ_aVQPaDV3nQ8m7c,1761
+fastapi/routing.py,sha256=gnGRnOzM-CBOYj7hI0bZlC_5c-RQKh6BPmlsDD8IVUo,176315
+fastapi/security/__init__.py,sha256=bO8pNmxqVRXUjfl2mOKiVZLn0FpBQ61VUYVjmppnbJw,881
+fastapi/security/__pycache__/__init__.cpython-312.pyc,,
+fastapi/security/__pycache__/api_key.cpython-312.pyc,,
+fastapi/security/__pycache__/base.cpython-312.pyc,,
+fastapi/security/__pycache__/http.cpython-312.pyc,,
+fastapi/security/__pycache__/oauth2.cpython-312.pyc,,
+fastapi/security/__pycache__/open_id_connect_url.cpython-312.pyc,,
+fastapi/security/__pycache__/utils.cpython-312.pyc,,
+fastapi/security/api_key.py,sha256=cBI5Z4zWVjL1uJrsjTeLy7MafHPAO2HQPzTrpyoIYWA,9094
+fastapi/security/base.py,sha256=dl4pvbC-RxjfbWgPtCWd8MVU-7CB2SZ22rJDXVCXO6c,141
+fastapi/security/http.py,sha256=rWR2x-5CUsjWmRucYthwRig6MG1o-boyrr4Xo-PuuxU,13606
+fastapi/security/oauth2.py,sha256=M1AFIDT7G3oQChq83poI3eg8ZDeibcvnGmya2CTS7JY,22036
+fastapi/security/open_id_connect_url.py,sha256=8vizZ2tGqEp1ur8SwtVgyHJhGAJ5AqahgcvSpaIioDI,2722
+fastapi/security/utils.py,sha256=bd8T0YM7UQD5ATKucr1bNtAvz_Y3__dVNAv5UebiPvc,293
+fastapi/staticfiles.py,sha256=iirGIt3sdY2QZXd36ijs3Cj-T0FuGFda3cd90kM9Ikw,69
+fastapi/templating.py,sha256=4zsuTWgcjcEainMJFAlW6-gnslm6AgOS1SiiDWfmQxk,76
+fastapi/testclient.py,sha256=nBvaAmX66YldReJNZXPOk1sfuo2Q6hs8bOvIaCep6LQ,66
+fastapi/types.py,sha256=nFb36sK3DSoqoyo7Miwy3meKK5UdFBgkAgLSzQlUVyI,383
+fastapi/utils.py,sha256=y8Bj5ttMaI9tS4D60OUgXqKnktBr99NdYUnHHV9LgoY,7948
+fastapi/websockets.py,sha256=419uncYObEKZG0YcrXscfQQYLSWoE10jqxVMetGdR98,222
diff --git a/venv/Lib/site-packages/fastapi-0.115.14.dist-info/REQUESTED b/venv/Lib/site-packages/fastapi-0.115.14.dist-info/REQUESTED
new file mode 100644
index 00000000..e69de29b
diff --git a/venv/Lib/site-packages/fastapi-0.115.14.dist-info/WHEEL b/venv/Lib/site-packages/fastapi-0.115.14.dist-info/WHEEL
new file mode 100644
index 00000000..45ec8c4e
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi-0.115.14.dist-info/WHEEL
@@ -0,0 +1,4 @@
+Wheel-Version: 1.0
+Generator: pdm-backend (2.4.4)
+Root-Is-Purelib: true
+Tag: py3-none-any
diff --git a/venv/Lib/site-packages/fastapi-0.115.14.dist-info/entry_points.txt b/venv/Lib/site-packages/fastapi-0.115.14.dist-info/entry_points.txt
new file mode 100644
index 00000000..b81849e1
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi-0.115.14.dist-info/entry_points.txt
@@ -0,0 +1,5 @@
+[console_scripts]
+fastapi = fastapi.cli:main
+
+[gui_scripts]
+
diff --git a/venv/Lib/site-packages/fastapi-0.115.14.dist-info/licenses/LICENSE b/venv/Lib/site-packages/fastapi-0.115.14.dist-info/licenses/LICENSE
new file mode 100644
index 00000000..3e92463e
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi-0.115.14.dist-info/licenses/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2018 Sebastián Ramírez
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/venv/Lib/site-packages/fastapi/__init__.py b/venv/Lib/site-packages/fastapi/__init__.py
new file mode 100644
index 00000000..e672ec9e
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/__init__.py
@@ -0,0 +1,25 @@
+"""FastAPI framework, high performance, easy to learn, fast to code, ready for production"""
+
+__version__ = "0.115.14"
+
+from starlette import status as status
+
+from .applications import FastAPI as FastAPI
+from .background import BackgroundTasks as BackgroundTasks
+from .datastructures import UploadFile as UploadFile
+from .exceptions import HTTPException as HTTPException
+from .exceptions import WebSocketException as WebSocketException
+from .param_functions import Body as Body
+from .param_functions import Cookie as Cookie
+from .param_functions import Depends as Depends
+from .param_functions import File as File
+from .param_functions import Form as Form
+from .param_functions import Header as Header
+from .param_functions import Path as Path
+from .param_functions import Query as Query
+from .param_functions import Security as Security
+from .requests import Request as Request
+from .responses import Response as Response
+from .routing import APIRouter as APIRouter
+from .websockets import WebSocket as WebSocket
+from .websockets import WebSocketDisconnect as WebSocketDisconnect
diff --git a/venv/Lib/site-packages/fastapi/__main__.py b/venv/Lib/site-packages/fastapi/__main__.py
new file mode 100644
index 00000000..fc36465f
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/__main__.py
@@ -0,0 +1,3 @@
+from fastapi.cli import main
+
+main()
diff --git a/venv/Lib/site-packages/fastapi/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/fastapi/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 00000000..7a55750b
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/__pycache__/__main__.cpython-312.pyc b/venv/Lib/site-packages/fastapi/__pycache__/__main__.cpython-312.pyc
new file mode 100644
index 00000000..ba9fdf10
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/__pycache__/__main__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/__pycache__/_compat.cpython-312.pyc b/venv/Lib/site-packages/fastapi/__pycache__/_compat.cpython-312.pyc
new file mode 100644
index 00000000..52d218ae
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/__pycache__/_compat.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/__pycache__/applications.cpython-312.pyc b/venv/Lib/site-packages/fastapi/__pycache__/applications.cpython-312.pyc
new file mode 100644
index 00000000..f2a87e51
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/__pycache__/applications.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/__pycache__/background.cpython-312.pyc b/venv/Lib/site-packages/fastapi/__pycache__/background.cpython-312.pyc
new file mode 100644
index 00000000..6ec09524
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/__pycache__/background.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/__pycache__/cli.cpython-312.pyc b/venv/Lib/site-packages/fastapi/__pycache__/cli.cpython-312.pyc
new file mode 100644
index 00000000..2bd803c7
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/__pycache__/cli.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/__pycache__/concurrency.cpython-312.pyc b/venv/Lib/site-packages/fastapi/__pycache__/concurrency.cpython-312.pyc
new file mode 100644
index 00000000..e7c0719d
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/__pycache__/concurrency.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/__pycache__/datastructures.cpython-312.pyc b/venv/Lib/site-packages/fastapi/__pycache__/datastructures.cpython-312.pyc
new file mode 100644
index 00000000..8b2c9669
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/__pycache__/datastructures.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/__pycache__/encoders.cpython-312.pyc b/venv/Lib/site-packages/fastapi/__pycache__/encoders.cpython-312.pyc
new file mode 100644
index 00000000..16e18d8f
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/__pycache__/encoders.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/__pycache__/exception_handlers.cpython-312.pyc b/venv/Lib/site-packages/fastapi/__pycache__/exception_handlers.cpython-312.pyc
new file mode 100644
index 00000000..0f9c4677
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/__pycache__/exception_handlers.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/__pycache__/exceptions.cpython-312.pyc b/venv/Lib/site-packages/fastapi/__pycache__/exceptions.cpython-312.pyc
new file mode 100644
index 00000000..2c83d659
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/__pycache__/exceptions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/__pycache__/logger.cpython-312.pyc b/venv/Lib/site-packages/fastapi/__pycache__/logger.cpython-312.pyc
new file mode 100644
index 00000000..5133344a
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/__pycache__/logger.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/__pycache__/param_functions.cpython-312.pyc b/venv/Lib/site-packages/fastapi/__pycache__/param_functions.cpython-312.pyc
new file mode 100644
index 00000000..ebc1c3ae
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/__pycache__/param_functions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/__pycache__/params.cpython-312.pyc b/venv/Lib/site-packages/fastapi/__pycache__/params.cpython-312.pyc
new file mode 100644
index 00000000..ae052d98
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/__pycache__/params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/__pycache__/requests.cpython-312.pyc b/venv/Lib/site-packages/fastapi/__pycache__/requests.cpython-312.pyc
new file mode 100644
index 00000000..08b8b7e9
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/__pycache__/requests.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/__pycache__/responses.cpython-312.pyc b/venv/Lib/site-packages/fastapi/__pycache__/responses.cpython-312.pyc
new file mode 100644
index 00000000..ae278fdf
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/__pycache__/responses.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/__pycache__/routing.cpython-312.pyc b/venv/Lib/site-packages/fastapi/__pycache__/routing.cpython-312.pyc
new file mode 100644
index 00000000..ac901a7f
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/__pycache__/routing.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/__pycache__/staticfiles.cpython-312.pyc b/venv/Lib/site-packages/fastapi/__pycache__/staticfiles.cpython-312.pyc
new file mode 100644
index 00000000..71a75c07
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/__pycache__/staticfiles.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/__pycache__/templating.cpython-312.pyc b/venv/Lib/site-packages/fastapi/__pycache__/templating.cpython-312.pyc
new file mode 100644
index 00000000..3022a791
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/__pycache__/templating.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/__pycache__/testclient.cpython-312.pyc b/venv/Lib/site-packages/fastapi/__pycache__/testclient.cpython-312.pyc
new file mode 100644
index 00000000..665bacaa
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/__pycache__/testclient.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/__pycache__/types.cpython-312.pyc b/venv/Lib/site-packages/fastapi/__pycache__/types.cpython-312.pyc
new file mode 100644
index 00000000..c468add3
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/__pycache__/types.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/__pycache__/utils.cpython-312.pyc b/venv/Lib/site-packages/fastapi/__pycache__/utils.cpython-312.pyc
new file mode 100644
index 00000000..30070740
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/__pycache__/utils.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/__pycache__/websockets.cpython-312.pyc b/venv/Lib/site-packages/fastapi/__pycache__/websockets.cpython-312.pyc
new file mode 100644
index 00000000..408b43e7
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/__pycache__/websockets.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/_compat.py b/venv/Lib/site-packages/fastapi/_compat.py
new file mode 100644
index 00000000..227ad837
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/_compat.py
@@ -0,0 +1,664 @@
+from collections import deque
+from copy import copy
+from dataclasses import dataclass, is_dataclass
+from enum import Enum
+from functools import lru_cache
+from typing import (
+ Any,
+ Callable,
+ Deque,
+ Dict,
+ FrozenSet,
+ List,
+ Mapping,
+ Sequence,
+ Set,
+ Tuple,
+ Type,
+ Union,
+ cast,
+)
+
+from fastapi.exceptions import RequestErrorModel
+from fastapi.types import IncEx, ModelNameMap, UnionType
+from pydantic import BaseModel, create_model
+from pydantic.version import VERSION as PYDANTIC_VERSION
+from starlette.datastructures import UploadFile
+from typing_extensions import Annotated, Literal, get_args, get_origin
+
+PYDANTIC_VERSION_MINOR_TUPLE = tuple(int(x) for x in PYDANTIC_VERSION.split(".")[:2])
+PYDANTIC_V2 = PYDANTIC_VERSION_MINOR_TUPLE[0] == 2
+
+
+sequence_annotation_to_type = {
+ Sequence: list,
+ List: list,
+ list: list,
+ Tuple: tuple,
+ tuple: tuple,
+ Set: set,
+ set: set,
+ FrozenSet: frozenset,
+ frozenset: frozenset,
+ Deque: deque,
+ deque: deque,
+}
+
+sequence_types = tuple(sequence_annotation_to_type.keys())
+
+Url: Type[Any]
+
+if PYDANTIC_V2:
+ from pydantic import PydanticSchemaGenerationError as PydanticSchemaGenerationError
+ from pydantic import TypeAdapter
+ from pydantic import ValidationError as ValidationError
+ from pydantic._internal._schema_generation_shared import ( # type: ignore[attr-defined]
+ GetJsonSchemaHandler as GetJsonSchemaHandler,
+ )
+ from pydantic._internal._typing_extra import eval_type_lenient
+ from pydantic._internal._utils import lenient_issubclass as lenient_issubclass
+ from pydantic.fields import FieldInfo
+ from pydantic.json_schema import GenerateJsonSchema as GenerateJsonSchema
+ from pydantic.json_schema import JsonSchemaValue as JsonSchemaValue
+ from pydantic_core import CoreSchema as CoreSchema
+ from pydantic_core import PydanticUndefined, PydanticUndefinedType
+ from pydantic_core import Url as Url
+
+ try:
+ from pydantic_core.core_schema import (
+ with_info_plain_validator_function as with_info_plain_validator_function,
+ )
+ except ImportError: # pragma: no cover
+ from pydantic_core.core_schema import (
+ general_plain_validator_function as with_info_plain_validator_function, # noqa: F401
+ )
+
+ RequiredParam = PydanticUndefined
+ Undefined = PydanticUndefined
+ UndefinedType = PydanticUndefinedType
+ evaluate_forwardref = eval_type_lenient
+ Validator = Any
+
+ class BaseConfig:
+ pass
+
+ class ErrorWrapper(Exception):
+ pass
+
+ @dataclass
+ class ModelField:
+ field_info: FieldInfo
+ name: str
+ mode: Literal["validation", "serialization"] = "validation"
+
+ @property
+ def alias(self) -> str:
+ a = self.field_info.alias
+ return a if a is not None else self.name
+
+ @property
+ def required(self) -> bool:
+ return self.field_info.is_required()
+
+ @property
+ def default(self) -> Any:
+ return self.get_default()
+
+ @property
+ def type_(self) -> Any:
+ return self.field_info.annotation
+
+ def __post_init__(self) -> None:
+ self._type_adapter: TypeAdapter[Any] = TypeAdapter(
+ Annotated[self.field_info.annotation, self.field_info]
+ )
+
+ def get_default(self) -> Any:
+ if self.field_info.is_required():
+ return Undefined
+ return self.field_info.get_default(call_default_factory=True)
+
+ def validate(
+ self,
+ value: Any,
+ values: Dict[str, Any] = {}, # noqa: B006
+ *,
+ loc: Tuple[Union[int, str], ...] = (),
+ ) -> Tuple[Any, Union[List[Dict[str, Any]], None]]:
+ try:
+ return (
+ self._type_adapter.validate_python(value, from_attributes=True),
+ None,
+ )
+ except ValidationError as exc:
+ return None, _regenerate_error_with_loc(
+ errors=exc.errors(include_url=False), loc_prefix=loc
+ )
+
+ def serialize(
+ self,
+ value: Any,
+ *,
+ mode: Literal["json", "python"] = "json",
+ include: Union[IncEx, None] = None,
+ exclude: Union[IncEx, None] = None,
+ by_alias: bool = True,
+ exclude_unset: bool = False,
+ exclude_defaults: bool = False,
+ exclude_none: bool = False,
+ ) -> Any:
+ # What calls this code passes a value that already called
+ # self._type_adapter.validate_python(value)
+ return self._type_adapter.dump_python(
+ value,
+ mode=mode,
+ include=include,
+ exclude=exclude,
+ by_alias=by_alias,
+ exclude_unset=exclude_unset,
+ exclude_defaults=exclude_defaults,
+ exclude_none=exclude_none,
+ )
+
+ def __hash__(self) -> int:
+ # Each ModelField is unique for our purposes, to allow making a dict from
+ # ModelField to its JSON Schema.
+ return id(self)
+
+ def get_annotation_from_field_info(
+ annotation: Any, field_info: FieldInfo, field_name: str
+ ) -> Any:
+ return annotation
+
+ def _normalize_errors(errors: Sequence[Any]) -> List[Dict[str, Any]]:
+ return errors # type: ignore[return-value]
+
+ def _model_rebuild(model: Type[BaseModel]) -> None:
+ model.model_rebuild()
+
+ def _model_dump(
+ model: BaseModel, mode: Literal["json", "python"] = "json", **kwargs: Any
+ ) -> Any:
+ return model.model_dump(mode=mode, **kwargs)
+
+ def _get_model_config(model: BaseModel) -> Any:
+ return model.model_config
+
+ def get_schema_from_model_field(
+ *,
+ field: ModelField,
+ schema_generator: GenerateJsonSchema,
+ model_name_map: ModelNameMap,
+ field_mapping: Dict[
+ Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
+ ],
+ separate_input_output_schemas: bool = True,
+ ) -> Dict[str, Any]:
+ override_mode: Union[Literal["validation"], None] = (
+ None if separate_input_output_schemas else "validation"
+ )
+ # This expects that GenerateJsonSchema was already used to generate the definitions
+ json_schema = field_mapping[(field, override_mode or field.mode)]
+ if "$ref" not in json_schema:
+ # TODO remove when deprecating Pydantic v1
+ # Ref: https://github.com/pydantic/pydantic/blob/d61792cc42c80b13b23e3ffa74bc37ec7c77f7d1/pydantic/schema.py#L207
+ json_schema["title"] = (
+ field.field_info.title or field.alias.title().replace("_", " ")
+ )
+ return json_schema
+
+ def get_compat_model_name_map(fields: List[ModelField]) -> ModelNameMap:
+ return {}
+
+ def get_definitions(
+ *,
+ fields: List[ModelField],
+ schema_generator: GenerateJsonSchema,
+ model_name_map: ModelNameMap,
+ separate_input_output_schemas: bool = True,
+ ) -> Tuple[
+ Dict[
+ Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
+ ],
+ Dict[str, Dict[str, Any]],
+ ]:
+ override_mode: Union[Literal["validation"], None] = (
+ None if separate_input_output_schemas else "validation"
+ )
+ inputs = [
+ (field, override_mode or field.mode, field._type_adapter.core_schema)
+ for field in fields
+ ]
+ field_mapping, definitions = schema_generator.generate_definitions(
+ inputs=inputs
+ )
+ for item_def in cast(Dict[str, Dict[str, Any]], definitions).values():
+ if "description" in item_def:
+ item_description = cast(str, item_def["description"]).split("\f")[0]
+ item_def["description"] = item_description
+ return field_mapping, definitions # type: ignore[return-value]
+
+ def is_scalar_field(field: ModelField) -> bool:
+ from fastapi import params
+
+ return field_annotation_is_scalar(
+ field.field_info.annotation
+ ) and not isinstance(field.field_info, params.Body)
+
+ def is_sequence_field(field: ModelField) -> bool:
+ return field_annotation_is_sequence(field.field_info.annotation)
+
+ def is_scalar_sequence_field(field: ModelField) -> bool:
+ return field_annotation_is_scalar_sequence(field.field_info.annotation)
+
+ def is_bytes_field(field: ModelField) -> bool:
+ return is_bytes_or_nonable_bytes_annotation(field.type_)
+
+ def is_bytes_sequence_field(field: ModelField) -> bool:
+ return is_bytes_sequence_annotation(field.type_)
+
+ def copy_field_info(*, field_info: FieldInfo, annotation: Any) -> FieldInfo:
+ cls = type(field_info)
+ merged_field_info = cls.from_annotation(annotation)
+ new_field_info = copy(field_info)
+ new_field_info.metadata = merged_field_info.metadata
+ new_field_info.annotation = merged_field_info.annotation
+ return new_field_info
+
+ def serialize_sequence_value(*, field: ModelField, value: Any) -> Sequence[Any]:
+ origin_type = (
+ get_origin(field.field_info.annotation) or field.field_info.annotation
+ )
+ assert issubclass(origin_type, sequence_types) # type: ignore[arg-type]
+ return sequence_annotation_to_type[origin_type](value) # type: ignore[no-any-return]
+
+ def get_missing_field_error(loc: Tuple[str, ...]) -> Dict[str, Any]:
+ error = ValidationError.from_exception_data(
+ "Field required", [{"type": "missing", "loc": loc, "input": {}}]
+ ).errors(include_url=False)[0]
+ error["input"] = None
+ return error # type: ignore[return-value]
+
+ def create_body_model(
+ *, fields: Sequence[ModelField], model_name: str
+ ) -> Type[BaseModel]:
+ field_params = {f.name: (f.field_info.annotation, f.field_info) for f in fields}
+ BodyModel: Type[BaseModel] = create_model(model_name, **field_params) # type: ignore[call-overload]
+ return BodyModel
+
+ def get_model_fields(model: Type[BaseModel]) -> List[ModelField]:
+ return [
+ ModelField(field_info=field_info, name=name)
+ for name, field_info in model.model_fields.items()
+ ]
+
+else:
+ from fastapi.openapi.constants import REF_PREFIX as REF_PREFIX
+ from pydantic import AnyUrl as Url # noqa: F401
+ from pydantic import ( # type: ignore[assignment]
+ BaseConfig as BaseConfig, # noqa: F401
+ )
+ from pydantic import ValidationError as ValidationError # noqa: F401
+ from pydantic.class_validators import ( # type: ignore[no-redef]
+ Validator as Validator, # noqa: F401
+ )
+ from pydantic.error_wrappers import ( # type: ignore[no-redef]
+ ErrorWrapper as ErrorWrapper, # noqa: F401
+ )
+ from pydantic.errors import MissingError
+ from pydantic.fields import ( # type: ignore[attr-defined]
+ SHAPE_FROZENSET,
+ SHAPE_LIST,
+ SHAPE_SEQUENCE,
+ SHAPE_SET,
+ SHAPE_SINGLETON,
+ SHAPE_TUPLE,
+ SHAPE_TUPLE_ELLIPSIS,
+ )
+ from pydantic.fields import FieldInfo as FieldInfo
+ from pydantic.fields import ( # type: ignore[no-redef,attr-defined]
+ ModelField as ModelField, # noqa: F401
+ )
+
+ # Keeping old "Required" functionality from Pydantic V1, without
+ # shadowing typing.Required.
+ RequiredParam: Any = Ellipsis # type: ignore[no-redef]
+ from pydantic.fields import ( # type: ignore[no-redef,attr-defined]
+ Undefined as Undefined,
+ )
+ from pydantic.fields import ( # type: ignore[no-redef, attr-defined]
+ UndefinedType as UndefinedType, # noqa: F401
+ )
+ from pydantic.schema import (
+ field_schema,
+ get_flat_models_from_fields,
+ get_model_name_map,
+ model_process_schema,
+ )
+ from pydantic.schema import ( # type: ignore[no-redef] # noqa: F401
+ get_annotation_from_field_info as get_annotation_from_field_info,
+ )
+ from pydantic.typing import ( # type: ignore[no-redef]
+ evaluate_forwardref as evaluate_forwardref, # noqa: F401
+ )
+ from pydantic.utils import ( # type: ignore[no-redef]
+ lenient_issubclass as lenient_issubclass, # noqa: F401
+ )
+
+ GetJsonSchemaHandler = Any # type: ignore[assignment,misc]
+ JsonSchemaValue = Dict[str, Any] # type: ignore[misc]
+ CoreSchema = Any # type: ignore[assignment,misc]
+
+ sequence_shapes = {
+ SHAPE_LIST,
+ SHAPE_SET,
+ SHAPE_FROZENSET,
+ SHAPE_TUPLE,
+ SHAPE_SEQUENCE,
+ SHAPE_TUPLE_ELLIPSIS,
+ }
+ sequence_shape_to_type = {
+ SHAPE_LIST: list,
+ SHAPE_SET: set,
+ SHAPE_TUPLE: tuple,
+ SHAPE_SEQUENCE: list,
+ SHAPE_TUPLE_ELLIPSIS: list,
+ }
+
+ @dataclass
+ class GenerateJsonSchema: # type: ignore[no-redef]
+ ref_template: str
+
+ class PydanticSchemaGenerationError(Exception): # type: ignore[no-redef]
+ pass
+
+ def with_info_plain_validator_function( # type: ignore[misc]
+ function: Callable[..., Any],
+ *,
+ ref: Union[str, None] = None,
+ metadata: Any = None,
+ serialization: Any = None,
+ ) -> Any:
+ return {}
+
+ def get_model_definitions(
+ *,
+ flat_models: Set[Union[Type[BaseModel], Type[Enum]]],
+ model_name_map: Dict[Union[Type[BaseModel], Type[Enum]], str],
+ ) -> Dict[str, Any]:
+ definitions: Dict[str, Dict[str, Any]] = {}
+ for model in flat_models:
+ m_schema, m_definitions, m_nested_models = model_process_schema(
+ model, model_name_map=model_name_map, ref_prefix=REF_PREFIX
+ )
+ definitions.update(m_definitions)
+ model_name = model_name_map[model]
+ if "description" in m_schema:
+ m_schema["description"] = m_schema["description"].split("\f")[0]
+ definitions[model_name] = m_schema
+ return definitions
+
+ def is_pv1_scalar_field(field: ModelField) -> bool:
+ from fastapi import params
+
+ field_info = field.field_info
+ if not (
+ field.shape == SHAPE_SINGLETON # type: ignore[attr-defined]
+ and not lenient_issubclass(field.type_, BaseModel)
+ and not lenient_issubclass(field.type_, dict)
+ and not field_annotation_is_sequence(field.type_)
+ and not is_dataclass(field.type_)
+ and not isinstance(field_info, params.Body)
+ ):
+ return False
+ if field.sub_fields: # type: ignore[attr-defined]
+ if not all(
+ is_pv1_scalar_field(f)
+ for f in field.sub_fields # type: ignore[attr-defined]
+ ):
+ return False
+ return True
+
+ def is_pv1_scalar_sequence_field(field: ModelField) -> bool:
+ if (field.shape in sequence_shapes) and not lenient_issubclass( # type: ignore[attr-defined]
+ field.type_, BaseModel
+ ):
+ if field.sub_fields is not None: # type: ignore[attr-defined]
+ for sub_field in field.sub_fields: # type: ignore[attr-defined]
+ if not is_pv1_scalar_field(sub_field):
+ return False
+ return True
+ if _annotation_is_sequence(field.type_):
+ return True
+ return False
+
+ def _normalize_errors(errors: Sequence[Any]) -> List[Dict[str, Any]]:
+ use_errors: List[Any] = []
+ for error in errors:
+ if isinstance(error, ErrorWrapper):
+ new_errors = ValidationError( # type: ignore[call-arg]
+ errors=[error], model=RequestErrorModel
+ ).errors()
+ use_errors.extend(new_errors)
+ elif isinstance(error, list):
+ use_errors.extend(_normalize_errors(error))
+ else:
+ use_errors.append(error)
+ return use_errors
+
+ def _model_rebuild(model: Type[BaseModel]) -> None:
+ model.update_forward_refs()
+
+ def _model_dump(
+ model: BaseModel, mode: Literal["json", "python"] = "json", **kwargs: Any
+ ) -> Any:
+ return model.dict(**kwargs)
+
+ def _get_model_config(model: BaseModel) -> Any:
+ return model.__config__ # type: ignore[attr-defined]
+
+ def get_schema_from_model_field(
+ *,
+ field: ModelField,
+ schema_generator: GenerateJsonSchema,
+ model_name_map: ModelNameMap,
+ field_mapping: Dict[
+ Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
+ ],
+ separate_input_output_schemas: bool = True,
+ ) -> Dict[str, Any]:
+ # This expects that GenerateJsonSchema was already used to generate the definitions
+ return field_schema( # type: ignore[no-any-return]
+ field, model_name_map=model_name_map, ref_prefix=REF_PREFIX
+ )[0]
+
+ def get_compat_model_name_map(fields: List[ModelField]) -> ModelNameMap:
+ models = get_flat_models_from_fields(fields, known_models=set())
+ return get_model_name_map(models) # type: ignore[no-any-return]
+
+ def get_definitions(
+ *,
+ fields: List[ModelField],
+ schema_generator: GenerateJsonSchema,
+ model_name_map: ModelNameMap,
+ separate_input_output_schemas: bool = True,
+ ) -> Tuple[
+ Dict[
+ Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
+ ],
+ Dict[str, Dict[str, Any]],
+ ]:
+ models = get_flat_models_from_fields(fields, known_models=set())
+ return {}, get_model_definitions(
+ flat_models=models, model_name_map=model_name_map
+ )
+
+ def is_scalar_field(field: ModelField) -> bool:
+ return is_pv1_scalar_field(field)
+
+ def is_sequence_field(field: ModelField) -> bool:
+ return field.shape in sequence_shapes or _annotation_is_sequence(field.type_) # type: ignore[attr-defined]
+
+ def is_scalar_sequence_field(field: ModelField) -> bool:
+ return is_pv1_scalar_sequence_field(field)
+
+ def is_bytes_field(field: ModelField) -> bool:
+ return lenient_issubclass(field.type_, bytes)
+
+ def is_bytes_sequence_field(field: ModelField) -> bool:
+ return field.shape in sequence_shapes and lenient_issubclass(field.type_, bytes) # type: ignore[attr-defined]
+
+ def copy_field_info(*, field_info: FieldInfo, annotation: Any) -> FieldInfo:
+ return copy(field_info)
+
+ def serialize_sequence_value(*, field: ModelField, value: Any) -> Sequence[Any]:
+ return sequence_shape_to_type[field.shape](value) # type: ignore[no-any-return,attr-defined]
+
+ def get_missing_field_error(loc: Tuple[str, ...]) -> Dict[str, Any]:
+ missing_field_error = ErrorWrapper(MissingError(), loc=loc) # type: ignore[call-arg]
+ new_error = ValidationError([missing_field_error], RequestErrorModel)
+ return new_error.errors()[0] # type: ignore[return-value]
+
+ def create_body_model(
+ *, fields: Sequence[ModelField], model_name: str
+ ) -> Type[BaseModel]:
+ BodyModel = create_model(model_name)
+ for f in fields:
+ BodyModel.__fields__[f.name] = f # type: ignore[index]
+ return BodyModel
+
+ def get_model_fields(model: Type[BaseModel]) -> List[ModelField]:
+ return list(model.__fields__.values()) # type: ignore[attr-defined]
+
+
+def _regenerate_error_with_loc(
+ *, errors: Sequence[Any], loc_prefix: Tuple[Union[str, int], ...]
+) -> List[Dict[str, Any]]:
+ updated_loc_errors: List[Any] = [
+ {**err, "loc": loc_prefix + err.get("loc", ())}
+ for err in _normalize_errors(errors)
+ ]
+
+ return updated_loc_errors
+
+
+def _annotation_is_sequence(annotation: Union[Type[Any], None]) -> bool:
+ if lenient_issubclass(annotation, (str, bytes)):
+ return False
+ return lenient_issubclass(annotation, sequence_types)
+
+
+def field_annotation_is_sequence(annotation: Union[Type[Any], None]) -> bool:
+ origin = get_origin(annotation)
+ if origin is Union or origin is UnionType:
+ for arg in get_args(annotation):
+ if field_annotation_is_sequence(arg):
+ return True
+ return False
+ return _annotation_is_sequence(annotation) or _annotation_is_sequence(
+ get_origin(annotation)
+ )
+
+
+def value_is_sequence(value: Any) -> bool:
+ return isinstance(value, sequence_types) and not isinstance(value, (str, bytes)) # type: ignore[arg-type]
+
+
+def _annotation_is_complex(annotation: Union[Type[Any], None]) -> bool:
+ return (
+ lenient_issubclass(annotation, (BaseModel, Mapping, UploadFile))
+ or _annotation_is_sequence(annotation)
+ or is_dataclass(annotation)
+ )
+
+
+def field_annotation_is_complex(annotation: Union[Type[Any], None]) -> bool:
+ origin = get_origin(annotation)
+ if origin is Union or origin is UnionType:
+ return any(field_annotation_is_complex(arg) for arg in get_args(annotation))
+
+ return (
+ _annotation_is_complex(annotation)
+ or _annotation_is_complex(origin)
+ or hasattr(origin, "__pydantic_core_schema__")
+ or hasattr(origin, "__get_pydantic_core_schema__")
+ )
+
+
+def field_annotation_is_scalar(annotation: Any) -> bool:
+ # handle Ellipsis here to make tuple[int, ...] work nicely
+ return annotation is Ellipsis or not field_annotation_is_complex(annotation)
+
+
+def field_annotation_is_scalar_sequence(annotation: Union[Type[Any], None]) -> bool:
+ origin = get_origin(annotation)
+ if origin is Union or origin is UnionType:
+ at_least_one_scalar_sequence = False
+ for arg in get_args(annotation):
+ if field_annotation_is_scalar_sequence(arg):
+ at_least_one_scalar_sequence = True
+ continue
+ elif not field_annotation_is_scalar(arg):
+ return False
+ return at_least_one_scalar_sequence
+ return field_annotation_is_sequence(annotation) and all(
+ field_annotation_is_scalar(sub_annotation)
+ for sub_annotation in get_args(annotation)
+ )
+
+
+def is_bytes_or_nonable_bytes_annotation(annotation: Any) -> bool:
+ if lenient_issubclass(annotation, bytes):
+ return True
+ origin = get_origin(annotation)
+ if origin is Union or origin is UnionType:
+ for arg in get_args(annotation):
+ if lenient_issubclass(arg, bytes):
+ return True
+ return False
+
+
+def is_uploadfile_or_nonable_uploadfile_annotation(annotation: Any) -> bool:
+ if lenient_issubclass(annotation, UploadFile):
+ return True
+ origin = get_origin(annotation)
+ if origin is Union or origin is UnionType:
+ for arg in get_args(annotation):
+ if lenient_issubclass(arg, UploadFile):
+ return True
+ return False
+
+
+def is_bytes_sequence_annotation(annotation: Any) -> bool:
+ origin = get_origin(annotation)
+ if origin is Union or origin is UnionType:
+ at_least_one = False
+ for arg in get_args(annotation):
+ if is_bytes_sequence_annotation(arg):
+ at_least_one = True
+ continue
+ return at_least_one
+ return field_annotation_is_sequence(annotation) and all(
+ is_bytes_or_nonable_bytes_annotation(sub_annotation)
+ for sub_annotation in get_args(annotation)
+ )
+
+
+def is_uploadfile_sequence_annotation(annotation: Any) -> bool:
+ origin = get_origin(annotation)
+ if origin is Union or origin is UnionType:
+ at_least_one = False
+ for arg in get_args(annotation):
+ if is_uploadfile_sequence_annotation(arg):
+ at_least_one = True
+ continue
+ return at_least_one
+ return field_annotation_is_sequence(annotation) and all(
+ is_uploadfile_or_nonable_uploadfile_annotation(sub_annotation)
+ for sub_annotation in get_args(annotation)
+ )
+
+
+@lru_cache
+def get_cached_model_fields(model: Type[BaseModel]) -> List[ModelField]:
+ return get_model_fields(model)
diff --git a/venv/Lib/site-packages/fastapi/applications.py b/venv/Lib/site-packages/fastapi/applications.py
new file mode 100644
index 00000000..05c7bd2b
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/applications.py
@@ -0,0 +1,4588 @@
+from enum import Enum
+from typing import (
+ Any,
+ Awaitable,
+ Callable,
+ Coroutine,
+ Dict,
+ List,
+ Optional,
+ Sequence,
+ Type,
+ TypeVar,
+ Union,
+)
+
+from fastapi import routing
+from fastapi.datastructures import Default, DefaultPlaceholder
+from fastapi.exception_handlers import (
+ http_exception_handler,
+ request_validation_exception_handler,
+ websocket_request_validation_exception_handler,
+)
+from fastapi.exceptions import RequestValidationError, WebSocketRequestValidationError
+from fastapi.logger import logger
+from fastapi.openapi.docs import (
+ get_redoc_html,
+ get_swagger_ui_html,
+ get_swagger_ui_oauth2_redirect_html,
+)
+from fastapi.openapi.utils import get_openapi
+from fastapi.params import Depends
+from fastapi.types import DecoratedCallable, IncEx
+from fastapi.utils import generate_unique_id
+from starlette.applications import Starlette
+from starlette.datastructures import State
+from starlette.exceptions import HTTPException
+from starlette.middleware import Middleware
+from starlette.middleware.base import BaseHTTPMiddleware
+from starlette.requests import Request
+from starlette.responses import HTMLResponse, JSONResponse, Response
+from starlette.routing import BaseRoute
+from starlette.types import ASGIApp, Lifespan, Receive, Scope, Send
+from typing_extensions import Annotated, Doc, deprecated
+
+AppType = TypeVar("AppType", bound="FastAPI")
+
+
+class FastAPI(Starlette):
+ """
+ `FastAPI` app class, the main entrypoint to use FastAPI.
+
+ Read more in the
+ [FastAPI docs for First Steps](https://fastapi.tiangolo.com/tutorial/first-steps/).
+
+ ## Example
+
+ ```python
+ from fastapi import FastAPI
+
+ app = FastAPI()
+ ```
+ """
+
+ def __init__(
+ self: AppType,
+ *,
+ debug: Annotated[
+ bool,
+ Doc(
+ """
+ Boolean indicating if debug tracebacks should be returned on server
+ errors.
+
+ Read more in the
+ [Starlette docs for Applications](https://www.starlette.io/applications/#instantiating-the-application).
+ """
+ ),
+ ] = False,
+ routes: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ **Note**: you probably shouldn't use this parameter, it is inherited
+ from Starlette and supported for compatibility.
+
+ ---
+
+ A list of routes to serve incoming HTTP and WebSocket requests.
+ """
+ ),
+ deprecated(
+ """
+ You normally wouldn't use this parameter with FastAPI, it is inherited
+ from Starlette and supported for compatibility.
+
+ In FastAPI, you normally would use the *path operation methods*,
+ like `app.get()`, `app.post()`, etc.
+ """
+ ),
+ ] = None,
+ title: Annotated[
+ str,
+ Doc(
+ """
+ The title of the API.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more in the
+ [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-api).
+
+ **Example**
+
+ ```python
+ from fastapi import FastAPI
+
+ app = FastAPI(title="ChimichangApp")
+ ```
+ """
+ ),
+ ] = "FastAPI",
+ summary: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A short summary of the API.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more in the
+ [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-api).
+
+ **Example**
+
+ ```python
+ from fastapi import FastAPI
+
+ app = FastAPI(summary="Deadpond's favorite app. Nuff said.")
+ ```
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ str,
+ Doc(
+ '''
+ A description of the API. Supports Markdown (using
+ [CommonMark syntax](https://commonmark.org/)).
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more in the
+ [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-api).
+
+ **Example**
+
+ ```python
+ from fastapi import FastAPI
+
+ app = FastAPI(
+ description="""
+ ChimichangApp API helps you do awesome stuff. 🚀
+
+ ## Items
+
+ You can **read items**.
+
+ ## Users
+
+ You will be able to:
+
+ * **Create users** (_not implemented_).
+ * **Read users** (_not implemented_).
+
+ """
+ )
+ ```
+ '''
+ ),
+ ] = "",
+ version: Annotated[
+ str,
+ Doc(
+ """
+ The version of the API.
+
+ **Note** This is the version of your application, not the version of
+ the OpenAPI specification nor the version of FastAPI being used.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more in the
+ [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-api).
+
+ **Example**
+
+ ```python
+ from fastapi import FastAPI
+
+ app = FastAPI(version="0.0.1")
+ ```
+ """
+ ),
+ ] = "0.1.0",
+ openapi_url: Annotated[
+ Optional[str],
+ Doc(
+ """
+ The URL where the OpenAPI schema will be served from.
+
+ If you set it to `None`, no OpenAPI schema will be served publicly, and
+ the default automatic endpoints `/docs` and `/redoc` will also be
+ disabled.
+
+ Read more in the
+ [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#openapi-url).
+
+ **Example**
+
+ ```python
+ from fastapi import FastAPI
+
+ app = FastAPI(openapi_url="/api/v1/openapi.json")
+ ```
+ """
+ ),
+ ] = "/openapi.json",
+ openapi_tags: Annotated[
+ Optional[List[Dict[str, Any]]],
+ Doc(
+ """
+ A list of tags used by OpenAPI, these are the same `tags` you can set
+ in the *path operations*, like:
+
+ * `@app.get("/users/", tags=["users"])`
+ * `@app.get("/items/", tags=["items"])`
+
+ The order of the tags can be used to specify the order shown in
+ tools like Swagger UI, used in the automatic path `/docs`.
+
+ It's not required to specify all the tags used.
+
+ The tags that are not declared MAY be organized randomly or based
+ on the tools' logic. Each tag name in the list MUST be unique.
+
+ The value of each item is a `dict` containing:
+
+ * `name`: The name of the tag.
+ * `description`: A short description of the tag.
+ [CommonMark syntax](https://commonmark.org/) MAY be used for rich
+ text representation.
+ * `externalDocs`: Additional external documentation for this tag. If
+ provided, it would contain a `dict` with:
+ * `description`: A short description of the target documentation.
+ [CommonMark syntax](https://commonmark.org/) MAY be used for
+ rich text representation.
+ * `url`: The URL for the target documentation. Value MUST be in
+ the form of a URL.
+
+ Read more in the
+ [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-tags).
+
+ **Example**
+
+ ```python
+ from fastapi import FastAPI
+
+ tags_metadata = [
+ {
+ "name": "users",
+ "description": "Operations with users. The **login** logic is also here.",
+ },
+ {
+ "name": "items",
+ "description": "Manage items. So _fancy_ they have their own docs.",
+ "externalDocs": {
+ "description": "Items external docs",
+ "url": "https://fastapi.tiangolo.com/",
+ },
+ },
+ ]
+
+ app = FastAPI(openapi_tags=tags_metadata)
+ ```
+ """
+ ),
+ ] = None,
+ servers: Annotated[
+ Optional[List[Dict[str, Union[str, Any]]]],
+ Doc(
+ """
+ A `list` of `dict`s with connectivity information to a target server.
+
+ You would use it, for example, if your application is served from
+ different domains and you want to use the same Swagger UI in the
+ browser to interact with each of them (instead of having multiple
+ browser tabs open). Or if you want to leave fixed the possible URLs.
+
+ If the servers `list` is not provided, or is an empty `list`, the
+ default value would be a `dict` with a `url` value of `/`.
+
+ Each item in the `list` is a `dict` containing:
+
+ * `url`: A URL to the target host. This URL supports Server Variables
+ and MAY be relative, to indicate that the host location is relative
+ to the location where the OpenAPI document is being served. Variable
+ substitutions will be made when a variable is named in `{`brackets`}`.
+ * `description`: An optional string describing the host designated by
+ the URL. [CommonMark syntax](https://commonmark.org/) MAY be used for
+ rich text representation.
+ * `variables`: A `dict` between a variable name and its value. The value
+ is used for substitution in the server's URL template.
+
+ Read more in the
+ [FastAPI docs for Behind a Proxy](https://fastapi.tiangolo.com/advanced/behind-a-proxy/#additional-servers).
+
+ **Example**
+
+ ```python
+ from fastapi import FastAPI
+
+ app = FastAPI(
+ servers=[
+ {"url": "https://stag.example.com", "description": "Staging environment"},
+ {"url": "https://prod.example.com", "description": "Production environment"},
+ ]
+ )
+ ```
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[Depends]],
+ Doc(
+ """
+ A list of global dependencies, they will be applied to each
+ *path operation*, including in sub-routers.
+
+ Read more about it in the
+ [FastAPI docs for Global Dependencies](https://fastapi.tiangolo.com/tutorial/dependencies/global-dependencies/).
+
+ **Example**
+
+ ```python
+ from fastapi import Depends, FastAPI
+
+ from .dependencies import func_dep_1, func_dep_2
+
+ app = FastAPI(dependencies=[Depends(func_dep_1), Depends(func_dep_2)])
+ ```
+ """
+ ),
+ ] = None,
+ default_response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ The default response class to be used.
+
+ Read more in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#default-response-class).
+
+ **Example**
+
+ ```python
+ from fastapi import FastAPI
+ from fastapi.responses import ORJSONResponse
+
+ app = FastAPI(default_response_class=ORJSONResponse)
+ ```
+ """
+ ),
+ ] = Default(JSONResponse),
+ redirect_slashes: Annotated[
+ bool,
+ Doc(
+ """
+ Whether to detect and redirect slashes in URLs when the client doesn't
+ use the same format.
+
+ **Example**
+
+ ```python
+ from fastapi import FastAPI
+
+ app = FastAPI(redirect_slashes=True) # the default
+
+ @app.get("/items/")
+ async def read_items():
+ return [{"item_id": "Foo"}]
+ ```
+
+ With this app, if a client goes to `/items` (without a trailing slash),
+ they will be automatically redirected with an HTTP status code of 307
+ to `/items/`.
+ """
+ ),
+ ] = True,
+ docs_url: Annotated[
+ Optional[str],
+ Doc(
+ """
+ The path to the automatic interactive API documentation.
+ It is handled in the browser by Swagger UI.
+
+ The default URL is `/docs`. You can disable it by setting it to `None`.
+
+ If `openapi_url` is set to `None`, this will be automatically disabled.
+
+ Read more in the
+ [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#docs-urls).
+
+ **Example**
+
+ ```python
+ from fastapi import FastAPI
+
+ app = FastAPI(docs_url="/documentation", redoc_url=None)
+ ```
+ """
+ ),
+ ] = "/docs",
+ redoc_url: Annotated[
+ Optional[str],
+ Doc(
+ """
+ The path to the alternative automatic interactive API documentation
+ provided by ReDoc.
+
+ The default URL is `/redoc`. You can disable it by setting it to `None`.
+
+ If `openapi_url` is set to `None`, this will be automatically disabled.
+
+ Read more in the
+ [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#docs-urls).
+
+ **Example**
+
+ ```python
+ from fastapi import FastAPI
+
+ app = FastAPI(docs_url="/documentation", redoc_url="redocumentation")
+ ```
+ """
+ ),
+ ] = "/redoc",
+ swagger_ui_oauth2_redirect_url: Annotated[
+ Optional[str],
+ Doc(
+ """
+ The OAuth2 redirect endpoint for the Swagger UI.
+
+ By default it is `/docs/oauth2-redirect`.
+
+ This is only used if you use OAuth2 (with the "Authorize" button)
+ with Swagger UI.
+ """
+ ),
+ ] = "/docs/oauth2-redirect",
+ swagger_ui_init_oauth: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ OAuth2 configuration for the Swagger UI, by default shown at `/docs`.
+
+ Read more about the available configuration options in the
+ [Swagger UI docs](https://swagger.io/docs/open-source-tools/swagger-ui/usage/oauth2/).
+ """
+ ),
+ ] = None,
+ middleware: Annotated[
+ Optional[Sequence[Middleware]],
+ Doc(
+ """
+ List of middleware to be added when creating the application.
+
+ In FastAPI you would normally do this with `app.add_middleware()`
+ instead.
+
+ Read more in the
+ [FastAPI docs for Middleware](https://fastapi.tiangolo.com/tutorial/middleware/).
+ """
+ ),
+ ] = None,
+ exception_handlers: Annotated[
+ Optional[
+ Dict[
+ Union[int, Type[Exception]],
+ Callable[[Request, Any], Coroutine[Any, Any, Response]],
+ ]
+ ],
+ Doc(
+ """
+ A dictionary with handlers for exceptions.
+
+ In FastAPI, you would normally use the decorator
+ `@app.exception_handler()`.
+
+ Read more in the
+ [FastAPI docs for Handling Errors](https://fastapi.tiangolo.com/tutorial/handling-errors/).
+ """
+ ),
+ ] = None,
+ on_startup: Annotated[
+ Optional[Sequence[Callable[[], Any]]],
+ Doc(
+ """
+ A list of startup event handler functions.
+
+ You should instead use the `lifespan` handlers.
+
+ Read more in the [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/).
+ """
+ ),
+ ] = None,
+ on_shutdown: Annotated[
+ Optional[Sequence[Callable[[], Any]]],
+ Doc(
+ """
+ A list of shutdown event handler functions.
+
+ You should instead use the `lifespan` handlers.
+
+ Read more in the
+ [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/).
+ """
+ ),
+ ] = None,
+ lifespan: Annotated[
+ Optional[Lifespan[AppType]],
+ Doc(
+ """
+ A `Lifespan` context manager handler. This replaces `startup` and
+ `shutdown` functions with a single context manager.
+
+ Read more in the
+ [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/).
+ """
+ ),
+ ] = None,
+ terms_of_service: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A URL to the Terms of Service for your API.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more at the
+ [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-api).
+
+ **Example**
+
+ ```python
+ app = FastAPI(terms_of_service="http://example.com/terms/")
+ ```
+ """
+ ),
+ ] = None,
+ contact: Annotated[
+ Optional[Dict[str, Union[str, Any]]],
+ Doc(
+ """
+ A dictionary with the contact information for the exposed API.
+
+ It can contain several fields.
+
+ * `name`: (`str`) The name of the contact person/organization.
+ * `url`: (`str`) A URL pointing to the contact information. MUST be in
+ the format of a URL.
+ * `email`: (`str`) The email address of the contact person/organization.
+ MUST be in the format of an email address.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more at the
+ [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-api).
+
+ **Example**
+
+ ```python
+ app = FastAPI(
+ contact={
+ "name": "Deadpoolio the Amazing",
+ "url": "http://x-force.example.com/contact/",
+ "email": "dp@x-force.example.com",
+ }
+ )
+ ```
+ """
+ ),
+ ] = None,
+ license_info: Annotated[
+ Optional[Dict[str, Union[str, Any]]],
+ Doc(
+ """
+ A dictionary with the license information for the exposed API.
+
+ It can contain several fields.
+
+ * `name`: (`str`) **REQUIRED** (if a `license_info` is set). The
+ license name used for the API.
+ * `identifier`: (`str`) An [SPDX](https://spdx.dev/) license expression
+ for the API. The `identifier` field is mutually exclusive of the `url`
+ field. Available since OpenAPI 3.1.0, FastAPI 0.99.0.
+ * `url`: (`str`) A URL to the license used for the API. This MUST be
+ the format of a URL.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more at the
+ [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-api).
+
+ **Example**
+
+ ```python
+ app = FastAPI(
+ license_info={
+ "name": "Apache 2.0",
+ "url": "https://www.apache.org/licenses/LICENSE-2.0.html",
+ }
+ )
+ ```
+ """
+ ),
+ ] = None,
+ openapi_prefix: Annotated[
+ str,
+ Doc(
+ """
+ A URL prefix for the OpenAPI URL.
+ """
+ ),
+ deprecated(
+ """
+ "openapi_prefix" has been deprecated in favor of "root_path", which
+ follows more closely the ASGI standard, is simpler, and more
+ automatic.
+ """
+ ),
+ ] = "",
+ root_path: Annotated[
+ str,
+ Doc(
+ """
+ A path prefix handled by a proxy that is not seen by the application
+ but is seen by external clients, which affects things like Swagger UI.
+
+ Read more about it at the
+ [FastAPI docs for Behind a Proxy](https://fastapi.tiangolo.com/advanced/behind-a-proxy/).
+
+ **Example**
+
+ ```python
+ from fastapi import FastAPI
+
+ app = FastAPI(root_path="/api/v1")
+ ```
+ """
+ ),
+ ] = "",
+ root_path_in_servers: Annotated[
+ bool,
+ Doc(
+ """
+ To disable automatically generating the URLs in the `servers` field
+ in the autogenerated OpenAPI using the `root_path`.
+
+ Read more about it in the
+ [FastAPI docs for Behind a Proxy](https://fastapi.tiangolo.com/advanced/behind-a-proxy/#disable-automatic-server-from-root_path).
+
+ **Example**
+
+ ```python
+ from fastapi import FastAPI
+
+ app = FastAPI(root_path_in_servers=False)
+ ```
+ """
+ ),
+ ] = True,
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses to be shown in OpenAPI.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Additional Responses in OpenAPI](https://fastapi.tiangolo.com/advanced/additional-responses/).
+
+ And in the
+ [FastAPI docs for Bigger Applications](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies).
+ """
+ ),
+ ] = None,
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ OpenAPI callbacks that should apply to all *path operations*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ webhooks: Annotated[
+ Optional[routing.APIRouter],
+ Doc(
+ """
+ Add OpenAPI webhooks. This is similar to `callbacks` but it doesn't
+ depend on specific *path operations*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ **Note**: This is available since OpenAPI 3.1.0, FastAPI 0.99.0.
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Webhooks](https://fastapi.tiangolo.com/advanced/openapi-webhooks/).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark all *path operations* as deprecated. You probably don't need it,
+ but it's available.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ To include (or not) all the *path operations* in the generated OpenAPI.
+ You probably don't need it, but it's available.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-parameters-from-openapi).
+ """
+ ),
+ ] = True,
+ swagger_ui_parameters: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ Parameters to configure Swagger UI, the autogenerated interactive API
+ documentation (by default at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs about how to Configure Swagger UI](https://fastapi.tiangolo.com/how-to/configure-swagger-ui/).
+ """
+ ),
+ ] = None,
+ generate_unique_id_function: Annotated[
+ Callable[[routing.APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
+ separate_input_output_schemas: Annotated[
+ bool,
+ Doc(
+ """
+ Whether to generate separate OpenAPI schemas for request body and
+ response body when the results would be more precise.
+
+ This is particularly useful when automatically generating clients.
+
+ For example, if you have a model like:
+
+ ```python
+ from pydantic import BaseModel
+
+ class Item(BaseModel):
+ name: str
+ tags: list[str] = []
+ ```
+
+ When `Item` is used for input, a request body, `tags` is not required,
+ the client doesn't have to provide it.
+
+ But when using `Item` for output, for a response body, `tags` is always
+ available because it has a default value, even if it's just an empty
+ list. So, the client should be able to always expect it.
+
+ In this case, there would be two different schemas, one for input and
+ another one for output.
+ """
+ ),
+ ] = True,
+ **extra: Annotated[
+ Any,
+ Doc(
+ """
+ Extra keyword arguments to be stored in the app, not used by FastAPI
+ anywhere.
+ """
+ ),
+ ],
+ ) -> None:
+ self.debug = debug
+ self.title = title
+ self.summary = summary
+ self.description = description
+ self.version = version
+ self.terms_of_service = terms_of_service
+ self.contact = contact
+ self.license_info = license_info
+ self.openapi_url = openapi_url
+ self.openapi_tags = openapi_tags
+ self.root_path_in_servers = root_path_in_servers
+ self.docs_url = docs_url
+ self.redoc_url = redoc_url
+ self.swagger_ui_oauth2_redirect_url = swagger_ui_oauth2_redirect_url
+ self.swagger_ui_init_oauth = swagger_ui_init_oauth
+ self.swagger_ui_parameters = swagger_ui_parameters
+ self.servers = servers or []
+ self.separate_input_output_schemas = separate_input_output_schemas
+ self.extra = extra
+ self.openapi_version: Annotated[
+ str,
+ Doc(
+ """
+ The version string of OpenAPI.
+
+ FastAPI will generate OpenAPI version 3.1.0, and will output that as
+ the OpenAPI version. But some tools, even though they might be
+ compatible with OpenAPI 3.1.0, might not recognize it as a valid.
+
+ So you could override this value to trick those tools into using
+ the generated OpenAPI. Have in mind that this is a hack. But if you
+ avoid using features added in OpenAPI 3.1.0, it might work for your
+ use case.
+
+ This is not passed as a parameter to the `FastAPI` class to avoid
+ giving the false idea that FastAPI would generate a different OpenAPI
+ schema. It is only available as an attribute.
+
+ **Example**
+
+ ```python
+ from fastapi import FastAPI
+
+ app = FastAPI()
+
+ app.openapi_version = "3.0.2"
+ ```
+ """
+ ),
+ ] = "3.1.0"
+ self.openapi_schema: Optional[Dict[str, Any]] = None
+ if self.openapi_url:
+ assert self.title, "A title must be provided for OpenAPI, e.g.: 'My API'"
+ assert self.version, "A version must be provided for OpenAPI, e.g.: '2.1.0'"
+ # TODO: remove when discarding the openapi_prefix parameter
+ if openapi_prefix:
+ logger.warning(
+ '"openapi_prefix" has been deprecated in favor of "root_path", which '
+ "follows more closely the ASGI standard, is simpler, and more "
+ "automatic. Check the docs at "
+ "https://fastapi.tiangolo.com/advanced/sub-applications/"
+ )
+ self.webhooks: Annotated[
+ routing.APIRouter,
+ Doc(
+ """
+ The `app.webhooks` attribute is an `APIRouter` with the *path
+ operations* that will be used just for documentation of webhooks.
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Webhooks](https://fastapi.tiangolo.com/advanced/openapi-webhooks/).
+ """
+ ),
+ ] = webhooks or routing.APIRouter()
+ self.root_path = root_path or openapi_prefix
+ self.state: Annotated[
+ State,
+ Doc(
+ """
+ A state object for the application. This is the same object for the
+ entire application, it doesn't change from request to request.
+
+ You normally wouldn't use this in FastAPI, for most of the cases you
+ would instead use FastAPI dependencies.
+
+ This is simply inherited from Starlette.
+
+ Read more about it in the
+ [Starlette docs for Applications](https://www.starlette.io/applications/#storing-state-on-the-app-instance).
+ """
+ ),
+ ] = State()
+ self.dependency_overrides: Annotated[
+ Dict[Callable[..., Any], Callable[..., Any]],
+ Doc(
+ """
+ A dictionary with overrides for the dependencies.
+
+ Each key is the original dependency callable, and the value is the
+ actual dependency that should be called.
+
+ This is for testing, to replace expensive dependencies with testing
+ versions.
+
+ Read more about it in the
+ [FastAPI docs for Testing Dependencies with Overrides](https://fastapi.tiangolo.com/advanced/testing-dependencies/).
+ """
+ ),
+ ] = {}
+ self.router: routing.APIRouter = routing.APIRouter(
+ routes=routes,
+ redirect_slashes=redirect_slashes,
+ dependency_overrides_provider=self,
+ on_startup=on_startup,
+ on_shutdown=on_shutdown,
+ lifespan=lifespan,
+ default_response_class=default_response_class,
+ dependencies=dependencies,
+ callbacks=callbacks,
+ deprecated=deprecated,
+ include_in_schema=include_in_schema,
+ responses=responses,
+ generate_unique_id_function=generate_unique_id_function,
+ )
+ self.exception_handlers: Dict[
+ Any, Callable[[Request, Any], Union[Response, Awaitable[Response]]]
+ ] = {} if exception_handlers is None else dict(exception_handlers)
+ self.exception_handlers.setdefault(HTTPException, http_exception_handler)
+ self.exception_handlers.setdefault(
+ RequestValidationError, request_validation_exception_handler
+ )
+ self.exception_handlers.setdefault(
+ WebSocketRequestValidationError,
+ # Starlette still has incorrect type specification for the handlers
+ websocket_request_validation_exception_handler, # type: ignore
+ )
+
+ self.user_middleware: List[Middleware] = (
+ [] if middleware is None else list(middleware)
+ )
+ self.middleware_stack: Union[ASGIApp, None] = None
+ self.setup()
+
+ def openapi(self) -> Dict[str, Any]:
+ """
+ Generate the OpenAPI schema of the application. This is called by FastAPI
+ internally.
+
+ The first time it is called it stores the result in the attribute
+ `app.openapi_schema`, and next times it is called, it just returns that same
+ result. To avoid the cost of generating the schema every time.
+
+ If you need to modify the generated OpenAPI schema, you could modify it.
+
+ Read more in the
+ [FastAPI docs for OpenAPI](https://fastapi.tiangolo.com/how-to/extending-openapi/).
+ """
+ if not self.openapi_schema:
+ self.openapi_schema = get_openapi(
+ title=self.title,
+ version=self.version,
+ openapi_version=self.openapi_version,
+ summary=self.summary,
+ description=self.description,
+ terms_of_service=self.terms_of_service,
+ contact=self.contact,
+ license_info=self.license_info,
+ routes=self.routes,
+ webhooks=self.webhooks.routes,
+ tags=self.openapi_tags,
+ servers=self.servers,
+ separate_input_output_schemas=self.separate_input_output_schemas,
+ )
+ return self.openapi_schema
+
+ def setup(self) -> None:
+ if self.openapi_url:
+ urls = (server_data.get("url") for server_data in self.servers)
+ server_urls = {url for url in urls if url}
+
+ async def openapi(req: Request) -> JSONResponse:
+ root_path = req.scope.get("root_path", "").rstrip("/")
+ if root_path not in server_urls:
+ if root_path and self.root_path_in_servers:
+ self.servers.insert(0, {"url": root_path})
+ server_urls.add(root_path)
+ return JSONResponse(self.openapi())
+
+ self.add_route(self.openapi_url, openapi, include_in_schema=False)
+ if self.openapi_url and self.docs_url:
+
+ async def swagger_ui_html(req: Request) -> HTMLResponse:
+ root_path = req.scope.get("root_path", "").rstrip("/")
+ openapi_url = root_path + self.openapi_url
+ oauth2_redirect_url = self.swagger_ui_oauth2_redirect_url
+ if oauth2_redirect_url:
+ oauth2_redirect_url = root_path + oauth2_redirect_url
+ return get_swagger_ui_html(
+ openapi_url=openapi_url,
+ title=f"{self.title} - Swagger UI",
+ oauth2_redirect_url=oauth2_redirect_url,
+ init_oauth=self.swagger_ui_init_oauth,
+ swagger_ui_parameters=self.swagger_ui_parameters,
+ )
+
+ self.add_route(self.docs_url, swagger_ui_html, include_in_schema=False)
+
+ if self.swagger_ui_oauth2_redirect_url:
+
+ async def swagger_ui_redirect(req: Request) -> HTMLResponse:
+ return get_swagger_ui_oauth2_redirect_html()
+
+ self.add_route(
+ self.swagger_ui_oauth2_redirect_url,
+ swagger_ui_redirect,
+ include_in_schema=False,
+ )
+ if self.openapi_url and self.redoc_url:
+
+ async def redoc_html(req: Request) -> HTMLResponse:
+ root_path = req.scope.get("root_path", "").rstrip("/")
+ openapi_url = root_path + self.openapi_url
+ return get_redoc_html(
+ openapi_url=openapi_url, title=f"{self.title} - ReDoc"
+ )
+
+ self.add_route(self.redoc_url, redoc_html, include_in_schema=False)
+
+ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
+ if self.root_path:
+ scope["root_path"] = self.root_path
+ await super().__call__(scope, receive, send)
+
+ def add_api_route(
+ self,
+ path: str,
+ endpoint: Callable[..., Any],
+ *,
+ response_model: Any = Default(None),
+ status_code: Optional[int] = None,
+ tags: Optional[List[Union[str, Enum]]] = None,
+ dependencies: Optional[Sequence[Depends]] = None,
+ summary: Optional[str] = None,
+ description: Optional[str] = None,
+ response_description: str = "Successful Response",
+ responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
+ deprecated: Optional[bool] = None,
+ methods: Optional[List[str]] = None,
+ operation_id: Optional[str] = None,
+ response_model_include: Optional[IncEx] = None,
+ response_model_exclude: Optional[IncEx] = None,
+ response_model_by_alias: bool = True,
+ response_model_exclude_unset: bool = False,
+ response_model_exclude_defaults: bool = False,
+ response_model_exclude_none: bool = False,
+ include_in_schema: bool = True,
+ response_class: Union[Type[Response], DefaultPlaceholder] = Default(
+ JSONResponse
+ ),
+ name: Optional[str] = None,
+ openapi_extra: Optional[Dict[str, Any]] = None,
+ generate_unique_id_function: Callable[[routing.APIRoute], str] = Default(
+ generate_unique_id
+ ),
+ ) -> None:
+ self.router.add_api_route(
+ path,
+ endpoint=endpoint,
+ response_model=response_model,
+ status_code=status_code,
+ tags=tags,
+ dependencies=dependencies,
+ summary=summary,
+ description=description,
+ response_description=response_description,
+ responses=responses,
+ deprecated=deprecated,
+ methods=methods,
+ operation_id=operation_id,
+ response_model_include=response_model_include,
+ response_model_exclude=response_model_exclude,
+ response_model_by_alias=response_model_by_alias,
+ response_model_exclude_unset=response_model_exclude_unset,
+ response_model_exclude_defaults=response_model_exclude_defaults,
+ response_model_exclude_none=response_model_exclude_none,
+ include_in_schema=include_in_schema,
+ response_class=response_class,
+ name=name,
+ openapi_extra=openapi_extra,
+ generate_unique_id_function=generate_unique_id_function,
+ )
+
+ def api_route(
+ self,
+ path: str,
+ *,
+ response_model: Any = Default(None),
+ status_code: Optional[int] = None,
+ tags: Optional[List[Union[str, Enum]]] = None,
+ dependencies: Optional[Sequence[Depends]] = None,
+ summary: Optional[str] = None,
+ description: Optional[str] = None,
+ response_description: str = "Successful Response",
+ responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
+ deprecated: Optional[bool] = None,
+ methods: Optional[List[str]] = None,
+ operation_id: Optional[str] = None,
+ response_model_include: Optional[IncEx] = None,
+ response_model_exclude: Optional[IncEx] = None,
+ response_model_by_alias: bool = True,
+ response_model_exclude_unset: bool = False,
+ response_model_exclude_defaults: bool = False,
+ response_model_exclude_none: bool = False,
+ include_in_schema: bool = True,
+ response_class: Type[Response] = Default(JSONResponse),
+ name: Optional[str] = None,
+ openapi_extra: Optional[Dict[str, Any]] = None,
+ generate_unique_id_function: Callable[[routing.APIRoute], str] = Default(
+ generate_unique_id
+ ),
+ ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ def decorator(func: DecoratedCallable) -> DecoratedCallable:
+ self.router.add_api_route(
+ path,
+ func,
+ response_model=response_model,
+ status_code=status_code,
+ tags=tags,
+ dependencies=dependencies,
+ summary=summary,
+ description=description,
+ response_description=response_description,
+ responses=responses,
+ deprecated=deprecated,
+ methods=methods,
+ operation_id=operation_id,
+ response_model_include=response_model_include,
+ response_model_exclude=response_model_exclude,
+ response_model_by_alias=response_model_by_alias,
+ response_model_exclude_unset=response_model_exclude_unset,
+ response_model_exclude_defaults=response_model_exclude_defaults,
+ response_model_exclude_none=response_model_exclude_none,
+ include_in_schema=include_in_schema,
+ response_class=response_class,
+ name=name,
+ openapi_extra=openapi_extra,
+ generate_unique_id_function=generate_unique_id_function,
+ )
+ return func
+
+ return decorator
+
+ def add_api_websocket_route(
+ self,
+ path: str,
+ endpoint: Callable[..., Any],
+ name: Optional[str] = None,
+ *,
+ dependencies: Optional[Sequence[Depends]] = None,
+ ) -> None:
+ self.router.add_api_websocket_route(
+ path,
+ endpoint,
+ name=name,
+ dependencies=dependencies,
+ )
+
+ def websocket(
+ self,
+ path: Annotated[
+ str,
+ Doc(
+ """
+ WebSocket path.
+ """
+ ),
+ ],
+ name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A name for the WebSocket. Only used internally.
+ """
+ ),
+ ] = None,
+ *,
+ dependencies: Annotated[
+ Optional[Sequence[Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be used for this
+ WebSocket.
+
+ Read more about it in the
+ [FastAPI docs for WebSockets](https://fastapi.tiangolo.com/advanced/websockets/).
+ """
+ ),
+ ] = None,
+ ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Decorate a WebSocket function.
+
+ Read more about it in the
+ [FastAPI docs for WebSockets](https://fastapi.tiangolo.com/advanced/websockets/).
+
+ **Example**
+
+ ```python
+ from fastapi import FastAPI, WebSocket
+
+ app = FastAPI()
+
+ @app.websocket("/ws")
+ async def websocket_endpoint(websocket: WebSocket):
+ await websocket.accept()
+ while True:
+ data = await websocket.receive_text()
+ await websocket.send_text(f"Message text was: {data}")
+ ```
+ """
+
+ def decorator(func: DecoratedCallable) -> DecoratedCallable:
+ self.add_api_websocket_route(
+ path,
+ func,
+ name=name,
+ dependencies=dependencies,
+ )
+ return func
+
+ return decorator
+
+ def include_router(
+ self,
+ router: Annotated[routing.APIRouter, Doc("The `APIRouter` to include.")],
+ *,
+ prefix: Annotated[str, Doc("An optional path prefix for the router.")] = "",
+ tags: Annotated[
+ Optional[List[Union[str, Enum]]],
+ Doc(
+ """
+ A list of tags to be applied to all the *path operations* in this
+ router.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be applied to all the
+ *path operations* in this router.
+
+ Read more about it in the
+ [FastAPI docs for Bigger Applications - Multiple Files](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies).
+
+ **Example**
+
+ ```python
+ from fastapi import Depends, FastAPI
+
+ from .dependencies import get_token_header
+ from .internal import admin
+
+ app = FastAPI()
+
+ app.include_router(
+ admin.router,
+ dependencies=[Depends(get_token_header)],
+ )
+ ```
+ """
+ ),
+ ] = None,
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses to be shown in OpenAPI.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Additional Responses in OpenAPI](https://fastapi.tiangolo.com/advanced/additional-responses/).
+
+ And in the
+ [FastAPI docs for Bigger Applications](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark all the *path operations* in this router as deprecated.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ **Example**
+
+ ```python
+ from fastapi import FastAPI
+
+ from .internal import old_api
+
+ app = FastAPI()
+
+ app.include_router(
+ old_api.router,
+ deprecated=True,
+ )
+ ```
+ """
+ ),
+ ] = None,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ Include (or not) all the *path operations* in this router in the
+ generated OpenAPI schema.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+ **Example**
+
+ ```python
+ from fastapi import FastAPI
+
+ from .internal import old_api
+
+ app = FastAPI()
+
+ app.include_router(
+ old_api.router,
+ include_in_schema=False,
+ )
+ ```
+ """
+ ),
+ ] = True,
+ default_response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ Default response class to be used for the *path operations* in this
+ router.
+
+ Read more in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#default-response-class).
+
+ **Example**
+
+ ```python
+ from fastapi import FastAPI
+ from fastapi.responses import ORJSONResponse
+
+ from .internal import old_api
+
+ app = FastAPI()
+
+ app.include_router(
+ old_api.router,
+ default_response_class=ORJSONResponse,
+ )
+ ```
+ """
+ ),
+ ] = Default(JSONResponse),
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ List of *path operations* that will be used as OpenAPI callbacks.
+
+ This is only for OpenAPI documentation, the callbacks won't be used
+ directly.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ generate_unique_id_function: Annotated[
+ Callable[[routing.APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
+ ) -> None:
+ """
+ Include an `APIRouter` in the same app.
+
+ Read more about it in the
+ [FastAPI docs for Bigger Applications](https://fastapi.tiangolo.com/tutorial/bigger-applications/).
+
+ ## Example
+
+ ```python
+ from fastapi import FastAPI
+
+ from .users import users_router
+
+ app = FastAPI()
+
+ app.include_router(users_router)
+ ```
+ """
+ self.router.include_router(
+ router,
+ prefix=prefix,
+ tags=tags,
+ dependencies=dependencies,
+ responses=responses,
+ deprecated=deprecated,
+ include_in_schema=include_in_schema,
+ default_response_class=default_response_class,
+ callbacks=callbacks,
+ generate_unique_id_function=generate_unique_id_function,
+ )
+
+ def get(
+ self,
+ path: Annotated[
+ str,
+ Doc(
+ """
+ The URL path to be used for this *path operation*.
+
+ For example, in `http://example.com/items`, the path is `/items`.
+ """
+ ),
+ ],
+ *,
+ response_model: Annotated[
+ Any,
+ Doc(
+ """
+ The type to use for the response.
+
+ It could be any valid Pydantic *field* type. So, it doesn't have to
+ be a Pydantic model, it could be other things, like a `list`, `dict`,
+ etc.
+
+ It will be used for:
+
+ * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+ show it as the response (JSON Schema).
+ * Serialization: you could return an arbitrary object and the
+ `response_model` would be used to serialize that object into the
+ corresponding JSON.
+ * Filtering: the JSON sent to the client will only contain the data
+ (fields) defined in the `response_model`. If you returned an object
+ that contains an attribute `password` but the `response_model` does
+ not include that field, the JSON sent to the client would not have
+ that `password`.
+ * Validation: whatever you return will be serialized with the
+ `response_model`, converting any data as necessary to generate the
+ corresponding JSON. But if the data in the object returned is not
+ valid, that would mean a violation of the contract with the client,
+ so it's an error from the API developer. So, FastAPI will raise an
+ error and return a 500 error code (Internal Server Error).
+
+ Read more about it in the
+ [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+ """
+ ),
+ ] = Default(None),
+ status_code: Annotated[
+ Optional[int],
+ Doc(
+ """
+ The default status code to be used for the response.
+
+ You could override the status code by returning a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+ """
+ ),
+ ] = None,
+ tags: Annotated[
+ Optional[List[Union[str, Enum]]],
+ Doc(
+ """
+ A list of tags to be applied to the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be applied to the
+ *path operation*.
+
+ Read more about it in the
+ [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+ """
+ ),
+ ] = None,
+ summary: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A summary for the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A description for the *path operation*.
+
+ If not provided, it will be extracted automatically from the docstring
+ of the *path operation function*.
+
+ It can contain Markdown.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ response_description: Annotated[
+ str,
+ Doc(
+ """
+ The description for the default response.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = "Successful Response",
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses that could be returned by this *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this *path operation* as deprecated.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ operation_id: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Custom operation ID to be used by this *path operation*.
+
+ By default, it is generated automatically.
+
+ If you provide a custom operation ID, you need to make sure it is
+ unique for the whole API.
+
+ You can customize the
+ operation ID generation with the parameter
+ `generate_unique_id_function` in the `FastAPI` class.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = None,
+ response_model_include: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to include only certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_exclude: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to exclude certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_by_alias: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response model
+ should be serialized by alias when an alias is used.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = True,
+ response_model_exclude_unset: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that were not set and
+ have their default values. This is different from
+ `response_model_exclude_defaults` in that if the fields are set,
+ they will be included in the response, even if the value is the same
+ as the default.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_defaults: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that have the same value
+ as the default. This is different from `response_model_exclude_unset`
+ in that if the fields are set but contain the same default values,
+ they will be excluded from the response.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_none: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data should
+ exclude fields set to `None`.
+
+ This is much simpler (less smart) than `response_model_exclude_unset`
+ and `response_model_exclude_defaults`. You probably want to use one of
+ those two instead of this one, as those allow returning `None` values
+ when it makes sense.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+ """
+ ),
+ ] = False,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ Include this *path operation* in the generated OpenAPI schema.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-parameters-from-openapi).
+ """
+ ),
+ ] = True,
+ response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ Response class to be used for this *path operation*.
+
+ This will not be used if you return a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+ """
+ ),
+ ] = Default(JSONResponse),
+ name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Name for this *path operation*. Only used internally.
+ """
+ ),
+ ] = None,
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ List of *path operations* that will be used as OpenAPI callbacks.
+
+ This is only for OpenAPI documentation, the callbacks won't be used
+ directly.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ openapi_extra: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ Extra metadata to be included in the OpenAPI schema for this *path
+ operation*.
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+ """
+ ),
+ ] = None,
+ generate_unique_id_function: Annotated[
+ Callable[[routing.APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
+ ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add a *path operation* using an HTTP GET operation.
+
+ ## Example
+
+ ```python
+ from fastapi import FastAPI
+
+ app = FastAPI()
+
+ @app.get("/items/")
+ def read_items():
+ return [{"name": "Empanada"}, {"name": "Arepa"}]
+ ```
+ """
+ return self.router.get(
+ path,
+ response_model=response_model,
+ status_code=status_code,
+ tags=tags,
+ dependencies=dependencies,
+ summary=summary,
+ description=description,
+ response_description=response_description,
+ responses=responses,
+ deprecated=deprecated,
+ operation_id=operation_id,
+ response_model_include=response_model_include,
+ response_model_exclude=response_model_exclude,
+ response_model_by_alias=response_model_by_alias,
+ response_model_exclude_unset=response_model_exclude_unset,
+ response_model_exclude_defaults=response_model_exclude_defaults,
+ response_model_exclude_none=response_model_exclude_none,
+ include_in_schema=include_in_schema,
+ response_class=response_class,
+ name=name,
+ callbacks=callbacks,
+ openapi_extra=openapi_extra,
+ generate_unique_id_function=generate_unique_id_function,
+ )
+
+ def put(
+ self,
+ path: Annotated[
+ str,
+ Doc(
+ """
+ The URL path to be used for this *path operation*.
+
+ For example, in `http://example.com/items`, the path is `/items`.
+ """
+ ),
+ ],
+ *,
+ response_model: Annotated[
+ Any,
+ Doc(
+ """
+ The type to use for the response.
+
+ It could be any valid Pydantic *field* type. So, it doesn't have to
+ be a Pydantic model, it could be other things, like a `list`, `dict`,
+ etc.
+
+ It will be used for:
+
+ * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+ show it as the response (JSON Schema).
+ * Serialization: you could return an arbitrary object and the
+ `response_model` would be used to serialize that object into the
+ corresponding JSON.
+ * Filtering: the JSON sent to the client will only contain the data
+ (fields) defined in the `response_model`. If you returned an object
+ that contains an attribute `password` but the `response_model` does
+ not include that field, the JSON sent to the client would not have
+ that `password`.
+ * Validation: whatever you return will be serialized with the
+ `response_model`, converting any data as necessary to generate the
+ corresponding JSON. But if the data in the object returned is not
+ valid, that would mean a violation of the contract with the client,
+ so it's an error from the API developer. So, FastAPI will raise an
+ error and return a 500 error code (Internal Server Error).
+
+ Read more about it in the
+ [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+ """
+ ),
+ ] = Default(None),
+ status_code: Annotated[
+ Optional[int],
+ Doc(
+ """
+ The default status code to be used for the response.
+
+ You could override the status code by returning a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+ """
+ ),
+ ] = None,
+ tags: Annotated[
+ Optional[List[Union[str, Enum]]],
+ Doc(
+ """
+ A list of tags to be applied to the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be applied to the
+ *path operation*.
+
+ Read more about it in the
+ [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+ """
+ ),
+ ] = None,
+ summary: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A summary for the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A description for the *path operation*.
+
+ If not provided, it will be extracted automatically from the docstring
+ of the *path operation function*.
+
+ It can contain Markdown.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ response_description: Annotated[
+ str,
+ Doc(
+ """
+ The description for the default response.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = "Successful Response",
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses that could be returned by this *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this *path operation* as deprecated.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ operation_id: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Custom operation ID to be used by this *path operation*.
+
+ By default, it is generated automatically.
+
+ If you provide a custom operation ID, you need to make sure it is
+ unique for the whole API.
+
+ You can customize the
+ operation ID generation with the parameter
+ `generate_unique_id_function` in the `FastAPI` class.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = None,
+ response_model_include: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to include only certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_exclude: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to exclude certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_by_alias: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response model
+ should be serialized by alias when an alias is used.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = True,
+ response_model_exclude_unset: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that were not set and
+ have their default values. This is different from
+ `response_model_exclude_defaults` in that if the fields are set,
+ they will be included in the response, even if the value is the same
+ as the default.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_defaults: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that have the same value
+ as the default. This is different from `response_model_exclude_unset`
+ in that if the fields are set but contain the same default values,
+ they will be excluded from the response.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_none: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data should
+ exclude fields set to `None`.
+
+ This is much simpler (less smart) than `response_model_exclude_unset`
+ and `response_model_exclude_defaults`. You probably want to use one of
+ those two instead of this one, as those allow returning `None` values
+ when it makes sense.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+ """
+ ),
+ ] = False,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ Include this *path operation* in the generated OpenAPI schema.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-parameters-from-openapi).
+ """
+ ),
+ ] = True,
+ response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ Response class to be used for this *path operation*.
+
+ This will not be used if you return a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+ """
+ ),
+ ] = Default(JSONResponse),
+ name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Name for this *path operation*. Only used internally.
+ """
+ ),
+ ] = None,
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ List of *path operations* that will be used as OpenAPI callbacks.
+
+ This is only for OpenAPI documentation, the callbacks won't be used
+ directly.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ openapi_extra: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ Extra metadata to be included in the OpenAPI schema for this *path
+ operation*.
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+ """
+ ),
+ ] = None,
+ generate_unique_id_function: Annotated[
+ Callable[[routing.APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
+ ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add a *path operation* using an HTTP PUT operation.
+
+ ## Example
+
+ ```python
+ from fastapi import FastAPI
+ from pydantic import BaseModel
+
+ class Item(BaseModel):
+ name: str
+ description: str | None = None
+
+ app = FastAPI()
+
+ @app.put("/items/{item_id}")
+ def replace_item(item_id: str, item: Item):
+ return {"message": "Item replaced", "id": item_id}
+ ```
+ """
+ return self.router.put(
+ path,
+ response_model=response_model,
+ status_code=status_code,
+ tags=tags,
+ dependencies=dependencies,
+ summary=summary,
+ description=description,
+ response_description=response_description,
+ responses=responses,
+ deprecated=deprecated,
+ operation_id=operation_id,
+ response_model_include=response_model_include,
+ response_model_exclude=response_model_exclude,
+ response_model_by_alias=response_model_by_alias,
+ response_model_exclude_unset=response_model_exclude_unset,
+ response_model_exclude_defaults=response_model_exclude_defaults,
+ response_model_exclude_none=response_model_exclude_none,
+ include_in_schema=include_in_schema,
+ response_class=response_class,
+ name=name,
+ callbacks=callbacks,
+ openapi_extra=openapi_extra,
+ generate_unique_id_function=generate_unique_id_function,
+ )
+
+ def post(
+ self,
+ path: Annotated[
+ str,
+ Doc(
+ """
+ The URL path to be used for this *path operation*.
+
+ For example, in `http://example.com/items`, the path is `/items`.
+ """
+ ),
+ ],
+ *,
+ response_model: Annotated[
+ Any,
+ Doc(
+ """
+ The type to use for the response.
+
+ It could be any valid Pydantic *field* type. So, it doesn't have to
+ be a Pydantic model, it could be other things, like a `list`, `dict`,
+ etc.
+
+ It will be used for:
+
+ * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+ show it as the response (JSON Schema).
+ * Serialization: you could return an arbitrary object and the
+ `response_model` would be used to serialize that object into the
+ corresponding JSON.
+ * Filtering: the JSON sent to the client will only contain the data
+ (fields) defined in the `response_model`. If you returned an object
+ that contains an attribute `password` but the `response_model` does
+ not include that field, the JSON sent to the client would not have
+ that `password`.
+ * Validation: whatever you return will be serialized with the
+ `response_model`, converting any data as necessary to generate the
+ corresponding JSON. But if the data in the object returned is not
+ valid, that would mean a violation of the contract with the client,
+ so it's an error from the API developer. So, FastAPI will raise an
+ error and return a 500 error code (Internal Server Error).
+
+ Read more about it in the
+ [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+ """
+ ),
+ ] = Default(None),
+ status_code: Annotated[
+ Optional[int],
+ Doc(
+ """
+ The default status code to be used for the response.
+
+ You could override the status code by returning a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+ """
+ ),
+ ] = None,
+ tags: Annotated[
+ Optional[List[Union[str, Enum]]],
+ Doc(
+ """
+ A list of tags to be applied to the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be applied to the
+ *path operation*.
+
+ Read more about it in the
+ [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+ """
+ ),
+ ] = None,
+ summary: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A summary for the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A description for the *path operation*.
+
+ If not provided, it will be extracted automatically from the docstring
+ of the *path operation function*.
+
+ It can contain Markdown.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ response_description: Annotated[
+ str,
+ Doc(
+ """
+ The description for the default response.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = "Successful Response",
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses that could be returned by this *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this *path operation* as deprecated.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ operation_id: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Custom operation ID to be used by this *path operation*.
+
+ By default, it is generated automatically.
+
+ If you provide a custom operation ID, you need to make sure it is
+ unique for the whole API.
+
+ You can customize the
+ operation ID generation with the parameter
+ `generate_unique_id_function` in the `FastAPI` class.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = None,
+ response_model_include: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to include only certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_exclude: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to exclude certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_by_alias: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response model
+ should be serialized by alias when an alias is used.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = True,
+ response_model_exclude_unset: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that were not set and
+ have their default values. This is different from
+ `response_model_exclude_defaults` in that if the fields are set,
+ they will be included in the response, even if the value is the same
+ as the default.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_defaults: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that have the same value
+ as the default. This is different from `response_model_exclude_unset`
+ in that if the fields are set but contain the same default values,
+ they will be excluded from the response.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_none: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data should
+ exclude fields set to `None`.
+
+ This is much simpler (less smart) than `response_model_exclude_unset`
+ and `response_model_exclude_defaults`. You probably want to use one of
+ those two instead of this one, as those allow returning `None` values
+ when it makes sense.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+ """
+ ),
+ ] = False,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ Include this *path operation* in the generated OpenAPI schema.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-parameters-from-openapi).
+ """
+ ),
+ ] = True,
+ response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ Response class to be used for this *path operation*.
+
+ This will not be used if you return a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+ """
+ ),
+ ] = Default(JSONResponse),
+ name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Name for this *path operation*. Only used internally.
+ """
+ ),
+ ] = None,
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ List of *path operations* that will be used as OpenAPI callbacks.
+
+ This is only for OpenAPI documentation, the callbacks won't be used
+ directly.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ openapi_extra: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ Extra metadata to be included in the OpenAPI schema for this *path
+ operation*.
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+ """
+ ),
+ ] = None,
+ generate_unique_id_function: Annotated[
+ Callable[[routing.APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
+ ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add a *path operation* using an HTTP POST operation.
+
+ ## Example
+
+ ```python
+ from fastapi import FastAPI
+ from pydantic import BaseModel
+
+ class Item(BaseModel):
+ name: str
+ description: str | None = None
+
+ app = FastAPI()
+
+ @app.post("/items/")
+ def create_item(item: Item):
+ return {"message": "Item created"}
+ ```
+ """
+ return self.router.post(
+ path,
+ response_model=response_model,
+ status_code=status_code,
+ tags=tags,
+ dependencies=dependencies,
+ summary=summary,
+ description=description,
+ response_description=response_description,
+ responses=responses,
+ deprecated=deprecated,
+ operation_id=operation_id,
+ response_model_include=response_model_include,
+ response_model_exclude=response_model_exclude,
+ response_model_by_alias=response_model_by_alias,
+ response_model_exclude_unset=response_model_exclude_unset,
+ response_model_exclude_defaults=response_model_exclude_defaults,
+ response_model_exclude_none=response_model_exclude_none,
+ include_in_schema=include_in_schema,
+ response_class=response_class,
+ name=name,
+ callbacks=callbacks,
+ openapi_extra=openapi_extra,
+ generate_unique_id_function=generate_unique_id_function,
+ )
+
+ def delete(
+ self,
+ path: Annotated[
+ str,
+ Doc(
+ """
+ The URL path to be used for this *path operation*.
+
+ For example, in `http://example.com/items`, the path is `/items`.
+ """
+ ),
+ ],
+ *,
+ response_model: Annotated[
+ Any,
+ Doc(
+ """
+ The type to use for the response.
+
+ It could be any valid Pydantic *field* type. So, it doesn't have to
+ be a Pydantic model, it could be other things, like a `list`, `dict`,
+ etc.
+
+ It will be used for:
+
+ * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+ show it as the response (JSON Schema).
+ * Serialization: you could return an arbitrary object and the
+ `response_model` would be used to serialize that object into the
+ corresponding JSON.
+ * Filtering: the JSON sent to the client will only contain the data
+ (fields) defined in the `response_model`. If you returned an object
+ that contains an attribute `password` but the `response_model` does
+ not include that field, the JSON sent to the client would not have
+ that `password`.
+ * Validation: whatever you return will be serialized with the
+ `response_model`, converting any data as necessary to generate the
+ corresponding JSON. But if the data in the object returned is not
+ valid, that would mean a violation of the contract with the client,
+ so it's an error from the API developer. So, FastAPI will raise an
+ error and return a 500 error code (Internal Server Error).
+
+ Read more about it in the
+ [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+ """
+ ),
+ ] = Default(None),
+ status_code: Annotated[
+ Optional[int],
+ Doc(
+ """
+ The default status code to be used for the response.
+
+ You could override the status code by returning a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+ """
+ ),
+ ] = None,
+ tags: Annotated[
+ Optional[List[Union[str, Enum]]],
+ Doc(
+ """
+ A list of tags to be applied to the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be applied to the
+ *path operation*.
+
+ Read more about it in the
+ [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+ """
+ ),
+ ] = None,
+ summary: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A summary for the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A description for the *path operation*.
+
+ If not provided, it will be extracted automatically from the docstring
+ of the *path operation function*.
+
+ It can contain Markdown.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ response_description: Annotated[
+ str,
+ Doc(
+ """
+ The description for the default response.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = "Successful Response",
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses that could be returned by this *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this *path operation* as deprecated.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ operation_id: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Custom operation ID to be used by this *path operation*.
+
+ By default, it is generated automatically.
+
+ If you provide a custom operation ID, you need to make sure it is
+ unique for the whole API.
+
+ You can customize the
+ operation ID generation with the parameter
+ `generate_unique_id_function` in the `FastAPI` class.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = None,
+ response_model_include: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to include only certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_exclude: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to exclude certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_by_alias: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response model
+ should be serialized by alias when an alias is used.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = True,
+ response_model_exclude_unset: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that were not set and
+ have their default values. This is different from
+ `response_model_exclude_defaults` in that if the fields are set,
+ they will be included in the response, even if the value is the same
+ as the default.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_defaults: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that have the same value
+ as the default. This is different from `response_model_exclude_unset`
+ in that if the fields are set but contain the same default values,
+ they will be excluded from the response.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_none: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data should
+ exclude fields set to `None`.
+
+ This is much simpler (less smart) than `response_model_exclude_unset`
+ and `response_model_exclude_defaults`. You probably want to use one of
+ those two instead of this one, as those allow returning `None` values
+ when it makes sense.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+ """
+ ),
+ ] = False,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ Include this *path operation* in the generated OpenAPI schema.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-parameters-from-openapi).
+ """
+ ),
+ ] = True,
+ response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ Response class to be used for this *path operation*.
+
+ This will not be used if you return a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+ """
+ ),
+ ] = Default(JSONResponse),
+ name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Name for this *path operation*. Only used internally.
+ """
+ ),
+ ] = None,
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ List of *path operations* that will be used as OpenAPI callbacks.
+
+ This is only for OpenAPI documentation, the callbacks won't be used
+ directly.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ openapi_extra: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ Extra metadata to be included in the OpenAPI schema for this *path
+ operation*.
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+ """
+ ),
+ ] = None,
+ generate_unique_id_function: Annotated[
+ Callable[[routing.APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
+ ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add a *path operation* using an HTTP DELETE operation.
+
+ ## Example
+
+ ```python
+ from fastapi import FastAPI
+
+ app = FastAPI()
+
+ @app.delete("/items/{item_id}")
+ def delete_item(item_id: str):
+ return {"message": "Item deleted"}
+ ```
+ """
+ return self.router.delete(
+ path,
+ response_model=response_model,
+ status_code=status_code,
+ tags=tags,
+ dependencies=dependencies,
+ summary=summary,
+ description=description,
+ response_description=response_description,
+ responses=responses,
+ deprecated=deprecated,
+ operation_id=operation_id,
+ response_model_include=response_model_include,
+ response_model_exclude=response_model_exclude,
+ response_model_by_alias=response_model_by_alias,
+ response_model_exclude_unset=response_model_exclude_unset,
+ response_model_exclude_defaults=response_model_exclude_defaults,
+ response_model_exclude_none=response_model_exclude_none,
+ include_in_schema=include_in_schema,
+ response_class=response_class,
+ name=name,
+ callbacks=callbacks,
+ openapi_extra=openapi_extra,
+ generate_unique_id_function=generate_unique_id_function,
+ )
+
+ def options(
+ self,
+ path: Annotated[
+ str,
+ Doc(
+ """
+ The URL path to be used for this *path operation*.
+
+ For example, in `http://example.com/items`, the path is `/items`.
+ """
+ ),
+ ],
+ *,
+ response_model: Annotated[
+ Any,
+ Doc(
+ """
+ The type to use for the response.
+
+ It could be any valid Pydantic *field* type. So, it doesn't have to
+ be a Pydantic model, it could be other things, like a `list`, `dict`,
+ etc.
+
+ It will be used for:
+
+ * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+ show it as the response (JSON Schema).
+ * Serialization: you could return an arbitrary object and the
+ `response_model` would be used to serialize that object into the
+ corresponding JSON.
+ * Filtering: the JSON sent to the client will only contain the data
+ (fields) defined in the `response_model`. If you returned an object
+ that contains an attribute `password` but the `response_model` does
+ not include that field, the JSON sent to the client would not have
+ that `password`.
+ * Validation: whatever you return will be serialized with the
+ `response_model`, converting any data as necessary to generate the
+ corresponding JSON. But if the data in the object returned is not
+ valid, that would mean a violation of the contract with the client,
+ so it's an error from the API developer. So, FastAPI will raise an
+ error and return a 500 error code (Internal Server Error).
+
+ Read more about it in the
+ [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+ """
+ ),
+ ] = Default(None),
+ status_code: Annotated[
+ Optional[int],
+ Doc(
+ """
+ The default status code to be used for the response.
+
+ You could override the status code by returning a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+ """
+ ),
+ ] = None,
+ tags: Annotated[
+ Optional[List[Union[str, Enum]]],
+ Doc(
+ """
+ A list of tags to be applied to the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be applied to the
+ *path operation*.
+
+ Read more about it in the
+ [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+ """
+ ),
+ ] = None,
+ summary: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A summary for the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A description for the *path operation*.
+
+ If not provided, it will be extracted automatically from the docstring
+ of the *path operation function*.
+
+ It can contain Markdown.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ response_description: Annotated[
+ str,
+ Doc(
+ """
+ The description for the default response.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = "Successful Response",
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses that could be returned by this *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this *path operation* as deprecated.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ operation_id: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Custom operation ID to be used by this *path operation*.
+
+ By default, it is generated automatically.
+
+ If you provide a custom operation ID, you need to make sure it is
+ unique for the whole API.
+
+ You can customize the
+ operation ID generation with the parameter
+ `generate_unique_id_function` in the `FastAPI` class.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = None,
+ response_model_include: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to include only certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_exclude: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to exclude certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_by_alias: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response model
+ should be serialized by alias when an alias is used.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = True,
+ response_model_exclude_unset: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that were not set and
+ have their default values. This is different from
+ `response_model_exclude_defaults` in that if the fields are set,
+ they will be included in the response, even if the value is the same
+ as the default.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_defaults: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that have the same value
+ as the default. This is different from `response_model_exclude_unset`
+ in that if the fields are set but contain the same default values,
+ they will be excluded from the response.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_none: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data should
+ exclude fields set to `None`.
+
+ This is much simpler (less smart) than `response_model_exclude_unset`
+ and `response_model_exclude_defaults`. You probably want to use one of
+ those two instead of this one, as those allow returning `None` values
+ when it makes sense.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+ """
+ ),
+ ] = False,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ Include this *path operation* in the generated OpenAPI schema.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-parameters-from-openapi).
+ """
+ ),
+ ] = True,
+ response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ Response class to be used for this *path operation*.
+
+ This will not be used if you return a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+ """
+ ),
+ ] = Default(JSONResponse),
+ name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Name for this *path operation*. Only used internally.
+ """
+ ),
+ ] = None,
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ List of *path operations* that will be used as OpenAPI callbacks.
+
+ This is only for OpenAPI documentation, the callbacks won't be used
+ directly.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ openapi_extra: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ Extra metadata to be included in the OpenAPI schema for this *path
+ operation*.
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+ """
+ ),
+ ] = None,
+ generate_unique_id_function: Annotated[
+ Callable[[routing.APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
+ ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add a *path operation* using an HTTP OPTIONS operation.
+
+ ## Example
+
+ ```python
+ from fastapi import FastAPI
+
+ app = FastAPI()
+
+ @app.options("/items/")
+ def get_item_options():
+ return {"additions": ["Aji", "Guacamole"]}
+ ```
+ """
+ return self.router.options(
+ path,
+ response_model=response_model,
+ status_code=status_code,
+ tags=tags,
+ dependencies=dependencies,
+ summary=summary,
+ description=description,
+ response_description=response_description,
+ responses=responses,
+ deprecated=deprecated,
+ operation_id=operation_id,
+ response_model_include=response_model_include,
+ response_model_exclude=response_model_exclude,
+ response_model_by_alias=response_model_by_alias,
+ response_model_exclude_unset=response_model_exclude_unset,
+ response_model_exclude_defaults=response_model_exclude_defaults,
+ response_model_exclude_none=response_model_exclude_none,
+ include_in_schema=include_in_schema,
+ response_class=response_class,
+ name=name,
+ callbacks=callbacks,
+ openapi_extra=openapi_extra,
+ generate_unique_id_function=generate_unique_id_function,
+ )
+
+ def head(
+ self,
+ path: Annotated[
+ str,
+ Doc(
+ """
+ The URL path to be used for this *path operation*.
+
+ For example, in `http://example.com/items`, the path is `/items`.
+ """
+ ),
+ ],
+ *,
+ response_model: Annotated[
+ Any,
+ Doc(
+ """
+ The type to use for the response.
+
+ It could be any valid Pydantic *field* type. So, it doesn't have to
+ be a Pydantic model, it could be other things, like a `list`, `dict`,
+ etc.
+
+ It will be used for:
+
+ * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+ show it as the response (JSON Schema).
+ * Serialization: you could return an arbitrary object and the
+ `response_model` would be used to serialize that object into the
+ corresponding JSON.
+ * Filtering: the JSON sent to the client will only contain the data
+ (fields) defined in the `response_model`. If you returned an object
+ that contains an attribute `password` but the `response_model` does
+ not include that field, the JSON sent to the client would not have
+ that `password`.
+ * Validation: whatever you return will be serialized with the
+ `response_model`, converting any data as necessary to generate the
+ corresponding JSON. But if the data in the object returned is not
+ valid, that would mean a violation of the contract with the client,
+ so it's an error from the API developer. So, FastAPI will raise an
+ error and return a 500 error code (Internal Server Error).
+
+ Read more about it in the
+ [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+ """
+ ),
+ ] = Default(None),
+ status_code: Annotated[
+ Optional[int],
+ Doc(
+ """
+ The default status code to be used for the response.
+
+ You could override the status code by returning a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+ """
+ ),
+ ] = None,
+ tags: Annotated[
+ Optional[List[Union[str, Enum]]],
+ Doc(
+ """
+ A list of tags to be applied to the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be applied to the
+ *path operation*.
+
+ Read more about it in the
+ [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+ """
+ ),
+ ] = None,
+ summary: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A summary for the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A description for the *path operation*.
+
+ If not provided, it will be extracted automatically from the docstring
+ of the *path operation function*.
+
+ It can contain Markdown.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ response_description: Annotated[
+ str,
+ Doc(
+ """
+ The description for the default response.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = "Successful Response",
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses that could be returned by this *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this *path operation* as deprecated.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ operation_id: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Custom operation ID to be used by this *path operation*.
+
+ By default, it is generated automatically.
+
+ If you provide a custom operation ID, you need to make sure it is
+ unique for the whole API.
+
+ You can customize the
+ operation ID generation with the parameter
+ `generate_unique_id_function` in the `FastAPI` class.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = None,
+ response_model_include: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to include only certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_exclude: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to exclude certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_by_alias: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response model
+ should be serialized by alias when an alias is used.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = True,
+ response_model_exclude_unset: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that were not set and
+ have their default values. This is different from
+ `response_model_exclude_defaults` in that if the fields are set,
+ they will be included in the response, even if the value is the same
+ as the default.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_defaults: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that have the same value
+ as the default. This is different from `response_model_exclude_unset`
+ in that if the fields are set but contain the same default values,
+ they will be excluded from the response.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_none: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data should
+ exclude fields set to `None`.
+
+ This is much simpler (less smart) than `response_model_exclude_unset`
+ and `response_model_exclude_defaults`. You probably want to use one of
+ those two instead of this one, as those allow returning `None` values
+ when it makes sense.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+ """
+ ),
+ ] = False,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ Include this *path operation* in the generated OpenAPI schema.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-parameters-from-openapi).
+ """
+ ),
+ ] = True,
+ response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ Response class to be used for this *path operation*.
+
+ This will not be used if you return a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+ """
+ ),
+ ] = Default(JSONResponse),
+ name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Name for this *path operation*. Only used internally.
+ """
+ ),
+ ] = None,
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ List of *path operations* that will be used as OpenAPI callbacks.
+
+ This is only for OpenAPI documentation, the callbacks won't be used
+ directly.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ openapi_extra: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ Extra metadata to be included in the OpenAPI schema for this *path
+ operation*.
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+ """
+ ),
+ ] = None,
+ generate_unique_id_function: Annotated[
+ Callable[[routing.APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
+ ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add a *path operation* using an HTTP HEAD operation.
+
+ ## Example
+
+ ```python
+ from fastapi import FastAPI, Response
+
+ app = FastAPI()
+
+ @app.head("/items/", status_code=204)
+ def get_items_headers(response: Response):
+ response.headers["X-Cat-Dog"] = "Alone in the world"
+ ```
+ """
+ return self.router.head(
+ path,
+ response_model=response_model,
+ status_code=status_code,
+ tags=tags,
+ dependencies=dependencies,
+ summary=summary,
+ description=description,
+ response_description=response_description,
+ responses=responses,
+ deprecated=deprecated,
+ operation_id=operation_id,
+ response_model_include=response_model_include,
+ response_model_exclude=response_model_exclude,
+ response_model_by_alias=response_model_by_alias,
+ response_model_exclude_unset=response_model_exclude_unset,
+ response_model_exclude_defaults=response_model_exclude_defaults,
+ response_model_exclude_none=response_model_exclude_none,
+ include_in_schema=include_in_schema,
+ response_class=response_class,
+ name=name,
+ callbacks=callbacks,
+ openapi_extra=openapi_extra,
+ generate_unique_id_function=generate_unique_id_function,
+ )
+
+ def patch(
+ self,
+ path: Annotated[
+ str,
+ Doc(
+ """
+ The URL path to be used for this *path operation*.
+
+ For example, in `http://example.com/items`, the path is `/items`.
+ """
+ ),
+ ],
+ *,
+ response_model: Annotated[
+ Any,
+ Doc(
+ """
+ The type to use for the response.
+
+ It could be any valid Pydantic *field* type. So, it doesn't have to
+ be a Pydantic model, it could be other things, like a `list`, `dict`,
+ etc.
+
+ It will be used for:
+
+ * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+ show it as the response (JSON Schema).
+ * Serialization: you could return an arbitrary object and the
+ `response_model` would be used to serialize that object into the
+ corresponding JSON.
+ * Filtering: the JSON sent to the client will only contain the data
+ (fields) defined in the `response_model`. If you returned an object
+ that contains an attribute `password` but the `response_model` does
+ not include that field, the JSON sent to the client would not have
+ that `password`.
+ * Validation: whatever you return will be serialized with the
+ `response_model`, converting any data as necessary to generate the
+ corresponding JSON. But if the data in the object returned is not
+ valid, that would mean a violation of the contract with the client,
+ so it's an error from the API developer. So, FastAPI will raise an
+ error and return a 500 error code (Internal Server Error).
+
+ Read more about it in the
+ [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+ """
+ ),
+ ] = Default(None),
+ status_code: Annotated[
+ Optional[int],
+ Doc(
+ """
+ The default status code to be used for the response.
+
+ You could override the status code by returning a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+ """
+ ),
+ ] = None,
+ tags: Annotated[
+ Optional[List[Union[str, Enum]]],
+ Doc(
+ """
+ A list of tags to be applied to the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be applied to the
+ *path operation*.
+
+ Read more about it in the
+ [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+ """
+ ),
+ ] = None,
+ summary: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A summary for the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A description for the *path operation*.
+
+ If not provided, it will be extracted automatically from the docstring
+ of the *path operation function*.
+
+ It can contain Markdown.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ response_description: Annotated[
+ str,
+ Doc(
+ """
+ The description for the default response.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = "Successful Response",
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses that could be returned by this *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this *path operation* as deprecated.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ operation_id: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Custom operation ID to be used by this *path operation*.
+
+ By default, it is generated automatically.
+
+ If you provide a custom operation ID, you need to make sure it is
+ unique for the whole API.
+
+ You can customize the
+ operation ID generation with the parameter
+ `generate_unique_id_function` in the `FastAPI` class.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = None,
+ response_model_include: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to include only certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_exclude: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to exclude certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_by_alias: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response model
+ should be serialized by alias when an alias is used.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = True,
+ response_model_exclude_unset: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that were not set and
+ have their default values. This is different from
+ `response_model_exclude_defaults` in that if the fields are set,
+ they will be included in the response, even if the value is the same
+ as the default.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_defaults: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that have the same value
+ as the default. This is different from `response_model_exclude_unset`
+ in that if the fields are set but contain the same default values,
+ they will be excluded from the response.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_none: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data should
+ exclude fields set to `None`.
+
+ This is much simpler (less smart) than `response_model_exclude_unset`
+ and `response_model_exclude_defaults`. You probably want to use one of
+ those two instead of this one, as those allow returning `None` values
+ when it makes sense.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+ """
+ ),
+ ] = False,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ Include this *path operation* in the generated OpenAPI schema.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-parameters-from-openapi).
+ """
+ ),
+ ] = True,
+ response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ Response class to be used for this *path operation*.
+
+ This will not be used if you return a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+ """
+ ),
+ ] = Default(JSONResponse),
+ name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Name for this *path operation*. Only used internally.
+ """
+ ),
+ ] = None,
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ List of *path operations* that will be used as OpenAPI callbacks.
+
+ This is only for OpenAPI documentation, the callbacks won't be used
+ directly.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ openapi_extra: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ Extra metadata to be included in the OpenAPI schema for this *path
+ operation*.
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+ """
+ ),
+ ] = None,
+ generate_unique_id_function: Annotated[
+ Callable[[routing.APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
+ ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add a *path operation* using an HTTP PATCH operation.
+
+ ## Example
+
+ ```python
+ from fastapi import FastAPI
+ from pydantic import BaseModel
+
+ class Item(BaseModel):
+ name: str
+ description: str | None = None
+
+ app = FastAPI()
+
+ @app.patch("/items/")
+ def update_item(item: Item):
+ return {"message": "Item updated in place"}
+ ```
+ """
+ return self.router.patch(
+ path,
+ response_model=response_model,
+ status_code=status_code,
+ tags=tags,
+ dependencies=dependencies,
+ summary=summary,
+ description=description,
+ response_description=response_description,
+ responses=responses,
+ deprecated=deprecated,
+ operation_id=operation_id,
+ response_model_include=response_model_include,
+ response_model_exclude=response_model_exclude,
+ response_model_by_alias=response_model_by_alias,
+ response_model_exclude_unset=response_model_exclude_unset,
+ response_model_exclude_defaults=response_model_exclude_defaults,
+ response_model_exclude_none=response_model_exclude_none,
+ include_in_schema=include_in_schema,
+ response_class=response_class,
+ name=name,
+ callbacks=callbacks,
+ openapi_extra=openapi_extra,
+ generate_unique_id_function=generate_unique_id_function,
+ )
+
+ def trace(
+ self,
+ path: Annotated[
+ str,
+ Doc(
+ """
+ The URL path to be used for this *path operation*.
+
+ For example, in `http://example.com/items`, the path is `/items`.
+ """
+ ),
+ ],
+ *,
+ response_model: Annotated[
+ Any,
+ Doc(
+ """
+ The type to use for the response.
+
+ It could be any valid Pydantic *field* type. So, it doesn't have to
+ be a Pydantic model, it could be other things, like a `list`, `dict`,
+ etc.
+
+ It will be used for:
+
+ * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+ show it as the response (JSON Schema).
+ * Serialization: you could return an arbitrary object and the
+ `response_model` would be used to serialize that object into the
+ corresponding JSON.
+ * Filtering: the JSON sent to the client will only contain the data
+ (fields) defined in the `response_model`. If you returned an object
+ that contains an attribute `password` but the `response_model` does
+ not include that field, the JSON sent to the client would not have
+ that `password`.
+ * Validation: whatever you return will be serialized with the
+ `response_model`, converting any data as necessary to generate the
+ corresponding JSON. But if the data in the object returned is not
+ valid, that would mean a violation of the contract with the client,
+ so it's an error from the API developer. So, FastAPI will raise an
+ error and return a 500 error code (Internal Server Error).
+
+ Read more about it in the
+ [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+ """
+ ),
+ ] = Default(None),
+ status_code: Annotated[
+ Optional[int],
+ Doc(
+ """
+ The default status code to be used for the response.
+
+ You could override the status code by returning a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+ """
+ ),
+ ] = None,
+ tags: Annotated[
+ Optional[List[Union[str, Enum]]],
+ Doc(
+ """
+ A list of tags to be applied to the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be applied to the
+ *path operation*.
+
+ Read more about it in the
+ [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+ """
+ ),
+ ] = None,
+ summary: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A summary for the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A description for the *path operation*.
+
+ If not provided, it will be extracted automatically from the docstring
+ of the *path operation function*.
+
+ It can contain Markdown.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ response_description: Annotated[
+ str,
+ Doc(
+ """
+ The description for the default response.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = "Successful Response",
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses that could be returned by this *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this *path operation* as deprecated.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ operation_id: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Custom operation ID to be used by this *path operation*.
+
+ By default, it is generated automatically.
+
+ If you provide a custom operation ID, you need to make sure it is
+ unique for the whole API.
+
+ You can customize the
+ operation ID generation with the parameter
+ `generate_unique_id_function` in the `FastAPI` class.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = None,
+ response_model_include: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to include only certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_exclude: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to exclude certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_by_alias: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response model
+ should be serialized by alias when an alias is used.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = True,
+ response_model_exclude_unset: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that were not set and
+ have their default values. This is different from
+ `response_model_exclude_defaults` in that if the fields are set,
+ they will be included in the response, even if the value is the same
+ as the default.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_defaults: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that have the same value
+ as the default. This is different from `response_model_exclude_unset`
+ in that if the fields are set but contain the same default values,
+ they will be excluded from the response.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_none: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data should
+ exclude fields set to `None`.
+
+ This is much simpler (less smart) than `response_model_exclude_unset`
+ and `response_model_exclude_defaults`. You probably want to use one of
+ those two instead of this one, as those allow returning `None` values
+ when it makes sense.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+ """
+ ),
+ ] = False,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ Include this *path operation* in the generated OpenAPI schema.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-parameters-from-openapi).
+ """
+ ),
+ ] = True,
+ response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ Response class to be used for this *path operation*.
+
+ This will not be used if you return a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+ """
+ ),
+ ] = Default(JSONResponse),
+ name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Name for this *path operation*. Only used internally.
+ """
+ ),
+ ] = None,
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ List of *path operations* that will be used as OpenAPI callbacks.
+
+ This is only for OpenAPI documentation, the callbacks won't be used
+ directly.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ openapi_extra: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ Extra metadata to be included in the OpenAPI schema for this *path
+ operation*.
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+ """
+ ),
+ ] = None,
+ generate_unique_id_function: Annotated[
+ Callable[[routing.APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
+ ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add a *path operation* using an HTTP TRACE operation.
+
+ ## Example
+
+ ```python
+ from fastapi import FastAPI
+
+ app = FastAPI()
+
+ @app.trace("/items/{item_id}")
+ def trace_item(item_id: str):
+ return None
+ ```
+ """
+ return self.router.trace(
+ path,
+ response_model=response_model,
+ status_code=status_code,
+ tags=tags,
+ dependencies=dependencies,
+ summary=summary,
+ description=description,
+ response_description=response_description,
+ responses=responses,
+ deprecated=deprecated,
+ operation_id=operation_id,
+ response_model_include=response_model_include,
+ response_model_exclude=response_model_exclude,
+ response_model_by_alias=response_model_by_alias,
+ response_model_exclude_unset=response_model_exclude_unset,
+ response_model_exclude_defaults=response_model_exclude_defaults,
+ response_model_exclude_none=response_model_exclude_none,
+ include_in_schema=include_in_schema,
+ response_class=response_class,
+ name=name,
+ callbacks=callbacks,
+ openapi_extra=openapi_extra,
+ generate_unique_id_function=generate_unique_id_function,
+ )
+
+ def websocket_route(
+ self, path: str, name: Union[str, None] = None
+ ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ def decorator(func: DecoratedCallable) -> DecoratedCallable:
+ self.router.add_websocket_route(path, func, name=name)
+ return func
+
+ return decorator
+
+ @deprecated(
+ """
+ on_event is deprecated, use lifespan event handlers instead.
+
+ Read more about it in the
+ [FastAPI docs for Lifespan Events](https://fastapi.tiangolo.com/advanced/events/).
+ """
+ )
+ def on_event(
+ self,
+ event_type: Annotated[
+ str,
+ Doc(
+ """
+ The type of event. `startup` or `shutdown`.
+ """
+ ),
+ ],
+ ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add an event handler for the application.
+
+ `on_event` is deprecated, use `lifespan` event handlers instead.
+
+ Read more about it in the
+ [FastAPI docs for Lifespan Events](https://fastapi.tiangolo.com/advanced/events/#alternative-events-deprecated).
+ """
+ return self.router.on_event(event_type)
+
+ def middleware(
+ self,
+ middleware_type: Annotated[
+ str,
+ Doc(
+ """
+ The type of middleware. Currently only supports `http`.
+ """
+ ),
+ ],
+ ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add a middleware to the application.
+
+ Read more about it in the
+ [FastAPI docs for Middleware](https://fastapi.tiangolo.com/tutorial/middleware/).
+
+ ## Example
+
+ ```python
+ import time
+ from typing import Awaitable, Callable
+
+ from fastapi import FastAPI, Request, Response
+
+ app = FastAPI()
+
+
+ @app.middleware("http")
+ async def add_process_time_header(
+ request: Request, call_next: Callable[[Request], Awaitable[Response]]
+ ) -> Response:
+ start_time = time.time()
+ response = await call_next(request)
+ process_time = time.time() - start_time
+ response.headers["X-Process-Time"] = str(process_time)
+ return response
+ ```
+ """
+
+ def decorator(func: DecoratedCallable) -> DecoratedCallable:
+ self.add_middleware(BaseHTTPMiddleware, dispatch=func)
+ return func
+
+ return decorator
+
+ def exception_handler(
+ self,
+ exc_class_or_status_code: Annotated[
+ Union[int, Type[Exception]],
+ Doc(
+ """
+ The Exception class this would handle, or a status code.
+ """
+ ),
+ ],
+ ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add an exception handler to the app.
+
+ Read more about it in the
+ [FastAPI docs for Handling Errors](https://fastapi.tiangolo.com/tutorial/handling-errors/).
+
+ ## Example
+
+ ```python
+ from fastapi import FastAPI, Request
+ from fastapi.responses import JSONResponse
+
+
+ class UnicornException(Exception):
+ def __init__(self, name: str):
+ self.name = name
+
+
+ app = FastAPI()
+
+
+ @app.exception_handler(UnicornException)
+ async def unicorn_exception_handler(request: Request, exc: UnicornException):
+ return JSONResponse(
+ status_code=418,
+ content={"message": f"Oops! {exc.name} did something. There goes a rainbow..."},
+ )
+ ```
+ """
+
+ def decorator(func: DecoratedCallable) -> DecoratedCallable:
+ self.add_exception_handler(exc_class_or_status_code, func)
+ return func
+
+ return decorator
diff --git a/venv/Lib/site-packages/fastapi/background.py b/venv/Lib/site-packages/fastapi/background.py
new file mode 100644
index 00000000..203578a4
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/background.py
@@ -0,0 +1,59 @@
+from typing import Any, Callable
+
+from starlette.background import BackgroundTasks as StarletteBackgroundTasks
+from typing_extensions import Annotated, Doc, ParamSpec
+
+P = ParamSpec("P")
+
+
+class BackgroundTasks(StarletteBackgroundTasks):
+ """
+ A collection of background tasks that will be called after a response has been
+ sent to the client.
+
+ Read more about it in the
+ [FastAPI docs for Background Tasks](https://fastapi.tiangolo.com/tutorial/background-tasks/).
+
+ ## Example
+
+ ```python
+ from fastapi import BackgroundTasks, FastAPI
+
+ app = FastAPI()
+
+
+ def write_notification(email: str, message=""):
+ with open("log.txt", mode="w") as email_file:
+ content = f"notification for {email}: {message}"
+ email_file.write(content)
+
+
+ @app.post("/send-notification/{email}")
+ async def send_notification(email: str, background_tasks: BackgroundTasks):
+ background_tasks.add_task(write_notification, email, message="some notification")
+ return {"message": "Notification sent in the background"}
+ ```
+ """
+
+ def add_task(
+ self,
+ func: Annotated[
+ Callable[P, Any],
+ Doc(
+ """
+ The function to call after the response is sent.
+
+ It can be a regular `def` function or an `async def` function.
+ """
+ ),
+ ],
+ *args: P.args,
+ **kwargs: P.kwargs,
+ ) -> None:
+ """
+ Add a function to be called in the background after the response is sent.
+
+ Read more about it in the
+ [FastAPI docs for Background Tasks](https://fastapi.tiangolo.com/tutorial/background-tasks/).
+ """
+ return super().add_task(func, *args, **kwargs)
diff --git a/venv/Lib/site-packages/fastapi/cli.py b/venv/Lib/site-packages/fastapi/cli.py
new file mode 100644
index 00000000..8d3301e9
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/cli.py
@@ -0,0 +1,13 @@
+try:
+ from fastapi_cli.cli import main as cli_main
+
+except ImportError: # pragma: no cover
+ cli_main = None # type: ignore
+
+
+def main() -> None:
+ if not cli_main: # type: ignore[truthy-function]
+ message = 'To use the fastapi command, please install "fastapi[standard]":\n\n\tpip install "fastapi[standard]"\n'
+ print(message)
+ raise RuntimeError(message) # noqa: B904
+ cli_main()
diff --git a/venv/Lib/site-packages/fastapi/concurrency.py b/venv/Lib/site-packages/fastapi/concurrency.py
new file mode 100644
index 00000000..3202c707
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/concurrency.py
@@ -0,0 +1,39 @@
+from contextlib import asynccontextmanager as asynccontextmanager
+from typing import AsyncGenerator, ContextManager, TypeVar
+
+import anyio.to_thread
+from anyio import CapacityLimiter
+from starlette.concurrency import iterate_in_threadpool as iterate_in_threadpool # noqa
+from starlette.concurrency import run_in_threadpool as run_in_threadpool # noqa
+from starlette.concurrency import ( # noqa
+ run_until_first_complete as run_until_first_complete,
+)
+
+_T = TypeVar("_T")
+
+
+@asynccontextmanager
+async def contextmanager_in_threadpool(
+ cm: ContextManager[_T],
+) -> AsyncGenerator[_T, None]:
+ # blocking __exit__ from running waiting on a free thread
+ # can create race conditions/deadlocks if the context manager itself
+ # has its own internal pool (e.g. a database connection pool)
+ # to avoid this we let __exit__ run without a capacity limit
+ # since we're creating a new limiter for each call, any non-zero limit
+ # works (1 is arbitrary)
+ exit_limiter = CapacityLimiter(1)
+ try:
+ yield await run_in_threadpool(cm.__enter__)
+ except Exception as e:
+ ok = bool(
+ await anyio.to_thread.run_sync(
+ cm.__exit__, type(e), e, e.__traceback__, limiter=exit_limiter
+ )
+ )
+ if not ok:
+ raise e
+ else:
+ await anyio.to_thread.run_sync(
+ cm.__exit__, None, None, None, limiter=exit_limiter
+ )
diff --git a/venv/Lib/site-packages/fastapi/datastructures.py b/venv/Lib/site-packages/fastapi/datastructures.py
new file mode 100644
index 00000000..cf8406b0
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/datastructures.py
@@ -0,0 +1,204 @@
+from typing import (
+ Any,
+ BinaryIO,
+ Callable,
+ Dict,
+ Iterable,
+ Optional,
+ Type,
+ TypeVar,
+ cast,
+)
+
+from fastapi._compat import (
+ PYDANTIC_V2,
+ CoreSchema,
+ GetJsonSchemaHandler,
+ JsonSchemaValue,
+ with_info_plain_validator_function,
+)
+from starlette.datastructures import URL as URL # noqa: F401
+from starlette.datastructures import Address as Address # noqa: F401
+from starlette.datastructures import FormData as FormData # noqa: F401
+from starlette.datastructures import Headers as Headers # noqa: F401
+from starlette.datastructures import QueryParams as QueryParams # noqa: F401
+from starlette.datastructures import State as State # noqa: F401
+from starlette.datastructures import UploadFile as StarletteUploadFile
+from typing_extensions import Annotated, Doc
+
+
+class UploadFile(StarletteUploadFile):
+ """
+ A file uploaded in a request.
+
+ Define it as a *path operation function* (or dependency) parameter.
+
+ If you are using a regular `def` function, you can use the `upload_file.file`
+ attribute to access the raw standard Python file (blocking, not async), useful and
+ needed for non-async code.
+
+ Read more about it in the
+ [FastAPI docs for Request Files](https://fastapi.tiangolo.com/tutorial/request-files/).
+
+ ## Example
+
+ ```python
+ from typing import Annotated
+
+ from fastapi import FastAPI, File, UploadFile
+
+ app = FastAPI()
+
+
+ @app.post("/files/")
+ async def create_file(file: Annotated[bytes, File()]):
+ return {"file_size": len(file)}
+
+
+ @app.post("/uploadfile/")
+ async def create_upload_file(file: UploadFile):
+ return {"filename": file.filename}
+ ```
+ """
+
+ file: Annotated[
+ BinaryIO,
+ Doc("The standard Python file object (non-async)."),
+ ]
+ filename: Annotated[Optional[str], Doc("The original file name.")]
+ size: Annotated[Optional[int], Doc("The size of the file in bytes.")]
+ headers: Annotated[Headers, Doc("The headers of the request.")]
+ content_type: Annotated[
+ Optional[str], Doc("The content type of the request, from the headers.")
+ ]
+
+ async def write(
+ self,
+ data: Annotated[
+ bytes,
+ Doc(
+ """
+ The bytes to write to the file.
+ """
+ ),
+ ],
+ ) -> None:
+ """
+ Write some bytes to the file.
+
+ You normally wouldn't use this from a file you read in a request.
+
+ To be awaitable, compatible with async, this is run in threadpool.
+ """
+ return await super().write(data)
+
+ async def read(
+ self,
+ size: Annotated[
+ int,
+ Doc(
+ """
+ The number of bytes to read from the file.
+ """
+ ),
+ ] = -1,
+ ) -> bytes:
+ """
+ Read some bytes from the file.
+
+ To be awaitable, compatible with async, this is run in threadpool.
+ """
+ return await super().read(size)
+
+ async def seek(
+ self,
+ offset: Annotated[
+ int,
+ Doc(
+ """
+ The position in bytes to seek to in the file.
+ """
+ ),
+ ],
+ ) -> None:
+ """
+ Move to a position in the file.
+
+ Any next read or write will be done from that position.
+
+ To be awaitable, compatible with async, this is run in threadpool.
+ """
+ return await super().seek(offset)
+
+ async def close(self) -> None:
+ """
+ Close the file.
+
+ To be awaitable, compatible with async, this is run in threadpool.
+ """
+ return await super().close()
+
+ @classmethod
+ def __get_validators__(cls: Type["UploadFile"]) -> Iterable[Callable[..., Any]]:
+ yield cls.validate
+
+ @classmethod
+ def validate(cls: Type["UploadFile"], v: Any) -> Any:
+ if not isinstance(v, StarletteUploadFile):
+ raise ValueError(f"Expected UploadFile, received: {type(v)}")
+ return v
+
+ @classmethod
+ def _validate(cls, __input_value: Any, _: Any) -> "UploadFile":
+ if not isinstance(__input_value, StarletteUploadFile):
+ raise ValueError(f"Expected UploadFile, received: {type(__input_value)}")
+ return cast(UploadFile, __input_value)
+
+ if not PYDANTIC_V2:
+
+ @classmethod
+ def __modify_schema__(cls, field_schema: Dict[str, Any]) -> None:
+ field_schema.update({"type": "string", "format": "binary"})
+
+ @classmethod
+ def __get_pydantic_json_schema__(
+ cls, core_schema: CoreSchema, handler: GetJsonSchemaHandler
+ ) -> JsonSchemaValue:
+ return {"type": "string", "format": "binary"}
+
+ @classmethod
+ def __get_pydantic_core_schema__(
+ cls, source: Type[Any], handler: Callable[[Any], CoreSchema]
+ ) -> CoreSchema:
+ return with_info_plain_validator_function(cls._validate)
+
+
+class DefaultPlaceholder:
+ """
+ You shouldn't use this class directly.
+
+ It's used internally to recognize when a default value has been overwritten, even
+ if the overridden default value was truthy.
+ """
+
+ def __init__(self, value: Any):
+ self.value = value
+
+ def __bool__(self) -> bool:
+ return bool(self.value)
+
+ def __eq__(self, o: object) -> bool:
+ return isinstance(o, DefaultPlaceholder) and o.value == self.value
+
+
+DefaultType = TypeVar("DefaultType")
+
+
+def Default(value: DefaultType) -> DefaultType:
+ """
+ You shouldn't use this function directly.
+
+ It's used internally to recognize when a default value has been overwritten, even
+ if the overridden default value was truthy.
+ """
+ return DefaultPlaceholder(value) # type: ignore
diff --git a/venv/Lib/site-packages/fastapi/dependencies/__init__.py b/venv/Lib/site-packages/fastapi/dependencies/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/venv/Lib/site-packages/fastapi/dependencies/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/fastapi/dependencies/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 00000000..1d200cfe
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/dependencies/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/dependencies/__pycache__/models.cpython-312.pyc b/venv/Lib/site-packages/fastapi/dependencies/__pycache__/models.cpython-312.pyc
new file mode 100644
index 00000000..2c4ec2a9
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/dependencies/__pycache__/models.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/dependencies/__pycache__/utils.cpython-312.pyc b/venv/Lib/site-packages/fastapi/dependencies/__pycache__/utils.cpython-312.pyc
new file mode 100644
index 00000000..285fdda6
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/dependencies/__pycache__/utils.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/dependencies/models.py b/venv/Lib/site-packages/fastapi/dependencies/models.py
new file mode 100644
index 00000000..418c1172
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/dependencies/models.py
@@ -0,0 +1,37 @@
+from dataclasses import dataclass, field
+from typing import Any, Callable, List, Optional, Sequence, Tuple
+
+from fastapi._compat import ModelField
+from fastapi.security.base import SecurityBase
+
+
+@dataclass
+class SecurityRequirement:
+ security_scheme: SecurityBase
+ scopes: Optional[Sequence[str]] = None
+
+
+@dataclass
+class Dependant:
+ path_params: List[ModelField] = field(default_factory=list)
+ query_params: List[ModelField] = field(default_factory=list)
+ header_params: List[ModelField] = field(default_factory=list)
+ cookie_params: List[ModelField] = field(default_factory=list)
+ body_params: List[ModelField] = field(default_factory=list)
+ dependencies: List["Dependant"] = field(default_factory=list)
+ security_requirements: List[SecurityRequirement] = field(default_factory=list)
+ name: Optional[str] = None
+ call: Optional[Callable[..., Any]] = None
+ request_param_name: Optional[str] = None
+ websocket_param_name: Optional[str] = None
+ http_connection_param_name: Optional[str] = None
+ response_param_name: Optional[str] = None
+ background_tasks_param_name: Optional[str] = None
+ security_scopes_param_name: Optional[str] = None
+ security_scopes: Optional[List[str]] = None
+ use_cache: bool = True
+ path: Optional[str] = None
+ cache_key: Tuple[Optional[Callable[..., Any]], Tuple[str, ...]] = field(init=False)
+
+ def __post_init__(self) -> None:
+ self.cache_key = (self.call, tuple(sorted(set(self.security_scopes or []))))
diff --git a/venv/Lib/site-packages/fastapi/dependencies/utils.py b/venv/Lib/site-packages/fastapi/dependencies/utils.py
new file mode 100644
index 00000000..081b63a8
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/dependencies/utils.py
@@ -0,0 +1,1001 @@
+import inspect
+from contextlib import AsyncExitStack, contextmanager
+from copy import copy, deepcopy
+from dataclasses import dataclass
+from typing import (
+ Any,
+ Callable,
+ Coroutine,
+ Dict,
+ ForwardRef,
+ List,
+ Mapping,
+ Optional,
+ Sequence,
+ Tuple,
+ Type,
+ Union,
+ cast,
+)
+
+import anyio
+from fastapi import params
+from fastapi._compat import (
+ PYDANTIC_V2,
+ ErrorWrapper,
+ ModelField,
+ RequiredParam,
+ Undefined,
+ _regenerate_error_with_loc,
+ copy_field_info,
+ create_body_model,
+ evaluate_forwardref,
+ field_annotation_is_scalar,
+ get_annotation_from_field_info,
+ get_cached_model_fields,
+ get_missing_field_error,
+ is_bytes_field,
+ is_bytes_sequence_field,
+ is_scalar_field,
+ is_scalar_sequence_field,
+ is_sequence_field,
+ is_uploadfile_or_nonable_uploadfile_annotation,
+ is_uploadfile_sequence_annotation,
+ lenient_issubclass,
+ sequence_types,
+ serialize_sequence_value,
+ value_is_sequence,
+)
+from fastapi.background import BackgroundTasks
+from fastapi.concurrency import (
+ asynccontextmanager,
+ contextmanager_in_threadpool,
+)
+from fastapi.dependencies.models import Dependant, SecurityRequirement
+from fastapi.logger import logger
+from fastapi.security.base import SecurityBase
+from fastapi.security.oauth2 import OAuth2, SecurityScopes
+from fastapi.security.open_id_connect_url import OpenIdConnect
+from fastapi.utils import create_model_field, get_path_param_names
+from pydantic import BaseModel
+from pydantic.fields import FieldInfo
+from starlette.background import BackgroundTasks as StarletteBackgroundTasks
+from starlette.concurrency import run_in_threadpool
+from starlette.datastructures import (
+ FormData,
+ Headers,
+ ImmutableMultiDict,
+ QueryParams,
+ UploadFile,
+)
+from starlette.requests import HTTPConnection, Request
+from starlette.responses import Response
+from starlette.websockets import WebSocket
+from typing_extensions import Annotated, get_args, get_origin
+
+multipart_not_installed_error = (
+ 'Form data requires "python-multipart" to be installed. \n'
+ 'You can install "python-multipart" with: \n\n'
+ "pip install python-multipart\n"
+)
+multipart_incorrect_install_error = (
+ 'Form data requires "python-multipart" to be installed. '
+ 'It seems you installed "multipart" instead. \n'
+ 'You can remove "multipart" with: \n\n'
+ "pip uninstall multipart\n\n"
+ 'And then install "python-multipart" with: \n\n'
+ "pip install python-multipart\n"
+)
+
+
+def ensure_multipart_is_installed() -> None:
+ try:
+ from python_multipart import __version__
+
+ # Import an attribute that can be mocked/deleted in testing
+ assert __version__ > "0.0.12"
+ except (ImportError, AssertionError):
+ try:
+ # __version__ is available in both multiparts, and can be mocked
+ from multipart import __version__ # type: ignore[no-redef,import-untyped]
+
+ assert __version__
+ try:
+ # parse_options_header is only available in the right multipart
+ from multipart.multipart import ( # type: ignore[import-untyped]
+ parse_options_header,
+ )
+
+ assert parse_options_header
+ except ImportError:
+ logger.error(multipart_incorrect_install_error)
+ raise RuntimeError(multipart_incorrect_install_error) from None
+ except ImportError:
+ logger.error(multipart_not_installed_error)
+ raise RuntimeError(multipart_not_installed_error) from None
+
+
+def get_param_sub_dependant(
+ *,
+ param_name: str,
+ depends: params.Depends,
+ path: str,
+ security_scopes: Optional[List[str]] = None,
+) -> Dependant:
+ assert depends.dependency
+ return get_sub_dependant(
+ depends=depends,
+ dependency=depends.dependency,
+ path=path,
+ name=param_name,
+ security_scopes=security_scopes,
+ )
+
+
+def get_parameterless_sub_dependant(*, depends: params.Depends, path: str) -> Dependant:
+ assert callable(depends.dependency), (
+ "A parameter-less dependency must have a callable dependency"
+ )
+ return get_sub_dependant(depends=depends, dependency=depends.dependency, path=path)
+
+
+def get_sub_dependant(
+ *,
+ depends: params.Depends,
+ dependency: Callable[..., Any],
+ path: str,
+ name: Optional[str] = None,
+ security_scopes: Optional[List[str]] = None,
+) -> Dependant:
+ security_requirement = None
+ security_scopes = security_scopes or []
+ if isinstance(depends, params.Security):
+ dependency_scopes = depends.scopes
+ security_scopes.extend(dependency_scopes)
+ if isinstance(dependency, SecurityBase):
+ use_scopes: List[str] = []
+ if isinstance(dependency, (OAuth2, OpenIdConnect)):
+ use_scopes = security_scopes
+ security_requirement = SecurityRequirement(
+ security_scheme=dependency, scopes=use_scopes
+ )
+ sub_dependant = get_dependant(
+ path=path,
+ call=dependency,
+ name=name,
+ security_scopes=security_scopes,
+ use_cache=depends.use_cache,
+ )
+ if security_requirement:
+ sub_dependant.security_requirements.append(security_requirement)
+ return sub_dependant
+
+
+CacheKey = Tuple[Optional[Callable[..., Any]], Tuple[str, ...]]
+
+
+def get_flat_dependant(
+ dependant: Dependant,
+ *,
+ skip_repeats: bool = False,
+ visited: Optional[List[CacheKey]] = None,
+) -> Dependant:
+ if visited is None:
+ visited = []
+ visited.append(dependant.cache_key)
+
+ flat_dependant = Dependant(
+ path_params=dependant.path_params.copy(),
+ query_params=dependant.query_params.copy(),
+ header_params=dependant.header_params.copy(),
+ cookie_params=dependant.cookie_params.copy(),
+ body_params=dependant.body_params.copy(),
+ security_requirements=dependant.security_requirements.copy(),
+ use_cache=dependant.use_cache,
+ path=dependant.path,
+ )
+ for sub_dependant in dependant.dependencies:
+ if skip_repeats and sub_dependant.cache_key in visited:
+ continue
+ flat_sub = get_flat_dependant(
+ sub_dependant, skip_repeats=skip_repeats, visited=visited
+ )
+ flat_dependant.path_params.extend(flat_sub.path_params)
+ flat_dependant.query_params.extend(flat_sub.query_params)
+ flat_dependant.header_params.extend(flat_sub.header_params)
+ flat_dependant.cookie_params.extend(flat_sub.cookie_params)
+ flat_dependant.body_params.extend(flat_sub.body_params)
+ flat_dependant.security_requirements.extend(flat_sub.security_requirements)
+ return flat_dependant
+
+
+def _get_flat_fields_from_params(fields: List[ModelField]) -> List[ModelField]:
+ if not fields:
+ return fields
+ first_field = fields[0]
+ if len(fields) == 1 and lenient_issubclass(first_field.type_, BaseModel):
+ fields_to_extract = get_cached_model_fields(first_field.type_)
+ return fields_to_extract
+ return fields
+
+
+def get_flat_params(dependant: Dependant) -> List[ModelField]:
+ flat_dependant = get_flat_dependant(dependant, skip_repeats=True)
+ path_params = _get_flat_fields_from_params(flat_dependant.path_params)
+ query_params = _get_flat_fields_from_params(flat_dependant.query_params)
+ header_params = _get_flat_fields_from_params(flat_dependant.header_params)
+ cookie_params = _get_flat_fields_from_params(flat_dependant.cookie_params)
+ return path_params + query_params + header_params + cookie_params
+
+
+def get_typed_signature(call: Callable[..., Any]) -> inspect.Signature:
+ signature = inspect.signature(call)
+ globalns = getattr(call, "__globals__", {})
+ typed_params = [
+ inspect.Parameter(
+ name=param.name,
+ kind=param.kind,
+ default=param.default,
+ annotation=get_typed_annotation(param.annotation, globalns),
+ )
+ for param in signature.parameters.values()
+ ]
+ typed_signature = inspect.Signature(typed_params)
+ return typed_signature
+
+
+def get_typed_annotation(annotation: Any, globalns: Dict[str, Any]) -> Any:
+ if isinstance(annotation, str):
+ annotation = ForwardRef(annotation)
+ annotation = evaluate_forwardref(annotation, globalns, globalns)
+ return annotation
+
+
+def get_typed_return_annotation(call: Callable[..., Any]) -> Any:
+ signature = inspect.signature(call)
+ annotation = signature.return_annotation
+
+ if annotation is inspect.Signature.empty:
+ return None
+
+ globalns = getattr(call, "__globals__", {})
+ return get_typed_annotation(annotation, globalns)
+
+
+def get_dependant(
+ *,
+ path: str,
+ call: Callable[..., Any],
+ name: Optional[str] = None,
+ security_scopes: Optional[List[str]] = None,
+ use_cache: bool = True,
+) -> Dependant:
+ path_param_names = get_path_param_names(path)
+ endpoint_signature = get_typed_signature(call)
+ signature_params = endpoint_signature.parameters
+ dependant = Dependant(
+ call=call,
+ name=name,
+ path=path,
+ security_scopes=security_scopes,
+ use_cache=use_cache,
+ )
+ for param_name, param in signature_params.items():
+ is_path_param = param_name in path_param_names
+ param_details = analyze_param(
+ param_name=param_name,
+ annotation=param.annotation,
+ value=param.default,
+ is_path_param=is_path_param,
+ )
+ if param_details.depends is not None:
+ sub_dependant = get_param_sub_dependant(
+ param_name=param_name,
+ depends=param_details.depends,
+ path=path,
+ security_scopes=security_scopes,
+ )
+ dependant.dependencies.append(sub_dependant)
+ continue
+ if add_non_field_param_to_dependency(
+ param_name=param_name,
+ type_annotation=param_details.type_annotation,
+ dependant=dependant,
+ ):
+ assert param_details.field is None, (
+ f"Cannot specify multiple FastAPI annotations for {param_name!r}"
+ )
+ continue
+ assert param_details.field is not None
+ if isinstance(param_details.field.field_info, params.Body):
+ dependant.body_params.append(param_details.field)
+ else:
+ add_param_to_fields(field=param_details.field, dependant=dependant)
+ return dependant
+
+
+def add_non_field_param_to_dependency(
+ *, param_name: str, type_annotation: Any, dependant: Dependant
+) -> Optional[bool]:
+ if lenient_issubclass(type_annotation, Request):
+ dependant.request_param_name = param_name
+ return True
+ elif lenient_issubclass(type_annotation, WebSocket):
+ dependant.websocket_param_name = param_name
+ return True
+ elif lenient_issubclass(type_annotation, HTTPConnection):
+ dependant.http_connection_param_name = param_name
+ return True
+ elif lenient_issubclass(type_annotation, Response):
+ dependant.response_param_name = param_name
+ return True
+ elif lenient_issubclass(type_annotation, StarletteBackgroundTasks):
+ dependant.background_tasks_param_name = param_name
+ return True
+ elif lenient_issubclass(type_annotation, SecurityScopes):
+ dependant.security_scopes_param_name = param_name
+ return True
+ return None
+
+
+@dataclass
+class ParamDetails:
+ type_annotation: Any
+ depends: Optional[params.Depends]
+ field: Optional[ModelField]
+
+
+def analyze_param(
+ *,
+ param_name: str,
+ annotation: Any,
+ value: Any,
+ is_path_param: bool,
+) -> ParamDetails:
+ field_info = None
+ depends = None
+ type_annotation: Any = Any
+ use_annotation: Any = Any
+ if annotation is not inspect.Signature.empty:
+ use_annotation = annotation
+ type_annotation = annotation
+ # Extract Annotated info
+ if get_origin(use_annotation) is Annotated:
+ annotated_args = get_args(annotation)
+ type_annotation = annotated_args[0]
+ fastapi_annotations = [
+ arg
+ for arg in annotated_args[1:]
+ if isinstance(arg, (FieldInfo, params.Depends))
+ ]
+ fastapi_specific_annotations = [
+ arg
+ for arg in fastapi_annotations
+ if isinstance(arg, (params.Param, params.Body, params.Depends))
+ ]
+ if fastapi_specific_annotations:
+ fastapi_annotation: Union[FieldInfo, params.Depends, None] = (
+ fastapi_specific_annotations[-1]
+ )
+ else:
+ fastapi_annotation = None
+ # Set default for Annotated FieldInfo
+ if isinstance(fastapi_annotation, FieldInfo):
+ # Copy `field_info` because we mutate `field_info.default` below.
+ field_info = copy_field_info(
+ field_info=fastapi_annotation, annotation=use_annotation
+ )
+ assert (
+ field_info.default is Undefined or field_info.default is RequiredParam
+ ), (
+ f"`{field_info.__class__.__name__}` default value cannot be set in"
+ f" `Annotated` for {param_name!r}. Set the default value with `=` instead."
+ )
+ if value is not inspect.Signature.empty:
+ assert not is_path_param, "Path parameters cannot have default values"
+ field_info.default = value
+ else:
+ field_info.default = RequiredParam
+ # Get Annotated Depends
+ elif isinstance(fastapi_annotation, params.Depends):
+ depends = fastapi_annotation
+ # Get Depends from default value
+ if isinstance(value, params.Depends):
+ assert depends is None, (
+ "Cannot specify `Depends` in `Annotated` and default value"
+ f" together for {param_name!r}"
+ )
+ assert field_info is None, (
+ "Cannot specify a FastAPI annotation in `Annotated` and `Depends` as a"
+ f" default value together for {param_name!r}"
+ )
+ depends = value
+ # Get FieldInfo from default value
+ elif isinstance(value, FieldInfo):
+ assert field_info is None, (
+ "Cannot specify FastAPI annotations in `Annotated` and default value"
+ f" together for {param_name!r}"
+ )
+ field_info = value
+ if PYDANTIC_V2:
+ field_info.annotation = type_annotation
+
+ # Get Depends from type annotation
+ if depends is not None and depends.dependency is None:
+ # Copy `depends` before mutating it
+ depends = copy(depends)
+ depends.dependency = type_annotation
+
+ # Handle non-param type annotations like Request
+ if lenient_issubclass(
+ type_annotation,
+ (
+ Request,
+ WebSocket,
+ HTTPConnection,
+ Response,
+ StarletteBackgroundTasks,
+ SecurityScopes,
+ ),
+ ):
+ assert depends is None, f"Cannot specify `Depends` for type {type_annotation!r}"
+ assert field_info is None, (
+ f"Cannot specify FastAPI annotation for type {type_annotation!r}"
+ )
+ # Handle default assignations, neither field_info nor depends was not found in Annotated nor default value
+ elif field_info is None and depends is None:
+ default_value = value if value is not inspect.Signature.empty else RequiredParam
+ if is_path_param:
+ # We might check here that `default_value is RequiredParam`, but the fact is that the same
+ # parameter might sometimes be a path parameter and sometimes not. See
+ # `tests/test_infer_param_optionality.py` for an example.
+ field_info = params.Path(annotation=use_annotation)
+ elif is_uploadfile_or_nonable_uploadfile_annotation(
+ type_annotation
+ ) or is_uploadfile_sequence_annotation(type_annotation):
+ field_info = params.File(annotation=use_annotation, default=default_value)
+ elif not field_annotation_is_scalar(annotation=type_annotation):
+ field_info = params.Body(annotation=use_annotation, default=default_value)
+ else:
+ field_info = params.Query(annotation=use_annotation, default=default_value)
+
+ field = None
+ # It's a field_info, not a dependency
+ if field_info is not None:
+ # Handle field_info.in_
+ if is_path_param:
+ assert isinstance(field_info, params.Path), (
+ f"Cannot use `{field_info.__class__.__name__}` for path param"
+ f" {param_name!r}"
+ )
+ elif (
+ isinstance(field_info, params.Param)
+ and getattr(field_info, "in_", None) is None
+ ):
+ field_info.in_ = params.ParamTypes.query
+ use_annotation_from_field_info = get_annotation_from_field_info(
+ use_annotation,
+ field_info,
+ param_name,
+ )
+ if isinstance(field_info, params.Form):
+ ensure_multipart_is_installed()
+ if not field_info.alias and getattr(field_info, "convert_underscores", None):
+ alias = param_name.replace("_", "-")
+ else:
+ alias = field_info.alias or param_name
+ field_info.alias = alias
+ field = create_model_field(
+ name=param_name,
+ type_=use_annotation_from_field_info,
+ default=field_info.default,
+ alias=alias,
+ required=field_info.default in (RequiredParam, Undefined),
+ field_info=field_info,
+ )
+ if is_path_param:
+ assert is_scalar_field(field=field), (
+ "Path params must be of one of the supported types"
+ )
+ elif isinstance(field_info, params.Query):
+ assert (
+ is_scalar_field(field)
+ or is_scalar_sequence_field(field)
+ or (
+ lenient_issubclass(field.type_, BaseModel)
+ # For Pydantic v1
+ and getattr(field, "shape", 1) == 1
+ )
+ )
+
+ return ParamDetails(type_annotation=type_annotation, depends=depends, field=field)
+
+
+def add_param_to_fields(*, field: ModelField, dependant: Dependant) -> None:
+ field_info = field.field_info
+ field_info_in = getattr(field_info, "in_", None)
+ if field_info_in == params.ParamTypes.path:
+ dependant.path_params.append(field)
+ elif field_info_in == params.ParamTypes.query:
+ dependant.query_params.append(field)
+ elif field_info_in == params.ParamTypes.header:
+ dependant.header_params.append(field)
+ else:
+ assert field_info_in == params.ParamTypes.cookie, (
+ f"non-body parameters must be in path, query, header or cookie: {field.name}"
+ )
+ dependant.cookie_params.append(field)
+
+
+def is_coroutine_callable(call: Callable[..., Any]) -> bool:
+ if inspect.isroutine(call):
+ return inspect.iscoroutinefunction(call)
+ if inspect.isclass(call):
+ return False
+ dunder_call = getattr(call, "__call__", None) # noqa: B004
+ return inspect.iscoroutinefunction(dunder_call)
+
+
+def is_async_gen_callable(call: Callable[..., Any]) -> bool:
+ if inspect.isasyncgenfunction(call):
+ return True
+ dunder_call = getattr(call, "__call__", None) # noqa: B004
+ return inspect.isasyncgenfunction(dunder_call)
+
+
+def is_gen_callable(call: Callable[..., Any]) -> bool:
+ if inspect.isgeneratorfunction(call):
+ return True
+ dunder_call = getattr(call, "__call__", None) # noqa: B004
+ return inspect.isgeneratorfunction(dunder_call)
+
+
+async def solve_generator(
+ *, call: Callable[..., Any], stack: AsyncExitStack, sub_values: Dict[str, Any]
+) -> Any:
+ if is_gen_callable(call):
+ cm = contextmanager_in_threadpool(contextmanager(call)(**sub_values))
+ elif is_async_gen_callable(call):
+ cm = asynccontextmanager(call)(**sub_values)
+ return await stack.enter_async_context(cm)
+
+
+@dataclass
+class SolvedDependency:
+ values: Dict[str, Any]
+ errors: List[Any]
+ background_tasks: Optional[StarletteBackgroundTasks]
+ response: Response
+ dependency_cache: Dict[Tuple[Callable[..., Any], Tuple[str]], Any]
+
+
+async def solve_dependencies(
+ *,
+ request: Union[Request, WebSocket],
+ dependant: Dependant,
+ body: Optional[Union[Dict[str, Any], FormData]] = None,
+ background_tasks: Optional[StarletteBackgroundTasks] = None,
+ response: Optional[Response] = None,
+ dependency_overrides_provider: Optional[Any] = None,
+ dependency_cache: Optional[Dict[Tuple[Callable[..., Any], Tuple[str]], Any]] = None,
+ async_exit_stack: AsyncExitStack,
+ embed_body_fields: bool,
+) -> SolvedDependency:
+ values: Dict[str, Any] = {}
+ errors: List[Any] = []
+ if response is None:
+ response = Response()
+ del response.headers["content-length"]
+ response.status_code = None # type: ignore
+ dependency_cache = dependency_cache or {}
+ sub_dependant: Dependant
+ for sub_dependant in dependant.dependencies:
+ sub_dependant.call = cast(Callable[..., Any], sub_dependant.call)
+ sub_dependant.cache_key = cast(
+ Tuple[Callable[..., Any], Tuple[str]], sub_dependant.cache_key
+ )
+ call = sub_dependant.call
+ use_sub_dependant = sub_dependant
+ if (
+ dependency_overrides_provider
+ and dependency_overrides_provider.dependency_overrides
+ ):
+ original_call = sub_dependant.call
+ call = getattr(
+ dependency_overrides_provider, "dependency_overrides", {}
+ ).get(original_call, original_call)
+ use_path: str = sub_dependant.path # type: ignore
+ use_sub_dependant = get_dependant(
+ path=use_path,
+ call=call,
+ name=sub_dependant.name,
+ security_scopes=sub_dependant.security_scopes,
+ )
+
+ solved_result = await solve_dependencies(
+ request=request,
+ dependant=use_sub_dependant,
+ body=body,
+ background_tasks=background_tasks,
+ response=response,
+ dependency_overrides_provider=dependency_overrides_provider,
+ dependency_cache=dependency_cache,
+ async_exit_stack=async_exit_stack,
+ embed_body_fields=embed_body_fields,
+ )
+ background_tasks = solved_result.background_tasks
+ dependency_cache.update(solved_result.dependency_cache)
+ if solved_result.errors:
+ errors.extend(solved_result.errors)
+ continue
+ if sub_dependant.use_cache and sub_dependant.cache_key in dependency_cache:
+ solved = dependency_cache[sub_dependant.cache_key]
+ elif is_gen_callable(call) or is_async_gen_callable(call):
+ solved = await solve_generator(
+ call=call, stack=async_exit_stack, sub_values=solved_result.values
+ )
+ elif is_coroutine_callable(call):
+ solved = await call(**solved_result.values)
+ else:
+ solved = await run_in_threadpool(call, **solved_result.values)
+ if sub_dependant.name is not None:
+ values[sub_dependant.name] = solved
+ if sub_dependant.cache_key not in dependency_cache:
+ dependency_cache[sub_dependant.cache_key] = solved
+ path_values, path_errors = request_params_to_args(
+ dependant.path_params, request.path_params
+ )
+ query_values, query_errors = request_params_to_args(
+ dependant.query_params, request.query_params
+ )
+ header_values, header_errors = request_params_to_args(
+ dependant.header_params, request.headers
+ )
+ cookie_values, cookie_errors = request_params_to_args(
+ dependant.cookie_params, request.cookies
+ )
+ values.update(path_values)
+ values.update(query_values)
+ values.update(header_values)
+ values.update(cookie_values)
+ errors += path_errors + query_errors + header_errors + cookie_errors
+ if dependant.body_params:
+ (
+ body_values,
+ body_errors,
+ ) = await request_body_to_args( # body_params checked above
+ body_fields=dependant.body_params,
+ received_body=body,
+ embed_body_fields=embed_body_fields,
+ )
+ values.update(body_values)
+ errors.extend(body_errors)
+ if dependant.http_connection_param_name:
+ values[dependant.http_connection_param_name] = request
+ if dependant.request_param_name and isinstance(request, Request):
+ values[dependant.request_param_name] = request
+ elif dependant.websocket_param_name and isinstance(request, WebSocket):
+ values[dependant.websocket_param_name] = request
+ if dependant.background_tasks_param_name:
+ if background_tasks is None:
+ background_tasks = BackgroundTasks()
+ values[dependant.background_tasks_param_name] = background_tasks
+ if dependant.response_param_name:
+ values[dependant.response_param_name] = response
+ if dependant.security_scopes_param_name:
+ values[dependant.security_scopes_param_name] = SecurityScopes(
+ scopes=dependant.security_scopes
+ )
+ return SolvedDependency(
+ values=values,
+ errors=errors,
+ background_tasks=background_tasks,
+ response=response,
+ dependency_cache=dependency_cache,
+ )
+
+
+def _validate_value_with_model_field(
+ *, field: ModelField, value: Any, values: Dict[str, Any], loc: Tuple[str, ...]
+) -> Tuple[Any, List[Any]]:
+ if value is None:
+ if field.required:
+ return None, [get_missing_field_error(loc=loc)]
+ else:
+ return deepcopy(field.default), []
+ v_, errors_ = field.validate(value, values, loc=loc)
+ if isinstance(errors_, ErrorWrapper):
+ return None, [errors_]
+ elif isinstance(errors_, list):
+ new_errors = _regenerate_error_with_loc(errors=errors_, loc_prefix=())
+ return None, new_errors
+ else:
+ return v_, []
+
+
+def _get_multidict_value(
+ field: ModelField, values: Mapping[str, Any], alias: Union[str, None] = None
+) -> Any:
+ alias = alias or field.alias
+ if is_sequence_field(field) and isinstance(values, (ImmutableMultiDict, Headers)):
+ value = values.getlist(alias)
+ else:
+ value = values.get(alias, None)
+ if (
+ value is None
+ or (
+ isinstance(field.field_info, params.Form)
+ and isinstance(value, str) # For type checks
+ and value == ""
+ )
+ or (is_sequence_field(field) and len(value) == 0)
+ ):
+ if field.required:
+ return
+ else:
+ return deepcopy(field.default)
+ return value
+
+
+def request_params_to_args(
+ fields: Sequence[ModelField],
+ received_params: Union[Mapping[str, Any], QueryParams, Headers],
+) -> Tuple[Dict[str, Any], List[Any]]:
+ values: Dict[str, Any] = {}
+ errors: List[Dict[str, Any]] = []
+
+ if not fields:
+ return values, errors
+
+ first_field = fields[0]
+ fields_to_extract = fields
+ single_not_embedded_field = False
+ default_convert_underscores = True
+ if len(fields) == 1 and lenient_issubclass(first_field.type_, BaseModel):
+ fields_to_extract = get_cached_model_fields(first_field.type_)
+ single_not_embedded_field = True
+ # If headers are in a Pydantic model, the way to disable convert_underscores
+ # would be with Header(convert_underscores=False) at the Pydantic model level
+ default_convert_underscores = getattr(
+ first_field.field_info, "convert_underscores", True
+ )
+
+ params_to_process: Dict[str, Any] = {}
+
+ processed_keys = set()
+
+ for field in fields_to_extract:
+ alias = None
+ if isinstance(received_params, Headers):
+ # Handle fields extracted from a Pydantic Model for a header, each field
+ # doesn't have a FieldInfo of type Header with the default convert_underscores=True
+ convert_underscores = getattr(
+ field.field_info, "convert_underscores", default_convert_underscores
+ )
+ if convert_underscores:
+ alias = (
+ field.alias
+ if field.alias != field.name
+ else field.name.replace("_", "-")
+ )
+ value = _get_multidict_value(field, received_params, alias=alias)
+ if value is not None:
+ params_to_process[field.name] = value
+ processed_keys.add(alias or field.alias)
+ processed_keys.add(field.name)
+
+ for key, value in received_params.items():
+ if key not in processed_keys:
+ params_to_process[key] = value
+
+ if single_not_embedded_field:
+ field_info = first_field.field_info
+ assert isinstance(field_info, params.Param), (
+ "Params must be subclasses of Param"
+ )
+ loc: Tuple[str, ...] = (field_info.in_.value,)
+ v_, errors_ = _validate_value_with_model_field(
+ field=first_field, value=params_to_process, values=values, loc=loc
+ )
+ return {first_field.name: v_}, errors_
+
+ for field in fields:
+ value = _get_multidict_value(field, received_params)
+ field_info = field.field_info
+ assert isinstance(field_info, params.Param), (
+ "Params must be subclasses of Param"
+ )
+ loc = (field_info.in_.value, field.alias)
+ v_, errors_ = _validate_value_with_model_field(
+ field=field, value=value, values=values, loc=loc
+ )
+ if errors_:
+ errors.extend(errors_)
+ else:
+ values[field.name] = v_
+ return values, errors
+
+
+def is_union_of_base_models(field_type: Any) -> bool:
+ """Check if field type is a Union where all members are BaseModel subclasses."""
+ from fastapi.types import UnionType
+
+ origin = get_origin(field_type)
+
+ # Check if it's a Union type (covers both typing.Union and types.UnionType in Python 3.10+)
+ if origin is not Union and origin is not UnionType:
+ return False
+
+ union_args = get_args(field_type)
+
+ for arg in union_args:
+ if not lenient_issubclass(arg, BaseModel):
+ return False
+
+ return True
+
+
+def _should_embed_body_fields(fields: List[ModelField]) -> bool:
+ if not fields:
+ return False
+ # More than one dependency could have the same field, it would show up as multiple
+ # fields but it's the same one, so count them by name
+ body_param_names_set = {field.name for field in fields}
+ # A top level field has to be a single field, not multiple
+ if len(body_param_names_set) > 1:
+ return True
+ first_field = fields[0]
+ # If it explicitly specifies it is embedded, it has to be embedded
+ if getattr(first_field.field_info, "embed", None):
+ return True
+ # If it's a Form (or File) field, it has to be a BaseModel (or a union of BaseModels) to be top level
+ # otherwise it has to be embedded, so that the key value pair can be extracted
+ if (
+ isinstance(first_field.field_info, params.Form)
+ and not lenient_issubclass(first_field.type_, BaseModel)
+ and not is_union_of_base_models(first_field.type_)
+ ):
+ return True
+ return False
+
+
+async def _extract_form_body(
+ body_fields: List[ModelField],
+ received_body: FormData,
+) -> Dict[str, Any]:
+ values = {}
+ first_field = body_fields[0]
+ first_field_info = first_field.field_info
+
+ for field in body_fields:
+ value = _get_multidict_value(field, received_body)
+ if (
+ isinstance(first_field_info, params.File)
+ and is_bytes_field(field)
+ and isinstance(value, UploadFile)
+ ):
+ value = await value.read()
+ elif (
+ is_bytes_sequence_field(field)
+ and isinstance(first_field_info, params.File)
+ and value_is_sequence(value)
+ ):
+ # For types
+ assert isinstance(value, sequence_types) # type: ignore[arg-type]
+ results: List[Union[bytes, str]] = []
+
+ async def process_fn(
+ fn: Callable[[], Coroutine[Any, Any, Any]],
+ ) -> None:
+ result = await fn()
+ results.append(result) # noqa: B023
+
+ async with anyio.create_task_group() as tg:
+ for sub_value in value:
+ tg.start_soon(process_fn, sub_value.read)
+ value = serialize_sequence_value(field=field, value=results)
+ if value is not None:
+ values[field.alias] = value
+ for key, value in received_body.items():
+ if key not in values:
+ values[key] = value
+ return values
+
+
+async def request_body_to_args(
+ body_fields: List[ModelField],
+ received_body: Optional[Union[Dict[str, Any], FormData]],
+ embed_body_fields: bool,
+) -> Tuple[Dict[str, Any], List[Dict[str, Any]]]:
+ values: Dict[str, Any] = {}
+ errors: List[Dict[str, Any]] = []
+ assert body_fields, "request_body_to_args() should be called with fields"
+ single_not_embedded_field = len(body_fields) == 1 and not embed_body_fields
+ first_field = body_fields[0]
+ body_to_process = received_body
+
+ fields_to_extract: List[ModelField] = body_fields
+
+ if single_not_embedded_field and lenient_issubclass(first_field.type_, BaseModel):
+ fields_to_extract = get_cached_model_fields(first_field.type_)
+
+ if isinstance(received_body, FormData):
+ body_to_process = await _extract_form_body(fields_to_extract, received_body)
+
+ if single_not_embedded_field:
+ loc: Tuple[str, ...] = ("body",)
+ v_, errors_ = _validate_value_with_model_field(
+ field=first_field, value=body_to_process, values=values, loc=loc
+ )
+ return {first_field.name: v_}, errors_
+ for field in body_fields:
+ loc = ("body", field.alias)
+ value: Optional[Any] = None
+ if body_to_process is not None:
+ try:
+ value = body_to_process.get(field.alias)
+ # If the received body is a list, not a dict
+ except AttributeError:
+ errors.append(get_missing_field_error(loc))
+ continue
+ v_, errors_ = _validate_value_with_model_field(
+ field=field, value=value, values=values, loc=loc
+ )
+ if errors_:
+ errors.extend(errors_)
+ else:
+ values[field.name] = v_
+ return values, errors
+
+
+def get_body_field(
+ *, flat_dependant: Dependant, name: str, embed_body_fields: bool
+) -> Optional[ModelField]:
+ """
+ Get a ModelField representing the request body for a path operation, combining
+ all body parameters into a single field if necessary.
+
+ Used to check if it's form data (with `isinstance(body_field, params.Form)`)
+ or JSON and to generate the JSON Schema for a request body.
+
+ This is **not** used to validate/parse the request body, that's done with each
+ individual body parameter.
+ """
+ if not flat_dependant.body_params:
+ return None
+ first_param = flat_dependant.body_params[0]
+ if not embed_body_fields:
+ return first_param
+ model_name = "Body_" + name
+ BodyModel = create_body_model(
+ fields=flat_dependant.body_params, model_name=model_name
+ )
+ required = any(True for f in flat_dependant.body_params if f.required)
+ BodyFieldInfo_kwargs: Dict[str, Any] = {
+ "annotation": BodyModel,
+ "alias": "body",
+ }
+ if not required:
+ BodyFieldInfo_kwargs["default"] = None
+ if any(isinstance(f.field_info, params.File) for f in flat_dependant.body_params):
+ BodyFieldInfo: Type[params.Body] = params.File
+ elif any(isinstance(f.field_info, params.Form) for f in flat_dependant.body_params):
+ BodyFieldInfo = params.Form
+ else:
+ BodyFieldInfo = params.Body
+
+ body_param_media_types = [
+ f.field_info.media_type
+ for f in flat_dependant.body_params
+ if isinstance(f.field_info, params.Body)
+ ]
+ if len(set(body_param_media_types)) == 1:
+ BodyFieldInfo_kwargs["media_type"] = body_param_media_types[0]
+ final_field = create_model_field(
+ name="body",
+ type_=BodyModel,
+ required=required,
+ alias="body",
+ field_info=BodyFieldInfo(**BodyFieldInfo_kwargs),
+ )
+ return final_field
diff --git a/venv/Lib/site-packages/fastapi/encoders.py b/venv/Lib/site-packages/fastapi/encoders.py
new file mode 100644
index 00000000..451ea076
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/encoders.py
@@ -0,0 +1,343 @@
+import dataclasses
+import datetime
+from collections import defaultdict, deque
+from decimal import Decimal
+from enum import Enum
+from ipaddress import (
+ IPv4Address,
+ IPv4Interface,
+ IPv4Network,
+ IPv6Address,
+ IPv6Interface,
+ IPv6Network,
+)
+from pathlib import Path, PurePath
+from re import Pattern
+from types import GeneratorType
+from typing import Any, Callable, Dict, List, Optional, Tuple, Type, Union
+from uuid import UUID
+
+from fastapi.types import IncEx
+from pydantic import BaseModel
+from pydantic.color import Color
+from pydantic.networks import AnyUrl, NameEmail
+from pydantic.types import SecretBytes, SecretStr
+from typing_extensions import Annotated, Doc
+
+from ._compat import PYDANTIC_V2, UndefinedType, Url, _model_dump
+
+
+# Taken from Pydantic v1 as is
+def isoformat(o: Union[datetime.date, datetime.time]) -> str:
+ return o.isoformat()
+
+
+# Taken from Pydantic v1 as is
+# TODO: pv2 should this return strings instead?
+def decimal_encoder(dec_value: Decimal) -> Union[int, float]:
+ """
+ Encodes a Decimal as int of there's no exponent, otherwise float
+
+ This is useful when we use ConstrainedDecimal to represent Numeric(x,0)
+ where a integer (but not int typed) is used. Encoding this as a float
+ results in failed round-tripping between encode and parse.
+ Our Id type is a prime example of this.
+
+ >>> decimal_encoder(Decimal("1.0"))
+ 1.0
+
+ >>> decimal_encoder(Decimal("1"))
+ 1
+ """
+ if dec_value.as_tuple().exponent >= 0: # type: ignore[operator]
+ return int(dec_value)
+ else:
+ return float(dec_value)
+
+
+ENCODERS_BY_TYPE: Dict[Type[Any], Callable[[Any], Any]] = {
+ bytes: lambda o: o.decode(),
+ Color: str,
+ datetime.date: isoformat,
+ datetime.datetime: isoformat,
+ datetime.time: isoformat,
+ datetime.timedelta: lambda td: td.total_seconds(),
+ Decimal: decimal_encoder,
+ Enum: lambda o: o.value,
+ frozenset: list,
+ deque: list,
+ GeneratorType: list,
+ IPv4Address: str,
+ IPv4Interface: str,
+ IPv4Network: str,
+ IPv6Address: str,
+ IPv6Interface: str,
+ IPv6Network: str,
+ NameEmail: str,
+ Path: str,
+ Pattern: lambda o: o.pattern,
+ SecretBytes: str,
+ SecretStr: str,
+ set: list,
+ UUID: str,
+ Url: str,
+ AnyUrl: str,
+}
+
+
+def generate_encoders_by_class_tuples(
+ type_encoder_map: Dict[Any, Callable[[Any], Any]],
+) -> Dict[Callable[[Any], Any], Tuple[Any, ...]]:
+ encoders_by_class_tuples: Dict[Callable[[Any], Any], Tuple[Any, ...]] = defaultdict(
+ tuple
+ )
+ for type_, encoder in type_encoder_map.items():
+ encoders_by_class_tuples[encoder] += (type_,)
+ return encoders_by_class_tuples
+
+
+encoders_by_class_tuples = generate_encoders_by_class_tuples(ENCODERS_BY_TYPE)
+
+
+def jsonable_encoder(
+ obj: Annotated[
+ Any,
+ Doc(
+ """
+ The input object to convert to JSON.
+ """
+ ),
+ ],
+ include: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Pydantic's `include` parameter, passed to Pydantic models to set the
+ fields to include.
+ """
+ ),
+ ] = None,
+ exclude: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Pydantic's `exclude` parameter, passed to Pydantic models to set the
+ fields to exclude.
+ """
+ ),
+ ] = None,
+ by_alias: Annotated[
+ bool,
+ Doc(
+ """
+ Pydantic's `by_alias` parameter, passed to Pydantic models to define if
+ the output should use the alias names (when provided) or the Python
+ attribute names. In an API, if you set an alias, it's probably because you
+ want to use it in the result, so you probably want to leave this set to
+ `True`.
+ """
+ ),
+ ] = True,
+ exclude_unset: Annotated[
+ bool,
+ Doc(
+ """
+ Pydantic's `exclude_unset` parameter, passed to Pydantic models to define
+ if it should exclude from the output the fields that were not explicitly
+ set (and that only had their default values).
+ """
+ ),
+ ] = False,
+ exclude_defaults: Annotated[
+ bool,
+ Doc(
+ """
+ Pydantic's `exclude_defaults` parameter, passed to Pydantic models to define
+ if it should exclude from the output the fields that had the same default
+ value, even when they were explicitly set.
+ """
+ ),
+ ] = False,
+ exclude_none: Annotated[
+ bool,
+ Doc(
+ """
+ Pydantic's `exclude_none` parameter, passed to Pydantic models to define
+ if it should exclude from the output any fields that have a `None` value.
+ """
+ ),
+ ] = False,
+ custom_encoder: Annotated[
+ Optional[Dict[Any, Callable[[Any], Any]]],
+ Doc(
+ """
+ Pydantic's `custom_encoder` parameter, passed to Pydantic models to define
+ a custom encoder.
+ """
+ ),
+ ] = None,
+ sqlalchemy_safe: Annotated[
+ bool,
+ Doc(
+ """
+ Exclude from the output any fields that start with the name `_sa`.
+
+ This is mainly a hack for compatibility with SQLAlchemy objects, they
+ store internal SQLAlchemy-specific state in attributes named with `_sa`,
+ and those objects can't (and shouldn't be) serialized to JSON.
+ """
+ ),
+ ] = True,
+) -> Any:
+ """
+ Convert any object to something that can be encoded in JSON.
+
+ This is used internally by FastAPI to make sure anything you return can be
+ encoded as JSON before it is sent to the client.
+
+ You can also use it yourself, for example to convert objects before saving them
+ in a database that supports only JSON.
+
+ Read more about it in the
+ [FastAPI docs for JSON Compatible Encoder](https://fastapi.tiangolo.com/tutorial/encoder/).
+ """
+ custom_encoder = custom_encoder or {}
+ if custom_encoder:
+ if type(obj) in custom_encoder:
+ return custom_encoder[type(obj)](obj)
+ else:
+ for encoder_type, encoder_instance in custom_encoder.items():
+ if isinstance(obj, encoder_type):
+ return encoder_instance(obj)
+ if include is not None and not isinstance(include, (set, dict)):
+ include = set(include)
+ if exclude is not None and not isinstance(exclude, (set, dict)):
+ exclude = set(exclude)
+ if isinstance(obj, BaseModel):
+ # TODO: remove when deprecating Pydantic v1
+ encoders: Dict[Any, Any] = {}
+ if not PYDANTIC_V2:
+ encoders = getattr(obj.__config__, "json_encoders", {}) # type: ignore[attr-defined]
+ if custom_encoder:
+ encoders.update(custom_encoder)
+ obj_dict = _model_dump(
+ obj,
+ mode="json",
+ include=include,
+ exclude=exclude,
+ by_alias=by_alias,
+ exclude_unset=exclude_unset,
+ exclude_none=exclude_none,
+ exclude_defaults=exclude_defaults,
+ )
+ if "__root__" in obj_dict:
+ obj_dict = obj_dict["__root__"]
+ return jsonable_encoder(
+ obj_dict,
+ exclude_none=exclude_none,
+ exclude_defaults=exclude_defaults,
+ # TODO: remove when deprecating Pydantic v1
+ custom_encoder=encoders,
+ sqlalchemy_safe=sqlalchemy_safe,
+ )
+ if dataclasses.is_dataclass(obj):
+ obj_dict = dataclasses.asdict(obj)
+ return jsonable_encoder(
+ obj_dict,
+ include=include,
+ exclude=exclude,
+ by_alias=by_alias,
+ exclude_unset=exclude_unset,
+ exclude_defaults=exclude_defaults,
+ exclude_none=exclude_none,
+ custom_encoder=custom_encoder,
+ sqlalchemy_safe=sqlalchemy_safe,
+ )
+ if isinstance(obj, Enum):
+ return obj.value
+ if isinstance(obj, PurePath):
+ return str(obj)
+ if isinstance(obj, (str, int, float, type(None))):
+ return obj
+ if isinstance(obj, UndefinedType):
+ return None
+ if isinstance(obj, dict):
+ encoded_dict = {}
+ allowed_keys = set(obj.keys())
+ if include is not None:
+ allowed_keys &= set(include)
+ if exclude is not None:
+ allowed_keys -= set(exclude)
+ for key, value in obj.items():
+ if (
+ (
+ not sqlalchemy_safe
+ or (not isinstance(key, str))
+ or (not key.startswith("_sa"))
+ )
+ and (value is not None or not exclude_none)
+ and key in allowed_keys
+ ):
+ encoded_key = jsonable_encoder(
+ key,
+ by_alias=by_alias,
+ exclude_unset=exclude_unset,
+ exclude_none=exclude_none,
+ custom_encoder=custom_encoder,
+ sqlalchemy_safe=sqlalchemy_safe,
+ )
+ encoded_value = jsonable_encoder(
+ value,
+ by_alias=by_alias,
+ exclude_unset=exclude_unset,
+ exclude_none=exclude_none,
+ custom_encoder=custom_encoder,
+ sqlalchemy_safe=sqlalchemy_safe,
+ )
+ encoded_dict[encoded_key] = encoded_value
+ return encoded_dict
+ if isinstance(obj, (list, set, frozenset, GeneratorType, tuple, deque)):
+ encoded_list = []
+ for item in obj:
+ encoded_list.append(
+ jsonable_encoder(
+ item,
+ include=include,
+ exclude=exclude,
+ by_alias=by_alias,
+ exclude_unset=exclude_unset,
+ exclude_defaults=exclude_defaults,
+ exclude_none=exclude_none,
+ custom_encoder=custom_encoder,
+ sqlalchemy_safe=sqlalchemy_safe,
+ )
+ )
+ return encoded_list
+
+ if type(obj) in ENCODERS_BY_TYPE:
+ return ENCODERS_BY_TYPE[type(obj)](obj)
+ for encoder, classes_tuple in encoders_by_class_tuples.items():
+ if isinstance(obj, classes_tuple):
+ return encoder(obj)
+
+ try:
+ data = dict(obj)
+ except Exception as e:
+ errors: List[Exception] = []
+ errors.append(e)
+ try:
+ data = vars(obj)
+ except Exception as e:
+ errors.append(e)
+ raise ValueError(errors) from e
+ return jsonable_encoder(
+ data,
+ include=include,
+ exclude=exclude,
+ by_alias=by_alias,
+ exclude_unset=exclude_unset,
+ exclude_defaults=exclude_defaults,
+ exclude_none=exclude_none,
+ custom_encoder=custom_encoder,
+ sqlalchemy_safe=sqlalchemy_safe,
+ )
diff --git a/venv/Lib/site-packages/fastapi/exception_handlers.py b/venv/Lib/site-packages/fastapi/exception_handlers.py
new file mode 100644
index 00000000..6c2ba7fe
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/exception_handlers.py
@@ -0,0 +1,34 @@
+from fastapi.encoders import jsonable_encoder
+from fastapi.exceptions import RequestValidationError, WebSocketRequestValidationError
+from fastapi.utils import is_body_allowed_for_status_code
+from fastapi.websockets import WebSocket
+from starlette.exceptions import HTTPException
+from starlette.requests import Request
+from starlette.responses import JSONResponse, Response
+from starlette.status import HTTP_422_UNPROCESSABLE_ENTITY, WS_1008_POLICY_VIOLATION
+
+
+async def http_exception_handler(request: Request, exc: HTTPException) -> Response:
+ headers = getattr(exc, "headers", None)
+ if not is_body_allowed_for_status_code(exc.status_code):
+ return Response(status_code=exc.status_code, headers=headers)
+ return JSONResponse(
+ {"detail": exc.detail}, status_code=exc.status_code, headers=headers
+ )
+
+
+async def request_validation_exception_handler(
+ request: Request, exc: RequestValidationError
+) -> JSONResponse:
+ return JSONResponse(
+ status_code=HTTP_422_UNPROCESSABLE_ENTITY,
+ content={"detail": jsonable_encoder(exc.errors())},
+ )
+
+
+async def websocket_request_validation_exception_handler(
+ websocket: WebSocket, exc: WebSocketRequestValidationError
+) -> None:
+ await websocket.close(
+ code=WS_1008_POLICY_VIOLATION, reason=jsonable_encoder(exc.errors())
+ )
diff --git a/venv/Lib/site-packages/fastapi/exceptions.py b/venv/Lib/site-packages/fastapi/exceptions.py
new file mode 100644
index 00000000..44d4ada8
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/exceptions.py
@@ -0,0 +1,176 @@
+from typing import Any, Dict, Optional, Sequence, Type, Union
+
+from pydantic import BaseModel, create_model
+from starlette.exceptions import HTTPException as StarletteHTTPException
+from starlette.exceptions import WebSocketException as StarletteWebSocketException
+from typing_extensions import Annotated, Doc
+
+
+class HTTPException(StarletteHTTPException):
+ """
+ An HTTP exception you can raise in your own code to show errors to the client.
+
+ This is for client errors, invalid authentication, invalid data, etc. Not for server
+ errors in your code.
+
+ Read more about it in the
+ [FastAPI docs for Handling Errors](https://fastapi.tiangolo.com/tutorial/handling-errors/).
+
+ ## Example
+
+ ```python
+ from fastapi import FastAPI, HTTPException
+
+ app = FastAPI()
+
+ items = {"foo": "The Foo Wrestlers"}
+
+
+ @app.get("/items/{item_id}")
+ async def read_item(item_id: str):
+ if item_id not in items:
+ raise HTTPException(status_code=404, detail="Item not found")
+ return {"item": items[item_id]}
+ ```
+ """
+
+ def __init__(
+ self,
+ status_code: Annotated[
+ int,
+ Doc(
+ """
+ HTTP status code to send to the client.
+ """
+ ),
+ ],
+ detail: Annotated[
+ Any,
+ Doc(
+ """
+ Any data to be sent to the client in the `detail` key of the JSON
+ response.
+ """
+ ),
+ ] = None,
+ headers: Annotated[
+ Optional[Dict[str, str]],
+ Doc(
+ """
+ Any headers to send to the client in the response.
+ """
+ ),
+ ] = None,
+ ) -> None:
+ super().__init__(status_code=status_code, detail=detail, headers=headers)
+
+
+class WebSocketException(StarletteWebSocketException):
+ """
+ A WebSocket exception you can raise in your own code to show errors to the client.
+
+ This is for client errors, invalid authentication, invalid data, etc. Not for server
+ errors in your code.
+
+ Read more about it in the
+ [FastAPI docs for WebSockets](https://fastapi.tiangolo.com/advanced/websockets/).
+
+ ## Example
+
+ ```python
+ from typing import Annotated
+
+ from fastapi import (
+ Cookie,
+ FastAPI,
+ WebSocket,
+ WebSocketException,
+ status,
+ )
+
+ app = FastAPI()
+
+ @app.websocket("/items/{item_id}/ws")
+ async def websocket_endpoint(
+ *,
+ websocket: WebSocket,
+ session: Annotated[str | None, Cookie()] = None,
+ item_id: str,
+ ):
+ if session is None:
+ raise WebSocketException(code=status.WS_1008_POLICY_VIOLATION)
+ await websocket.accept()
+ while True:
+ data = await websocket.receive_text()
+ await websocket.send_text(f"Session cookie is: {session}")
+ await websocket.send_text(f"Message text was: {data}, for item ID: {item_id}")
+ ```
+ """
+
+ def __init__(
+ self,
+ code: Annotated[
+ int,
+ Doc(
+ """
+ A closing code from the
+ [valid codes defined in the specification](https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.1).
+ """
+ ),
+ ],
+ reason: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ The reason to close the WebSocket connection.
+
+ It is UTF-8-encoded data. The interpretation of the reason is up to the
+ application, it is not specified by the WebSocket specification.
+
+ It could contain text that could be human-readable or interpretable
+ by the client code, etc.
+ """
+ ),
+ ] = None,
+ ) -> None:
+ super().__init__(code=code, reason=reason)
+
+
+RequestErrorModel: Type[BaseModel] = create_model("Request")
+WebSocketErrorModel: Type[BaseModel] = create_model("WebSocket")
+
+
+class FastAPIError(RuntimeError):
+ """
+ A generic, FastAPI-specific error.
+ """
+
+
+class ValidationException(Exception):
+ def __init__(self, errors: Sequence[Any]) -> None:
+ self._errors = errors
+
+ def errors(self) -> Sequence[Any]:
+ return self._errors
+
+
+class RequestValidationError(ValidationException):
+ def __init__(self, errors: Sequence[Any], *, body: Any = None) -> None:
+ super().__init__(errors)
+ self.body = body
+
+
+class WebSocketRequestValidationError(ValidationException):
+ pass
+
+
+class ResponseValidationError(ValidationException):
+ def __init__(self, errors: Sequence[Any], *, body: Any = None) -> None:
+ super().__init__(errors)
+ self.body = body
+
+ def __str__(self) -> str:
+ message = f"{len(self._errors)} validation errors:\n"
+ for err in self._errors:
+ message += f" {err}\n"
+ return message
diff --git a/venv/Lib/site-packages/fastapi/logger.py b/venv/Lib/site-packages/fastapi/logger.py
new file mode 100644
index 00000000..5b2c4ad5
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/logger.py
@@ -0,0 +1,3 @@
+import logging
+
+logger = logging.getLogger("fastapi")
diff --git a/venv/Lib/site-packages/fastapi/middleware/__init__.py b/venv/Lib/site-packages/fastapi/middleware/__init__.py
new file mode 100644
index 00000000..620296d5
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/middleware/__init__.py
@@ -0,0 +1 @@
+from starlette.middleware import Middleware as Middleware
diff --git a/venv/Lib/site-packages/fastapi/middleware/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/fastapi/middleware/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 00000000..dc98e2f7
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/middleware/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/middleware/__pycache__/cors.cpython-312.pyc b/venv/Lib/site-packages/fastapi/middleware/__pycache__/cors.cpython-312.pyc
new file mode 100644
index 00000000..e6f0911e
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/middleware/__pycache__/cors.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/middleware/__pycache__/gzip.cpython-312.pyc b/venv/Lib/site-packages/fastapi/middleware/__pycache__/gzip.cpython-312.pyc
new file mode 100644
index 00000000..7e97bc05
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/middleware/__pycache__/gzip.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/middleware/__pycache__/httpsredirect.cpython-312.pyc b/venv/Lib/site-packages/fastapi/middleware/__pycache__/httpsredirect.cpython-312.pyc
new file mode 100644
index 00000000..d87b370f
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/middleware/__pycache__/httpsredirect.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/middleware/__pycache__/trustedhost.cpython-312.pyc b/venv/Lib/site-packages/fastapi/middleware/__pycache__/trustedhost.cpython-312.pyc
new file mode 100644
index 00000000..1a0d4890
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/middleware/__pycache__/trustedhost.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/middleware/__pycache__/wsgi.cpython-312.pyc b/venv/Lib/site-packages/fastapi/middleware/__pycache__/wsgi.cpython-312.pyc
new file mode 100644
index 00000000..a69526cf
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/middleware/__pycache__/wsgi.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/middleware/cors.py b/venv/Lib/site-packages/fastapi/middleware/cors.py
new file mode 100644
index 00000000..8dfaad0d
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/middleware/cors.py
@@ -0,0 +1 @@
+from starlette.middleware.cors import CORSMiddleware as CORSMiddleware # noqa
diff --git a/venv/Lib/site-packages/fastapi/middleware/gzip.py b/venv/Lib/site-packages/fastapi/middleware/gzip.py
new file mode 100644
index 00000000..bbeb2cc7
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/middleware/gzip.py
@@ -0,0 +1 @@
+from starlette.middleware.gzip import GZipMiddleware as GZipMiddleware # noqa
diff --git a/venv/Lib/site-packages/fastapi/middleware/httpsredirect.py b/venv/Lib/site-packages/fastapi/middleware/httpsredirect.py
new file mode 100644
index 00000000..b7a3d8e0
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/middleware/httpsredirect.py
@@ -0,0 +1,3 @@
+from starlette.middleware.httpsredirect import ( # noqa
+ HTTPSRedirectMiddleware as HTTPSRedirectMiddleware,
+)
diff --git a/venv/Lib/site-packages/fastapi/middleware/trustedhost.py b/venv/Lib/site-packages/fastapi/middleware/trustedhost.py
new file mode 100644
index 00000000..08d7e035
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/middleware/trustedhost.py
@@ -0,0 +1,3 @@
+from starlette.middleware.trustedhost import ( # noqa
+ TrustedHostMiddleware as TrustedHostMiddleware,
+)
diff --git a/venv/Lib/site-packages/fastapi/middleware/wsgi.py b/venv/Lib/site-packages/fastapi/middleware/wsgi.py
new file mode 100644
index 00000000..c4c6a797
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/middleware/wsgi.py
@@ -0,0 +1 @@
+from starlette.middleware.wsgi import WSGIMiddleware as WSGIMiddleware # noqa
diff --git a/venv/Lib/site-packages/fastapi/openapi/__init__.py b/venv/Lib/site-packages/fastapi/openapi/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/venv/Lib/site-packages/fastapi/openapi/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/fastapi/openapi/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 00000000..4c2deaa5
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/openapi/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/openapi/__pycache__/constants.cpython-312.pyc b/venv/Lib/site-packages/fastapi/openapi/__pycache__/constants.cpython-312.pyc
new file mode 100644
index 00000000..17190f73
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/openapi/__pycache__/constants.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/openapi/__pycache__/docs.cpython-312.pyc b/venv/Lib/site-packages/fastapi/openapi/__pycache__/docs.cpython-312.pyc
new file mode 100644
index 00000000..f5694150
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/openapi/__pycache__/docs.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/openapi/__pycache__/models.cpython-312.pyc b/venv/Lib/site-packages/fastapi/openapi/__pycache__/models.cpython-312.pyc
new file mode 100644
index 00000000..e473898b
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/openapi/__pycache__/models.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/openapi/__pycache__/utils.cpython-312.pyc b/venv/Lib/site-packages/fastapi/openapi/__pycache__/utils.cpython-312.pyc
new file mode 100644
index 00000000..cf99bb3a
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/openapi/__pycache__/utils.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/openapi/constants.py b/venv/Lib/site-packages/fastapi/openapi/constants.py
new file mode 100644
index 00000000..d724ee3c
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/openapi/constants.py
@@ -0,0 +1,3 @@
+METHODS_WITH_BODY = {"GET", "HEAD", "POST", "PUT", "DELETE", "PATCH"}
+REF_PREFIX = "#/components/schemas/"
+REF_TEMPLATE = "#/components/schemas/{model}"
diff --git a/venv/Lib/site-packages/fastapi/openapi/docs.py b/venv/Lib/site-packages/fastapi/openapi/docs.py
new file mode 100644
index 00000000..f181b43c
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/openapi/docs.py
@@ -0,0 +1,344 @@
+import json
+from typing import Any, Dict, Optional
+
+from fastapi.encoders import jsonable_encoder
+from starlette.responses import HTMLResponse
+from typing_extensions import Annotated, Doc
+
+swagger_ui_default_parameters: Annotated[
+ Dict[str, Any],
+ Doc(
+ """
+ Default configurations for Swagger UI.
+
+ You can use it as a template to add any other configurations needed.
+ """
+ ),
+] = {
+ "dom_id": "#swagger-ui",
+ "layout": "BaseLayout",
+ "deepLinking": True,
+ "showExtensions": True,
+ "showCommonExtensions": True,
+}
+
+
+def get_swagger_ui_html(
+ *,
+ openapi_url: Annotated[
+ str,
+ Doc(
+ """
+ The OpenAPI URL that Swagger UI should load and use.
+
+ This is normally done automatically by FastAPI using the default URL
+ `/openapi.json`.
+ """
+ ),
+ ],
+ title: Annotated[
+ str,
+ Doc(
+ """
+ The HTML `` content, normally shown in the browser tab.
+ """
+ ),
+ ],
+ swagger_js_url: Annotated[
+ str,
+ Doc(
+ """
+ The URL to use to load the Swagger UI JavaScript.
+
+ It is normally set to a CDN URL.
+ """
+ ),
+ ] = "https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui-bundle.js",
+ swagger_css_url: Annotated[
+ str,
+ Doc(
+ """
+ The URL to use to load the Swagger UI CSS.
+
+ It is normally set to a CDN URL.
+ """
+ ),
+ ] = "https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui.css",
+ swagger_favicon_url: Annotated[
+ str,
+ Doc(
+ """
+ The URL of the favicon to use. It is normally shown in the browser tab.
+ """
+ ),
+ ] = "https://fastapi.tiangolo.com/img/favicon.png",
+ oauth2_redirect_url: Annotated[
+ Optional[str],
+ Doc(
+ """
+ The OAuth2 redirect URL, it is normally automatically handled by FastAPI.
+ """
+ ),
+ ] = None,
+ init_oauth: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ A dictionary with Swagger UI OAuth2 initialization configurations.
+ """
+ ),
+ ] = None,
+ swagger_ui_parameters: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ Configuration parameters for Swagger UI.
+
+ It defaults to [swagger_ui_default_parameters][fastapi.openapi.docs.swagger_ui_default_parameters].
+ """
+ ),
+ ] = None,
+) -> HTMLResponse:
+ """
+ Generate and return the HTML that loads Swagger UI for the interactive
+ API docs (normally served at `/docs`).
+
+ You would only call this function yourself if you needed to override some parts,
+ for example the URLs to use to load Swagger UI's JavaScript and CSS.
+
+ Read more about it in the
+ [FastAPI docs for Configure Swagger UI](https://fastapi.tiangolo.com/how-to/configure-swagger-ui/)
+ and the [FastAPI docs for Custom Docs UI Static Assets (Self-Hosting)](https://fastapi.tiangolo.com/how-to/custom-docs-ui-assets/).
+ """
+ current_swagger_ui_parameters = swagger_ui_default_parameters.copy()
+ if swagger_ui_parameters:
+ current_swagger_ui_parameters.update(swagger_ui_parameters)
+
+ html = f"""
+
+
+
+
+
+ {title}
+
+
+
+
+
+
+
+
+
+ """
+ return HTMLResponse(html)
+
+
+def get_redoc_html(
+ *,
+ openapi_url: Annotated[
+ str,
+ Doc(
+ """
+ The OpenAPI URL that ReDoc should load and use.
+
+ This is normally done automatically by FastAPI using the default URL
+ `/openapi.json`.
+ """
+ ),
+ ],
+ title: Annotated[
+ str,
+ Doc(
+ """
+ The HTML `` content, normally shown in the browser tab.
+ """
+ ),
+ ],
+ redoc_js_url: Annotated[
+ str,
+ Doc(
+ """
+ The URL to use to load the ReDoc JavaScript.
+
+ It is normally set to a CDN URL.
+ """
+ ),
+ ] = "https://cdn.jsdelivr.net/npm/redoc@2/bundles/redoc.standalone.js",
+ redoc_favicon_url: Annotated[
+ str,
+ Doc(
+ """
+ The URL of the favicon to use. It is normally shown in the browser tab.
+ """
+ ),
+ ] = "https://fastapi.tiangolo.com/img/favicon.png",
+ with_google_fonts: Annotated[
+ bool,
+ Doc(
+ """
+ Load and use Google Fonts.
+ """
+ ),
+ ] = True,
+) -> HTMLResponse:
+ """
+ Generate and return the HTML response that loads ReDoc for the alternative
+ API docs (normally served at `/redoc`).
+
+ You would only call this function yourself if you needed to override some parts,
+ for example the URLs to use to load ReDoc's JavaScript and CSS.
+
+ Read more about it in the
+ [FastAPI docs for Custom Docs UI Static Assets (Self-Hosting)](https://fastapi.tiangolo.com/how-to/custom-docs-ui-assets/).
+ """
+ html = f"""
+
+
+
+ {title}
+
+
+
+ """
+ if with_google_fonts:
+ html += """
+
+ """
+ html += f"""
+
+
+
+
+
+
+
+
+
+
+ """
+ return HTMLResponse(html)
+
+
+def get_swagger_ui_oauth2_redirect_html() -> HTMLResponse:
+ """
+ Generate the HTML response with the OAuth2 redirection for Swagger UI.
+
+ You normally don't need to use or change this.
+ """
+ # copied from https://github.com/swagger-api/swagger-ui/blob/v4.14.0/dist/oauth2-redirect.html
+ html = """
+
+
+
+ Swagger UI: OAuth2 Redirect
+
+
+
+
+
+ """
+ return HTMLResponse(content=html)
diff --git a/venv/Lib/site-packages/fastapi/openapi/models.py b/venv/Lib/site-packages/fastapi/openapi/models.py
new file mode 100644
index 00000000..ed07b40f
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/openapi/models.py
@@ -0,0 +1,445 @@
+from enum import Enum
+from typing import Any, Callable, Dict, Iterable, List, Optional, Set, Type, Union
+
+from fastapi._compat import (
+ PYDANTIC_V2,
+ CoreSchema,
+ GetJsonSchemaHandler,
+ JsonSchemaValue,
+ _model_rebuild,
+ with_info_plain_validator_function,
+)
+from fastapi.logger import logger
+from pydantic import AnyUrl, BaseModel, Field
+from typing_extensions import Annotated, Literal, TypedDict
+from typing_extensions import deprecated as typing_deprecated
+
+try:
+ import email_validator
+
+ assert email_validator # make autoflake ignore the unused import
+ from pydantic import EmailStr
+except ImportError: # pragma: no cover
+
+ class EmailStr(str): # type: ignore
+ @classmethod
+ def __get_validators__(cls) -> Iterable[Callable[..., Any]]:
+ yield cls.validate
+
+ @classmethod
+ def validate(cls, v: Any) -> str:
+ logger.warning(
+ "email-validator not installed, email fields will be treated as str.\n"
+ "To install, run: pip install email-validator"
+ )
+ return str(v)
+
+ @classmethod
+ def _validate(cls, __input_value: Any, _: Any) -> str:
+ logger.warning(
+ "email-validator not installed, email fields will be treated as str.\n"
+ "To install, run: pip install email-validator"
+ )
+ return str(__input_value)
+
+ @classmethod
+ def __get_pydantic_json_schema__(
+ cls, core_schema: CoreSchema, handler: GetJsonSchemaHandler
+ ) -> JsonSchemaValue:
+ return {"type": "string", "format": "email"}
+
+ @classmethod
+ def __get_pydantic_core_schema__(
+ cls, source: Type[Any], handler: Callable[[Any], CoreSchema]
+ ) -> CoreSchema:
+ return with_info_plain_validator_function(cls._validate)
+
+
+class BaseModelWithConfig(BaseModel):
+ if PYDANTIC_V2:
+ model_config = {"extra": "allow"}
+
+ else:
+
+ class Config:
+ extra = "allow"
+
+
+class Contact(BaseModelWithConfig):
+ name: Optional[str] = None
+ url: Optional[AnyUrl] = None
+ email: Optional[EmailStr] = None
+
+
+class License(BaseModelWithConfig):
+ name: str
+ identifier: Optional[str] = None
+ url: Optional[AnyUrl] = None
+
+
+class Info(BaseModelWithConfig):
+ title: str
+ summary: Optional[str] = None
+ description: Optional[str] = None
+ termsOfService: Optional[str] = None
+ contact: Optional[Contact] = None
+ license: Optional[License] = None
+ version: str
+
+
+class ServerVariable(BaseModelWithConfig):
+ enum: Annotated[Optional[List[str]], Field(min_length=1)] = None
+ default: str
+ description: Optional[str] = None
+
+
+class Server(BaseModelWithConfig):
+ url: Union[AnyUrl, str]
+ description: Optional[str] = None
+ variables: Optional[Dict[str, ServerVariable]] = None
+
+
+class Reference(BaseModel):
+ ref: str = Field(alias="$ref")
+
+
+class Discriminator(BaseModel):
+ propertyName: str
+ mapping: Optional[Dict[str, str]] = None
+
+
+class XML(BaseModelWithConfig):
+ name: Optional[str] = None
+ namespace: Optional[str] = None
+ prefix: Optional[str] = None
+ attribute: Optional[bool] = None
+ wrapped: Optional[bool] = None
+
+
+class ExternalDocumentation(BaseModelWithConfig):
+ description: Optional[str] = None
+ url: AnyUrl
+
+
+class Schema(BaseModelWithConfig):
+ # Ref: JSON Schema 2020-12: https://json-schema.org/draft/2020-12/json-schema-core.html#name-the-json-schema-core-vocabu
+ # Core Vocabulary
+ schema_: Optional[str] = Field(default=None, alias="$schema")
+ vocabulary: Optional[str] = Field(default=None, alias="$vocabulary")
+ id: Optional[str] = Field(default=None, alias="$id")
+ anchor: Optional[str] = Field(default=None, alias="$anchor")
+ dynamicAnchor: Optional[str] = Field(default=None, alias="$dynamicAnchor")
+ ref: Optional[str] = Field(default=None, alias="$ref")
+ dynamicRef: Optional[str] = Field(default=None, alias="$dynamicRef")
+ defs: Optional[Dict[str, "SchemaOrBool"]] = Field(default=None, alias="$defs")
+ comment: Optional[str] = Field(default=None, alias="$comment")
+ # Ref: JSON Schema 2020-12: https://json-schema.org/draft/2020-12/json-schema-core.html#name-a-vocabulary-for-applying-s
+ # A Vocabulary for Applying Subschemas
+ allOf: Optional[List["SchemaOrBool"]] = None
+ anyOf: Optional[List["SchemaOrBool"]] = None
+ oneOf: Optional[List["SchemaOrBool"]] = None
+ not_: Optional["SchemaOrBool"] = Field(default=None, alias="not")
+ if_: Optional["SchemaOrBool"] = Field(default=None, alias="if")
+ then: Optional["SchemaOrBool"] = None
+ else_: Optional["SchemaOrBool"] = Field(default=None, alias="else")
+ dependentSchemas: Optional[Dict[str, "SchemaOrBool"]] = None
+ prefixItems: Optional[List["SchemaOrBool"]] = None
+ # TODO: uncomment and remove below when deprecating Pydantic v1
+ # It generales a list of schemas for tuples, before prefixItems was available
+ # items: Optional["SchemaOrBool"] = None
+ items: Optional[Union["SchemaOrBool", List["SchemaOrBool"]]] = None
+ contains: Optional["SchemaOrBool"] = None
+ properties: Optional[Dict[str, "SchemaOrBool"]] = None
+ patternProperties: Optional[Dict[str, "SchemaOrBool"]] = None
+ additionalProperties: Optional["SchemaOrBool"] = None
+ propertyNames: Optional["SchemaOrBool"] = None
+ unevaluatedItems: Optional["SchemaOrBool"] = None
+ unevaluatedProperties: Optional["SchemaOrBool"] = None
+ # Ref: JSON Schema Validation 2020-12: https://json-schema.org/draft/2020-12/json-schema-validation.html#name-a-vocabulary-for-structural
+ # A Vocabulary for Structural Validation
+ type: Optional[str] = None
+ enum: Optional[List[Any]] = None
+ const: Optional[Any] = None
+ multipleOf: Optional[float] = Field(default=None, gt=0)
+ maximum: Optional[float] = None
+ exclusiveMaximum: Optional[float] = None
+ minimum: Optional[float] = None
+ exclusiveMinimum: Optional[float] = None
+ maxLength: Optional[int] = Field(default=None, ge=0)
+ minLength: Optional[int] = Field(default=None, ge=0)
+ pattern: Optional[str] = None
+ maxItems: Optional[int] = Field(default=None, ge=0)
+ minItems: Optional[int] = Field(default=None, ge=0)
+ uniqueItems: Optional[bool] = None
+ maxContains: Optional[int] = Field(default=None, ge=0)
+ minContains: Optional[int] = Field(default=None, ge=0)
+ maxProperties: Optional[int] = Field(default=None, ge=0)
+ minProperties: Optional[int] = Field(default=None, ge=0)
+ required: Optional[List[str]] = None
+ dependentRequired: Optional[Dict[str, Set[str]]] = None
+ # Ref: JSON Schema Validation 2020-12: https://json-schema.org/draft/2020-12/json-schema-validation.html#name-vocabularies-for-semantic-c
+ # Vocabularies for Semantic Content With "format"
+ format: Optional[str] = None
+ # Ref: JSON Schema Validation 2020-12: https://json-schema.org/draft/2020-12/json-schema-validation.html#name-a-vocabulary-for-the-conten
+ # A Vocabulary for the Contents of String-Encoded Data
+ contentEncoding: Optional[str] = None
+ contentMediaType: Optional[str] = None
+ contentSchema: Optional["SchemaOrBool"] = None
+ # Ref: JSON Schema Validation 2020-12: https://json-schema.org/draft/2020-12/json-schema-validation.html#name-a-vocabulary-for-basic-meta
+ # A Vocabulary for Basic Meta-Data Annotations
+ title: Optional[str] = None
+ description: Optional[str] = None
+ default: Optional[Any] = None
+ deprecated: Optional[bool] = None
+ readOnly: Optional[bool] = None
+ writeOnly: Optional[bool] = None
+ examples: Optional[List[Any]] = None
+ # Ref: OpenAPI 3.1.0: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#schema-object
+ # Schema Object
+ discriminator: Optional[Discriminator] = None
+ xml: Optional[XML] = None
+ externalDocs: Optional[ExternalDocumentation] = None
+ example: Annotated[
+ Optional[Any],
+ typing_deprecated(
+ "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
+ "although still supported. Use examples instead."
+ ),
+ ] = None
+
+
+# Ref: https://json-schema.org/draft/2020-12/json-schema-core.html#name-json-schema-documents
+# A JSON Schema MUST be an object or a boolean.
+SchemaOrBool = Union[Schema, bool]
+
+
+class Example(TypedDict, total=False):
+ summary: Optional[str]
+ description: Optional[str]
+ value: Optional[Any]
+ externalValue: Optional[AnyUrl]
+
+ if PYDANTIC_V2: # type: ignore [misc]
+ __pydantic_config__ = {"extra": "allow"}
+
+ else:
+
+ class Config:
+ extra = "allow"
+
+
+class ParameterInType(Enum):
+ query = "query"
+ header = "header"
+ path = "path"
+ cookie = "cookie"
+
+
+class Encoding(BaseModelWithConfig):
+ contentType: Optional[str] = None
+ headers: Optional[Dict[str, Union["Header", Reference]]] = None
+ style: Optional[str] = None
+ explode: Optional[bool] = None
+ allowReserved: Optional[bool] = None
+
+
+class MediaType(BaseModelWithConfig):
+ schema_: Optional[Union[Schema, Reference]] = Field(default=None, alias="schema")
+ example: Optional[Any] = None
+ examples: Optional[Dict[str, Union[Example, Reference]]] = None
+ encoding: Optional[Dict[str, Encoding]] = None
+
+
+class ParameterBase(BaseModelWithConfig):
+ description: Optional[str] = None
+ required: Optional[bool] = None
+ deprecated: Optional[bool] = None
+ # Serialization rules for simple scenarios
+ style: Optional[str] = None
+ explode: Optional[bool] = None
+ allowReserved: Optional[bool] = None
+ schema_: Optional[Union[Schema, Reference]] = Field(default=None, alias="schema")
+ example: Optional[Any] = None
+ examples: Optional[Dict[str, Union[Example, Reference]]] = None
+ # Serialization rules for more complex scenarios
+ content: Optional[Dict[str, MediaType]] = None
+
+
+class Parameter(ParameterBase):
+ name: str
+ in_: ParameterInType = Field(alias="in")
+
+
+class Header(ParameterBase):
+ pass
+
+
+class RequestBody(BaseModelWithConfig):
+ description: Optional[str] = None
+ content: Dict[str, MediaType]
+ required: Optional[bool] = None
+
+
+class Link(BaseModelWithConfig):
+ operationRef: Optional[str] = None
+ operationId: Optional[str] = None
+ parameters: Optional[Dict[str, Union[Any, str]]] = None
+ requestBody: Optional[Union[Any, str]] = None
+ description: Optional[str] = None
+ server: Optional[Server] = None
+
+
+class Response(BaseModelWithConfig):
+ description: str
+ headers: Optional[Dict[str, Union[Header, Reference]]] = None
+ content: Optional[Dict[str, MediaType]] = None
+ links: Optional[Dict[str, Union[Link, Reference]]] = None
+
+
+class Operation(BaseModelWithConfig):
+ tags: Optional[List[str]] = None
+ summary: Optional[str] = None
+ description: Optional[str] = None
+ externalDocs: Optional[ExternalDocumentation] = None
+ operationId: Optional[str] = None
+ parameters: Optional[List[Union[Parameter, Reference]]] = None
+ requestBody: Optional[Union[RequestBody, Reference]] = None
+ # Using Any for Specification Extensions
+ responses: Optional[Dict[str, Union[Response, Any]]] = None
+ callbacks: Optional[Dict[str, Union[Dict[str, "PathItem"], Reference]]] = None
+ deprecated: Optional[bool] = None
+ security: Optional[List[Dict[str, List[str]]]] = None
+ servers: Optional[List[Server]] = None
+
+
+class PathItem(BaseModelWithConfig):
+ ref: Optional[str] = Field(default=None, alias="$ref")
+ summary: Optional[str] = None
+ description: Optional[str] = None
+ get: Optional[Operation] = None
+ put: Optional[Operation] = None
+ post: Optional[Operation] = None
+ delete: Optional[Operation] = None
+ options: Optional[Operation] = None
+ head: Optional[Operation] = None
+ patch: Optional[Operation] = None
+ trace: Optional[Operation] = None
+ servers: Optional[List[Server]] = None
+ parameters: Optional[List[Union[Parameter, Reference]]] = None
+
+
+class SecuritySchemeType(Enum):
+ apiKey = "apiKey"
+ http = "http"
+ oauth2 = "oauth2"
+ openIdConnect = "openIdConnect"
+
+
+class SecurityBase(BaseModelWithConfig):
+ type_: SecuritySchemeType = Field(alias="type")
+ description: Optional[str] = None
+
+
+class APIKeyIn(Enum):
+ query = "query"
+ header = "header"
+ cookie = "cookie"
+
+
+class APIKey(SecurityBase):
+ type_: SecuritySchemeType = Field(default=SecuritySchemeType.apiKey, alias="type")
+ in_: APIKeyIn = Field(alias="in")
+ name: str
+
+
+class HTTPBase(SecurityBase):
+ type_: SecuritySchemeType = Field(default=SecuritySchemeType.http, alias="type")
+ scheme: str
+
+
+class HTTPBearer(HTTPBase):
+ scheme: Literal["bearer"] = "bearer"
+ bearerFormat: Optional[str] = None
+
+
+class OAuthFlow(BaseModelWithConfig):
+ refreshUrl: Optional[str] = None
+ scopes: Dict[str, str] = {}
+
+
+class OAuthFlowImplicit(OAuthFlow):
+ authorizationUrl: str
+
+
+class OAuthFlowPassword(OAuthFlow):
+ tokenUrl: str
+
+
+class OAuthFlowClientCredentials(OAuthFlow):
+ tokenUrl: str
+
+
+class OAuthFlowAuthorizationCode(OAuthFlow):
+ authorizationUrl: str
+ tokenUrl: str
+
+
+class OAuthFlows(BaseModelWithConfig):
+ implicit: Optional[OAuthFlowImplicit] = None
+ password: Optional[OAuthFlowPassword] = None
+ clientCredentials: Optional[OAuthFlowClientCredentials] = None
+ authorizationCode: Optional[OAuthFlowAuthorizationCode] = None
+
+
+class OAuth2(SecurityBase):
+ type_: SecuritySchemeType = Field(default=SecuritySchemeType.oauth2, alias="type")
+ flows: OAuthFlows
+
+
+class OpenIdConnect(SecurityBase):
+ type_: SecuritySchemeType = Field(
+ default=SecuritySchemeType.openIdConnect, alias="type"
+ )
+ openIdConnectUrl: str
+
+
+SecurityScheme = Union[APIKey, HTTPBase, OAuth2, OpenIdConnect, HTTPBearer]
+
+
+class Components(BaseModelWithConfig):
+ schemas: Optional[Dict[str, Union[Schema, Reference]]] = None
+ responses: Optional[Dict[str, Union[Response, Reference]]] = None
+ parameters: Optional[Dict[str, Union[Parameter, Reference]]] = None
+ examples: Optional[Dict[str, Union[Example, Reference]]] = None
+ requestBodies: Optional[Dict[str, Union[RequestBody, Reference]]] = None
+ headers: Optional[Dict[str, Union[Header, Reference]]] = None
+ securitySchemes: Optional[Dict[str, Union[SecurityScheme, Reference]]] = None
+ links: Optional[Dict[str, Union[Link, Reference]]] = None
+ # Using Any for Specification Extensions
+ callbacks: Optional[Dict[str, Union[Dict[str, PathItem], Reference, Any]]] = None
+ pathItems: Optional[Dict[str, Union[PathItem, Reference]]] = None
+
+
+class Tag(BaseModelWithConfig):
+ name: str
+ description: Optional[str] = None
+ externalDocs: Optional[ExternalDocumentation] = None
+
+
+class OpenAPI(BaseModelWithConfig):
+ openapi: str
+ info: Info
+ jsonSchemaDialect: Optional[str] = None
+ servers: Optional[List[Server]] = None
+ # Using Any for Specification Extensions
+ paths: Optional[Dict[str, Union[PathItem, Any]]] = None
+ webhooks: Optional[Dict[str, Union[PathItem, Reference]]] = None
+ components: Optional[Components] = None
+ security: Optional[List[Dict[str, List[str]]]] = None
+ tags: Optional[List[Tag]] = None
+ externalDocs: Optional[ExternalDocumentation] = None
+
+
+_model_rebuild(Schema)
+_model_rebuild(Operation)
+_model_rebuild(Encoding)
diff --git a/venv/Lib/site-packages/fastapi/openapi/utils.py b/venv/Lib/site-packages/fastapi/openapi/utils.py
new file mode 100644
index 00000000..808646cc
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/openapi/utils.py
@@ -0,0 +1,569 @@
+import http.client
+import inspect
+import warnings
+from typing import Any, Dict, List, Optional, Sequence, Set, Tuple, Type, Union, cast
+
+from fastapi import routing
+from fastapi._compat import (
+ GenerateJsonSchema,
+ JsonSchemaValue,
+ ModelField,
+ Undefined,
+ get_compat_model_name_map,
+ get_definitions,
+ get_schema_from_model_field,
+ lenient_issubclass,
+)
+from fastapi.datastructures import DefaultPlaceholder
+from fastapi.dependencies.models import Dependant
+from fastapi.dependencies.utils import (
+ _get_flat_fields_from_params,
+ get_flat_dependant,
+ get_flat_params,
+)
+from fastapi.encoders import jsonable_encoder
+from fastapi.openapi.constants import METHODS_WITH_BODY, REF_PREFIX, REF_TEMPLATE
+from fastapi.openapi.models import OpenAPI
+from fastapi.params import Body, ParamTypes
+from fastapi.responses import Response
+from fastapi.types import ModelNameMap
+from fastapi.utils import (
+ deep_dict_update,
+ generate_operation_id_for_path,
+ is_body_allowed_for_status_code,
+)
+from pydantic import BaseModel
+from starlette.responses import JSONResponse
+from starlette.routing import BaseRoute
+from starlette.status import HTTP_422_UNPROCESSABLE_ENTITY
+from typing_extensions import Literal
+
+validation_error_definition = {
+ "title": "ValidationError",
+ "type": "object",
+ "properties": {
+ "loc": {
+ "title": "Location",
+ "type": "array",
+ "items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
+ },
+ "msg": {"title": "Message", "type": "string"},
+ "type": {"title": "Error Type", "type": "string"},
+ },
+ "required": ["loc", "msg", "type"],
+}
+
+validation_error_response_definition = {
+ "title": "HTTPValidationError",
+ "type": "object",
+ "properties": {
+ "detail": {
+ "title": "Detail",
+ "type": "array",
+ "items": {"$ref": REF_PREFIX + "ValidationError"},
+ }
+ },
+}
+
+status_code_ranges: Dict[str, str] = {
+ "1XX": "Information",
+ "2XX": "Success",
+ "3XX": "Redirection",
+ "4XX": "Client Error",
+ "5XX": "Server Error",
+ "DEFAULT": "Default Response",
+}
+
+
+def get_openapi_security_definitions(
+ flat_dependant: Dependant,
+) -> Tuple[Dict[str, Any], List[Dict[str, Any]]]:
+ security_definitions = {}
+ operation_security = []
+ for security_requirement in flat_dependant.security_requirements:
+ security_definition = jsonable_encoder(
+ security_requirement.security_scheme.model,
+ by_alias=True,
+ exclude_none=True,
+ )
+ security_name = security_requirement.security_scheme.scheme_name
+ security_definitions[security_name] = security_definition
+ operation_security.append({security_name: security_requirement.scopes})
+ return security_definitions, operation_security
+
+
+def _get_openapi_operation_parameters(
+ *,
+ dependant: Dependant,
+ schema_generator: GenerateJsonSchema,
+ model_name_map: ModelNameMap,
+ field_mapping: Dict[
+ Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
+ ],
+ separate_input_output_schemas: bool = True,
+) -> List[Dict[str, Any]]:
+ parameters = []
+ flat_dependant = get_flat_dependant(dependant, skip_repeats=True)
+ path_params = _get_flat_fields_from_params(flat_dependant.path_params)
+ query_params = _get_flat_fields_from_params(flat_dependant.query_params)
+ header_params = _get_flat_fields_from_params(flat_dependant.header_params)
+ cookie_params = _get_flat_fields_from_params(flat_dependant.cookie_params)
+ parameter_groups = [
+ (ParamTypes.path, path_params),
+ (ParamTypes.query, query_params),
+ (ParamTypes.header, header_params),
+ (ParamTypes.cookie, cookie_params),
+ ]
+ default_convert_underscores = True
+ if len(flat_dependant.header_params) == 1:
+ first_field = flat_dependant.header_params[0]
+ if lenient_issubclass(first_field.type_, BaseModel):
+ default_convert_underscores = getattr(
+ first_field.field_info, "convert_underscores", True
+ )
+ for param_type, param_group in parameter_groups:
+ for param in param_group:
+ field_info = param.field_info
+ # field_info = cast(Param, field_info)
+ if not getattr(field_info, "include_in_schema", True):
+ continue
+ param_schema = get_schema_from_model_field(
+ field=param,
+ schema_generator=schema_generator,
+ model_name_map=model_name_map,
+ field_mapping=field_mapping,
+ separate_input_output_schemas=separate_input_output_schemas,
+ )
+ name = param.alias
+ convert_underscores = getattr(
+ param.field_info,
+ "convert_underscores",
+ default_convert_underscores,
+ )
+ if (
+ param_type == ParamTypes.header
+ and param.alias == param.name
+ and convert_underscores
+ ):
+ name = param.name.replace("_", "-")
+
+ parameter = {
+ "name": name,
+ "in": param_type.value,
+ "required": param.required,
+ "schema": param_schema,
+ }
+ if field_info.description:
+ parameter["description"] = field_info.description
+ openapi_examples = getattr(field_info, "openapi_examples", None)
+ example = getattr(field_info, "example", None)
+ if openapi_examples:
+ parameter["examples"] = jsonable_encoder(openapi_examples)
+ elif example != Undefined:
+ parameter["example"] = jsonable_encoder(example)
+ if getattr(field_info, "deprecated", None):
+ parameter["deprecated"] = True
+ parameters.append(parameter)
+ return parameters
+
+
+def get_openapi_operation_request_body(
+ *,
+ body_field: Optional[ModelField],
+ schema_generator: GenerateJsonSchema,
+ model_name_map: ModelNameMap,
+ field_mapping: Dict[
+ Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
+ ],
+ separate_input_output_schemas: bool = True,
+) -> Optional[Dict[str, Any]]:
+ if not body_field:
+ return None
+ assert isinstance(body_field, ModelField)
+ body_schema = get_schema_from_model_field(
+ field=body_field,
+ schema_generator=schema_generator,
+ model_name_map=model_name_map,
+ field_mapping=field_mapping,
+ separate_input_output_schemas=separate_input_output_schemas,
+ )
+ field_info = cast(Body, body_field.field_info)
+ request_media_type = field_info.media_type
+ required = body_field.required
+ request_body_oai: Dict[str, Any] = {}
+ if required:
+ request_body_oai["required"] = required
+ request_media_content: Dict[str, Any] = {"schema": body_schema}
+ if field_info.openapi_examples:
+ request_media_content["examples"] = jsonable_encoder(
+ field_info.openapi_examples
+ )
+ elif field_info.example != Undefined:
+ request_media_content["example"] = jsonable_encoder(field_info.example)
+ request_body_oai["content"] = {request_media_type: request_media_content}
+ return request_body_oai
+
+
+def generate_operation_id(
+ *, route: routing.APIRoute, method: str
+) -> str: # pragma: nocover
+ warnings.warn(
+ "fastapi.openapi.utils.generate_operation_id() was deprecated, "
+ "it is not used internally, and will be removed soon",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ if route.operation_id:
+ return route.operation_id
+ path: str = route.path_format
+ return generate_operation_id_for_path(name=route.name, path=path, method=method)
+
+
+def generate_operation_summary(*, route: routing.APIRoute, method: str) -> str:
+ if route.summary:
+ return route.summary
+ return route.name.replace("_", " ").title()
+
+
+def get_openapi_operation_metadata(
+ *, route: routing.APIRoute, method: str, operation_ids: Set[str]
+) -> Dict[str, Any]:
+ operation: Dict[str, Any] = {}
+ if route.tags:
+ operation["tags"] = route.tags
+ operation["summary"] = generate_operation_summary(route=route, method=method)
+ if route.description:
+ operation["description"] = route.description
+ operation_id = route.operation_id or route.unique_id
+ if operation_id in operation_ids:
+ message = (
+ f"Duplicate Operation ID {operation_id} for function "
+ + f"{route.endpoint.__name__}"
+ )
+ file_name = getattr(route.endpoint, "__globals__", {}).get("__file__")
+ if file_name:
+ message += f" at {file_name}"
+ warnings.warn(message, stacklevel=1)
+ operation_ids.add(operation_id)
+ operation["operationId"] = operation_id
+ if route.deprecated:
+ operation["deprecated"] = route.deprecated
+ return operation
+
+
+def get_openapi_path(
+ *,
+ route: routing.APIRoute,
+ operation_ids: Set[str],
+ schema_generator: GenerateJsonSchema,
+ model_name_map: ModelNameMap,
+ field_mapping: Dict[
+ Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
+ ],
+ separate_input_output_schemas: bool = True,
+) -> Tuple[Dict[str, Any], Dict[str, Any], Dict[str, Any]]:
+ path = {}
+ security_schemes: Dict[str, Any] = {}
+ definitions: Dict[str, Any] = {}
+ assert route.methods is not None, "Methods must be a list"
+ if isinstance(route.response_class, DefaultPlaceholder):
+ current_response_class: Type[Response] = route.response_class.value
+ else:
+ current_response_class = route.response_class
+ assert current_response_class, "A response class is needed to generate OpenAPI"
+ route_response_media_type: Optional[str] = current_response_class.media_type
+ if route.include_in_schema:
+ for method in route.methods:
+ operation = get_openapi_operation_metadata(
+ route=route, method=method, operation_ids=operation_ids
+ )
+ parameters: List[Dict[str, Any]] = []
+ flat_dependant = get_flat_dependant(route.dependant, skip_repeats=True)
+ security_definitions, operation_security = get_openapi_security_definitions(
+ flat_dependant=flat_dependant
+ )
+ if operation_security:
+ operation.setdefault("security", []).extend(operation_security)
+ if security_definitions:
+ security_schemes.update(security_definitions)
+ operation_parameters = _get_openapi_operation_parameters(
+ dependant=route.dependant,
+ schema_generator=schema_generator,
+ model_name_map=model_name_map,
+ field_mapping=field_mapping,
+ separate_input_output_schemas=separate_input_output_schemas,
+ )
+ parameters.extend(operation_parameters)
+ if parameters:
+ all_parameters = {
+ (param["in"], param["name"]): param for param in parameters
+ }
+ required_parameters = {
+ (param["in"], param["name"]): param
+ for param in parameters
+ if param.get("required")
+ }
+ # Make sure required definitions of the same parameter take precedence
+ # over non-required definitions
+ all_parameters.update(required_parameters)
+ operation["parameters"] = list(all_parameters.values())
+ if method in METHODS_WITH_BODY:
+ request_body_oai = get_openapi_operation_request_body(
+ body_field=route.body_field,
+ schema_generator=schema_generator,
+ model_name_map=model_name_map,
+ field_mapping=field_mapping,
+ separate_input_output_schemas=separate_input_output_schemas,
+ )
+ if request_body_oai:
+ operation["requestBody"] = request_body_oai
+ if route.callbacks:
+ callbacks = {}
+ for callback in route.callbacks:
+ if isinstance(callback, routing.APIRoute):
+ (
+ cb_path,
+ cb_security_schemes,
+ cb_definitions,
+ ) = get_openapi_path(
+ route=callback,
+ operation_ids=operation_ids,
+ schema_generator=schema_generator,
+ model_name_map=model_name_map,
+ field_mapping=field_mapping,
+ separate_input_output_schemas=separate_input_output_schemas,
+ )
+ callbacks[callback.name] = {callback.path: cb_path}
+ operation["callbacks"] = callbacks
+ if route.status_code is not None:
+ status_code = str(route.status_code)
+ else:
+ # It would probably make more sense for all response classes to have an
+ # explicit default status_code, and to extract it from them, instead of
+ # doing this inspection tricks, that would probably be in the future
+ # TODO: probably make status_code a default class attribute for all
+ # responses in Starlette
+ response_signature = inspect.signature(current_response_class.__init__)
+ status_code_param = response_signature.parameters.get("status_code")
+ if status_code_param is not None:
+ if isinstance(status_code_param.default, int):
+ status_code = str(status_code_param.default)
+ operation.setdefault("responses", {}).setdefault(status_code, {})[
+ "description"
+ ] = route.response_description
+ if route_response_media_type and is_body_allowed_for_status_code(
+ route.status_code
+ ):
+ response_schema = {"type": "string"}
+ if lenient_issubclass(current_response_class, JSONResponse):
+ if route.response_field:
+ response_schema = get_schema_from_model_field(
+ field=route.response_field,
+ schema_generator=schema_generator,
+ model_name_map=model_name_map,
+ field_mapping=field_mapping,
+ separate_input_output_schemas=separate_input_output_schemas,
+ )
+ else:
+ response_schema = {}
+ operation.setdefault("responses", {}).setdefault(
+ status_code, {}
+ ).setdefault("content", {}).setdefault(route_response_media_type, {})[
+ "schema"
+ ] = response_schema
+ if route.responses:
+ operation_responses = operation.setdefault("responses", {})
+ for (
+ additional_status_code,
+ additional_response,
+ ) in route.responses.items():
+ process_response = additional_response.copy()
+ process_response.pop("model", None)
+ status_code_key = str(additional_status_code).upper()
+ if status_code_key == "DEFAULT":
+ status_code_key = "default"
+ openapi_response = operation_responses.setdefault(
+ status_code_key, {}
+ )
+ assert isinstance(process_response, dict), (
+ "An additional response must be a dict"
+ )
+ field = route.response_fields.get(additional_status_code)
+ additional_field_schema: Optional[Dict[str, Any]] = None
+ if field:
+ additional_field_schema = get_schema_from_model_field(
+ field=field,
+ schema_generator=schema_generator,
+ model_name_map=model_name_map,
+ field_mapping=field_mapping,
+ separate_input_output_schemas=separate_input_output_schemas,
+ )
+ media_type = route_response_media_type or "application/json"
+ additional_schema = (
+ process_response.setdefault("content", {})
+ .setdefault(media_type, {})
+ .setdefault("schema", {})
+ )
+ deep_dict_update(additional_schema, additional_field_schema)
+ status_text: Optional[str] = status_code_ranges.get(
+ str(additional_status_code).upper()
+ ) or http.client.responses.get(int(additional_status_code))
+ description = (
+ process_response.get("description")
+ or openapi_response.get("description")
+ or status_text
+ or "Additional Response"
+ )
+ deep_dict_update(openapi_response, process_response)
+ openapi_response["description"] = description
+ http422 = str(HTTP_422_UNPROCESSABLE_ENTITY)
+ all_route_params = get_flat_params(route.dependant)
+ if (all_route_params or route.body_field) and not any(
+ status in operation["responses"]
+ for status in [http422, "4XX", "default"]
+ ):
+ operation["responses"][http422] = {
+ "description": "Validation Error",
+ "content": {
+ "application/json": {
+ "schema": {"$ref": REF_PREFIX + "HTTPValidationError"}
+ }
+ },
+ }
+ if "ValidationError" not in definitions:
+ definitions.update(
+ {
+ "ValidationError": validation_error_definition,
+ "HTTPValidationError": validation_error_response_definition,
+ }
+ )
+ if route.openapi_extra:
+ deep_dict_update(operation, route.openapi_extra)
+ path[method.lower()] = operation
+ return path, security_schemes, definitions
+
+
+def get_fields_from_routes(
+ routes: Sequence[BaseRoute],
+) -> List[ModelField]:
+ body_fields_from_routes: List[ModelField] = []
+ responses_from_routes: List[ModelField] = []
+ request_fields_from_routes: List[ModelField] = []
+ callback_flat_models: List[ModelField] = []
+ for route in routes:
+ if getattr(route, "include_in_schema", None) and isinstance(
+ route, routing.APIRoute
+ ):
+ if route.body_field:
+ assert isinstance(route.body_field, ModelField), (
+ "A request body must be a Pydantic Field"
+ )
+ body_fields_from_routes.append(route.body_field)
+ if route.response_field:
+ responses_from_routes.append(route.response_field)
+ if route.response_fields:
+ responses_from_routes.extend(route.response_fields.values())
+ if route.callbacks:
+ callback_flat_models.extend(get_fields_from_routes(route.callbacks))
+ params = get_flat_params(route.dependant)
+ request_fields_from_routes.extend(params)
+
+ flat_models = callback_flat_models + list(
+ body_fields_from_routes + responses_from_routes + request_fields_from_routes
+ )
+ return flat_models
+
+
+def get_openapi(
+ *,
+ title: str,
+ version: str,
+ openapi_version: str = "3.1.0",
+ summary: Optional[str] = None,
+ description: Optional[str] = None,
+ routes: Sequence[BaseRoute],
+ webhooks: Optional[Sequence[BaseRoute]] = None,
+ tags: Optional[List[Dict[str, Any]]] = None,
+ servers: Optional[List[Dict[str, Union[str, Any]]]] = None,
+ terms_of_service: Optional[str] = None,
+ contact: Optional[Dict[str, Union[str, Any]]] = None,
+ license_info: Optional[Dict[str, Union[str, Any]]] = None,
+ separate_input_output_schemas: bool = True,
+) -> Dict[str, Any]:
+ info: Dict[str, Any] = {"title": title, "version": version}
+ if summary:
+ info["summary"] = summary
+ if description:
+ info["description"] = description
+ if terms_of_service:
+ info["termsOfService"] = terms_of_service
+ if contact:
+ info["contact"] = contact
+ if license_info:
+ info["license"] = license_info
+ output: Dict[str, Any] = {"openapi": openapi_version, "info": info}
+ if servers:
+ output["servers"] = servers
+ components: Dict[str, Dict[str, Any]] = {}
+ paths: Dict[str, Dict[str, Any]] = {}
+ webhook_paths: Dict[str, Dict[str, Any]] = {}
+ operation_ids: Set[str] = set()
+ all_fields = get_fields_from_routes(list(routes or []) + list(webhooks or []))
+ model_name_map = get_compat_model_name_map(all_fields)
+ schema_generator = GenerateJsonSchema(ref_template=REF_TEMPLATE)
+ field_mapping, definitions = get_definitions(
+ fields=all_fields,
+ schema_generator=schema_generator,
+ model_name_map=model_name_map,
+ separate_input_output_schemas=separate_input_output_schemas,
+ )
+ for route in routes or []:
+ if isinstance(route, routing.APIRoute):
+ result = get_openapi_path(
+ route=route,
+ operation_ids=operation_ids,
+ schema_generator=schema_generator,
+ model_name_map=model_name_map,
+ field_mapping=field_mapping,
+ separate_input_output_schemas=separate_input_output_schemas,
+ )
+ if result:
+ path, security_schemes, path_definitions = result
+ if path:
+ paths.setdefault(route.path_format, {}).update(path)
+ if security_schemes:
+ components.setdefault("securitySchemes", {}).update(
+ security_schemes
+ )
+ if path_definitions:
+ definitions.update(path_definitions)
+ for webhook in webhooks or []:
+ if isinstance(webhook, routing.APIRoute):
+ result = get_openapi_path(
+ route=webhook,
+ operation_ids=operation_ids,
+ schema_generator=schema_generator,
+ model_name_map=model_name_map,
+ field_mapping=field_mapping,
+ separate_input_output_schemas=separate_input_output_schemas,
+ )
+ if result:
+ path, security_schemes, path_definitions = result
+ if path:
+ webhook_paths.setdefault(webhook.path_format, {}).update(path)
+ if security_schemes:
+ components.setdefault("securitySchemes", {}).update(
+ security_schemes
+ )
+ if path_definitions:
+ definitions.update(path_definitions)
+ if definitions:
+ components["schemas"] = {k: definitions[k] for k in sorted(definitions)}
+ if components:
+ output["components"] = components
+ output["paths"] = paths
+ if webhook_paths:
+ output["webhooks"] = webhook_paths
+ if tags:
+ output["tags"] = tags
+ return jsonable_encoder(OpenAPI(**output), by_alias=True, exclude_none=True) # type: ignore
diff --git a/venv/Lib/site-packages/fastapi/param_functions.py b/venv/Lib/site-packages/fastapi/param_functions.py
new file mode 100644
index 00000000..b3621626
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/param_functions.py
@@ -0,0 +1,2360 @@
+from typing import Any, Callable, Dict, List, Optional, Sequence, Union
+
+from fastapi import params
+from fastapi._compat import Undefined
+from fastapi.openapi.models import Example
+from typing_extensions import Annotated, Doc, deprecated
+
+_Unset: Any = Undefined
+
+
+def Path( # noqa: N802
+ default: Annotated[
+ Any,
+ Doc(
+ """
+ Default value if the parameter field is not set.
+
+ This doesn't affect `Path` parameters as the value is always required.
+ The parameter is available only for compatibility.
+ """
+ ),
+ ] = ...,
+ *,
+ default_factory: Annotated[
+ Union[Callable[[], Any], None],
+ Doc(
+ """
+ A callable to generate the default value.
+
+ This doesn't affect `Path` parameters as the value is always required.
+ The parameter is available only for compatibility.
+ """
+ ),
+ ] = _Unset,
+ alias: Annotated[
+ Optional[str],
+ Doc(
+ """
+ An alternative name for the parameter field.
+
+ This will be used to extract the data and for the generated OpenAPI.
+ It is particularly useful when you can't use the name you want because it
+ is a Python reserved keyword or similar.
+ """
+ ),
+ ] = None,
+ alias_priority: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Priority of the alias. This affects whether an alias generator is used.
+ """
+ ),
+ ] = _Unset,
+ # TODO: update when deprecating Pydantic v1, import these types
+ # validation_alias: str | AliasPath | AliasChoices | None
+ validation_alias: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ 'Whitelist' validation step. The parameter field will be the single one
+ allowed by the alias or set of aliases defined.
+ """
+ ),
+ ] = None,
+ serialization_alias: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ 'Blacklist' validation step. The vanilla parameter field will be the
+ single one of the alias' or set of aliases' fields and all the other
+ fields will be ignored at serialization time.
+ """
+ ),
+ ] = None,
+ title: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Human-readable title.
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Human-readable description.
+ """
+ ),
+ ] = None,
+ gt: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Greater than. If set, value must be greater than this. Only applicable to
+ numbers.
+ """
+ ),
+ ] = None,
+ ge: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Greater than or equal. If set, value must be greater than or equal to
+ this. Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ lt: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Less than. If set, value must be less than this. Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ le: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Less than or equal. If set, value must be less than or equal to this.
+ Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ min_length: Annotated[
+ Optional[int],
+ Doc(
+ """
+ Minimum length for strings.
+ """
+ ),
+ ] = None,
+ max_length: Annotated[
+ Optional[int],
+ Doc(
+ """
+ Maximum length for strings.
+ """
+ ),
+ ] = None,
+ pattern: Annotated[
+ Optional[str],
+ Doc(
+ """
+ RegEx pattern for strings.
+ """
+ ),
+ ] = None,
+ regex: Annotated[
+ Optional[str],
+ Doc(
+ """
+ RegEx pattern for strings.
+ """
+ ),
+ deprecated(
+ "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
+ ),
+ ] = None,
+ discriminator: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ Parameter field name for discriminating the type in a tagged union.
+ """
+ ),
+ ] = None,
+ strict: Annotated[
+ Union[bool, None],
+ Doc(
+ """
+ If `True`, strict validation is applied to the field.
+ """
+ ),
+ ] = _Unset,
+ multiple_of: Annotated[
+ Union[float, None],
+ Doc(
+ """
+ Value must be a multiple of this. Only applicable to numbers.
+ """
+ ),
+ ] = _Unset,
+ allow_inf_nan: Annotated[
+ Union[bool, None],
+ Doc(
+ """
+ Allow `inf`, `-inf`, `nan`. Only applicable to numbers.
+ """
+ ),
+ ] = _Unset,
+ max_digits: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Maximum number of allow digits for strings.
+ """
+ ),
+ ] = _Unset,
+ decimal_places: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Maximum number of decimal places allowed for numbers.
+ """
+ ),
+ ] = _Unset,
+ examples: Annotated[
+ Optional[List[Any]],
+ Doc(
+ """
+ Example values for this field.
+ """
+ ),
+ ] = None,
+ example: Annotated[
+ Optional[Any],
+ deprecated(
+ "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
+ "although still supported. Use examples instead."
+ ),
+ ] = _Unset,
+ openapi_examples: Annotated[
+ Optional[Dict[str, Example]],
+ Doc(
+ """
+ OpenAPI-specific examples.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Swagger UI (that provides the `/docs` interface) has better support for the
+ OpenAPI-specific examples than the JSON Schema `examples`, that's the main
+ use case for this.
+
+ Read more about it in the
+ [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/#using-the-openapi_examples-parameter).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Union[deprecated, str, bool, None],
+ Doc(
+ """
+ Mark this parameter field as deprecated.
+
+ It will affect the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ To include (or not) this parameter field in the generated OpenAPI.
+ You probably don't need it, but it's available.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = True,
+ json_schema_extra: Annotated[
+ Union[Dict[str, Any], None],
+ Doc(
+ """
+ Any additional JSON schema data.
+ """
+ ),
+ ] = None,
+ **extra: Annotated[
+ Any,
+ Doc(
+ """
+ Include extra fields used by the JSON Schema.
+ """
+ ),
+ deprecated(
+ """
+ The `extra` kwargs is deprecated. Use `json_schema_extra` instead.
+ """
+ ),
+ ],
+) -> Any:
+ """
+ Declare a path parameter for a *path operation*.
+
+ Read more about it in the
+ [FastAPI docs for Path Parameters and Numeric Validations](https://fastapi.tiangolo.com/tutorial/path-params-numeric-validations/).
+
+ ```python
+ from typing import Annotated
+
+ from fastapi import FastAPI, Path
+
+ app = FastAPI()
+
+
+ @app.get("/items/{item_id}")
+ async def read_items(
+ item_id: Annotated[int, Path(title="The ID of the item to get")],
+ ):
+ return {"item_id": item_id}
+ ```
+ """
+ return params.Path(
+ default=default,
+ default_factory=default_factory,
+ alias=alias,
+ alias_priority=alias_priority,
+ validation_alias=validation_alias,
+ serialization_alias=serialization_alias,
+ title=title,
+ description=description,
+ gt=gt,
+ ge=ge,
+ lt=lt,
+ le=le,
+ min_length=min_length,
+ max_length=max_length,
+ pattern=pattern,
+ regex=regex,
+ discriminator=discriminator,
+ strict=strict,
+ multiple_of=multiple_of,
+ allow_inf_nan=allow_inf_nan,
+ max_digits=max_digits,
+ decimal_places=decimal_places,
+ example=example,
+ examples=examples,
+ openapi_examples=openapi_examples,
+ deprecated=deprecated,
+ include_in_schema=include_in_schema,
+ json_schema_extra=json_schema_extra,
+ **extra,
+ )
+
+
+def Query( # noqa: N802
+ default: Annotated[
+ Any,
+ Doc(
+ """
+ Default value if the parameter field is not set.
+ """
+ ),
+ ] = Undefined,
+ *,
+ default_factory: Annotated[
+ Union[Callable[[], Any], None],
+ Doc(
+ """
+ A callable to generate the default value.
+
+ This doesn't affect `Path` parameters as the value is always required.
+ The parameter is available only for compatibility.
+ """
+ ),
+ ] = _Unset,
+ alias: Annotated[
+ Optional[str],
+ Doc(
+ """
+ An alternative name for the parameter field.
+
+ This will be used to extract the data and for the generated OpenAPI.
+ It is particularly useful when you can't use the name you want because it
+ is a Python reserved keyword or similar.
+ """
+ ),
+ ] = None,
+ alias_priority: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Priority of the alias. This affects whether an alias generator is used.
+ """
+ ),
+ ] = _Unset,
+ # TODO: update when deprecating Pydantic v1, import these types
+ # validation_alias: str | AliasPath | AliasChoices | None
+ validation_alias: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ 'Whitelist' validation step. The parameter field will be the single one
+ allowed by the alias or set of aliases defined.
+ """
+ ),
+ ] = None,
+ serialization_alias: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ 'Blacklist' validation step. The vanilla parameter field will be the
+ single one of the alias' or set of aliases' fields and all the other
+ fields will be ignored at serialization time.
+ """
+ ),
+ ] = None,
+ title: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Human-readable title.
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Human-readable description.
+ """
+ ),
+ ] = None,
+ gt: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Greater than. If set, value must be greater than this. Only applicable to
+ numbers.
+ """
+ ),
+ ] = None,
+ ge: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Greater than or equal. If set, value must be greater than or equal to
+ this. Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ lt: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Less than. If set, value must be less than this. Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ le: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Less than or equal. If set, value must be less than or equal to this.
+ Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ min_length: Annotated[
+ Optional[int],
+ Doc(
+ """
+ Minimum length for strings.
+ """
+ ),
+ ] = None,
+ max_length: Annotated[
+ Optional[int],
+ Doc(
+ """
+ Maximum length for strings.
+ """
+ ),
+ ] = None,
+ pattern: Annotated[
+ Optional[str],
+ Doc(
+ """
+ RegEx pattern for strings.
+ """
+ ),
+ ] = None,
+ regex: Annotated[
+ Optional[str],
+ Doc(
+ """
+ RegEx pattern for strings.
+ """
+ ),
+ deprecated(
+ "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
+ ),
+ ] = None,
+ discriminator: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ Parameter field name for discriminating the type in a tagged union.
+ """
+ ),
+ ] = None,
+ strict: Annotated[
+ Union[bool, None],
+ Doc(
+ """
+ If `True`, strict validation is applied to the field.
+ """
+ ),
+ ] = _Unset,
+ multiple_of: Annotated[
+ Union[float, None],
+ Doc(
+ """
+ Value must be a multiple of this. Only applicable to numbers.
+ """
+ ),
+ ] = _Unset,
+ allow_inf_nan: Annotated[
+ Union[bool, None],
+ Doc(
+ """
+ Allow `inf`, `-inf`, `nan`. Only applicable to numbers.
+ """
+ ),
+ ] = _Unset,
+ max_digits: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Maximum number of allow digits for strings.
+ """
+ ),
+ ] = _Unset,
+ decimal_places: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Maximum number of decimal places allowed for numbers.
+ """
+ ),
+ ] = _Unset,
+ examples: Annotated[
+ Optional[List[Any]],
+ Doc(
+ """
+ Example values for this field.
+ """
+ ),
+ ] = None,
+ example: Annotated[
+ Optional[Any],
+ deprecated(
+ "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
+ "although still supported. Use examples instead."
+ ),
+ ] = _Unset,
+ openapi_examples: Annotated[
+ Optional[Dict[str, Example]],
+ Doc(
+ """
+ OpenAPI-specific examples.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Swagger UI (that provides the `/docs` interface) has better support for the
+ OpenAPI-specific examples than the JSON Schema `examples`, that's the main
+ use case for this.
+
+ Read more about it in the
+ [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/#using-the-openapi_examples-parameter).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Union[deprecated, str, bool, None],
+ Doc(
+ """
+ Mark this parameter field as deprecated.
+
+ It will affect the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ To include (or not) this parameter field in the generated OpenAPI.
+ You probably don't need it, but it's available.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = True,
+ json_schema_extra: Annotated[
+ Union[Dict[str, Any], None],
+ Doc(
+ """
+ Any additional JSON schema data.
+ """
+ ),
+ ] = None,
+ **extra: Annotated[
+ Any,
+ Doc(
+ """
+ Include extra fields used by the JSON Schema.
+ """
+ ),
+ deprecated(
+ """
+ The `extra` kwargs is deprecated. Use `json_schema_extra` instead.
+ """
+ ),
+ ],
+) -> Any:
+ return params.Query(
+ default=default,
+ default_factory=default_factory,
+ alias=alias,
+ alias_priority=alias_priority,
+ validation_alias=validation_alias,
+ serialization_alias=serialization_alias,
+ title=title,
+ description=description,
+ gt=gt,
+ ge=ge,
+ lt=lt,
+ le=le,
+ min_length=min_length,
+ max_length=max_length,
+ pattern=pattern,
+ regex=regex,
+ discriminator=discriminator,
+ strict=strict,
+ multiple_of=multiple_of,
+ allow_inf_nan=allow_inf_nan,
+ max_digits=max_digits,
+ decimal_places=decimal_places,
+ example=example,
+ examples=examples,
+ openapi_examples=openapi_examples,
+ deprecated=deprecated,
+ include_in_schema=include_in_schema,
+ json_schema_extra=json_schema_extra,
+ **extra,
+ )
+
+
+def Header( # noqa: N802
+ default: Annotated[
+ Any,
+ Doc(
+ """
+ Default value if the parameter field is not set.
+ """
+ ),
+ ] = Undefined,
+ *,
+ default_factory: Annotated[
+ Union[Callable[[], Any], None],
+ Doc(
+ """
+ A callable to generate the default value.
+
+ This doesn't affect `Path` parameters as the value is always required.
+ The parameter is available only for compatibility.
+ """
+ ),
+ ] = _Unset,
+ alias: Annotated[
+ Optional[str],
+ Doc(
+ """
+ An alternative name for the parameter field.
+
+ This will be used to extract the data and for the generated OpenAPI.
+ It is particularly useful when you can't use the name you want because it
+ is a Python reserved keyword or similar.
+ """
+ ),
+ ] = None,
+ alias_priority: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Priority of the alias. This affects whether an alias generator is used.
+ """
+ ),
+ ] = _Unset,
+ # TODO: update when deprecating Pydantic v1, import these types
+ # validation_alias: str | AliasPath | AliasChoices | None
+ validation_alias: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ 'Whitelist' validation step. The parameter field will be the single one
+ allowed by the alias or set of aliases defined.
+ """
+ ),
+ ] = None,
+ serialization_alias: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ 'Blacklist' validation step. The vanilla parameter field will be the
+ single one of the alias' or set of aliases' fields and all the other
+ fields will be ignored at serialization time.
+ """
+ ),
+ ] = None,
+ convert_underscores: Annotated[
+ bool,
+ Doc(
+ """
+ Automatically convert underscores to hyphens in the parameter field name.
+
+ Read more about it in the
+ [FastAPI docs for Header Parameters](https://fastapi.tiangolo.com/tutorial/header-params/#automatic-conversion)
+ """
+ ),
+ ] = True,
+ title: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Human-readable title.
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Human-readable description.
+ """
+ ),
+ ] = None,
+ gt: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Greater than. If set, value must be greater than this. Only applicable to
+ numbers.
+ """
+ ),
+ ] = None,
+ ge: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Greater than or equal. If set, value must be greater than or equal to
+ this. Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ lt: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Less than. If set, value must be less than this. Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ le: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Less than or equal. If set, value must be less than or equal to this.
+ Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ min_length: Annotated[
+ Optional[int],
+ Doc(
+ """
+ Minimum length for strings.
+ """
+ ),
+ ] = None,
+ max_length: Annotated[
+ Optional[int],
+ Doc(
+ """
+ Maximum length for strings.
+ """
+ ),
+ ] = None,
+ pattern: Annotated[
+ Optional[str],
+ Doc(
+ """
+ RegEx pattern for strings.
+ """
+ ),
+ ] = None,
+ regex: Annotated[
+ Optional[str],
+ Doc(
+ """
+ RegEx pattern for strings.
+ """
+ ),
+ deprecated(
+ "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
+ ),
+ ] = None,
+ discriminator: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ Parameter field name for discriminating the type in a tagged union.
+ """
+ ),
+ ] = None,
+ strict: Annotated[
+ Union[bool, None],
+ Doc(
+ """
+ If `True`, strict validation is applied to the field.
+ """
+ ),
+ ] = _Unset,
+ multiple_of: Annotated[
+ Union[float, None],
+ Doc(
+ """
+ Value must be a multiple of this. Only applicable to numbers.
+ """
+ ),
+ ] = _Unset,
+ allow_inf_nan: Annotated[
+ Union[bool, None],
+ Doc(
+ """
+ Allow `inf`, `-inf`, `nan`. Only applicable to numbers.
+ """
+ ),
+ ] = _Unset,
+ max_digits: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Maximum number of allow digits for strings.
+ """
+ ),
+ ] = _Unset,
+ decimal_places: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Maximum number of decimal places allowed for numbers.
+ """
+ ),
+ ] = _Unset,
+ examples: Annotated[
+ Optional[List[Any]],
+ Doc(
+ """
+ Example values for this field.
+ """
+ ),
+ ] = None,
+ example: Annotated[
+ Optional[Any],
+ deprecated(
+ "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
+ "although still supported. Use examples instead."
+ ),
+ ] = _Unset,
+ openapi_examples: Annotated[
+ Optional[Dict[str, Example]],
+ Doc(
+ """
+ OpenAPI-specific examples.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Swagger UI (that provides the `/docs` interface) has better support for the
+ OpenAPI-specific examples than the JSON Schema `examples`, that's the main
+ use case for this.
+
+ Read more about it in the
+ [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/#using-the-openapi_examples-parameter).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Union[deprecated, str, bool, None],
+ Doc(
+ """
+ Mark this parameter field as deprecated.
+
+ It will affect the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ To include (or not) this parameter field in the generated OpenAPI.
+ You probably don't need it, but it's available.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = True,
+ json_schema_extra: Annotated[
+ Union[Dict[str, Any], None],
+ Doc(
+ """
+ Any additional JSON schema data.
+ """
+ ),
+ ] = None,
+ **extra: Annotated[
+ Any,
+ Doc(
+ """
+ Include extra fields used by the JSON Schema.
+ """
+ ),
+ deprecated(
+ """
+ The `extra` kwargs is deprecated. Use `json_schema_extra` instead.
+ """
+ ),
+ ],
+) -> Any:
+ return params.Header(
+ default=default,
+ default_factory=default_factory,
+ alias=alias,
+ alias_priority=alias_priority,
+ validation_alias=validation_alias,
+ serialization_alias=serialization_alias,
+ convert_underscores=convert_underscores,
+ title=title,
+ description=description,
+ gt=gt,
+ ge=ge,
+ lt=lt,
+ le=le,
+ min_length=min_length,
+ max_length=max_length,
+ pattern=pattern,
+ regex=regex,
+ discriminator=discriminator,
+ strict=strict,
+ multiple_of=multiple_of,
+ allow_inf_nan=allow_inf_nan,
+ max_digits=max_digits,
+ decimal_places=decimal_places,
+ example=example,
+ examples=examples,
+ openapi_examples=openapi_examples,
+ deprecated=deprecated,
+ include_in_schema=include_in_schema,
+ json_schema_extra=json_schema_extra,
+ **extra,
+ )
+
+
+def Cookie( # noqa: N802
+ default: Annotated[
+ Any,
+ Doc(
+ """
+ Default value if the parameter field is not set.
+ """
+ ),
+ ] = Undefined,
+ *,
+ default_factory: Annotated[
+ Union[Callable[[], Any], None],
+ Doc(
+ """
+ A callable to generate the default value.
+
+ This doesn't affect `Path` parameters as the value is always required.
+ The parameter is available only for compatibility.
+ """
+ ),
+ ] = _Unset,
+ alias: Annotated[
+ Optional[str],
+ Doc(
+ """
+ An alternative name for the parameter field.
+
+ This will be used to extract the data and for the generated OpenAPI.
+ It is particularly useful when you can't use the name you want because it
+ is a Python reserved keyword or similar.
+ """
+ ),
+ ] = None,
+ alias_priority: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Priority of the alias. This affects whether an alias generator is used.
+ """
+ ),
+ ] = _Unset,
+ # TODO: update when deprecating Pydantic v1, import these types
+ # validation_alias: str | AliasPath | AliasChoices | None
+ validation_alias: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ 'Whitelist' validation step. The parameter field will be the single one
+ allowed by the alias or set of aliases defined.
+ """
+ ),
+ ] = None,
+ serialization_alias: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ 'Blacklist' validation step. The vanilla parameter field will be the
+ single one of the alias' or set of aliases' fields and all the other
+ fields will be ignored at serialization time.
+ """
+ ),
+ ] = None,
+ title: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Human-readable title.
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Human-readable description.
+ """
+ ),
+ ] = None,
+ gt: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Greater than. If set, value must be greater than this. Only applicable to
+ numbers.
+ """
+ ),
+ ] = None,
+ ge: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Greater than or equal. If set, value must be greater than or equal to
+ this. Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ lt: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Less than. If set, value must be less than this. Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ le: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Less than or equal. If set, value must be less than or equal to this.
+ Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ min_length: Annotated[
+ Optional[int],
+ Doc(
+ """
+ Minimum length for strings.
+ """
+ ),
+ ] = None,
+ max_length: Annotated[
+ Optional[int],
+ Doc(
+ """
+ Maximum length for strings.
+ """
+ ),
+ ] = None,
+ pattern: Annotated[
+ Optional[str],
+ Doc(
+ """
+ RegEx pattern for strings.
+ """
+ ),
+ ] = None,
+ regex: Annotated[
+ Optional[str],
+ Doc(
+ """
+ RegEx pattern for strings.
+ """
+ ),
+ deprecated(
+ "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
+ ),
+ ] = None,
+ discriminator: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ Parameter field name for discriminating the type in a tagged union.
+ """
+ ),
+ ] = None,
+ strict: Annotated[
+ Union[bool, None],
+ Doc(
+ """
+ If `True`, strict validation is applied to the field.
+ """
+ ),
+ ] = _Unset,
+ multiple_of: Annotated[
+ Union[float, None],
+ Doc(
+ """
+ Value must be a multiple of this. Only applicable to numbers.
+ """
+ ),
+ ] = _Unset,
+ allow_inf_nan: Annotated[
+ Union[bool, None],
+ Doc(
+ """
+ Allow `inf`, `-inf`, `nan`. Only applicable to numbers.
+ """
+ ),
+ ] = _Unset,
+ max_digits: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Maximum number of allow digits for strings.
+ """
+ ),
+ ] = _Unset,
+ decimal_places: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Maximum number of decimal places allowed for numbers.
+ """
+ ),
+ ] = _Unset,
+ examples: Annotated[
+ Optional[List[Any]],
+ Doc(
+ """
+ Example values for this field.
+ """
+ ),
+ ] = None,
+ example: Annotated[
+ Optional[Any],
+ deprecated(
+ "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
+ "although still supported. Use examples instead."
+ ),
+ ] = _Unset,
+ openapi_examples: Annotated[
+ Optional[Dict[str, Example]],
+ Doc(
+ """
+ OpenAPI-specific examples.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Swagger UI (that provides the `/docs` interface) has better support for the
+ OpenAPI-specific examples than the JSON Schema `examples`, that's the main
+ use case for this.
+
+ Read more about it in the
+ [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/#using-the-openapi_examples-parameter).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Union[deprecated, str, bool, None],
+ Doc(
+ """
+ Mark this parameter field as deprecated.
+
+ It will affect the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ To include (or not) this parameter field in the generated OpenAPI.
+ You probably don't need it, but it's available.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = True,
+ json_schema_extra: Annotated[
+ Union[Dict[str, Any], None],
+ Doc(
+ """
+ Any additional JSON schema data.
+ """
+ ),
+ ] = None,
+ **extra: Annotated[
+ Any,
+ Doc(
+ """
+ Include extra fields used by the JSON Schema.
+ """
+ ),
+ deprecated(
+ """
+ The `extra` kwargs is deprecated. Use `json_schema_extra` instead.
+ """
+ ),
+ ],
+) -> Any:
+ return params.Cookie(
+ default=default,
+ default_factory=default_factory,
+ alias=alias,
+ alias_priority=alias_priority,
+ validation_alias=validation_alias,
+ serialization_alias=serialization_alias,
+ title=title,
+ description=description,
+ gt=gt,
+ ge=ge,
+ lt=lt,
+ le=le,
+ min_length=min_length,
+ max_length=max_length,
+ pattern=pattern,
+ regex=regex,
+ discriminator=discriminator,
+ strict=strict,
+ multiple_of=multiple_of,
+ allow_inf_nan=allow_inf_nan,
+ max_digits=max_digits,
+ decimal_places=decimal_places,
+ example=example,
+ examples=examples,
+ openapi_examples=openapi_examples,
+ deprecated=deprecated,
+ include_in_schema=include_in_schema,
+ json_schema_extra=json_schema_extra,
+ **extra,
+ )
+
+
+def Body( # noqa: N802
+ default: Annotated[
+ Any,
+ Doc(
+ """
+ Default value if the parameter field is not set.
+ """
+ ),
+ ] = Undefined,
+ *,
+ default_factory: Annotated[
+ Union[Callable[[], Any], None],
+ Doc(
+ """
+ A callable to generate the default value.
+
+ This doesn't affect `Path` parameters as the value is always required.
+ The parameter is available only for compatibility.
+ """
+ ),
+ ] = _Unset,
+ embed: Annotated[
+ Union[bool, None],
+ Doc(
+ """
+ When `embed` is `True`, the parameter will be expected in a JSON body as a
+ key instead of being the JSON body itself.
+
+ This happens automatically when more than one `Body` parameter is declared.
+
+ Read more about it in the
+ [FastAPI docs for Body - Multiple Parameters](https://fastapi.tiangolo.com/tutorial/body-multiple-params/#embed-a-single-body-parameter).
+ """
+ ),
+ ] = None,
+ media_type: Annotated[
+ str,
+ Doc(
+ """
+ The media type of this parameter field. Changing it would affect the
+ generated OpenAPI, but currently it doesn't affect the parsing of the data.
+ """
+ ),
+ ] = "application/json",
+ alias: Annotated[
+ Optional[str],
+ Doc(
+ """
+ An alternative name for the parameter field.
+
+ This will be used to extract the data and for the generated OpenAPI.
+ It is particularly useful when you can't use the name you want because it
+ is a Python reserved keyword or similar.
+ """
+ ),
+ ] = None,
+ alias_priority: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Priority of the alias. This affects whether an alias generator is used.
+ """
+ ),
+ ] = _Unset,
+ # TODO: update when deprecating Pydantic v1, import these types
+ # validation_alias: str | AliasPath | AliasChoices | None
+ validation_alias: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ 'Whitelist' validation step. The parameter field will be the single one
+ allowed by the alias or set of aliases defined.
+ """
+ ),
+ ] = None,
+ serialization_alias: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ 'Blacklist' validation step. The vanilla parameter field will be the
+ single one of the alias' or set of aliases' fields and all the other
+ fields will be ignored at serialization time.
+ """
+ ),
+ ] = None,
+ title: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Human-readable title.
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Human-readable description.
+ """
+ ),
+ ] = None,
+ gt: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Greater than. If set, value must be greater than this. Only applicable to
+ numbers.
+ """
+ ),
+ ] = None,
+ ge: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Greater than or equal. If set, value must be greater than or equal to
+ this. Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ lt: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Less than. If set, value must be less than this. Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ le: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Less than or equal. If set, value must be less than or equal to this.
+ Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ min_length: Annotated[
+ Optional[int],
+ Doc(
+ """
+ Minimum length for strings.
+ """
+ ),
+ ] = None,
+ max_length: Annotated[
+ Optional[int],
+ Doc(
+ """
+ Maximum length for strings.
+ """
+ ),
+ ] = None,
+ pattern: Annotated[
+ Optional[str],
+ Doc(
+ """
+ RegEx pattern for strings.
+ """
+ ),
+ ] = None,
+ regex: Annotated[
+ Optional[str],
+ Doc(
+ """
+ RegEx pattern for strings.
+ """
+ ),
+ deprecated(
+ "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
+ ),
+ ] = None,
+ discriminator: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ Parameter field name for discriminating the type in a tagged union.
+ """
+ ),
+ ] = None,
+ strict: Annotated[
+ Union[bool, None],
+ Doc(
+ """
+ If `True`, strict validation is applied to the field.
+ """
+ ),
+ ] = _Unset,
+ multiple_of: Annotated[
+ Union[float, None],
+ Doc(
+ """
+ Value must be a multiple of this. Only applicable to numbers.
+ """
+ ),
+ ] = _Unset,
+ allow_inf_nan: Annotated[
+ Union[bool, None],
+ Doc(
+ """
+ Allow `inf`, `-inf`, `nan`. Only applicable to numbers.
+ """
+ ),
+ ] = _Unset,
+ max_digits: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Maximum number of allow digits for strings.
+ """
+ ),
+ ] = _Unset,
+ decimal_places: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Maximum number of decimal places allowed for numbers.
+ """
+ ),
+ ] = _Unset,
+ examples: Annotated[
+ Optional[List[Any]],
+ Doc(
+ """
+ Example values for this field.
+ """
+ ),
+ ] = None,
+ example: Annotated[
+ Optional[Any],
+ deprecated(
+ "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
+ "although still supported. Use examples instead."
+ ),
+ ] = _Unset,
+ openapi_examples: Annotated[
+ Optional[Dict[str, Example]],
+ Doc(
+ """
+ OpenAPI-specific examples.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Swagger UI (that provides the `/docs` interface) has better support for the
+ OpenAPI-specific examples than the JSON Schema `examples`, that's the main
+ use case for this.
+
+ Read more about it in the
+ [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/#using-the-openapi_examples-parameter).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Union[deprecated, str, bool, None],
+ Doc(
+ """
+ Mark this parameter field as deprecated.
+
+ It will affect the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ To include (or not) this parameter field in the generated OpenAPI.
+ You probably don't need it, but it's available.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = True,
+ json_schema_extra: Annotated[
+ Union[Dict[str, Any], None],
+ Doc(
+ """
+ Any additional JSON schema data.
+ """
+ ),
+ ] = None,
+ **extra: Annotated[
+ Any,
+ Doc(
+ """
+ Include extra fields used by the JSON Schema.
+ """
+ ),
+ deprecated(
+ """
+ The `extra` kwargs is deprecated. Use `json_schema_extra` instead.
+ """
+ ),
+ ],
+) -> Any:
+ return params.Body(
+ default=default,
+ default_factory=default_factory,
+ embed=embed,
+ media_type=media_type,
+ alias=alias,
+ alias_priority=alias_priority,
+ validation_alias=validation_alias,
+ serialization_alias=serialization_alias,
+ title=title,
+ description=description,
+ gt=gt,
+ ge=ge,
+ lt=lt,
+ le=le,
+ min_length=min_length,
+ max_length=max_length,
+ pattern=pattern,
+ regex=regex,
+ discriminator=discriminator,
+ strict=strict,
+ multiple_of=multiple_of,
+ allow_inf_nan=allow_inf_nan,
+ max_digits=max_digits,
+ decimal_places=decimal_places,
+ example=example,
+ examples=examples,
+ openapi_examples=openapi_examples,
+ deprecated=deprecated,
+ include_in_schema=include_in_schema,
+ json_schema_extra=json_schema_extra,
+ **extra,
+ )
+
+
+def Form( # noqa: N802
+ default: Annotated[
+ Any,
+ Doc(
+ """
+ Default value if the parameter field is not set.
+ """
+ ),
+ ] = Undefined,
+ *,
+ default_factory: Annotated[
+ Union[Callable[[], Any], None],
+ Doc(
+ """
+ A callable to generate the default value.
+
+ This doesn't affect `Path` parameters as the value is always required.
+ The parameter is available only for compatibility.
+ """
+ ),
+ ] = _Unset,
+ media_type: Annotated[
+ str,
+ Doc(
+ """
+ The media type of this parameter field. Changing it would affect the
+ generated OpenAPI, but currently it doesn't affect the parsing of the data.
+ """
+ ),
+ ] = "application/x-www-form-urlencoded",
+ alias: Annotated[
+ Optional[str],
+ Doc(
+ """
+ An alternative name for the parameter field.
+
+ This will be used to extract the data and for the generated OpenAPI.
+ It is particularly useful when you can't use the name you want because it
+ is a Python reserved keyword or similar.
+ """
+ ),
+ ] = None,
+ alias_priority: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Priority of the alias. This affects whether an alias generator is used.
+ """
+ ),
+ ] = _Unset,
+ # TODO: update when deprecating Pydantic v1, import these types
+ # validation_alias: str | AliasPath | AliasChoices | None
+ validation_alias: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ 'Whitelist' validation step. The parameter field will be the single one
+ allowed by the alias or set of aliases defined.
+ """
+ ),
+ ] = None,
+ serialization_alias: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ 'Blacklist' validation step. The vanilla parameter field will be the
+ single one of the alias' or set of aliases' fields and all the other
+ fields will be ignored at serialization time.
+ """
+ ),
+ ] = None,
+ title: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Human-readable title.
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Human-readable description.
+ """
+ ),
+ ] = None,
+ gt: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Greater than. If set, value must be greater than this. Only applicable to
+ numbers.
+ """
+ ),
+ ] = None,
+ ge: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Greater than or equal. If set, value must be greater than or equal to
+ this. Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ lt: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Less than. If set, value must be less than this. Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ le: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Less than or equal. If set, value must be less than or equal to this.
+ Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ min_length: Annotated[
+ Optional[int],
+ Doc(
+ """
+ Minimum length for strings.
+ """
+ ),
+ ] = None,
+ max_length: Annotated[
+ Optional[int],
+ Doc(
+ """
+ Maximum length for strings.
+ """
+ ),
+ ] = None,
+ pattern: Annotated[
+ Optional[str],
+ Doc(
+ """
+ RegEx pattern for strings.
+ """
+ ),
+ ] = None,
+ regex: Annotated[
+ Optional[str],
+ Doc(
+ """
+ RegEx pattern for strings.
+ """
+ ),
+ deprecated(
+ "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
+ ),
+ ] = None,
+ discriminator: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ Parameter field name for discriminating the type in a tagged union.
+ """
+ ),
+ ] = None,
+ strict: Annotated[
+ Union[bool, None],
+ Doc(
+ """
+ If `True`, strict validation is applied to the field.
+ """
+ ),
+ ] = _Unset,
+ multiple_of: Annotated[
+ Union[float, None],
+ Doc(
+ """
+ Value must be a multiple of this. Only applicable to numbers.
+ """
+ ),
+ ] = _Unset,
+ allow_inf_nan: Annotated[
+ Union[bool, None],
+ Doc(
+ """
+ Allow `inf`, `-inf`, `nan`. Only applicable to numbers.
+ """
+ ),
+ ] = _Unset,
+ max_digits: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Maximum number of allow digits for strings.
+ """
+ ),
+ ] = _Unset,
+ decimal_places: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Maximum number of decimal places allowed for numbers.
+ """
+ ),
+ ] = _Unset,
+ examples: Annotated[
+ Optional[List[Any]],
+ Doc(
+ """
+ Example values for this field.
+ """
+ ),
+ ] = None,
+ example: Annotated[
+ Optional[Any],
+ deprecated(
+ "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
+ "although still supported. Use examples instead."
+ ),
+ ] = _Unset,
+ openapi_examples: Annotated[
+ Optional[Dict[str, Example]],
+ Doc(
+ """
+ OpenAPI-specific examples.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Swagger UI (that provides the `/docs` interface) has better support for the
+ OpenAPI-specific examples than the JSON Schema `examples`, that's the main
+ use case for this.
+
+ Read more about it in the
+ [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/#using-the-openapi_examples-parameter).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Union[deprecated, str, bool, None],
+ Doc(
+ """
+ Mark this parameter field as deprecated.
+
+ It will affect the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ To include (or not) this parameter field in the generated OpenAPI.
+ You probably don't need it, but it's available.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = True,
+ json_schema_extra: Annotated[
+ Union[Dict[str, Any], None],
+ Doc(
+ """
+ Any additional JSON schema data.
+ """
+ ),
+ ] = None,
+ **extra: Annotated[
+ Any,
+ Doc(
+ """
+ Include extra fields used by the JSON Schema.
+ """
+ ),
+ deprecated(
+ """
+ The `extra` kwargs is deprecated. Use `json_schema_extra` instead.
+ """
+ ),
+ ],
+) -> Any:
+ return params.Form(
+ default=default,
+ default_factory=default_factory,
+ media_type=media_type,
+ alias=alias,
+ alias_priority=alias_priority,
+ validation_alias=validation_alias,
+ serialization_alias=serialization_alias,
+ title=title,
+ description=description,
+ gt=gt,
+ ge=ge,
+ lt=lt,
+ le=le,
+ min_length=min_length,
+ max_length=max_length,
+ pattern=pattern,
+ regex=regex,
+ discriminator=discriminator,
+ strict=strict,
+ multiple_of=multiple_of,
+ allow_inf_nan=allow_inf_nan,
+ max_digits=max_digits,
+ decimal_places=decimal_places,
+ example=example,
+ examples=examples,
+ openapi_examples=openapi_examples,
+ deprecated=deprecated,
+ include_in_schema=include_in_schema,
+ json_schema_extra=json_schema_extra,
+ **extra,
+ )
+
+
+def File( # noqa: N802
+ default: Annotated[
+ Any,
+ Doc(
+ """
+ Default value if the parameter field is not set.
+ """
+ ),
+ ] = Undefined,
+ *,
+ default_factory: Annotated[
+ Union[Callable[[], Any], None],
+ Doc(
+ """
+ A callable to generate the default value.
+
+ This doesn't affect `Path` parameters as the value is always required.
+ The parameter is available only for compatibility.
+ """
+ ),
+ ] = _Unset,
+ media_type: Annotated[
+ str,
+ Doc(
+ """
+ The media type of this parameter field. Changing it would affect the
+ generated OpenAPI, but currently it doesn't affect the parsing of the data.
+ """
+ ),
+ ] = "multipart/form-data",
+ alias: Annotated[
+ Optional[str],
+ Doc(
+ """
+ An alternative name for the parameter field.
+
+ This will be used to extract the data and for the generated OpenAPI.
+ It is particularly useful when you can't use the name you want because it
+ is a Python reserved keyword or similar.
+ """
+ ),
+ ] = None,
+ alias_priority: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Priority of the alias. This affects whether an alias generator is used.
+ """
+ ),
+ ] = _Unset,
+ # TODO: update when deprecating Pydantic v1, import these types
+ # validation_alias: str | AliasPath | AliasChoices | None
+ validation_alias: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ 'Whitelist' validation step. The parameter field will be the single one
+ allowed by the alias or set of aliases defined.
+ """
+ ),
+ ] = None,
+ serialization_alias: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ 'Blacklist' validation step. The vanilla parameter field will be the
+ single one of the alias' or set of aliases' fields and all the other
+ fields will be ignored at serialization time.
+ """
+ ),
+ ] = None,
+ title: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Human-readable title.
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Human-readable description.
+ """
+ ),
+ ] = None,
+ gt: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Greater than. If set, value must be greater than this. Only applicable to
+ numbers.
+ """
+ ),
+ ] = None,
+ ge: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Greater than or equal. If set, value must be greater than or equal to
+ this. Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ lt: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Less than. If set, value must be less than this. Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ le: Annotated[
+ Optional[float],
+ Doc(
+ """
+ Less than or equal. If set, value must be less than or equal to this.
+ Only applicable to numbers.
+ """
+ ),
+ ] = None,
+ min_length: Annotated[
+ Optional[int],
+ Doc(
+ """
+ Minimum length for strings.
+ """
+ ),
+ ] = None,
+ max_length: Annotated[
+ Optional[int],
+ Doc(
+ """
+ Maximum length for strings.
+ """
+ ),
+ ] = None,
+ pattern: Annotated[
+ Optional[str],
+ Doc(
+ """
+ RegEx pattern for strings.
+ """
+ ),
+ ] = None,
+ regex: Annotated[
+ Optional[str],
+ Doc(
+ """
+ RegEx pattern for strings.
+ """
+ ),
+ deprecated(
+ "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
+ ),
+ ] = None,
+ discriminator: Annotated[
+ Union[str, None],
+ Doc(
+ """
+ Parameter field name for discriminating the type in a tagged union.
+ """
+ ),
+ ] = None,
+ strict: Annotated[
+ Union[bool, None],
+ Doc(
+ """
+ If `True`, strict validation is applied to the field.
+ """
+ ),
+ ] = _Unset,
+ multiple_of: Annotated[
+ Union[float, None],
+ Doc(
+ """
+ Value must be a multiple of this. Only applicable to numbers.
+ """
+ ),
+ ] = _Unset,
+ allow_inf_nan: Annotated[
+ Union[bool, None],
+ Doc(
+ """
+ Allow `inf`, `-inf`, `nan`. Only applicable to numbers.
+ """
+ ),
+ ] = _Unset,
+ max_digits: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Maximum number of allow digits for strings.
+ """
+ ),
+ ] = _Unset,
+ decimal_places: Annotated[
+ Union[int, None],
+ Doc(
+ """
+ Maximum number of decimal places allowed for numbers.
+ """
+ ),
+ ] = _Unset,
+ examples: Annotated[
+ Optional[List[Any]],
+ Doc(
+ """
+ Example values for this field.
+ """
+ ),
+ ] = None,
+ example: Annotated[
+ Optional[Any],
+ deprecated(
+ "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
+ "although still supported. Use examples instead."
+ ),
+ ] = _Unset,
+ openapi_examples: Annotated[
+ Optional[Dict[str, Example]],
+ Doc(
+ """
+ OpenAPI-specific examples.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Swagger UI (that provides the `/docs` interface) has better support for the
+ OpenAPI-specific examples than the JSON Schema `examples`, that's the main
+ use case for this.
+
+ Read more about it in the
+ [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/#using-the-openapi_examples-parameter).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Union[deprecated, str, bool, None],
+ Doc(
+ """
+ Mark this parameter field as deprecated.
+
+ It will affect the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ To include (or not) this parameter field in the generated OpenAPI.
+ You probably don't need it, but it's available.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = True,
+ json_schema_extra: Annotated[
+ Union[Dict[str, Any], None],
+ Doc(
+ """
+ Any additional JSON schema data.
+ """
+ ),
+ ] = None,
+ **extra: Annotated[
+ Any,
+ Doc(
+ """
+ Include extra fields used by the JSON Schema.
+ """
+ ),
+ deprecated(
+ """
+ The `extra` kwargs is deprecated. Use `json_schema_extra` instead.
+ """
+ ),
+ ],
+) -> Any:
+ return params.File(
+ default=default,
+ default_factory=default_factory,
+ media_type=media_type,
+ alias=alias,
+ alias_priority=alias_priority,
+ validation_alias=validation_alias,
+ serialization_alias=serialization_alias,
+ title=title,
+ description=description,
+ gt=gt,
+ ge=ge,
+ lt=lt,
+ le=le,
+ min_length=min_length,
+ max_length=max_length,
+ pattern=pattern,
+ regex=regex,
+ discriminator=discriminator,
+ strict=strict,
+ multiple_of=multiple_of,
+ allow_inf_nan=allow_inf_nan,
+ max_digits=max_digits,
+ decimal_places=decimal_places,
+ example=example,
+ examples=examples,
+ openapi_examples=openapi_examples,
+ deprecated=deprecated,
+ include_in_schema=include_in_schema,
+ json_schema_extra=json_schema_extra,
+ **extra,
+ )
+
+
+def Depends( # noqa: N802
+ dependency: Annotated[
+ Optional[Callable[..., Any]],
+ Doc(
+ """
+ A "dependable" callable (like a function).
+
+ Don't call it directly, FastAPI will call it for you, just pass the object
+ directly.
+ """
+ ),
+ ] = None,
+ *,
+ use_cache: Annotated[
+ bool,
+ Doc(
+ """
+ By default, after a dependency is called the first time in a request, if
+ the dependency is declared again for the rest of the request (for example
+ if the dependency is needed by several dependencies), the value will be
+ re-used for the rest of the request.
+
+ Set `use_cache` to `False` to disable this behavior and ensure the
+ dependency is called again (if declared more than once) in the same request.
+ """
+ ),
+ ] = True,
+) -> Any:
+ """
+ Declare a FastAPI dependency.
+
+ It takes a single "dependable" callable (like a function).
+
+ Don't call it directly, FastAPI will call it for you.
+
+ Read more about it in the
+ [FastAPI docs for Dependencies](https://fastapi.tiangolo.com/tutorial/dependencies/).
+
+ **Example**
+
+ ```python
+ from typing import Annotated
+
+ from fastapi import Depends, FastAPI
+
+ app = FastAPI()
+
+
+ async def common_parameters(q: str | None = None, skip: int = 0, limit: int = 100):
+ return {"q": q, "skip": skip, "limit": limit}
+
+
+ @app.get("/items/")
+ async def read_items(commons: Annotated[dict, Depends(common_parameters)]):
+ return commons
+ ```
+ """
+ return params.Depends(dependency=dependency, use_cache=use_cache)
+
+
+def Security( # noqa: N802
+ dependency: Annotated[
+ Optional[Callable[..., Any]],
+ Doc(
+ """
+ A "dependable" callable (like a function).
+
+ Don't call it directly, FastAPI will call it for you, just pass the object
+ directly.
+ """
+ ),
+ ] = None,
+ *,
+ scopes: Annotated[
+ Optional[Sequence[str]],
+ Doc(
+ """
+ OAuth2 scopes required for the *path operation* that uses this Security
+ dependency.
+
+ The term "scope" comes from the OAuth2 specification, it seems to be
+ intentionally vague and interpretable. It normally refers to permissions,
+ in cases to roles.
+
+ These scopes are integrated with OpenAPI (and the API docs at `/docs`).
+ So they are visible in the OpenAPI specification.
+ )
+ """
+ ),
+ ] = None,
+ use_cache: Annotated[
+ bool,
+ Doc(
+ """
+ By default, after a dependency is called the first time in a request, if
+ the dependency is declared again for the rest of the request (for example
+ if the dependency is needed by several dependencies), the value will be
+ re-used for the rest of the request.
+
+ Set `use_cache` to `False` to disable this behavior and ensure the
+ dependency is called again (if declared more than once) in the same request.
+ """
+ ),
+ ] = True,
+) -> Any:
+ """
+ Declare a FastAPI Security dependency.
+
+ The only difference with a regular dependency is that it can declare OAuth2
+ scopes that will be integrated with OpenAPI and the automatic UI docs (by default
+ at `/docs`).
+
+ It takes a single "dependable" callable (like a function).
+
+ Don't call it directly, FastAPI will call it for you.
+
+ Read more about it in the
+ [FastAPI docs for Security](https://fastapi.tiangolo.com/tutorial/security/) and
+ in the
+ [FastAPI docs for OAuth2 scopes](https://fastapi.tiangolo.com/advanced/security/oauth2-scopes/).
+
+ **Example**
+
+ ```python
+ from typing import Annotated
+
+ from fastapi import Security, FastAPI
+
+ from .db import User
+ from .security import get_current_active_user
+
+ app = FastAPI()
+
+ @app.get("/users/me/items/")
+ async def read_own_items(
+ current_user: Annotated[User, Security(get_current_active_user, scopes=["items"])]
+ ):
+ return [{"item_id": "Foo", "owner": current_user.username}]
+ ```
+ """
+ return params.Security(dependency=dependency, scopes=scopes, use_cache=use_cache)
diff --git a/venv/Lib/site-packages/fastapi/params.py b/venv/Lib/site-packages/fastapi/params.py
new file mode 100644
index 00000000..8f5601dd
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/params.py
@@ -0,0 +1,786 @@
+import warnings
+from enum import Enum
+from typing import Any, Callable, Dict, List, Optional, Sequence, Union
+
+from fastapi.openapi.models import Example
+from pydantic.fields import FieldInfo
+from typing_extensions import Annotated, deprecated
+
+from ._compat import (
+ PYDANTIC_V2,
+ PYDANTIC_VERSION_MINOR_TUPLE,
+ Undefined,
+)
+
+_Unset: Any = Undefined
+
+
+class ParamTypes(Enum):
+ query = "query"
+ header = "header"
+ path = "path"
+ cookie = "cookie"
+
+
+class Param(FieldInfo):
+ in_: ParamTypes
+
+ def __init__(
+ self,
+ default: Any = Undefined,
+ *,
+ default_factory: Union[Callable[[], Any], None] = _Unset,
+ annotation: Optional[Any] = None,
+ alias: Optional[str] = None,
+ alias_priority: Union[int, None] = _Unset,
+ # TODO: update when deprecating Pydantic v1, import these types
+ # validation_alias: str | AliasPath | AliasChoices | None
+ validation_alias: Union[str, None] = None,
+ serialization_alias: Union[str, None] = None,
+ title: Optional[str] = None,
+ description: Optional[str] = None,
+ gt: Optional[float] = None,
+ ge: Optional[float] = None,
+ lt: Optional[float] = None,
+ le: Optional[float] = None,
+ min_length: Optional[int] = None,
+ max_length: Optional[int] = None,
+ pattern: Optional[str] = None,
+ regex: Annotated[
+ Optional[str],
+ deprecated(
+ "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
+ ),
+ ] = None,
+ discriminator: Union[str, None] = None,
+ strict: Union[bool, None] = _Unset,
+ multiple_of: Union[float, None] = _Unset,
+ allow_inf_nan: Union[bool, None] = _Unset,
+ max_digits: Union[int, None] = _Unset,
+ decimal_places: Union[int, None] = _Unset,
+ examples: Optional[List[Any]] = None,
+ example: Annotated[
+ Optional[Any],
+ deprecated(
+ "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
+ "although still supported. Use examples instead."
+ ),
+ ] = _Unset,
+ openapi_examples: Optional[Dict[str, Example]] = None,
+ deprecated: Union[deprecated, str, bool, None] = None,
+ include_in_schema: bool = True,
+ json_schema_extra: Union[Dict[str, Any], None] = None,
+ **extra: Any,
+ ):
+ if example is not _Unset:
+ warnings.warn(
+ "`example` has been deprecated, please use `examples` instead",
+ category=DeprecationWarning,
+ stacklevel=4,
+ )
+ self.example = example
+ self.include_in_schema = include_in_schema
+ self.openapi_examples = openapi_examples
+ kwargs = dict(
+ default=default,
+ default_factory=default_factory,
+ alias=alias,
+ title=title,
+ description=description,
+ gt=gt,
+ ge=ge,
+ lt=lt,
+ le=le,
+ min_length=min_length,
+ max_length=max_length,
+ discriminator=discriminator,
+ multiple_of=multiple_of,
+ allow_inf_nan=allow_inf_nan,
+ max_digits=max_digits,
+ decimal_places=decimal_places,
+ **extra,
+ )
+ if examples is not None:
+ kwargs["examples"] = examples
+ if regex is not None:
+ warnings.warn(
+ "`regex` has been deprecated, please use `pattern` instead",
+ category=DeprecationWarning,
+ stacklevel=4,
+ )
+ current_json_schema_extra = json_schema_extra or extra
+ if PYDANTIC_VERSION_MINOR_TUPLE < (2, 7):
+ self.deprecated = deprecated
+ else:
+ kwargs["deprecated"] = deprecated
+ if PYDANTIC_V2:
+ kwargs.update(
+ {
+ "annotation": annotation,
+ "alias_priority": alias_priority,
+ "validation_alias": validation_alias,
+ "serialization_alias": serialization_alias,
+ "strict": strict,
+ "json_schema_extra": current_json_schema_extra,
+ }
+ )
+ kwargs["pattern"] = pattern or regex
+ else:
+ kwargs["regex"] = pattern or regex
+ kwargs.update(**current_json_schema_extra)
+ use_kwargs = {k: v for k, v in kwargs.items() if v is not _Unset}
+
+ super().__init__(**use_kwargs)
+
+ def __repr__(self) -> str:
+ return f"{self.__class__.__name__}({self.default})"
+
+
+class Path(Param):
+ in_ = ParamTypes.path
+
+ def __init__(
+ self,
+ default: Any = ...,
+ *,
+ default_factory: Union[Callable[[], Any], None] = _Unset,
+ annotation: Optional[Any] = None,
+ alias: Optional[str] = None,
+ alias_priority: Union[int, None] = _Unset,
+ # TODO: update when deprecating Pydantic v1, import these types
+ # validation_alias: str | AliasPath | AliasChoices | None
+ validation_alias: Union[str, None] = None,
+ serialization_alias: Union[str, None] = None,
+ title: Optional[str] = None,
+ description: Optional[str] = None,
+ gt: Optional[float] = None,
+ ge: Optional[float] = None,
+ lt: Optional[float] = None,
+ le: Optional[float] = None,
+ min_length: Optional[int] = None,
+ max_length: Optional[int] = None,
+ pattern: Optional[str] = None,
+ regex: Annotated[
+ Optional[str],
+ deprecated(
+ "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
+ ),
+ ] = None,
+ discriminator: Union[str, None] = None,
+ strict: Union[bool, None] = _Unset,
+ multiple_of: Union[float, None] = _Unset,
+ allow_inf_nan: Union[bool, None] = _Unset,
+ max_digits: Union[int, None] = _Unset,
+ decimal_places: Union[int, None] = _Unset,
+ examples: Optional[List[Any]] = None,
+ example: Annotated[
+ Optional[Any],
+ deprecated(
+ "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
+ "although still supported. Use examples instead."
+ ),
+ ] = _Unset,
+ openapi_examples: Optional[Dict[str, Example]] = None,
+ deprecated: Union[deprecated, str, bool, None] = None,
+ include_in_schema: bool = True,
+ json_schema_extra: Union[Dict[str, Any], None] = None,
+ **extra: Any,
+ ):
+ assert default is ..., "Path parameters cannot have a default value"
+ self.in_ = self.in_
+ super().__init__(
+ default=default,
+ default_factory=default_factory,
+ annotation=annotation,
+ alias=alias,
+ alias_priority=alias_priority,
+ validation_alias=validation_alias,
+ serialization_alias=serialization_alias,
+ title=title,
+ description=description,
+ gt=gt,
+ ge=ge,
+ lt=lt,
+ le=le,
+ min_length=min_length,
+ max_length=max_length,
+ pattern=pattern,
+ regex=regex,
+ discriminator=discriminator,
+ strict=strict,
+ multiple_of=multiple_of,
+ allow_inf_nan=allow_inf_nan,
+ max_digits=max_digits,
+ decimal_places=decimal_places,
+ deprecated=deprecated,
+ example=example,
+ examples=examples,
+ openapi_examples=openapi_examples,
+ include_in_schema=include_in_schema,
+ json_schema_extra=json_schema_extra,
+ **extra,
+ )
+
+
+class Query(Param):
+ in_ = ParamTypes.query
+
+ def __init__(
+ self,
+ default: Any = Undefined,
+ *,
+ default_factory: Union[Callable[[], Any], None] = _Unset,
+ annotation: Optional[Any] = None,
+ alias: Optional[str] = None,
+ alias_priority: Union[int, None] = _Unset,
+ # TODO: update when deprecating Pydantic v1, import these types
+ # validation_alias: str | AliasPath | AliasChoices | None
+ validation_alias: Union[str, None] = None,
+ serialization_alias: Union[str, None] = None,
+ title: Optional[str] = None,
+ description: Optional[str] = None,
+ gt: Optional[float] = None,
+ ge: Optional[float] = None,
+ lt: Optional[float] = None,
+ le: Optional[float] = None,
+ min_length: Optional[int] = None,
+ max_length: Optional[int] = None,
+ pattern: Optional[str] = None,
+ regex: Annotated[
+ Optional[str],
+ deprecated(
+ "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
+ ),
+ ] = None,
+ discriminator: Union[str, None] = None,
+ strict: Union[bool, None] = _Unset,
+ multiple_of: Union[float, None] = _Unset,
+ allow_inf_nan: Union[bool, None] = _Unset,
+ max_digits: Union[int, None] = _Unset,
+ decimal_places: Union[int, None] = _Unset,
+ examples: Optional[List[Any]] = None,
+ example: Annotated[
+ Optional[Any],
+ deprecated(
+ "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
+ "although still supported. Use examples instead."
+ ),
+ ] = _Unset,
+ openapi_examples: Optional[Dict[str, Example]] = None,
+ deprecated: Union[deprecated, str, bool, None] = None,
+ include_in_schema: bool = True,
+ json_schema_extra: Union[Dict[str, Any], None] = None,
+ **extra: Any,
+ ):
+ super().__init__(
+ default=default,
+ default_factory=default_factory,
+ annotation=annotation,
+ alias=alias,
+ alias_priority=alias_priority,
+ validation_alias=validation_alias,
+ serialization_alias=serialization_alias,
+ title=title,
+ description=description,
+ gt=gt,
+ ge=ge,
+ lt=lt,
+ le=le,
+ min_length=min_length,
+ max_length=max_length,
+ pattern=pattern,
+ regex=regex,
+ discriminator=discriminator,
+ strict=strict,
+ multiple_of=multiple_of,
+ allow_inf_nan=allow_inf_nan,
+ max_digits=max_digits,
+ decimal_places=decimal_places,
+ deprecated=deprecated,
+ example=example,
+ examples=examples,
+ openapi_examples=openapi_examples,
+ include_in_schema=include_in_schema,
+ json_schema_extra=json_schema_extra,
+ **extra,
+ )
+
+
+class Header(Param):
+ in_ = ParamTypes.header
+
+ def __init__(
+ self,
+ default: Any = Undefined,
+ *,
+ default_factory: Union[Callable[[], Any], None] = _Unset,
+ annotation: Optional[Any] = None,
+ alias: Optional[str] = None,
+ alias_priority: Union[int, None] = _Unset,
+ # TODO: update when deprecating Pydantic v1, import these types
+ # validation_alias: str | AliasPath | AliasChoices | None
+ validation_alias: Union[str, None] = None,
+ serialization_alias: Union[str, None] = None,
+ convert_underscores: bool = True,
+ title: Optional[str] = None,
+ description: Optional[str] = None,
+ gt: Optional[float] = None,
+ ge: Optional[float] = None,
+ lt: Optional[float] = None,
+ le: Optional[float] = None,
+ min_length: Optional[int] = None,
+ max_length: Optional[int] = None,
+ pattern: Optional[str] = None,
+ regex: Annotated[
+ Optional[str],
+ deprecated(
+ "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
+ ),
+ ] = None,
+ discriminator: Union[str, None] = None,
+ strict: Union[bool, None] = _Unset,
+ multiple_of: Union[float, None] = _Unset,
+ allow_inf_nan: Union[bool, None] = _Unset,
+ max_digits: Union[int, None] = _Unset,
+ decimal_places: Union[int, None] = _Unset,
+ examples: Optional[List[Any]] = None,
+ example: Annotated[
+ Optional[Any],
+ deprecated(
+ "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
+ "although still supported. Use examples instead."
+ ),
+ ] = _Unset,
+ openapi_examples: Optional[Dict[str, Example]] = None,
+ deprecated: Union[deprecated, str, bool, None] = None,
+ include_in_schema: bool = True,
+ json_schema_extra: Union[Dict[str, Any], None] = None,
+ **extra: Any,
+ ):
+ self.convert_underscores = convert_underscores
+ super().__init__(
+ default=default,
+ default_factory=default_factory,
+ annotation=annotation,
+ alias=alias,
+ alias_priority=alias_priority,
+ validation_alias=validation_alias,
+ serialization_alias=serialization_alias,
+ title=title,
+ description=description,
+ gt=gt,
+ ge=ge,
+ lt=lt,
+ le=le,
+ min_length=min_length,
+ max_length=max_length,
+ pattern=pattern,
+ regex=regex,
+ discriminator=discriminator,
+ strict=strict,
+ multiple_of=multiple_of,
+ allow_inf_nan=allow_inf_nan,
+ max_digits=max_digits,
+ decimal_places=decimal_places,
+ deprecated=deprecated,
+ example=example,
+ examples=examples,
+ openapi_examples=openapi_examples,
+ include_in_schema=include_in_schema,
+ json_schema_extra=json_schema_extra,
+ **extra,
+ )
+
+
+class Cookie(Param):
+ in_ = ParamTypes.cookie
+
+ def __init__(
+ self,
+ default: Any = Undefined,
+ *,
+ default_factory: Union[Callable[[], Any], None] = _Unset,
+ annotation: Optional[Any] = None,
+ alias: Optional[str] = None,
+ alias_priority: Union[int, None] = _Unset,
+ # TODO: update when deprecating Pydantic v1, import these types
+ # validation_alias: str | AliasPath | AliasChoices | None
+ validation_alias: Union[str, None] = None,
+ serialization_alias: Union[str, None] = None,
+ title: Optional[str] = None,
+ description: Optional[str] = None,
+ gt: Optional[float] = None,
+ ge: Optional[float] = None,
+ lt: Optional[float] = None,
+ le: Optional[float] = None,
+ min_length: Optional[int] = None,
+ max_length: Optional[int] = None,
+ pattern: Optional[str] = None,
+ regex: Annotated[
+ Optional[str],
+ deprecated(
+ "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
+ ),
+ ] = None,
+ discriminator: Union[str, None] = None,
+ strict: Union[bool, None] = _Unset,
+ multiple_of: Union[float, None] = _Unset,
+ allow_inf_nan: Union[bool, None] = _Unset,
+ max_digits: Union[int, None] = _Unset,
+ decimal_places: Union[int, None] = _Unset,
+ examples: Optional[List[Any]] = None,
+ example: Annotated[
+ Optional[Any],
+ deprecated(
+ "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
+ "although still supported. Use examples instead."
+ ),
+ ] = _Unset,
+ openapi_examples: Optional[Dict[str, Example]] = None,
+ deprecated: Union[deprecated, str, bool, None] = None,
+ include_in_schema: bool = True,
+ json_schema_extra: Union[Dict[str, Any], None] = None,
+ **extra: Any,
+ ):
+ super().__init__(
+ default=default,
+ default_factory=default_factory,
+ annotation=annotation,
+ alias=alias,
+ alias_priority=alias_priority,
+ validation_alias=validation_alias,
+ serialization_alias=serialization_alias,
+ title=title,
+ description=description,
+ gt=gt,
+ ge=ge,
+ lt=lt,
+ le=le,
+ min_length=min_length,
+ max_length=max_length,
+ pattern=pattern,
+ regex=regex,
+ discriminator=discriminator,
+ strict=strict,
+ multiple_of=multiple_of,
+ allow_inf_nan=allow_inf_nan,
+ max_digits=max_digits,
+ decimal_places=decimal_places,
+ deprecated=deprecated,
+ example=example,
+ examples=examples,
+ openapi_examples=openapi_examples,
+ include_in_schema=include_in_schema,
+ json_schema_extra=json_schema_extra,
+ **extra,
+ )
+
+
+class Body(FieldInfo):
+ def __init__(
+ self,
+ default: Any = Undefined,
+ *,
+ default_factory: Union[Callable[[], Any], None] = _Unset,
+ annotation: Optional[Any] = None,
+ embed: Union[bool, None] = None,
+ media_type: str = "application/json",
+ alias: Optional[str] = None,
+ alias_priority: Union[int, None] = _Unset,
+ # TODO: update when deprecating Pydantic v1, import these types
+ # validation_alias: str | AliasPath | AliasChoices | None
+ validation_alias: Union[str, None] = None,
+ serialization_alias: Union[str, None] = None,
+ title: Optional[str] = None,
+ description: Optional[str] = None,
+ gt: Optional[float] = None,
+ ge: Optional[float] = None,
+ lt: Optional[float] = None,
+ le: Optional[float] = None,
+ min_length: Optional[int] = None,
+ max_length: Optional[int] = None,
+ pattern: Optional[str] = None,
+ regex: Annotated[
+ Optional[str],
+ deprecated(
+ "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
+ ),
+ ] = None,
+ discriminator: Union[str, None] = None,
+ strict: Union[bool, None] = _Unset,
+ multiple_of: Union[float, None] = _Unset,
+ allow_inf_nan: Union[bool, None] = _Unset,
+ max_digits: Union[int, None] = _Unset,
+ decimal_places: Union[int, None] = _Unset,
+ examples: Optional[List[Any]] = None,
+ example: Annotated[
+ Optional[Any],
+ deprecated(
+ "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
+ "although still supported. Use examples instead."
+ ),
+ ] = _Unset,
+ openapi_examples: Optional[Dict[str, Example]] = None,
+ deprecated: Union[deprecated, str, bool, None] = None,
+ include_in_schema: bool = True,
+ json_schema_extra: Union[Dict[str, Any], None] = None,
+ **extra: Any,
+ ):
+ self.embed = embed
+ self.media_type = media_type
+ if example is not _Unset:
+ warnings.warn(
+ "`example` has been deprecated, please use `examples` instead",
+ category=DeprecationWarning,
+ stacklevel=4,
+ )
+ self.example = example
+ self.include_in_schema = include_in_schema
+ self.openapi_examples = openapi_examples
+ kwargs = dict(
+ default=default,
+ default_factory=default_factory,
+ alias=alias,
+ title=title,
+ description=description,
+ gt=gt,
+ ge=ge,
+ lt=lt,
+ le=le,
+ min_length=min_length,
+ max_length=max_length,
+ discriminator=discriminator,
+ multiple_of=multiple_of,
+ allow_inf_nan=allow_inf_nan,
+ max_digits=max_digits,
+ decimal_places=decimal_places,
+ **extra,
+ )
+ if examples is not None:
+ kwargs["examples"] = examples
+ if regex is not None:
+ warnings.warn(
+ "`regex` has been deprecated, please use `pattern` instead",
+ category=DeprecationWarning,
+ stacklevel=4,
+ )
+ current_json_schema_extra = json_schema_extra or extra
+ if PYDANTIC_VERSION_MINOR_TUPLE < (2, 7):
+ self.deprecated = deprecated
+ else:
+ kwargs["deprecated"] = deprecated
+ if PYDANTIC_V2:
+ kwargs.update(
+ {
+ "annotation": annotation,
+ "alias_priority": alias_priority,
+ "validation_alias": validation_alias,
+ "serialization_alias": serialization_alias,
+ "strict": strict,
+ "json_schema_extra": current_json_schema_extra,
+ }
+ )
+ kwargs["pattern"] = pattern or regex
+ else:
+ kwargs["regex"] = pattern or regex
+ kwargs.update(**current_json_schema_extra)
+
+ use_kwargs = {k: v for k, v in kwargs.items() if v is not _Unset}
+
+ super().__init__(**use_kwargs)
+
+ def __repr__(self) -> str:
+ return f"{self.__class__.__name__}({self.default})"
+
+
+class Form(Body):
+ def __init__(
+ self,
+ default: Any = Undefined,
+ *,
+ default_factory: Union[Callable[[], Any], None] = _Unset,
+ annotation: Optional[Any] = None,
+ media_type: str = "application/x-www-form-urlencoded",
+ alias: Optional[str] = None,
+ alias_priority: Union[int, None] = _Unset,
+ # TODO: update when deprecating Pydantic v1, import these types
+ # validation_alias: str | AliasPath | AliasChoices | None
+ validation_alias: Union[str, None] = None,
+ serialization_alias: Union[str, None] = None,
+ title: Optional[str] = None,
+ description: Optional[str] = None,
+ gt: Optional[float] = None,
+ ge: Optional[float] = None,
+ lt: Optional[float] = None,
+ le: Optional[float] = None,
+ min_length: Optional[int] = None,
+ max_length: Optional[int] = None,
+ pattern: Optional[str] = None,
+ regex: Annotated[
+ Optional[str],
+ deprecated(
+ "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
+ ),
+ ] = None,
+ discriminator: Union[str, None] = None,
+ strict: Union[bool, None] = _Unset,
+ multiple_of: Union[float, None] = _Unset,
+ allow_inf_nan: Union[bool, None] = _Unset,
+ max_digits: Union[int, None] = _Unset,
+ decimal_places: Union[int, None] = _Unset,
+ examples: Optional[List[Any]] = None,
+ example: Annotated[
+ Optional[Any],
+ deprecated(
+ "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
+ "although still supported. Use examples instead."
+ ),
+ ] = _Unset,
+ openapi_examples: Optional[Dict[str, Example]] = None,
+ deprecated: Union[deprecated, str, bool, None] = None,
+ include_in_schema: bool = True,
+ json_schema_extra: Union[Dict[str, Any], None] = None,
+ **extra: Any,
+ ):
+ super().__init__(
+ default=default,
+ default_factory=default_factory,
+ annotation=annotation,
+ media_type=media_type,
+ alias=alias,
+ alias_priority=alias_priority,
+ validation_alias=validation_alias,
+ serialization_alias=serialization_alias,
+ title=title,
+ description=description,
+ gt=gt,
+ ge=ge,
+ lt=lt,
+ le=le,
+ min_length=min_length,
+ max_length=max_length,
+ pattern=pattern,
+ regex=regex,
+ discriminator=discriminator,
+ strict=strict,
+ multiple_of=multiple_of,
+ allow_inf_nan=allow_inf_nan,
+ max_digits=max_digits,
+ decimal_places=decimal_places,
+ deprecated=deprecated,
+ example=example,
+ examples=examples,
+ openapi_examples=openapi_examples,
+ include_in_schema=include_in_schema,
+ json_schema_extra=json_schema_extra,
+ **extra,
+ )
+
+
+class File(Form):
+ def __init__(
+ self,
+ default: Any = Undefined,
+ *,
+ default_factory: Union[Callable[[], Any], None] = _Unset,
+ annotation: Optional[Any] = None,
+ media_type: str = "multipart/form-data",
+ alias: Optional[str] = None,
+ alias_priority: Union[int, None] = _Unset,
+ # TODO: update when deprecating Pydantic v1, import these types
+ # validation_alias: str | AliasPath | AliasChoices | None
+ validation_alias: Union[str, None] = None,
+ serialization_alias: Union[str, None] = None,
+ title: Optional[str] = None,
+ description: Optional[str] = None,
+ gt: Optional[float] = None,
+ ge: Optional[float] = None,
+ lt: Optional[float] = None,
+ le: Optional[float] = None,
+ min_length: Optional[int] = None,
+ max_length: Optional[int] = None,
+ pattern: Optional[str] = None,
+ regex: Annotated[
+ Optional[str],
+ deprecated(
+ "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
+ ),
+ ] = None,
+ discriminator: Union[str, None] = None,
+ strict: Union[bool, None] = _Unset,
+ multiple_of: Union[float, None] = _Unset,
+ allow_inf_nan: Union[bool, None] = _Unset,
+ max_digits: Union[int, None] = _Unset,
+ decimal_places: Union[int, None] = _Unset,
+ examples: Optional[List[Any]] = None,
+ example: Annotated[
+ Optional[Any],
+ deprecated(
+ "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
+ "although still supported. Use examples instead."
+ ),
+ ] = _Unset,
+ openapi_examples: Optional[Dict[str, Example]] = None,
+ deprecated: Union[deprecated, str, bool, None] = None,
+ include_in_schema: bool = True,
+ json_schema_extra: Union[Dict[str, Any], None] = None,
+ **extra: Any,
+ ):
+ super().__init__(
+ default=default,
+ default_factory=default_factory,
+ annotation=annotation,
+ media_type=media_type,
+ alias=alias,
+ alias_priority=alias_priority,
+ validation_alias=validation_alias,
+ serialization_alias=serialization_alias,
+ title=title,
+ description=description,
+ gt=gt,
+ ge=ge,
+ lt=lt,
+ le=le,
+ min_length=min_length,
+ max_length=max_length,
+ pattern=pattern,
+ regex=regex,
+ discriminator=discriminator,
+ strict=strict,
+ multiple_of=multiple_of,
+ allow_inf_nan=allow_inf_nan,
+ max_digits=max_digits,
+ decimal_places=decimal_places,
+ deprecated=deprecated,
+ example=example,
+ examples=examples,
+ openapi_examples=openapi_examples,
+ include_in_schema=include_in_schema,
+ json_schema_extra=json_schema_extra,
+ **extra,
+ )
+
+
+class Depends:
+ def __init__(
+ self, dependency: Optional[Callable[..., Any]] = None, *, use_cache: bool = True
+ ):
+ self.dependency = dependency
+ self.use_cache = use_cache
+
+ def __repr__(self) -> str:
+ attr = getattr(self.dependency, "__name__", type(self.dependency).__name__)
+ cache = "" if self.use_cache else ", use_cache=False"
+ return f"{self.__class__.__name__}({attr}{cache})"
+
+
+class Security(Depends):
+ def __init__(
+ self,
+ dependency: Optional[Callable[..., Any]] = None,
+ *,
+ scopes: Optional[Sequence[str]] = None,
+ use_cache: bool = True,
+ ):
+ super().__init__(dependency=dependency, use_cache=use_cache)
+ self.scopes = scopes or []
diff --git a/venv/Lib/site-packages/fastapi/py.typed b/venv/Lib/site-packages/fastapi/py.typed
new file mode 100644
index 00000000..e69de29b
diff --git a/venv/Lib/site-packages/fastapi/requests.py b/venv/Lib/site-packages/fastapi/requests.py
new file mode 100644
index 00000000..d16552c0
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/requests.py
@@ -0,0 +1,2 @@
+from starlette.requests import HTTPConnection as HTTPConnection # noqa: F401
+from starlette.requests import Request as Request # noqa: F401
diff --git a/venv/Lib/site-packages/fastapi/responses.py b/venv/Lib/site-packages/fastapi/responses.py
new file mode 100644
index 00000000..6c8db6f3
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/responses.py
@@ -0,0 +1,48 @@
+from typing import Any
+
+from starlette.responses import FileResponse as FileResponse # noqa
+from starlette.responses import HTMLResponse as HTMLResponse # noqa
+from starlette.responses import JSONResponse as JSONResponse # noqa
+from starlette.responses import PlainTextResponse as PlainTextResponse # noqa
+from starlette.responses import RedirectResponse as RedirectResponse # noqa
+from starlette.responses import Response as Response # noqa
+from starlette.responses import StreamingResponse as StreamingResponse # noqa
+
+try:
+ import ujson
+except ImportError: # pragma: nocover
+ ujson = None # type: ignore
+
+
+try:
+ import orjson
+except ImportError: # pragma: nocover
+ orjson = None # type: ignore
+
+
+class UJSONResponse(JSONResponse):
+ """
+ JSON response using the high-performance ujson library to serialize data to JSON.
+
+ Read more about it in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/).
+ """
+
+ def render(self, content: Any) -> bytes:
+ assert ujson is not None, "ujson must be installed to use UJSONResponse"
+ return ujson.dumps(content, ensure_ascii=False).encode("utf-8")
+
+
+class ORJSONResponse(JSONResponse):
+ """
+ JSON response using the high-performance orjson library to serialize data to JSON.
+
+ Read more about it in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/).
+ """
+
+ def render(self, content: Any) -> bytes:
+ assert orjson is not None, "orjson must be installed to use ORJSONResponse"
+ return orjson.dumps(
+ content, option=orjson.OPT_NON_STR_KEYS | orjson.OPT_SERIALIZE_NUMPY
+ )
diff --git a/venv/Lib/site-packages/fastapi/routing.py b/venv/Lib/site-packages/fastapi/routing.py
new file mode 100644
index 00000000..bf61a65c
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/routing.py
@@ -0,0 +1,4439 @@
+import asyncio
+import dataclasses
+import email.message
+import inspect
+import json
+from contextlib import AsyncExitStack, asynccontextmanager
+from enum import Enum, IntEnum
+from typing import (
+ Any,
+ AsyncIterator,
+ Callable,
+ Coroutine,
+ Dict,
+ List,
+ Mapping,
+ Optional,
+ Sequence,
+ Set,
+ Tuple,
+ Type,
+ Union,
+)
+
+from fastapi import params
+from fastapi._compat import (
+ ModelField,
+ Undefined,
+ _get_model_config,
+ _model_dump,
+ _normalize_errors,
+ lenient_issubclass,
+)
+from fastapi.datastructures import Default, DefaultPlaceholder
+from fastapi.dependencies.models import Dependant
+from fastapi.dependencies.utils import (
+ _should_embed_body_fields,
+ get_body_field,
+ get_dependant,
+ get_flat_dependant,
+ get_parameterless_sub_dependant,
+ get_typed_return_annotation,
+ solve_dependencies,
+)
+from fastapi.encoders import jsonable_encoder
+from fastapi.exceptions import (
+ FastAPIError,
+ RequestValidationError,
+ ResponseValidationError,
+ WebSocketRequestValidationError,
+)
+from fastapi.types import DecoratedCallable, IncEx
+from fastapi.utils import (
+ create_cloned_field,
+ create_model_field,
+ generate_unique_id,
+ get_value_or_default,
+ is_body_allowed_for_status_code,
+)
+from pydantic import BaseModel
+from starlette import routing
+from starlette.concurrency import run_in_threadpool
+from starlette.exceptions import HTTPException
+from starlette.requests import Request
+from starlette.responses import JSONResponse, Response
+from starlette.routing import (
+ BaseRoute,
+ Match,
+ compile_path,
+ get_name,
+ request_response,
+ websocket_session,
+)
+from starlette.routing import Mount as Mount # noqa
+from starlette.types import AppType, ASGIApp, Lifespan, Scope
+from starlette.websockets import WebSocket
+from typing_extensions import Annotated, Doc, deprecated
+
+
+def _prepare_response_content(
+ res: Any,
+ *,
+ exclude_unset: bool,
+ exclude_defaults: bool = False,
+ exclude_none: bool = False,
+) -> Any:
+ if isinstance(res, BaseModel):
+ read_with_orm_mode = getattr(_get_model_config(res), "read_with_orm_mode", None)
+ if read_with_orm_mode:
+ # Let from_orm extract the data from this model instead of converting
+ # it now to a dict.
+ # Otherwise, there's no way to extract lazy data that requires attribute
+ # access instead of dict iteration, e.g. lazy relationships.
+ return res
+ return _model_dump(
+ res,
+ by_alias=True,
+ exclude_unset=exclude_unset,
+ exclude_defaults=exclude_defaults,
+ exclude_none=exclude_none,
+ )
+ elif isinstance(res, list):
+ return [
+ _prepare_response_content(
+ item,
+ exclude_unset=exclude_unset,
+ exclude_defaults=exclude_defaults,
+ exclude_none=exclude_none,
+ )
+ for item in res
+ ]
+ elif isinstance(res, dict):
+ return {
+ k: _prepare_response_content(
+ v,
+ exclude_unset=exclude_unset,
+ exclude_defaults=exclude_defaults,
+ exclude_none=exclude_none,
+ )
+ for k, v in res.items()
+ }
+ elif dataclasses.is_dataclass(res):
+ return dataclasses.asdict(res)
+ return res
+
+
+def _merge_lifespan_context(
+ original_context: Lifespan[Any], nested_context: Lifespan[Any]
+) -> Lifespan[Any]:
+ @asynccontextmanager
+ async def merged_lifespan(
+ app: AppType,
+ ) -> AsyncIterator[Optional[Mapping[str, Any]]]:
+ async with original_context(app) as maybe_original_state:
+ async with nested_context(app) as maybe_nested_state:
+ if maybe_nested_state is None and maybe_original_state is None:
+ yield None # old ASGI compatibility
+ else:
+ yield {**(maybe_nested_state or {}), **(maybe_original_state or {})}
+
+ return merged_lifespan # type: ignore[return-value]
+
+
+async def serialize_response(
+ *,
+ field: Optional[ModelField] = None,
+ response_content: Any,
+ include: Optional[IncEx] = None,
+ exclude: Optional[IncEx] = None,
+ by_alias: bool = True,
+ exclude_unset: bool = False,
+ exclude_defaults: bool = False,
+ exclude_none: bool = False,
+ is_coroutine: bool = True,
+) -> Any:
+ if field:
+ errors = []
+ if not hasattr(field, "serialize"):
+ # pydantic v1
+ response_content = _prepare_response_content(
+ response_content,
+ exclude_unset=exclude_unset,
+ exclude_defaults=exclude_defaults,
+ exclude_none=exclude_none,
+ )
+ if is_coroutine:
+ value, errors_ = field.validate(response_content, {}, loc=("response",))
+ else:
+ value, errors_ = await run_in_threadpool(
+ field.validate, response_content, {}, loc=("response",)
+ )
+ if isinstance(errors_, list):
+ errors.extend(errors_)
+ elif errors_:
+ errors.append(errors_)
+ if errors:
+ raise ResponseValidationError(
+ errors=_normalize_errors(errors), body=response_content
+ )
+
+ if hasattr(field, "serialize"):
+ return field.serialize(
+ value,
+ include=include,
+ exclude=exclude,
+ by_alias=by_alias,
+ exclude_unset=exclude_unset,
+ exclude_defaults=exclude_defaults,
+ exclude_none=exclude_none,
+ )
+
+ return jsonable_encoder(
+ value,
+ include=include,
+ exclude=exclude,
+ by_alias=by_alias,
+ exclude_unset=exclude_unset,
+ exclude_defaults=exclude_defaults,
+ exclude_none=exclude_none,
+ )
+ else:
+ return jsonable_encoder(response_content)
+
+
+async def run_endpoint_function(
+ *, dependant: Dependant, values: Dict[str, Any], is_coroutine: bool
+) -> Any:
+ # Only called by get_request_handler. Has been split into its own function to
+ # facilitate profiling endpoints, since inner functions are harder to profile.
+ assert dependant.call is not None, "dependant.call must be a function"
+
+ if is_coroutine:
+ return await dependant.call(**values)
+ else:
+ return await run_in_threadpool(dependant.call, **values)
+
+
+def get_request_handler(
+ dependant: Dependant,
+ body_field: Optional[ModelField] = None,
+ status_code: Optional[int] = None,
+ response_class: Union[Type[Response], DefaultPlaceholder] = Default(JSONResponse),
+ response_field: Optional[ModelField] = None,
+ response_model_include: Optional[IncEx] = None,
+ response_model_exclude: Optional[IncEx] = None,
+ response_model_by_alias: bool = True,
+ response_model_exclude_unset: bool = False,
+ response_model_exclude_defaults: bool = False,
+ response_model_exclude_none: bool = False,
+ dependency_overrides_provider: Optional[Any] = None,
+ embed_body_fields: bool = False,
+) -> Callable[[Request], Coroutine[Any, Any, Response]]:
+ assert dependant.call is not None, "dependant.call must be a function"
+ is_coroutine = asyncio.iscoroutinefunction(dependant.call)
+ is_body_form = body_field and isinstance(body_field.field_info, params.Form)
+ if isinstance(response_class, DefaultPlaceholder):
+ actual_response_class: Type[Response] = response_class.value
+ else:
+ actual_response_class = response_class
+
+ async def app(request: Request) -> Response:
+ response: Union[Response, None] = None
+ async with AsyncExitStack() as file_stack:
+ try:
+ body: Any = None
+ if body_field:
+ if is_body_form:
+ body = await request.form()
+ file_stack.push_async_callback(body.close)
+ else:
+ body_bytes = await request.body()
+ if body_bytes:
+ json_body: Any = Undefined
+ content_type_value = request.headers.get("content-type")
+ if not content_type_value:
+ json_body = await request.json()
+ else:
+ message = email.message.Message()
+ message["content-type"] = content_type_value
+ if message.get_content_maintype() == "application":
+ subtype = message.get_content_subtype()
+ if subtype == "json" or subtype.endswith("+json"):
+ json_body = await request.json()
+ if json_body != Undefined:
+ body = json_body
+ else:
+ body = body_bytes
+ except json.JSONDecodeError as e:
+ validation_error = RequestValidationError(
+ [
+ {
+ "type": "json_invalid",
+ "loc": ("body", e.pos),
+ "msg": "JSON decode error",
+ "input": {},
+ "ctx": {"error": e.msg},
+ }
+ ],
+ body=e.doc,
+ )
+ raise validation_error from e
+ except HTTPException:
+ # If a middleware raises an HTTPException, it should be raised again
+ raise
+ except Exception as e:
+ http_error = HTTPException(
+ status_code=400, detail="There was an error parsing the body"
+ )
+ raise http_error from e
+ errors: List[Any] = []
+ async with AsyncExitStack() as async_exit_stack:
+ solved_result = await solve_dependencies(
+ request=request,
+ dependant=dependant,
+ body=body,
+ dependency_overrides_provider=dependency_overrides_provider,
+ async_exit_stack=async_exit_stack,
+ embed_body_fields=embed_body_fields,
+ )
+ errors = solved_result.errors
+ if not errors:
+ raw_response = await run_endpoint_function(
+ dependant=dependant,
+ values=solved_result.values,
+ is_coroutine=is_coroutine,
+ )
+ if isinstance(raw_response, Response):
+ if raw_response.background is None:
+ raw_response.background = solved_result.background_tasks
+ response = raw_response
+ else:
+ response_args: Dict[str, Any] = {
+ "background": solved_result.background_tasks
+ }
+ # If status_code was set, use it, otherwise use the default from the
+ # response class, in the case of redirect it's 307
+ current_status_code = (
+ status_code
+ if status_code
+ else solved_result.response.status_code
+ )
+ if current_status_code is not None:
+ response_args["status_code"] = current_status_code
+ if solved_result.response.status_code:
+ response_args["status_code"] = (
+ solved_result.response.status_code
+ )
+ content = await serialize_response(
+ field=response_field,
+ response_content=raw_response,
+ include=response_model_include,
+ exclude=response_model_exclude,
+ by_alias=response_model_by_alias,
+ exclude_unset=response_model_exclude_unset,
+ exclude_defaults=response_model_exclude_defaults,
+ exclude_none=response_model_exclude_none,
+ is_coroutine=is_coroutine,
+ )
+ response = actual_response_class(content, **response_args)
+ if not is_body_allowed_for_status_code(response.status_code):
+ response.body = b""
+ response.headers.raw.extend(solved_result.response.headers.raw)
+ if errors:
+ validation_error = RequestValidationError(
+ _normalize_errors(errors), body=body
+ )
+ raise validation_error
+ if response is None:
+ raise FastAPIError(
+ "No response object was returned. There's a high chance that the "
+ "application code is raising an exception and a dependency with yield "
+ "has a block with a bare except, or a block with except Exception, "
+ "and is not raising the exception again. Read more about it in the "
+ "docs: https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-with-yield/#dependencies-with-yield-and-except"
+ )
+ return response
+
+ return app
+
+
+def get_websocket_app(
+ dependant: Dependant,
+ dependency_overrides_provider: Optional[Any] = None,
+ embed_body_fields: bool = False,
+) -> Callable[[WebSocket], Coroutine[Any, Any, Any]]:
+ async def app(websocket: WebSocket) -> None:
+ async with AsyncExitStack() as async_exit_stack:
+ # TODO: remove this scope later, after a few releases
+ # This scope fastapi_astack is no longer used by FastAPI, kept for
+ # compatibility, just in case
+ websocket.scope["fastapi_astack"] = async_exit_stack
+ solved_result = await solve_dependencies(
+ request=websocket,
+ dependant=dependant,
+ dependency_overrides_provider=dependency_overrides_provider,
+ async_exit_stack=async_exit_stack,
+ embed_body_fields=embed_body_fields,
+ )
+ if solved_result.errors:
+ raise WebSocketRequestValidationError(
+ _normalize_errors(solved_result.errors)
+ )
+ assert dependant.call is not None, "dependant.call must be a function"
+ await dependant.call(**solved_result.values)
+
+ return app
+
+
+class APIWebSocketRoute(routing.WebSocketRoute):
+ def __init__(
+ self,
+ path: str,
+ endpoint: Callable[..., Any],
+ *,
+ name: Optional[str] = None,
+ dependencies: Optional[Sequence[params.Depends]] = None,
+ dependency_overrides_provider: Optional[Any] = None,
+ ) -> None:
+ self.path = path
+ self.endpoint = endpoint
+ self.name = get_name(endpoint) if name is None else name
+ self.dependencies = list(dependencies or [])
+ self.path_regex, self.path_format, self.param_convertors = compile_path(path)
+ self.dependant = get_dependant(path=self.path_format, call=self.endpoint)
+ for depends in self.dependencies[::-1]:
+ self.dependant.dependencies.insert(
+ 0,
+ get_parameterless_sub_dependant(depends=depends, path=self.path_format),
+ )
+ self._flat_dependant = get_flat_dependant(self.dependant)
+ self._embed_body_fields = _should_embed_body_fields(
+ self._flat_dependant.body_params
+ )
+ self.app = websocket_session(
+ get_websocket_app(
+ dependant=self.dependant,
+ dependency_overrides_provider=dependency_overrides_provider,
+ embed_body_fields=self._embed_body_fields,
+ )
+ )
+
+ def matches(self, scope: Scope) -> Tuple[Match, Scope]:
+ match, child_scope = super().matches(scope)
+ if match != Match.NONE:
+ child_scope["route"] = self
+ return match, child_scope
+
+
+class APIRoute(routing.Route):
+ def __init__(
+ self,
+ path: str,
+ endpoint: Callable[..., Any],
+ *,
+ response_model: Any = Default(None),
+ status_code: Optional[int] = None,
+ tags: Optional[List[Union[str, Enum]]] = None,
+ dependencies: Optional[Sequence[params.Depends]] = None,
+ summary: Optional[str] = None,
+ description: Optional[str] = None,
+ response_description: str = "Successful Response",
+ responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
+ deprecated: Optional[bool] = None,
+ name: Optional[str] = None,
+ methods: Optional[Union[Set[str], List[str]]] = None,
+ operation_id: Optional[str] = None,
+ response_model_include: Optional[IncEx] = None,
+ response_model_exclude: Optional[IncEx] = None,
+ response_model_by_alias: bool = True,
+ response_model_exclude_unset: bool = False,
+ response_model_exclude_defaults: bool = False,
+ response_model_exclude_none: bool = False,
+ include_in_schema: bool = True,
+ response_class: Union[Type[Response], DefaultPlaceholder] = Default(
+ JSONResponse
+ ),
+ dependency_overrides_provider: Optional[Any] = None,
+ callbacks: Optional[List[BaseRoute]] = None,
+ openapi_extra: Optional[Dict[str, Any]] = None,
+ generate_unique_id_function: Union[
+ Callable[["APIRoute"], str], DefaultPlaceholder
+ ] = Default(generate_unique_id),
+ ) -> None:
+ self.path = path
+ self.endpoint = endpoint
+ if isinstance(response_model, DefaultPlaceholder):
+ return_annotation = get_typed_return_annotation(endpoint)
+ if lenient_issubclass(return_annotation, Response):
+ response_model = None
+ else:
+ response_model = return_annotation
+ self.response_model = response_model
+ self.summary = summary
+ self.response_description = response_description
+ self.deprecated = deprecated
+ self.operation_id = operation_id
+ self.response_model_include = response_model_include
+ self.response_model_exclude = response_model_exclude
+ self.response_model_by_alias = response_model_by_alias
+ self.response_model_exclude_unset = response_model_exclude_unset
+ self.response_model_exclude_defaults = response_model_exclude_defaults
+ self.response_model_exclude_none = response_model_exclude_none
+ self.include_in_schema = include_in_schema
+ self.response_class = response_class
+ self.dependency_overrides_provider = dependency_overrides_provider
+ self.callbacks = callbacks
+ self.openapi_extra = openapi_extra
+ self.generate_unique_id_function = generate_unique_id_function
+ self.tags = tags or []
+ self.responses = responses or {}
+ self.name = get_name(endpoint) if name is None else name
+ self.path_regex, self.path_format, self.param_convertors = compile_path(path)
+ if methods is None:
+ methods = ["GET"]
+ self.methods: Set[str] = {method.upper() for method in methods}
+ if isinstance(generate_unique_id_function, DefaultPlaceholder):
+ current_generate_unique_id: Callable[[APIRoute], str] = (
+ generate_unique_id_function.value
+ )
+ else:
+ current_generate_unique_id = generate_unique_id_function
+ self.unique_id = self.operation_id or current_generate_unique_id(self)
+ # normalize enums e.g. http.HTTPStatus
+ if isinstance(status_code, IntEnum):
+ status_code = int(status_code)
+ self.status_code = status_code
+ if self.response_model:
+ assert is_body_allowed_for_status_code(status_code), (
+ f"Status code {status_code} must not have a response body"
+ )
+ response_name = "Response_" + self.unique_id
+ self.response_field = create_model_field(
+ name=response_name,
+ type_=self.response_model,
+ mode="serialization",
+ )
+ # Create a clone of the field, so that a Pydantic submodel is not returned
+ # as is just because it's an instance of a subclass of a more limited class
+ # e.g. UserInDB (containing hashed_password) could be a subclass of User
+ # that doesn't have the hashed_password. But because it's a subclass, it
+ # would pass the validation and be returned as is.
+ # By being a new field, no inheritance will be passed as is. A new model
+ # will always be created.
+ # TODO: remove when deprecating Pydantic v1
+ self.secure_cloned_response_field: Optional[ModelField] = (
+ create_cloned_field(self.response_field)
+ )
+ else:
+ self.response_field = None # type: ignore
+ self.secure_cloned_response_field = None
+ self.dependencies = list(dependencies or [])
+ self.description = description or inspect.cleandoc(self.endpoint.__doc__ or "")
+ # if a "form feed" character (page break) is found in the description text,
+ # truncate description text to the content preceding the first "form feed"
+ self.description = self.description.split("\f")[0].strip()
+ response_fields = {}
+ for additional_status_code, response in self.responses.items():
+ assert isinstance(response, dict), "An additional response must be a dict"
+ model = response.get("model")
+ if model:
+ assert is_body_allowed_for_status_code(additional_status_code), (
+ f"Status code {additional_status_code} must not have a response body"
+ )
+ response_name = f"Response_{additional_status_code}_{self.unique_id}"
+ response_field = create_model_field(
+ name=response_name, type_=model, mode="serialization"
+ )
+ response_fields[additional_status_code] = response_field
+ if response_fields:
+ self.response_fields: Dict[Union[int, str], ModelField] = response_fields
+ else:
+ self.response_fields = {}
+
+ assert callable(endpoint), "An endpoint must be a callable"
+ self.dependant = get_dependant(path=self.path_format, call=self.endpoint)
+ for depends in self.dependencies[::-1]:
+ self.dependant.dependencies.insert(
+ 0,
+ get_parameterless_sub_dependant(depends=depends, path=self.path_format),
+ )
+ self._flat_dependant = get_flat_dependant(self.dependant)
+ self._embed_body_fields = _should_embed_body_fields(
+ self._flat_dependant.body_params
+ )
+ self.body_field = get_body_field(
+ flat_dependant=self._flat_dependant,
+ name=self.unique_id,
+ embed_body_fields=self._embed_body_fields,
+ )
+ self.app = request_response(self.get_route_handler())
+
+ def get_route_handler(self) -> Callable[[Request], Coroutine[Any, Any, Response]]:
+ return get_request_handler(
+ dependant=self.dependant,
+ body_field=self.body_field,
+ status_code=self.status_code,
+ response_class=self.response_class,
+ response_field=self.secure_cloned_response_field,
+ response_model_include=self.response_model_include,
+ response_model_exclude=self.response_model_exclude,
+ response_model_by_alias=self.response_model_by_alias,
+ response_model_exclude_unset=self.response_model_exclude_unset,
+ response_model_exclude_defaults=self.response_model_exclude_defaults,
+ response_model_exclude_none=self.response_model_exclude_none,
+ dependency_overrides_provider=self.dependency_overrides_provider,
+ embed_body_fields=self._embed_body_fields,
+ )
+
+ def matches(self, scope: Scope) -> Tuple[Match, Scope]:
+ match, child_scope = super().matches(scope)
+ if match != Match.NONE:
+ child_scope["route"] = self
+ return match, child_scope
+
+
+class APIRouter(routing.Router):
+ """
+ `APIRouter` class, used to group *path operations*, for example to structure
+ an app in multiple files. It would then be included in the `FastAPI` app, or
+ in another `APIRouter` (ultimately included in the app).
+
+ Read more about it in the
+ [FastAPI docs for Bigger Applications - Multiple Files](https://fastapi.tiangolo.com/tutorial/bigger-applications/).
+
+ ## Example
+
+ ```python
+ from fastapi import APIRouter, FastAPI
+
+ app = FastAPI()
+ router = APIRouter()
+
+
+ @router.get("/users/", tags=["users"])
+ async def read_users():
+ return [{"username": "Rick"}, {"username": "Morty"}]
+
+
+ app.include_router(router)
+ ```
+ """
+
+ def __init__(
+ self,
+ *,
+ prefix: Annotated[str, Doc("An optional path prefix for the router.")] = "",
+ tags: Annotated[
+ Optional[List[Union[str, Enum]]],
+ Doc(
+ """
+ A list of tags to be applied to all the *path operations* in this
+ router.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[params.Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be applied to all the
+ *path operations* in this router.
+
+ Read more about it in the
+ [FastAPI docs for Bigger Applications - Multiple Files](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies).
+ """
+ ),
+ ] = None,
+ default_response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ The default response class to be used.
+
+ Read more in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#default-response-class).
+ """
+ ),
+ ] = Default(JSONResponse),
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses to be shown in OpenAPI.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Additional Responses in OpenAPI](https://fastapi.tiangolo.com/advanced/additional-responses/).
+
+ And in the
+ [FastAPI docs for Bigger Applications](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies).
+ """
+ ),
+ ] = None,
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ OpenAPI callbacks that should apply to all *path operations* in this
+ router.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ routes: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ **Note**: you probably shouldn't use this parameter, it is inherited
+ from Starlette and supported for compatibility.
+
+ ---
+
+ A list of routes to serve incoming HTTP and WebSocket requests.
+ """
+ ),
+ deprecated(
+ """
+ You normally wouldn't use this parameter with FastAPI, it is inherited
+ from Starlette and supported for compatibility.
+
+ In FastAPI, you normally would use the *path operation methods*,
+ like `router.get()`, `router.post()`, etc.
+ """
+ ),
+ ] = None,
+ redirect_slashes: Annotated[
+ bool,
+ Doc(
+ """
+ Whether to detect and redirect slashes in URLs when the client doesn't
+ use the same format.
+ """
+ ),
+ ] = True,
+ default: Annotated[
+ Optional[ASGIApp],
+ Doc(
+ """
+ Default function handler for this router. Used to handle
+ 404 Not Found errors.
+ """
+ ),
+ ] = None,
+ dependency_overrides_provider: Annotated[
+ Optional[Any],
+ Doc(
+ """
+ Only used internally by FastAPI to handle dependency overrides.
+
+ You shouldn't need to use it. It normally points to the `FastAPI` app
+ object.
+ """
+ ),
+ ] = None,
+ route_class: Annotated[
+ Type[APIRoute],
+ Doc(
+ """
+ Custom route (*path operation*) class to be used by this router.
+
+ Read more about it in the
+ [FastAPI docs for Custom Request and APIRoute class](https://fastapi.tiangolo.com/how-to/custom-request-and-route/#custom-apiroute-class-in-a-router).
+ """
+ ),
+ ] = APIRoute,
+ on_startup: Annotated[
+ Optional[Sequence[Callable[[], Any]]],
+ Doc(
+ """
+ A list of startup event handler functions.
+
+ You should instead use the `lifespan` handlers.
+
+ Read more in the [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/).
+ """
+ ),
+ ] = None,
+ on_shutdown: Annotated[
+ Optional[Sequence[Callable[[], Any]]],
+ Doc(
+ """
+ A list of shutdown event handler functions.
+
+ You should instead use the `lifespan` handlers.
+
+ Read more in the
+ [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/).
+ """
+ ),
+ ] = None,
+ # the generic to Lifespan[AppType] is the type of the top level application
+ # which the router cannot know statically, so we use typing.Any
+ lifespan: Annotated[
+ Optional[Lifespan[Any]],
+ Doc(
+ """
+ A `Lifespan` context manager handler. This replaces `startup` and
+ `shutdown` functions with a single context manager.
+
+ Read more in the
+ [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark all *path operations* in this router as deprecated.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ To include (or not) all the *path operations* in this router in the
+ generated OpenAPI.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-parameters-from-openapi).
+ """
+ ),
+ ] = True,
+ generate_unique_id_function: Annotated[
+ Callable[[APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
+ ) -> None:
+ super().__init__(
+ routes=routes,
+ redirect_slashes=redirect_slashes,
+ default=default,
+ on_startup=on_startup,
+ on_shutdown=on_shutdown,
+ lifespan=lifespan,
+ )
+ if prefix:
+ assert prefix.startswith("/"), "A path prefix must start with '/'"
+ assert not prefix.endswith("/"), (
+ "A path prefix must not end with '/', as the routes will start with '/'"
+ )
+ self.prefix = prefix
+ self.tags: List[Union[str, Enum]] = tags or []
+ self.dependencies = list(dependencies or [])
+ self.deprecated = deprecated
+ self.include_in_schema = include_in_schema
+ self.responses = responses or {}
+ self.callbacks = callbacks or []
+ self.dependency_overrides_provider = dependency_overrides_provider
+ self.route_class = route_class
+ self.default_response_class = default_response_class
+ self.generate_unique_id_function = generate_unique_id_function
+
+ def route(
+ self,
+ path: str,
+ methods: Optional[List[str]] = None,
+ name: Optional[str] = None,
+ include_in_schema: bool = True,
+ ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ def decorator(func: DecoratedCallable) -> DecoratedCallable:
+ self.add_route(
+ path,
+ func,
+ methods=methods,
+ name=name,
+ include_in_schema=include_in_schema,
+ )
+ return func
+
+ return decorator
+
+ def add_api_route(
+ self,
+ path: str,
+ endpoint: Callable[..., Any],
+ *,
+ response_model: Any = Default(None),
+ status_code: Optional[int] = None,
+ tags: Optional[List[Union[str, Enum]]] = None,
+ dependencies: Optional[Sequence[params.Depends]] = None,
+ summary: Optional[str] = None,
+ description: Optional[str] = None,
+ response_description: str = "Successful Response",
+ responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
+ deprecated: Optional[bool] = None,
+ methods: Optional[Union[Set[str], List[str]]] = None,
+ operation_id: Optional[str] = None,
+ response_model_include: Optional[IncEx] = None,
+ response_model_exclude: Optional[IncEx] = None,
+ response_model_by_alias: bool = True,
+ response_model_exclude_unset: bool = False,
+ response_model_exclude_defaults: bool = False,
+ response_model_exclude_none: bool = False,
+ include_in_schema: bool = True,
+ response_class: Union[Type[Response], DefaultPlaceholder] = Default(
+ JSONResponse
+ ),
+ name: Optional[str] = None,
+ route_class_override: Optional[Type[APIRoute]] = None,
+ callbacks: Optional[List[BaseRoute]] = None,
+ openapi_extra: Optional[Dict[str, Any]] = None,
+ generate_unique_id_function: Union[
+ Callable[[APIRoute], str], DefaultPlaceholder
+ ] = Default(generate_unique_id),
+ ) -> None:
+ route_class = route_class_override or self.route_class
+ responses = responses or {}
+ combined_responses = {**self.responses, **responses}
+ current_response_class = get_value_or_default(
+ response_class, self.default_response_class
+ )
+ current_tags = self.tags.copy()
+ if tags:
+ current_tags.extend(tags)
+ current_dependencies = self.dependencies.copy()
+ if dependencies:
+ current_dependencies.extend(dependencies)
+ current_callbacks = self.callbacks.copy()
+ if callbacks:
+ current_callbacks.extend(callbacks)
+ current_generate_unique_id = get_value_or_default(
+ generate_unique_id_function, self.generate_unique_id_function
+ )
+ route = route_class(
+ self.prefix + path,
+ endpoint=endpoint,
+ response_model=response_model,
+ status_code=status_code,
+ tags=current_tags,
+ dependencies=current_dependencies,
+ summary=summary,
+ description=description,
+ response_description=response_description,
+ responses=combined_responses,
+ deprecated=deprecated or self.deprecated,
+ methods=methods,
+ operation_id=operation_id,
+ response_model_include=response_model_include,
+ response_model_exclude=response_model_exclude,
+ response_model_by_alias=response_model_by_alias,
+ response_model_exclude_unset=response_model_exclude_unset,
+ response_model_exclude_defaults=response_model_exclude_defaults,
+ response_model_exclude_none=response_model_exclude_none,
+ include_in_schema=include_in_schema and self.include_in_schema,
+ response_class=current_response_class,
+ name=name,
+ dependency_overrides_provider=self.dependency_overrides_provider,
+ callbacks=current_callbacks,
+ openapi_extra=openapi_extra,
+ generate_unique_id_function=current_generate_unique_id,
+ )
+ self.routes.append(route)
+
+ def api_route(
+ self,
+ path: str,
+ *,
+ response_model: Any = Default(None),
+ status_code: Optional[int] = None,
+ tags: Optional[List[Union[str, Enum]]] = None,
+ dependencies: Optional[Sequence[params.Depends]] = None,
+ summary: Optional[str] = None,
+ description: Optional[str] = None,
+ response_description: str = "Successful Response",
+ responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
+ deprecated: Optional[bool] = None,
+ methods: Optional[List[str]] = None,
+ operation_id: Optional[str] = None,
+ response_model_include: Optional[IncEx] = None,
+ response_model_exclude: Optional[IncEx] = None,
+ response_model_by_alias: bool = True,
+ response_model_exclude_unset: bool = False,
+ response_model_exclude_defaults: bool = False,
+ response_model_exclude_none: bool = False,
+ include_in_schema: bool = True,
+ response_class: Type[Response] = Default(JSONResponse),
+ name: Optional[str] = None,
+ callbacks: Optional[List[BaseRoute]] = None,
+ openapi_extra: Optional[Dict[str, Any]] = None,
+ generate_unique_id_function: Callable[[APIRoute], str] = Default(
+ generate_unique_id
+ ),
+ ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ def decorator(func: DecoratedCallable) -> DecoratedCallable:
+ self.add_api_route(
+ path,
+ func,
+ response_model=response_model,
+ status_code=status_code,
+ tags=tags,
+ dependencies=dependencies,
+ summary=summary,
+ description=description,
+ response_description=response_description,
+ responses=responses,
+ deprecated=deprecated,
+ methods=methods,
+ operation_id=operation_id,
+ response_model_include=response_model_include,
+ response_model_exclude=response_model_exclude,
+ response_model_by_alias=response_model_by_alias,
+ response_model_exclude_unset=response_model_exclude_unset,
+ response_model_exclude_defaults=response_model_exclude_defaults,
+ response_model_exclude_none=response_model_exclude_none,
+ include_in_schema=include_in_schema,
+ response_class=response_class,
+ name=name,
+ callbacks=callbacks,
+ openapi_extra=openapi_extra,
+ generate_unique_id_function=generate_unique_id_function,
+ )
+ return func
+
+ return decorator
+
+ def add_api_websocket_route(
+ self,
+ path: str,
+ endpoint: Callable[..., Any],
+ name: Optional[str] = None,
+ *,
+ dependencies: Optional[Sequence[params.Depends]] = None,
+ ) -> None:
+ current_dependencies = self.dependencies.copy()
+ if dependencies:
+ current_dependencies.extend(dependencies)
+
+ route = APIWebSocketRoute(
+ self.prefix + path,
+ endpoint=endpoint,
+ name=name,
+ dependencies=current_dependencies,
+ dependency_overrides_provider=self.dependency_overrides_provider,
+ )
+ self.routes.append(route)
+
+ def websocket(
+ self,
+ path: Annotated[
+ str,
+ Doc(
+ """
+ WebSocket path.
+ """
+ ),
+ ],
+ name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A name for the WebSocket. Only used internally.
+ """
+ ),
+ ] = None,
+ *,
+ dependencies: Annotated[
+ Optional[Sequence[params.Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be used for this
+ WebSocket.
+
+ Read more about it in the
+ [FastAPI docs for WebSockets](https://fastapi.tiangolo.com/advanced/websockets/).
+ """
+ ),
+ ] = None,
+ ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Decorate a WebSocket function.
+
+ Read more about it in the
+ [FastAPI docs for WebSockets](https://fastapi.tiangolo.com/advanced/websockets/).
+
+ **Example**
+
+ ## Example
+
+ ```python
+ from fastapi import APIRouter, FastAPI, WebSocket
+
+ app = FastAPI()
+ router = APIRouter()
+
+ @router.websocket("/ws")
+ async def websocket_endpoint(websocket: WebSocket):
+ await websocket.accept()
+ while True:
+ data = await websocket.receive_text()
+ await websocket.send_text(f"Message text was: {data}")
+
+ app.include_router(router)
+ ```
+ """
+
+ def decorator(func: DecoratedCallable) -> DecoratedCallable:
+ self.add_api_websocket_route(
+ path, func, name=name, dependencies=dependencies
+ )
+ return func
+
+ return decorator
+
+ def websocket_route(
+ self, path: str, name: Union[str, None] = None
+ ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ def decorator(func: DecoratedCallable) -> DecoratedCallable:
+ self.add_websocket_route(path, func, name=name)
+ return func
+
+ return decorator
+
+ def include_router(
+ self,
+ router: Annotated["APIRouter", Doc("The `APIRouter` to include.")],
+ *,
+ prefix: Annotated[str, Doc("An optional path prefix for the router.")] = "",
+ tags: Annotated[
+ Optional[List[Union[str, Enum]]],
+ Doc(
+ """
+ A list of tags to be applied to all the *path operations* in this
+ router.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[params.Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be applied to all the
+ *path operations* in this router.
+
+ Read more about it in the
+ [FastAPI docs for Bigger Applications - Multiple Files](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies).
+ """
+ ),
+ ] = None,
+ default_response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ The default response class to be used.
+
+ Read more in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#default-response-class).
+ """
+ ),
+ ] = Default(JSONResponse),
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses to be shown in OpenAPI.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Additional Responses in OpenAPI](https://fastapi.tiangolo.com/advanced/additional-responses/).
+
+ And in the
+ [FastAPI docs for Bigger Applications](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies).
+ """
+ ),
+ ] = None,
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ OpenAPI callbacks that should apply to all *path operations* in this
+ router.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark all *path operations* in this router as deprecated.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ Include (or not) all the *path operations* in this router in the
+ generated OpenAPI schema.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = True,
+ generate_unique_id_function: Annotated[
+ Callable[[APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
+ ) -> None:
+ """
+ Include another `APIRouter` in the same current `APIRouter`.
+
+ Read more about it in the
+ [FastAPI docs for Bigger Applications](https://fastapi.tiangolo.com/tutorial/bigger-applications/).
+
+ ## Example
+
+ ```python
+ from fastapi import APIRouter, FastAPI
+
+ app = FastAPI()
+ internal_router = APIRouter()
+ users_router = APIRouter()
+
+ @users_router.get("/users/")
+ def read_users():
+ return [{"name": "Rick"}, {"name": "Morty"}]
+
+ internal_router.include_router(users_router)
+ app.include_router(internal_router)
+ ```
+ """
+ if prefix:
+ assert prefix.startswith("/"), "A path prefix must start with '/'"
+ assert not prefix.endswith("/"), (
+ "A path prefix must not end with '/', as the routes will start with '/'"
+ )
+ else:
+ for r in router.routes:
+ path = getattr(r, "path") # noqa: B009
+ name = getattr(r, "name", "unknown")
+ if path is not None and not path:
+ raise FastAPIError(
+ f"Prefix and path cannot be both empty (path operation: {name})"
+ )
+ if responses is None:
+ responses = {}
+ for route in router.routes:
+ if isinstance(route, APIRoute):
+ combined_responses = {**responses, **route.responses}
+ use_response_class = get_value_or_default(
+ route.response_class,
+ router.default_response_class,
+ default_response_class,
+ self.default_response_class,
+ )
+ current_tags = []
+ if tags:
+ current_tags.extend(tags)
+ if route.tags:
+ current_tags.extend(route.tags)
+ current_dependencies: List[params.Depends] = []
+ if dependencies:
+ current_dependencies.extend(dependencies)
+ if route.dependencies:
+ current_dependencies.extend(route.dependencies)
+ current_callbacks = []
+ if callbacks:
+ current_callbacks.extend(callbacks)
+ if route.callbacks:
+ current_callbacks.extend(route.callbacks)
+ current_generate_unique_id = get_value_or_default(
+ route.generate_unique_id_function,
+ router.generate_unique_id_function,
+ generate_unique_id_function,
+ self.generate_unique_id_function,
+ )
+ self.add_api_route(
+ prefix + route.path,
+ route.endpoint,
+ response_model=route.response_model,
+ status_code=route.status_code,
+ tags=current_tags,
+ dependencies=current_dependencies,
+ summary=route.summary,
+ description=route.description,
+ response_description=route.response_description,
+ responses=combined_responses,
+ deprecated=route.deprecated or deprecated or self.deprecated,
+ methods=route.methods,
+ operation_id=route.operation_id,
+ response_model_include=route.response_model_include,
+ response_model_exclude=route.response_model_exclude,
+ response_model_by_alias=route.response_model_by_alias,
+ response_model_exclude_unset=route.response_model_exclude_unset,
+ response_model_exclude_defaults=route.response_model_exclude_defaults,
+ response_model_exclude_none=route.response_model_exclude_none,
+ include_in_schema=route.include_in_schema
+ and self.include_in_schema
+ and include_in_schema,
+ response_class=use_response_class,
+ name=route.name,
+ route_class_override=type(route),
+ callbacks=current_callbacks,
+ openapi_extra=route.openapi_extra,
+ generate_unique_id_function=current_generate_unique_id,
+ )
+ elif isinstance(route, routing.Route):
+ methods = list(route.methods or [])
+ self.add_route(
+ prefix + route.path,
+ route.endpoint,
+ methods=methods,
+ include_in_schema=route.include_in_schema,
+ name=route.name,
+ )
+ elif isinstance(route, APIWebSocketRoute):
+ current_dependencies = []
+ if dependencies:
+ current_dependencies.extend(dependencies)
+ if route.dependencies:
+ current_dependencies.extend(route.dependencies)
+ self.add_api_websocket_route(
+ prefix + route.path,
+ route.endpoint,
+ dependencies=current_dependencies,
+ name=route.name,
+ )
+ elif isinstance(route, routing.WebSocketRoute):
+ self.add_websocket_route(
+ prefix + route.path, route.endpoint, name=route.name
+ )
+ for handler in router.on_startup:
+ self.add_event_handler("startup", handler)
+ for handler in router.on_shutdown:
+ self.add_event_handler("shutdown", handler)
+ self.lifespan_context = _merge_lifespan_context(
+ self.lifespan_context,
+ router.lifespan_context,
+ )
+
+ def get(
+ self,
+ path: Annotated[
+ str,
+ Doc(
+ """
+ The URL path to be used for this *path operation*.
+
+ For example, in `http://example.com/items`, the path is `/items`.
+ """
+ ),
+ ],
+ *,
+ response_model: Annotated[
+ Any,
+ Doc(
+ """
+ The type to use for the response.
+
+ It could be any valid Pydantic *field* type. So, it doesn't have to
+ be a Pydantic model, it could be other things, like a `list`, `dict`,
+ etc.
+
+ It will be used for:
+
+ * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+ show it as the response (JSON Schema).
+ * Serialization: you could return an arbitrary object and the
+ `response_model` would be used to serialize that object into the
+ corresponding JSON.
+ * Filtering: the JSON sent to the client will only contain the data
+ (fields) defined in the `response_model`. If you returned an object
+ that contains an attribute `password` but the `response_model` does
+ not include that field, the JSON sent to the client would not have
+ that `password`.
+ * Validation: whatever you return will be serialized with the
+ `response_model`, converting any data as necessary to generate the
+ corresponding JSON. But if the data in the object returned is not
+ valid, that would mean a violation of the contract with the client,
+ so it's an error from the API developer. So, FastAPI will raise an
+ error and return a 500 error code (Internal Server Error).
+
+ Read more about it in the
+ [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+ """
+ ),
+ ] = Default(None),
+ status_code: Annotated[
+ Optional[int],
+ Doc(
+ """
+ The default status code to be used for the response.
+
+ You could override the status code by returning a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+ """
+ ),
+ ] = None,
+ tags: Annotated[
+ Optional[List[Union[str, Enum]]],
+ Doc(
+ """
+ A list of tags to be applied to the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[params.Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be applied to the
+ *path operation*.
+
+ Read more about it in the
+ [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+ """
+ ),
+ ] = None,
+ summary: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A summary for the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A description for the *path operation*.
+
+ If not provided, it will be extracted automatically from the docstring
+ of the *path operation function*.
+
+ It can contain Markdown.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ response_description: Annotated[
+ str,
+ Doc(
+ """
+ The description for the default response.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = "Successful Response",
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses that could be returned by this *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this *path operation* as deprecated.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ operation_id: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Custom operation ID to be used by this *path operation*.
+
+ By default, it is generated automatically.
+
+ If you provide a custom operation ID, you need to make sure it is
+ unique for the whole API.
+
+ You can customize the
+ operation ID generation with the parameter
+ `generate_unique_id_function` in the `FastAPI` class.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = None,
+ response_model_include: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to include only certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_exclude: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to exclude certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_by_alias: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response model
+ should be serialized by alias when an alias is used.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = True,
+ response_model_exclude_unset: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that were not set and
+ have their default values. This is different from
+ `response_model_exclude_defaults` in that if the fields are set,
+ they will be included in the response, even if the value is the same
+ as the default.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_defaults: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that have the same value
+ as the default. This is different from `response_model_exclude_unset`
+ in that if the fields are set but contain the same default values,
+ they will be excluded from the response.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_none: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data should
+ exclude fields set to `None`.
+
+ This is much simpler (less smart) than `response_model_exclude_unset`
+ and `response_model_exclude_defaults`. You probably want to use one of
+ those two instead of this one, as those allow returning `None` values
+ when it makes sense.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+ """
+ ),
+ ] = False,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ Include this *path operation* in the generated OpenAPI schema.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-parameters-from-openapi).
+ """
+ ),
+ ] = True,
+ response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ Response class to be used for this *path operation*.
+
+ This will not be used if you return a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+ """
+ ),
+ ] = Default(JSONResponse),
+ name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Name for this *path operation*. Only used internally.
+ """
+ ),
+ ] = None,
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ List of *path operations* that will be used as OpenAPI callbacks.
+
+ This is only for OpenAPI documentation, the callbacks won't be used
+ directly.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ openapi_extra: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ Extra metadata to be included in the OpenAPI schema for this *path
+ operation*.
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+ """
+ ),
+ ] = None,
+ generate_unique_id_function: Annotated[
+ Callable[[APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
+ ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add a *path operation* using an HTTP GET operation.
+
+ ## Example
+
+ ```python
+ from fastapi import APIRouter, FastAPI
+
+ app = FastAPI()
+ router = APIRouter()
+
+ @router.get("/items/")
+ def read_items():
+ return [{"name": "Empanada"}, {"name": "Arepa"}]
+
+ app.include_router(router)
+ ```
+ """
+ return self.api_route(
+ path=path,
+ response_model=response_model,
+ status_code=status_code,
+ tags=tags,
+ dependencies=dependencies,
+ summary=summary,
+ description=description,
+ response_description=response_description,
+ responses=responses,
+ deprecated=deprecated,
+ methods=["GET"],
+ operation_id=operation_id,
+ response_model_include=response_model_include,
+ response_model_exclude=response_model_exclude,
+ response_model_by_alias=response_model_by_alias,
+ response_model_exclude_unset=response_model_exclude_unset,
+ response_model_exclude_defaults=response_model_exclude_defaults,
+ response_model_exclude_none=response_model_exclude_none,
+ include_in_schema=include_in_schema,
+ response_class=response_class,
+ name=name,
+ callbacks=callbacks,
+ openapi_extra=openapi_extra,
+ generate_unique_id_function=generate_unique_id_function,
+ )
+
+ def put(
+ self,
+ path: Annotated[
+ str,
+ Doc(
+ """
+ The URL path to be used for this *path operation*.
+
+ For example, in `http://example.com/items`, the path is `/items`.
+ """
+ ),
+ ],
+ *,
+ response_model: Annotated[
+ Any,
+ Doc(
+ """
+ The type to use for the response.
+
+ It could be any valid Pydantic *field* type. So, it doesn't have to
+ be a Pydantic model, it could be other things, like a `list`, `dict`,
+ etc.
+
+ It will be used for:
+
+ * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+ show it as the response (JSON Schema).
+ * Serialization: you could return an arbitrary object and the
+ `response_model` would be used to serialize that object into the
+ corresponding JSON.
+ * Filtering: the JSON sent to the client will only contain the data
+ (fields) defined in the `response_model`. If you returned an object
+ that contains an attribute `password` but the `response_model` does
+ not include that field, the JSON sent to the client would not have
+ that `password`.
+ * Validation: whatever you return will be serialized with the
+ `response_model`, converting any data as necessary to generate the
+ corresponding JSON. But if the data in the object returned is not
+ valid, that would mean a violation of the contract with the client,
+ so it's an error from the API developer. So, FastAPI will raise an
+ error and return a 500 error code (Internal Server Error).
+
+ Read more about it in the
+ [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+ """
+ ),
+ ] = Default(None),
+ status_code: Annotated[
+ Optional[int],
+ Doc(
+ """
+ The default status code to be used for the response.
+
+ You could override the status code by returning a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+ """
+ ),
+ ] = None,
+ tags: Annotated[
+ Optional[List[Union[str, Enum]]],
+ Doc(
+ """
+ A list of tags to be applied to the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[params.Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be applied to the
+ *path operation*.
+
+ Read more about it in the
+ [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+ """
+ ),
+ ] = None,
+ summary: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A summary for the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A description for the *path operation*.
+
+ If not provided, it will be extracted automatically from the docstring
+ of the *path operation function*.
+
+ It can contain Markdown.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ response_description: Annotated[
+ str,
+ Doc(
+ """
+ The description for the default response.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = "Successful Response",
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses that could be returned by this *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this *path operation* as deprecated.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ operation_id: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Custom operation ID to be used by this *path operation*.
+
+ By default, it is generated automatically.
+
+ If you provide a custom operation ID, you need to make sure it is
+ unique for the whole API.
+
+ You can customize the
+ operation ID generation with the parameter
+ `generate_unique_id_function` in the `FastAPI` class.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = None,
+ response_model_include: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to include only certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_exclude: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to exclude certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_by_alias: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response model
+ should be serialized by alias when an alias is used.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = True,
+ response_model_exclude_unset: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that were not set and
+ have their default values. This is different from
+ `response_model_exclude_defaults` in that if the fields are set,
+ they will be included in the response, even if the value is the same
+ as the default.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_defaults: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that have the same value
+ as the default. This is different from `response_model_exclude_unset`
+ in that if the fields are set but contain the same default values,
+ they will be excluded from the response.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_none: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data should
+ exclude fields set to `None`.
+
+ This is much simpler (less smart) than `response_model_exclude_unset`
+ and `response_model_exclude_defaults`. You probably want to use one of
+ those two instead of this one, as those allow returning `None` values
+ when it makes sense.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+ """
+ ),
+ ] = False,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ Include this *path operation* in the generated OpenAPI schema.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-parameters-from-openapi).
+ """
+ ),
+ ] = True,
+ response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ Response class to be used for this *path operation*.
+
+ This will not be used if you return a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+ """
+ ),
+ ] = Default(JSONResponse),
+ name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Name for this *path operation*. Only used internally.
+ """
+ ),
+ ] = None,
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ List of *path operations* that will be used as OpenAPI callbacks.
+
+ This is only for OpenAPI documentation, the callbacks won't be used
+ directly.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ openapi_extra: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ Extra metadata to be included in the OpenAPI schema for this *path
+ operation*.
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+ """
+ ),
+ ] = None,
+ generate_unique_id_function: Annotated[
+ Callable[[APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
+ ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add a *path operation* using an HTTP PUT operation.
+
+ ## Example
+
+ ```python
+ from fastapi import APIRouter, FastAPI
+ from pydantic import BaseModel
+
+ class Item(BaseModel):
+ name: str
+ description: str | None = None
+
+ app = FastAPI()
+ router = APIRouter()
+
+ @router.put("/items/{item_id}")
+ def replace_item(item_id: str, item: Item):
+ return {"message": "Item replaced", "id": item_id}
+
+ app.include_router(router)
+ ```
+ """
+ return self.api_route(
+ path=path,
+ response_model=response_model,
+ status_code=status_code,
+ tags=tags,
+ dependencies=dependencies,
+ summary=summary,
+ description=description,
+ response_description=response_description,
+ responses=responses,
+ deprecated=deprecated,
+ methods=["PUT"],
+ operation_id=operation_id,
+ response_model_include=response_model_include,
+ response_model_exclude=response_model_exclude,
+ response_model_by_alias=response_model_by_alias,
+ response_model_exclude_unset=response_model_exclude_unset,
+ response_model_exclude_defaults=response_model_exclude_defaults,
+ response_model_exclude_none=response_model_exclude_none,
+ include_in_schema=include_in_schema,
+ response_class=response_class,
+ name=name,
+ callbacks=callbacks,
+ openapi_extra=openapi_extra,
+ generate_unique_id_function=generate_unique_id_function,
+ )
+
+ def post(
+ self,
+ path: Annotated[
+ str,
+ Doc(
+ """
+ The URL path to be used for this *path operation*.
+
+ For example, in `http://example.com/items`, the path is `/items`.
+ """
+ ),
+ ],
+ *,
+ response_model: Annotated[
+ Any,
+ Doc(
+ """
+ The type to use for the response.
+
+ It could be any valid Pydantic *field* type. So, it doesn't have to
+ be a Pydantic model, it could be other things, like a `list`, `dict`,
+ etc.
+
+ It will be used for:
+
+ * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+ show it as the response (JSON Schema).
+ * Serialization: you could return an arbitrary object and the
+ `response_model` would be used to serialize that object into the
+ corresponding JSON.
+ * Filtering: the JSON sent to the client will only contain the data
+ (fields) defined in the `response_model`. If you returned an object
+ that contains an attribute `password` but the `response_model` does
+ not include that field, the JSON sent to the client would not have
+ that `password`.
+ * Validation: whatever you return will be serialized with the
+ `response_model`, converting any data as necessary to generate the
+ corresponding JSON. But if the data in the object returned is not
+ valid, that would mean a violation of the contract with the client,
+ so it's an error from the API developer. So, FastAPI will raise an
+ error and return a 500 error code (Internal Server Error).
+
+ Read more about it in the
+ [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+ """
+ ),
+ ] = Default(None),
+ status_code: Annotated[
+ Optional[int],
+ Doc(
+ """
+ The default status code to be used for the response.
+
+ You could override the status code by returning a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+ """
+ ),
+ ] = None,
+ tags: Annotated[
+ Optional[List[Union[str, Enum]]],
+ Doc(
+ """
+ A list of tags to be applied to the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[params.Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be applied to the
+ *path operation*.
+
+ Read more about it in the
+ [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+ """
+ ),
+ ] = None,
+ summary: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A summary for the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A description for the *path operation*.
+
+ If not provided, it will be extracted automatically from the docstring
+ of the *path operation function*.
+
+ It can contain Markdown.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ response_description: Annotated[
+ str,
+ Doc(
+ """
+ The description for the default response.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = "Successful Response",
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses that could be returned by this *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this *path operation* as deprecated.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ operation_id: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Custom operation ID to be used by this *path operation*.
+
+ By default, it is generated automatically.
+
+ If you provide a custom operation ID, you need to make sure it is
+ unique for the whole API.
+
+ You can customize the
+ operation ID generation with the parameter
+ `generate_unique_id_function` in the `FastAPI` class.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = None,
+ response_model_include: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to include only certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_exclude: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to exclude certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_by_alias: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response model
+ should be serialized by alias when an alias is used.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = True,
+ response_model_exclude_unset: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that were not set and
+ have their default values. This is different from
+ `response_model_exclude_defaults` in that if the fields are set,
+ they will be included in the response, even if the value is the same
+ as the default.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_defaults: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that have the same value
+ as the default. This is different from `response_model_exclude_unset`
+ in that if the fields are set but contain the same default values,
+ they will be excluded from the response.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_none: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data should
+ exclude fields set to `None`.
+
+ This is much simpler (less smart) than `response_model_exclude_unset`
+ and `response_model_exclude_defaults`. You probably want to use one of
+ those two instead of this one, as those allow returning `None` values
+ when it makes sense.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+ """
+ ),
+ ] = False,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ Include this *path operation* in the generated OpenAPI schema.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-parameters-from-openapi).
+ """
+ ),
+ ] = True,
+ response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ Response class to be used for this *path operation*.
+
+ This will not be used if you return a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+ """
+ ),
+ ] = Default(JSONResponse),
+ name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Name for this *path operation*. Only used internally.
+ """
+ ),
+ ] = None,
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ List of *path operations* that will be used as OpenAPI callbacks.
+
+ This is only for OpenAPI documentation, the callbacks won't be used
+ directly.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ openapi_extra: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ Extra metadata to be included in the OpenAPI schema for this *path
+ operation*.
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+ """
+ ),
+ ] = None,
+ generate_unique_id_function: Annotated[
+ Callable[[APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
+ ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add a *path operation* using an HTTP POST operation.
+
+ ## Example
+
+ ```python
+ from fastapi import APIRouter, FastAPI
+ from pydantic import BaseModel
+
+ class Item(BaseModel):
+ name: str
+ description: str | None = None
+
+ app = FastAPI()
+ router = APIRouter()
+
+ @router.post("/items/")
+ def create_item(item: Item):
+ return {"message": "Item created"}
+
+ app.include_router(router)
+ ```
+ """
+ return self.api_route(
+ path=path,
+ response_model=response_model,
+ status_code=status_code,
+ tags=tags,
+ dependencies=dependencies,
+ summary=summary,
+ description=description,
+ response_description=response_description,
+ responses=responses,
+ deprecated=deprecated,
+ methods=["POST"],
+ operation_id=operation_id,
+ response_model_include=response_model_include,
+ response_model_exclude=response_model_exclude,
+ response_model_by_alias=response_model_by_alias,
+ response_model_exclude_unset=response_model_exclude_unset,
+ response_model_exclude_defaults=response_model_exclude_defaults,
+ response_model_exclude_none=response_model_exclude_none,
+ include_in_schema=include_in_schema,
+ response_class=response_class,
+ name=name,
+ callbacks=callbacks,
+ openapi_extra=openapi_extra,
+ generate_unique_id_function=generate_unique_id_function,
+ )
+
+ def delete(
+ self,
+ path: Annotated[
+ str,
+ Doc(
+ """
+ The URL path to be used for this *path operation*.
+
+ For example, in `http://example.com/items`, the path is `/items`.
+ """
+ ),
+ ],
+ *,
+ response_model: Annotated[
+ Any,
+ Doc(
+ """
+ The type to use for the response.
+
+ It could be any valid Pydantic *field* type. So, it doesn't have to
+ be a Pydantic model, it could be other things, like a `list`, `dict`,
+ etc.
+
+ It will be used for:
+
+ * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+ show it as the response (JSON Schema).
+ * Serialization: you could return an arbitrary object and the
+ `response_model` would be used to serialize that object into the
+ corresponding JSON.
+ * Filtering: the JSON sent to the client will only contain the data
+ (fields) defined in the `response_model`. If you returned an object
+ that contains an attribute `password` but the `response_model` does
+ not include that field, the JSON sent to the client would not have
+ that `password`.
+ * Validation: whatever you return will be serialized with the
+ `response_model`, converting any data as necessary to generate the
+ corresponding JSON. But if the data in the object returned is not
+ valid, that would mean a violation of the contract with the client,
+ so it's an error from the API developer. So, FastAPI will raise an
+ error and return a 500 error code (Internal Server Error).
+
+ Read more about it in the
+ [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+ """
+ ),
+ ] = Default(None),
+ status_code: Annotated[
+ Optional[int],
+ Doc(
+ """
+ The default status code to be used for the response.
+
+ You could override the status code by returning a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+ """
+ ),
+ ] = None,
+ tags: Annotated[
+ Optional[List[Union[str, Enum]]],
+ Doc(
+ """
+ A list of tags to be applied to the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[params.Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be applied to the
+ *path operation*.
+
+ Read more about it in the
+ [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+ """
+ ),
+ ] = None,
+ summary: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A summary for the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A description for the *path operation*.
+
+ If not provided, it will be extracted automatically from the docstring
+ of the *path operation function*.
+
+ It can contain Markdown.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ response_description: Annotated[
+ str,
+ Doc(
+ """
+ The description for the default response.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = "Successful Response",
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses that could be returned by this *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this *path operation* as deprecated.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ operation_id: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Custom operation ID to be used by this *path operation*.
+
+ By default, it is generated automatically.
+
+ If you provide a custom operation ID, you need to make sure it is
+ unique for the whole API.
+
+ You can customize the
+ operation ID generation with the parameter
+ `generate_unique_id_function` in the `FastAPI` class.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = None,
+ response_model_include: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to include only certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_exclude: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to exclude certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_by_alias: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response model
+ should be serialized by alias when an alias is used.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = True,
+ response_model_exclude_unset: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that were not set and
+ have their default values. This is different from
+ `response_model_exclude_defaults` in that if the fields are set,
+ they will be included in the response, even if the value is the same
+ as the default.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_defaults: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that have the same value
+ as the default. This is different from `response_model_exclude_unset`
+ in that if the fields are set but contain the same default values,
+ they will be excluded from the response.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_none: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data should
+ exclude fields set to `None`.
+
+ This is much simpler (less smart) than `response_model_exclude_unset`
+ and `response_model_exclude_defaults`. You probably want to use one of
+ those two instead of this one, as those allow returning `None` values
+ when it makes sense.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+ """
+ ),
+ ] = False,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ Include this *path operation* in the generated OpenAPI schema.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-parameters-from-openapi).
+ """
+ ),
+ ] = True,
+ response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ Response class to be used for this *path operation*.
+
+ This will not be used if you return a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+ """
+ ),
+ ] = Default(JSONResponse),
+ name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Name for this *path operation*. Only used internally.
+ """
+ ),
+ ] = None,
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ List of *path operations* that will be used as OpenAPI callbacks.
+
+ This is only for OpenAPI documentation, the callbacks won't be used
+ directly.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ openapi_extra: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ Extra metadata to be included in the OpenAPI schema for this *path
+ operation*.
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+ """
+ ),
+ ] = None,
+ generate_unique_id_function: Annotated[
+ Callable[[APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
+ ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add a *path operation* using an HTTP DELETE operation.
+
+ ## Example
+
+ ```python
+ from fastapi import APIRouter, FastAPI
+
+ app = FastAPI()
+ router = APIRouter()
+
+ @router.delete("/items/{item_id}")
+ def delete_item(item_id: str):
+ return {"message": "Item deleted"}
+
+ app.include_router(router)
+ ```
+ """
+ return self.api_route(
+ path=path,
+ response_model=response_model,
+ status_code=status_code,
+ tags=tags,
+ dependencies=dependencies,
+ summary=summary,
+ description=description,
+ response_description=response_description,
+ responses=responses,
+ deprecated=deprecated,
+ methods=["DELETE"],
+ operation_id=operation_id,
+ response_model_include=response_model_include,
+ response_model_exclude=response_model_exclude,
+ response_model_by_alias=response_model_by_alias,
+ response_model_exclude_unset=response_model_exclude_unset,
+ response_model_exclude_defaults=response_model_exclude_defaults,
+ response_model_exclude_none=response_model_exclude_none,
+ include_in_schema=include_in_schema,
+ response_class=response_class,
+ name=name,
+ callbacks=callbacks,
+ openapi_extra=openapi_extra,
+ generate_unique_id_function=generate_unique_id_function,
+ )
+
+ def options(
+ self,
+ path: Annotated[
+ str,
+ Doc(
+ """
+ The URL path to be used for this *path operation*.
+
+ For example, in `http://example.com/items`, the path is `/items`.
+ """
+ ),
+ ],
+ *,
+ response_model: Annotated[
+ Any,
+ Doc(
+ """
+ The type to use for the response.
+
+ It could be any valid Pydantic *field* type. So, it doesn't have to
+ be a Pydantic model, it could be other things, like a `list`, `dict`,
+ etc.
+
+ It will be used for:
+
+ * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+ show it as the response (JSON Schema).
+ * Serialization: you could return an arbitrary object and the
+ `response_model` would be used to serialize that object into the
+ corresponding JSON.
+ * Filtering: the JSON sent to the client will only contain the data
+ (fields) defined in the `response_model`. If you returned an object
+ that contains an attribute `password` but the `response_model` does
+ not include that field, the JSON sent to the client would not have
+ that `password`.
+ * Validation: whatever you return will be serialized with the
+ `response_model`, converting any data as necessary to generate the
+ corresponding JSON. But if the data in the object returned is not
+ valid, that would mean a violation of the contract with the client,
+ so it's an error from the API developer. So, FastAPI will raise an
+ error and return a 500 error code (Internal Server Error).
+
+ Read more about it in the
+ [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+ """
+ ),
+ ] = Default(None),
+ status_code: Annotated[
+ Optional[int],
+ Doc(
+ """
+ The default status code to be used for the response.
+
+ You could override the status code by returning a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+ """
+ ),
+ ] = None,
+ tags: Annotated[
+ Optional[List[Union[str, Enum]]],
+ Doc(
+ """
+ A list of tags to be applied to the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[params.Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be applied to the
+ *path operation*.
+
+ Read more about it in the
+ [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+ """
+ ),
+ ] = None,
+ summary: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A summary for the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A description for the *path operation*.
+
+ If not provided, it will be extracted automatically from the docstring
+ of the *path operation function*.
+
+ It can contain Markdown.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ response_description: Annotated[
+ str,
+ Doc(
+ """
+ The description for the default response.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = "Successful Response",
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses that could be returned by this *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this *path operation* as deprecated.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ operation_id: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Custom operation ID to be used by this *path operation*.
+
+ By default, it is generated automatically.
+
+ If you provide a custom operation ID, you need to make sure it is
+ unique for the whole API.
+
+ You can customize the
+ operation ID generation with the parameter
+ `generate_unique_id_function` in the `FastAPI` class.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = None,
+ response_model_include: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to include only certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_exclude: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to exclude certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_by_alias: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response model
+ should be serialized by alias when an alias is used.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = True,
+ response_model_exclude_unset: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that were not set and
+ have their default values. This is different from
+ `response_model_exclude_defaults` in that if the fields are set,
+ they will be included in the response, even if the value is the same
+ as the default.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_defaults: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that have the same value
+ as the default. This is different from `response_model_exclude_unset`
+ in that if the fields are set but contain the same default values,
+ they will be excluded from the response.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_none: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data should
+ exclude fields set to `None`.
+
+ This is much simpler (less smart) than `response_model_exclude_unset`
+ and `response_model_exclude_defaults`. You probably want to use one of
+ those two instead of this one, as those allow returning `None` values
+ when it makes sense.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+ """
+ ),
+ ] = False,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ Include this *path operation* in the generated OpenAPI schema.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-parameters-from-openapi).
+ """
+ ),
+ ] = True,
+ response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ Response class to be used for this *path operation*.
+
+ This will not be used if you return a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+ """
+ ),
+ ] = Default(JSONResponse),
+ name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Name for this *path operation*. Only used internally.
+ """
+ ),
+ ] = None,
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ List of *path operations* that will be used as OpenAPI callbacks.
+
+ This is only for OpenAPI documentation, the callbacks won't be used
+ directly.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ openapi_extra: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ Extra metadata to be included in the OpenAPI schema for this *path
+ operation*.
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+ """
+ ),
+ ] = None,
+ generate_unique_id_function: Annotated[
+ Callable[[APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
+ ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add a *path operation* using an HTTP OPTIONS operation.
+
+ ## Example
+
+ ```python
+ from fastapi import APIRouter, FastAPI
+
+ app = FastAPI()
+ router = APIRouter()
+
+ @router.options("/items/")
+ def get_item_options():
+ return {"additions": ["Aji", "Guacamole"]}
+
+ app.include_router(router)
+ ```
+ """
+ return self.api_route(
+ path=path,
+ response_model=response_model,
+ status_code=status_code,
+ tags=tags,
+ dependencies=dependencies,
+ summary=summary,
+ description=description,
+ response_description=response_description,
+ responses=responses,
+ deprecated=deprecated,
+ methods=["OPTIONS"],
+ operation_id=operation_id,
+ response_model_include=response_model_include,
+ response_model_exclude=response_model_exclude,
+ response_model_by_alias=response_model_by_alias,
+ response_model_exclude_unset=response_model_exclude_unset,
+ response_model_exclude_defaults=response_model_exclude_defaults,
+ response_model_exclude_none=response_model_exclude_none,
+ include_in_schema=include_in_schema,
+ response_class=response_class,
+ name=name,
+ callbacks=callbacks,
+ openapi_extra=openapi_extra,
+ generate_unique_id_function=generate_unique_id_function,
+ )
+
+ def head(
+ self,
+ path: Annotated[
+ str,
+ Doc(
+ """
+ The URL path to be used for this *path operation*.
+
+ For example, in `http://example.com/items`, the path is `/items`.
+ """
+ ),
+ ],
+ *,
+ response_model: Annotated[
+ Any,
+ Doc(
+ """
+ The type to use for the response.
+
+ It could be any valid Pydantic *field* type. So, it doesn't have to
+ be a Pydantic model, it could be other things, like a `list`, `dict`,
+ etc.
+
+ It will be used for:
+
+ * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+ show it as the response (JSON Schema).
+ * Serialization: you could return an arbitrary object and the
+ `response_model` would be used to serialize that object into the
+ corresponding JSON.
+ * Filtering: the JSON sent to the client will only contain the data
+ (fields) defined in the `response_model`. If you returned an object
+ that contains an attribute `password` but the `response_model` does
+ not include that field, the JSON sent to the client would not have
+ that `password`.
+ * Validation: whatever you return will be serialized with the
+ `response_model`, converting any data as necessary to generate the
+ corresponding JSON. But if the data in the object returned is not
+ valid, that would mean a violation of the contract with the client,
+ so it's an error from the API developer. So, FastAPI will raise an
+ error and return a 500 error code (Internal Server Error).
+
+ Read more about it in the
+ [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+ """
+ ),
+ ] = Default(None),
+ status_code: Annotated[
+ Optional[int],
+ Doc(
+ """
+ The default status code to be used for the response.
+
+ You could override the status code by returning a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+ """
+ ),
+ ] = None,
+ tags: Annotated[
+ Optional[List[Union[str, Enum]]],
+ Doc(
+ """
+ A list of tags to be applied to the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[params.Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be applied to the
+ *path operation*.
+
+ Read more about it in the
+ [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+ """
+ ),
+ ] = None,
+ summary: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A summary for the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A description for the *path operation*.
+
+ If not provided, it will be extracted automatically from the docstring
+ of the *path operation function*.
+
+ It can contain Markdown.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ response_description: Annotated[
+ str,
+ Doc(
+ """
+ The description for the default response.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = "Successful Response",
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses that could be returned by this *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this *path operation* as deprecated.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ operation_id: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Custom operation ID to be used by this *path operation*.
+
+ By default, it is generated automatically.
+
+ If you provide a custom operation ID, you need to make sure it is
+ unique for the whole API.
+
+ You can customize the
+ operation ID generation with the parameter
+ `generate_unique_id_function` in the `FastAPI` class.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = None,
+ response_model_include: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to include only certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_exclude: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to exclude certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_by_alias: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response model
+ should be serialized by alias when an alias is used.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = True,
+ response_model_exclude_unset: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that were not set and
+ have their default values. This is different from
+ `response_model_exclude_defaults` in that if the fields are set,
+ they will be included in the response, even if the value is the same
+ as the default.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_defaults: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that have the same value
+ as the default. This is different from `response_model_exclude_unset`
+ in that if the fields are set but contain the same default values,
+ they will be excluded from the response.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_none: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data should
+ exclude fields set to `None`.
+
+ This is much simpler (less smart) than `response_model_exclude_unset`
+ and `response_model_exclude_defaults`. You probably want to use one of
+ those two instead of this one, as those allow returning `None` values
+ when it makes sense.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+ """
+ ),
+ ] = False,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ Include this *path operation* in the generated OpenAPI schema.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-parameters-from-openapi).
+ """
+ ),
+ ] = True,
+ response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ Response class to be used for this *path operation*.
+
+ This will not be used if you return a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+ """
+ ),
+ ] = Default(JSONResponse),
+ name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Name for this *path operation*. Only used internally.
+ """
+ ),
+ ] = None,
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ List of *path operations* that will be used as OpenAPI callbacks.
+
+ This is only for OpenAPI documentation, the callbacks won't be used
+ directly.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ openapi_extra: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ Extra metadata to be included in the OpenAPI schema for this *path
+ operation*.
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+ """
+ ),
+ ] = None,
+ generate_unique_id_function: Annotated[
+ Callable[[APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
+ ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add a *path operation* using an HTTP HEAD operation.
+
+ ## Example
+
+ ```python
+ from fastapi import APIRouter, FastAPI
+ from pydantic import BaseModel
+
+ class Item(BaseModel):
+ name: str
+ description: str | None = None
+
+ app = FastAPI()
+ router = APIRouter()
+
+ @router.head("/items/", status_code=204)
+ def get_items_headers(response: Response):
+ response.headers["X-Cat-Dog"] = "Alone in the world"
+
+ app.include_router(router)
+ ```
+ """
+ return self.api_route(
+ path=path,
+ response_model=response_model,
+ status_code=status_code,
+ tags=tags,
+ dependencies=dependencies,
+ summary=summary,
+ description=description,
+ response_description=response_description,
+ responses=responses,
+ deprecated=deprecated,
+ methods=["HEAD"],
+ operation_id=operation_id,
+ response_model_include=response_model_include,
+ response_model_exclude=response_model_exclude,
+ response_model_by_alias=response_model_by_alias,
+ response_model_exclude_unset=response_model_exclude_unset,
+ response_model_exclude_defaults=response_model_exclude_defaults,
+ response_model_exclude_none=response_model_exclude_none,
+ include_in_schema=include_in_schema,
+ response_class=response_class,
+ name=name,
+ callbacks=callbacks,
+ openapi_extra=openapi_extra,
+ generate_unique_id_function=generate_unique_id_function,
+ )
+
+ def patch(
+ self,
+ path: Annotated[
+ str,
+ Doc(
+ """
+ The URL path to be used for this *path operation*.
+
+ For example, in `http://example.com/items`, the path is `/items`.
+ """
+ ),
+ ],
+ *,
+ response_model: Annotated[
+ Any,
+ Doc(
+ """
+ The type to use for the response.
+
+ It could be any valid Pydantic *field* type. So, it doesn't have to
+ be a Pydantic model, it could be other things, like a `list`, `dict`,
+ etc.
+
+ It will be used for:
+
+ * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+ show it as the response (JSON Schema).
+ * Serialization: you could return an arbitrary object and the
+ `response_model` would be used to serialize that object into the
+ corresponding JSON.
+ * Filtering: the JSON sent to the client will only contain the data
+ (fields) defined in the `response_model`. If you returned an object
+ that contains an attribute `password` but the `response_model` does
+ not include that field, the JSON sent to the client would not have
+ that `password`.
+ * Validation: whatever you return will be serialized with the
+ `response_model`, converting any data as necessary to generate the
+ corresponding JSON. But if the data in the object returned is not
+ valid, that would mean a violation of the contract with the client,
+ so it's an error from the API developer. So, FastAPI will raise an
+ error and return a 500 error code (Internal Server Error).
+
+ Read more about it in the
+ [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+ """
+ ),
+ ] = Default(None),
+ status_code: Annotated[
+ Optional[int],
+ Doc(
+ """
+ The default status code to be used for the response.
+
+ You could override the status code by returning a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+ """
+ ),
+ ] = None,
+ tags: Annotated[
+ Optional[List[Union[str, Enum]]],
+ Doc(
+ """
+ A list of tags to be applied to the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[params.Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be applied to the
+ *path operation*.
+
+ Read more about it in the
+ [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+ """
+ ),
+ ] = None,
+ summary: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A summary for the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A description for the *path operation*.
+
+ If not provided, it will be extracted automatically from the docstring
+ of the *path operation function*.
+
+ It can contain Markdown.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ response_description: Annotated[
+ str,
+ Doc(
+ """
+ The description for the default response.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = "Successful Response",
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses that could be returned by this *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this *path operation* as deprecated.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ operation_id: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Custom operation ID to be used by this *path operation*.
+
+ By default, it is generated automatically.
+
+ If you provide a custom operation ID, you need to make sure it is
+ unique for the whole API.
+
+ You can customize the
+ operation ID generation with the parameter
+ `generate_unique_id_function` in the `FastAPI` class.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = None,
+ response_model_include: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to include only certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_exclude: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to exclude certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_by_alias: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response model
+ should be serialized by alias when an alias is used.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = True,
+ response_model_exclude_unset: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that were not set and
+ have their default values. This is different from
+ `response_model_exclude_defaults` in that if the fields are set,
+ they will be included in the response, even if the value is the same
+ as the default.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_defaults: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that have the same value
+ as the default. This is different from `response_model_exclude_unset`
+ in that if the fields are set but contain the same default values,
+ they will be excluded from the response.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_none: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data should
+ exclude fields set to `None`.
+
+ This is much simpler (less smart) than `response_model_exclude_unset`
+ and `response_model_exclude_defaults`. You probably want to use one of
+ those two instead of this one, as those allow returning `None` values
+ when it makes sense.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+ """
+ ),
+ ] = False,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ Include this *path operation* in the generated OpenAPI schema.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-parameters-from-openapi).
+ """
+ ),
+ ] = True,
+ response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ Response class to be used for this *path operation*.
+
+ This will not be used if you return a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+ """
+ ),
+ ] = Default(JSONResponse),
+ name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Name for this *path operation*. Only used internally.
+ """
+ ),
+ ] = None,
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ List of *path operations* that will be used as OpenAPI callbacks.
+
+ This is only for OpenAPI documentation, the callbacks won't be used
+ directly.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ openapi_extra: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ Extra metadata to be included in the OpenAPI schema for this *path
+ operation*.
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+ """
+ ),
+ ] = None,
+ generate_unique_id_function: Annotated[
+ Callable[[APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
+ ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add a *path operation* using an HTTP PATCH operation.
+
+ ## Example
+
+ ```python
+ from fastapi import APIRouter, FastAPI
+ from pydantic import BaseModel
+
+ class Item(BaseModel):
+ name: str
+ description: str | None = None
+
+ app = FastAPI()
+ router = APIRouter()
+
+ @router.patch("/items/")
+ def update_item(item: Item):
+ return {"message": "Item updated in place"}
+
+ app.include_router(router)
+ ```
+ """
+ return self.api_route(
+ path=path,
+ response_model=response_model,
+ status_code=status_code,
+ tags=tags,
+ dependencies=dependencies,
+ summary=summary,
+ description=description,
+ response_description=response_description,
+ responses=responses,
+ deprecated=deprecated,
+ methods=["PATCH"],
+ operation_id=operation_id,
+ response_model_include=response_model_include,
+ response_model_exclude=response_model_exclude,
+ response_model_by_alias=response_model_by_alias,
+ response_model_exclude_unset=response_model_exclude_unset,
+ response_model_exclude_defaults=response_model_exclude_defaults,
+ response_model_exclude_none=response_model_exclude_none,
+ include_in_schema=include_in_schema,
+ response_class=response_class,
+ name=name,
+ callbacks=callbacks,
+ openapi_extra=openapi_extra,
+ generate_unique_id_function=generate_unique_id_function,
+ )
+
+ def trace(
+ self,
+ path: Annotated[
+ str,
+ Doc(
+ """
+ The URL path to be used for this *path operation*.
+
+ For example, in `http://example.com/items`, the path is `/items`.
+ """
+ ),
+ ],
+ *,
+ response_model: Annotated[
+ Any,
+ Doc(
+ """
+ The type to use for the response.
+
+ It could be any valid Pydantic *field* type. So, it doesn't have to
+ be a Pydantic model, it could be other things, like a `list`, `dict`,
+ etc.
+
+ It will be used for:
+
+ * Documentation: the generated OpenAPI (and the UI at `/docs`) will
+ show it as the response (JSON Schema).
+ * Serialization: you could return an arbitrary object and the
+ `response_model` would be used to serialize that object into the
+ corresponding JSON.
+ * Filtering: the JSON sent to the client will only contain the data
+ (fields) defined in the `response_model`. If you returned an object
+ that contains an attribute `password` but the `response_model` does
+ not include that field, the JSON sent to the client would not have
+ that `password`.
+ * Validation: whatever you return will be serialized with the
+ `response_model`, converting any data as necessary to generate the
+ corresponding JSON. But if the data in the object returned is not
+ valid, that would mean a violation of the contract with the client,
+ so it's an error from the API developer. So, FastAPI will raise an
+ error and return a 500 error code (Internal Server Error).
+
+ Read more about it in the
+ [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
+ """
+ ),
+ ] = Default(None),
+ status_code: Annotated[
+ Optional[int],
+ Doc(
+ """
+ The default status code to be used for the response.
+
+ You could override the status code by returning a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/).
+ """
+ ),
+ ] = None,
+ tags: Annotated[
+ Optional[List[Union[str, Enum]]],
+ Doc(
+ """
+ A list of tags to be applied to the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags).
+ """
+ ),
+ ] = None,
+ dependencies: Annotated[
+ Optional[Sequence[params.Depends]],
+ Doc(
+ """
+ A list of dependencies (using `Depends()`) to be applied to the
+ *path operation*.
+
+ Read more about it in the
+ [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/).
+ """
+ ),
+ ] = None,
+ summary: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A summary for the *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ A description for the *path operation*.
+
+ If not provided, it will be extracted automatically from the docstring
+ of the *path operation function*.
+
+ It can contain Markdown.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/).
+ """
+ ),
+ ] = None,
+ response_description: Annotated[
+ str,
+ Doc(
+ """
+ The description for the default response.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = "Successful Response",
+ responses: Annotated[
+ Optional[Dict[Union[int, str], Dict[str, Any]]],
+ Doc(
+ """
+ Additional responses that could be returned by this *path operation*.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ deprecated: Annotated[
+ Optional[bool],
+ Doc(
+ """
+ Mark this *path operation* as deprecated.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ operation_id: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Custom operation ID to be used by this *path operation*.
+
+ By default, it is generated automatically.
+
+ If you provide a custom operation ID, you need to make sure it is
+ unique for the whole API.
+
+ You can customize the
+ operation ID generation with the parameter
+ `generate_unique_id_function` in the `FastAPI` class.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = None,
+ response_model_include: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to include only certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_exclude: Annotated[
+ Optional[IncEx],
+ Doc(
+ """
+ Configuration passed to Pydantic to exclude certain fields in the
+ response data.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = None,
+ response_model_by_alias: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response model
+ should be serialized by alias when an alias is used.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude).
+ """
+ ),
+ ] = True,
+ response_model_exclude_unset: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that were not set and
+ have their default values. This is different from
+ `response_model_exclude_defaults` in that if the fields are set,
+ they will be included in the response, even if the value is the same
+ as the default.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_defaults: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data
+ should have all the fields, including the ones that have the same value
+ as the default. This is different from `response_model_exclude_unset`
+ in that if the fields are set but contain the same default values,
+ they will be excluded from the response.
+
+ When `True`, default values are omitted from the response.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter).
+ """
+ ),
+ ] = False,
+ response_model_exclude_none: Annotated[
+ bool,
+ Doc(
+ """
+ Configuration passed to Pydantic to define if the response data should
+ exclude fields set to `None`.
+
+ This is much simpler (less smart) than `response_model_exclude_unset`
+ and `response_model_exclude_defaults`. You probably want to use one of
+ those two instead of this one, as those allow returning `None` values
+ when it makes sense.
+
+ Read more about it in the
+ [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none).
+ """
+ ),
+ ] = False,
+ include_in_schema: Annotated[
+ bool,
+ Doc(
+ """
+ Include this *path operation* in the generated OpenAPI schema.
+
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-parameters-from-openapi).
+ """
+ ),
+ ] = True,
+ response_class: Annotated[
+ Type[Response],
+ Doc(
+ """
+ Response class to be used for this *path operation*.
+
+ This will not be used if you return a response directly.
+
+ Read more about it in the
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse).
+ """
+ ),
+ ] = Default(JSONResponse),
+ name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Name for this *path operation*. Only used internally.
+ """
+ ),
+ ] = None,
+ callbacks: Annotated[
+ Optional[List[BaseRoute]],
+ Doc(
+ """
+ List of *path operations* that will be used as OpenAPI callbacks.
+
+ This is only for OpenAPI documentation, the callbacks won't be used
+ directly.
+
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
+
+ Read more about it in the
+ [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/).
+ """
+ ),
+ ] = None,
+ openapi_extra: Annotated[
+ Optional[Dict[str, Any]],
+ Doc(
+ """
+ Extra metadata to be included in the OpenAPI schema for this *path
+ operation*.
+
+ Read more about it in the
+ [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema).
+ """
+ ),
+ ] = None,
+ generate_unique_id_function: Annotated[
+ Callable[[APIRoute], str],
+ Doc(
+ """
+ Customize the function used to generate unique IDs for the *path
+ operations* shown in the generated OpenAPI.
+
+ This is particularly useful when automatically generating clients or
+ SDKs for your API.
+
+ Read more about it in the
+ [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function).
+ """
+ ),
+ ] = Default(generate_unique_id),
+ ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add a *path operation* using an HTTP TRACE operation.
+
+ ## Example
+
+ ```python
+ from fastapi import APIRouter, FastAPI
+ from pydantic import BaseModel
+
+ class Item(BaseModel):
+ name: str
+ description: str | None = None
+
+ app = FastAPI()
+ router = APIRouter()
+
+ @router.trace("/items/{item_id}")
+ def trace_item(item_id: str):
+ return None
+
+ app.include_router(router)
+ ```
+ """
+ return self.api_route(
+ path=path,
+ response_model=response_model,
+ status_code=status_code,
+ tags=tags,
+ dependencies=dependencies,
+ summary=summary,
+ description=description,
+ response_description=response_description,
+ responses=responses,
+ deprecated=deprecated,
+ methods=["TRACE"],
+ operation_id=operation_id,
+ response_model_include=response_model_include,
+ response_model_exclude=response_model_exclude,
+ response_model_by_alias=response_model_by_alias,
+ response_model_exclude_unset=response_model_exclude_unset,
+ response_model_exclude_defaults=response_model_exclude_defaults,
+ response_model_exclude_none=response_model_exclude_none,
+ include_in_schema=include_in_schema,
+ response_class=response_class,
+ name=name,
+ callbacks=callbacks,
+ openapi_extra=openapi_extra,
+ generate_unique_id_function=generate_unique_id_function,
+ )
+
+ @deprecated(
+ """
+ on_event is deprecated, use lifespan event handlers instead.
+
+ Read more about it in the
+ [FastAPI docs for Lifespan Events](https://fastapi.tiangolo.com/advanced/events/).
+ """
+ )
+ def on_event(
+ self,
+ event_type: Annotated[
+ str,
+ Doc(
+ """
+ The type of event. `startup` or `shutdown`.
+ """
+ ),
+ ],
+ ) -> Callable[[DecoratedCallable], DecoratedCallable]:
+ """
+ Add an event handler for the router.
+
+ `on_event` is deprecated, use `lifespan` event handlers instead.
+
+ Read more about it in the
+ [FastAPI docs for Lifespan Events](https://fastapi.tiangolo.com/advanced/events/#alternative-events-deprecated).
+ """
+
+ def decorator(func: DecoratedCallable) -> DecoratedCallable:
+ self.add_event_handler(event_type, func)
+ return func
+
+ return decorator
diff --git a/venv/Lib/site-packages/fastapi/security/__init__.py b/venv/Lib/site-packages/fastapi/security/__init__.py
new file mode 100644
index 00000000..3aa6bf21
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/security/__init__.py
@@ -0,0 +1,15 @@
+from .api_key import APIKeyCookie as APIKeyCookie
+from .api_key import APIKeyHeader as APIKeyHeader
+from .api_key import APIKeyQuery as APIKeyQuery
+from .http import HTTPAuthorizationCredentials as HTTPAuthorizationCredentials
+from .http import HTTPBasic as HTTPBasic
+from .http import HTTPBasicCredentials as HTTPBasicCredentials
+from .http import HTTPBearer as HTTPBearer
+from .http import HTTPDigest as HTTPDigest
+from .oauth2 import OAuth2 as OAuth2
+from .oauth2 import OAuth2AuthorizationCodeBearer as OAuth2AuthorizationCodeBearer
+from .oauth2 import OAuth2PasswordBearer as OAuth2PasswordBearer
+from .oauth2 import OAuth2PasswordRequestForm as OAuth2PasswordRequestForm
+from .oauth2 import OAuth2PasswordRequestFormStrict as OAuth2PasswordRequestFormStrict
+from .oauth2 import SecurityScopes as SecurityScopes
+from .open_id_connect_url import OpenIdConnect as OpenIdConnect
diff --git a/venv/Lib/site-packages/fastapi/security/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/fastapi/security/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 00000000..cabfb59b
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/security/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/security/__pycache__/api_key.cpython-312.pyc b/venv/Lib/site-packages/fastapi/security/__pycache__/api_key.cpython-312.pyc
new file mode 100644
index 00000000..893e6d23
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/security/__pycache__/api_key.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/security/__pycache__/base.cpython-312.pyc b/venv/Lib/site-packages/fastapi/security/__pycache__/base.cpython-312.pyc
new file mode 100644
index 00000000..160b70cb
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/security/__pycache__/base.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/security/__pycache__/http.cpython-312.pyc b/venv/Lib/site-packages/fastapi/security/__pycache__/http.cpython-312.pyc
new file mode 100644
index 00000000..bf2faeea
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/security/__pycache__/http.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/security/__pycache__/oauth2.cpython-312.pyc b/venv/Lib/site-packages/fastapi/security/__pycache__/oauth2.cpython-312.pyc
new file mode 100644
index 00000000..7375ee09
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/security/__pycache__/oauth2.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/security/__pycache__/open_id_connect_url.cpython-312.pyc b/venv/Lib/site-packages/fastapi/security/__pycache__/open_id_connect_url.cpython-312.pyc
new file mode 100644
index 00000000..b835322e
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/security/__pycache__/open_id_connect_url.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/security/__pycache__/utils.cpython-312.pyc b/venv/Lib/site-packages/fastapi/security/__pycache__/utils.cpython-312.pyc
new file mode 100644
index 00000000..60a96ebe
Binary files /dev/null and b/venv/Lib/site-packages/fastapi/security/__pycache__/utils.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/fastapi/security/api_key.py b/venv/Lib/site-packages/fastapi/security/api_key.py
new file mode 100644
index 00000000..70c2dca8
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/security/api_key.py
@@ -0,0 +1,288 @@
+from typing import Optional
+
+from fastapi.openapi.models import APIKey, APIKeyIn
+from fastapi.security.base import SecurityBase
+from starlette.exceptions import HTTPException
+from starlette.requests import Request
+from starlette.status import HTTP_403_FORBIDDEN
+from typing_extensions import Annotated, Doc
+
+
+class APIKeyBase(SecurityBase):
+ @staticmethod
+ def check_api_key(api_key: Optional[str], auto_error: bool) -> Optional[str]:
+ if not api_key:
+ if auto_error:
+ raise HTTPException(
+ status_code=HTTP_403_FORBIDDEN, detail="Not authenticated"
+ )
+ return None
+ return api_key
+
+
+class APIKeyQuery(APIKeyBase):
+ """
+ API key authentication using a query parameter.
+
+ This defines the name of the query parameter that should be provided in the request
+ with the API key and integrates that into the OpenAPI documentation. It extracts
+ the key value sent in the query parameter automatically and provides it as the
+ dependency result. But it doesn't define how to send that API key to the client.
+
+ ## Usage
+
+ Create an instance object and use that object as the dependency in `Depends()`.
+
+ The dependency result will be a string containing the key value.
+
+ ## Example
+
+ ```python
+ from fastapi import Depends, FastAPI
+ from fastapi.security import APIKeyQuery
+
+ app = FastAPI()
+
+ query_scheme = APIKeyQuery(name="api_key")
+
+
+ @app.get("/items/")
+ async def read_items(api_key: str = Depends(query_scheme)):
+ return {"api_key": api_key}
+ ```
+ """
+
+ def __init__(
+ self,
+ *,
+ name: Annotated[
+ str,
+ Doc("Query parameter name."),
+ ],
+ scheme_name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme name.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme description.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ auto_error: Annotated[
+ bool,
+ Doc(
+ """
+ By default, if the query parameter is not provided, `APIKeyQuery` will
+ automatically cancel the request and send the client an error.
+
+ If `auto_error` is set to `False`, when the query parameter is not
+ available, instead of erroring out, the dependency result will be
+ `None`.
+
+ This is useful when you want to have optional authentication.
+
+ It is also useful when you want to have authentication that can be
+ provided in one of multiple optional ways (for example, in a query
+ parameter or in an HTTP Bearer token).
+ """
+ ),
+ ] = True,
+ ):
+ self.model: APIKey = APIKey(
+ **{"in": APIKeyIn.query}, # type: ignore[arg-type]
+ name=name,
+ description=description,
+ )
+ self.scheme_name = scheme_name or self.__class__.__name__
+ self.auto_error = auto_error
+
+ async def __call__(self, request: Request) -> Optional[str]:
+ api_key = request.query_params.get(self.model.name)
+ return self.check_api_key(api_key, self.auto_error)
+
+
+class APIKeyHeader(APIKeyBase):
+ """
+ API key authentication using a header.
+
+ This defines the name of the header that should be provided in the request with
+ the API key and integrates that into the OpenAPI documentation. It extracts
+ the key value sent in the header automatically and provides it as the dependency
+ result. But it doesn't define how to send that key to the client.
+
+ ## Usage
+
+ Create an instance object and use that object as the dependency in `Depends()`.
+
+ The dependency result will be a string containing the key value.
+
+ ## Example
+
+ ```python
+ from fastapi import Depends, FastAPI
+ from fastapi.security import APIKeyHeader
+
+ app = FastAPI()
+
+ header_scheme = APIKeyHeader(name="x-key")
+
+
+ @app.get("/items/")
+ async def read_items(key: str = Depends(header_scheme)):
+ return {"key": key}
+ ```
+ """
+
+ def __init__(
+ self,
+ *,
+ name: Annotated[str, Doc("Header name.")],
+ scheme_name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme name.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme description.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ auto_error: Annotated[
+ bool,
+ Doc(
+ """
+ By default, if the header is not provided, `APIKeyHeader` will
+ automatically cancel the request and send the client an error.
+
+ If `auto_error` is set to `False`, when the header is not available,
+ instead of erroring out, the dependency result will be `None`.
+
+ This is useful when you want to have optional authentication.
+
+ It is also useful when you want to have authentication that can be
+ provided in one of multiple optional ways (for example, in a header or
+ in an HTTP Bearer token).
+ """
+ ),
+ ] = True,
+ ):
+ self.model: APIKey = APIKey(
+ **{"in": APIKeyIn.header}, # type: ignore[arg-type]
+ name=name,
+ description=description,
+ )
+ self.scheme_name = scheme_name or self.__class__.__name__
+ self.auto_error = auto_error
+
+ async def __call__(self, request: Request) -> Optional[str]:
+ api_key = request.headers.get(self.model.name)
+ return self.check_api_key(api_key, self.auto_error)
+
+
+class APIKeyCookie(APIKeyBase):
+ """
+ API key authentication using a cookie.
+
+ This defines the name of the cookie that should be provided in the request with
+ the API key and integrates that into the OpenAPI documentation. It extracts
+ the key value sent in the cookie automatically and provides it as the dependency
+ result. But it doesn't define how to set that cookie.
+
+ ## Usage
+
+ Create an instance object and use that object as the dependency in `Depends()`.
+
+ The dependency result will be a string containing the key value.
+
+ ## Example
+
+ ```python
+ from fastapi import Depends, FastAPI
+ from fastapi.security import APIKeyCookie
+
+ app = FastAPI()
+
+ cookie_scheme = APIKeyCookie(name="session")
+
+
+ @app.get("/items/")
+ async def read_items(session: str = Depends(cookie_scheme)):
+ return {"session": session}
+ ```
+ """
+
+ def __init__(
+ self,
+ *,
+ name: Annotated[str, Doc("Cookie name.")],
+ scheme_name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme name.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme description.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ auto_error: Annotated[
+ bool,
+ Doc(
+ """
+ By default, if the cookie is not provided, `APIKeyCookie` will
+ automatically cancel the request and send the client an error.
+
+ If `auto_error` is set to `False`, when the cookie is not available,
+ instead of erroring out, the dependency result will be `None`.
+
+ This is useful when you want to have optional authentication.
+
+ It is also useful when you want to have authentication that can be
+ provided in one of multiple optional ways (for example, in a cookie or
+ in an HTTP Bearer token).
+ """
+ ),
+ ] = True,
+ ):
+ self.model: APIKey = APIKey(
+ **{"in": APIKeyIn.cookie}, # type: ignore[arg-type]
+ name=name,
+ description=description,
+ )
+ self.scheme_name = scheme_name or self.__class__.__name__
+ self.auto_error = auto_error
+
+ async def __call__(self, request: Request) -> Optional[str]:
+ api_key = request.cookies.get(self.model.name)
+ return self.check_api_key(api_key, self.auto_error)
diff --git a/venv/Lib/site-packages/fastapi/security/base.py b/venv/Lib/site-packages/fastapi/security/base.py
new file mode 100644
index 00000000..c43555de
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/security/base.py
@@ -0,0 +1,6 @@
+from fastapi.openapi.models import SecurityBase as SecurityBaseModel
+
+
+class SecurityBase:
+ model: SecurityBaseModel
+ scheme_name: str
diff --git a/venv/Lib/site-packages/fastapi/security/http.py b/venv/Lib/site-packages/fastapi/security/http.py
new file mode 100644
index 00000000..9ab2df3c
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/security/http.py
@@ -0,0 +1,423 @@
+import binascii
+from base64 import b64decode
+from typing import Optional
+
+from fastapi.exceptions import HTTPException
+from fastapi.openapi.models import HTTPBase as HTTPBaseModel
+from fastapi.openapi.models import HTTPBearer as HTTPBearerModel
+from fastapi.security.base import SecurityBase
+from fastapi.security.utils import get_authorization_scheme_param
+from pydantic import BaseModel
+from starlette.requests import Request
+from starlette.status import HTTP_401_UNAUTHORIZED, HTTP_403_FORBIDDEN
+from typing_extensions import Annotated, Doc
+
+
+class HTTPBasicCredentials(BaseModel):
+ """
+ The HTTP Basic credentials given as the result of using `HTTPBasic` in a
+ dependency.
+
+ Read more about it in the
+ [FastAPI docs for HTTP Basic Auth](https://fastapi.tiangolo.com/advanced/security/http-basic-auth/).
+ """
+
+ username: Annotated[str, Doc("The HTTP Basic username.")]
+ password: Annotated[str, Doc("The HTTP Basic password.")]
+
+
+class HTTPAuthorizationCredentials(BaseModel):
+ """
+ The HTTP authorization credentials in the result of using `HTTPBearer` or
+ `HTTPDigest` in a dependency.
+
+ The HTTP authorization header value is split by the first space.
+
+ The first part is the `scheme`, the second part is the `credentials`.
+
+ For example, in an HTTP Bearer token scheme, the client will send a header
+ like:
+
+ ```
+ Authorization: Bearer deadbeef12346
+ ```
+
+ In this case:
+
+ * `scheme` will have the value `"Bearer"`
+ * `credentials` will have the value `"deadbeef12346"`
+ """
+
+ scheme: Annotated[
+ str,
+ Doc(
+ """
+ The HTTP authorization scheme extracted from the header value.
+ """
+ ),
+ ]
+ credentials: Annotated[
+ str,
+ Doc(
+ """
+ The HTTP authorization credentials extracted from the header value.
+ """
+ ),
+ ]
+
+
+class HTTPBase(SecurityBase):
+ def __init__(
+ self,
+ *,
+ scheme: str,
+ scheme_name: Optional[str] = None,
+ description: Optional[str] = None,
+ auto_error: bool = True,
+ ):
+ self.model = HTTPBaseModel(scheme=scheme, description=description)
+ self.scheme_name = scheme_name or self.__class__.__name__
+ self.auto_error = auto_error
+
+ async def __call__(
+ self, request: Request
+ ) -> Optional[HTTPAuthorizationCredentials]:
+ authorization = request.headers.get("Authorization")
+ scheme, credentials = get_authorization_scheme_param(authorization)
+ if not (authorization and scheme and credentials):
+ if self.auto_error:
+ raise HTTPException(
+ status_code=HTTP_403_FORBIDDEN, detail="Not authenticated"
+ )
+ else:
+ return None
+ return HTTPAuthorizationCredentials(scheme=scheme, credentials=credentials)
+
+
+class HTTPBasic(HTTPBase):
+ """
+ HTTP Basic authentication.
+
+ ## Usage
+
+ Create an instance object and use that object as the dependency in `Depends()`.
+
+ The dependency result will be an `HTTPBasicCredentials` object containing the
+ `username` and the `password`.
+
+ Read more about it in the
+ [FastAPI docs for HTTP Basic Auth](https://fastapi.tiangolo.com/advanced/security/http-basic-auth/).
+
+ ## Example
+
+ ```python
+ from typing import Annotated
+
+ from fastapi import Depends, FastAPI
+ from fastapi.security import HTTPBasic, HTTPBasicCredentials
+
+ app = FastAPI()
+
+ security = HTTPBasic()
+
+
+ @app.get("/users/me")
+ def read_current_user(credentials: Annotated[HTTPBasicCredentials, Depends(security)]):
+ return {"username": credentials.username, "password": credentials.password}
+ ```
+ """
+
+ def __init__(
+ self,
+ *,
+ scheme_name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme name.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ realm: Annotated[
+ Optional[str],
+ Doc(
+ """
+ HTTP Basic authentication realm.
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme description.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ auto_error: Annotated[
+ bool,
+ Doc(
+ """
+ By default, if the HTTP Basic authentication is not provided (a
+ header), `HTTPBasic` will automatically cancel the request and send the
+ client an error.
+
+ If `auto_error` is set to `False`, when the HTTP Basic authentication
+ is not available, instead of erroring out, the dependency result will
+ be `None`.
+
+ This is useful when you want to have optional authentication.
+
+ It is also useful when you want to have authentication that can be
+ provided in one of multiple optional ways (for example, in HTTP Basic
+ authentication or in an HTTP Bearer token).
+ """
+ ),
+ ] = True,
+ ):
+ self.model = HTTPBaseModel(scheme="basic", description=description)
+ self.scheme_name = scheme_name or self.__class__.__name__
+ self.realm = realm
+ self.auto_error = auto_error
+
+ async def __call__( # type: ignore
+ self, request: Request
+ ) -> Optional[HTTPBasicCredentials]:
+ authorization = request.headers.get("Authorization")
+ scheme, param = get_authorization_scheme_param(authorization)
+ if self.realm:
+ unauthorized_headers = {"WWW-Authenticate": f'Basic realm="{self.realm}"'}
+ else:
+ unauthorized_headers = {"WWW-Authenticate": "Basic"}
+ if not authorization or scheme.lower() != "basic":
+ if self.auto_error:
+ raise HTTPException(
+ status_code=HTTP_401_UNAUTHORIZED,
+ detail="Not authenticated",
+ headers=unauthorized_headers,
+ )
+ else:
+ return None
+ invalid_user_credentials_exc = HTTPException(
+ status_code=HTTP_401_UNAUTHORIZED,
+ detail="Invalid authentication credentials",
+ headers=unauthorized_headers,
+ )
+ try:
+ data = b64decode(param).decode("ascii")
+ except (ValueError, UnicodeDecodeError, binascii.Error):
+ raise invalid_user_credentials_exc # noqa: B904
+ username, separator, password = data.partition(":")
+ if not separator:
+ raise invalid_user_credentials_exc
+ return HTTPBasicCredentials(username=username, password=password)
+
+
+class HTTPBearer(HTTPBase):
+ """
+ HTTP Bearer token authentication.
+
+ ## Usage
+
+ Create an instance object and use that object as the dependency in `Depends()`.
+
+ The dependency result will be an `HTTPAuthorizationCredentials` object containing
+ the `scheme` and the `credentials`.
+
+ ## Example
+
+ ```python
+ from typing import Annotated
+
+ from fastapi import Depends, FastAPI
+ from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
+
+ app = FastAPI()
+
+ security = HTTPBearer()
+
+
+ @app.get("/users/me")
+ def read_current_user(
+ credentials: Annotated[HTTPAuthorizationCredentials, Depends(security)]
+ ):
+ return {"scheme": credentials.scheme, "credentials": credentials.credentials}
+ ```
+ """
+
+ def __init__(
+ self,
+ *,
+ bearerFormat: Annotated[Optional[str], Doc("Bearer token format.")] = None,
+ scheme_name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme name.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme description.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ auto_error: Annotated[
+ bool,
+ Doc(
+ """
+ By default, if the HTTP Bearer token is not provided (in an
+ `Authorization` header), `HTTPBearer` will automatically cancel the
+ request and send the client an error.
+
+ If `auto_error` is set to `False`, when the HTTP Bearer token
+ is not available, instead of erroring out, the dependency result will
+ be `None`.
+
+ This is useful when you want to have optional authentication.
+
+ It is also useful when you want to have authentication that can be
+ provided in one of multiple optional ways (for example, in an HTTP
+ Bearer token or in a cookie).
+ """
+ ),
+ ] = True,
+ ):
+ self.model = HTTPBearerModel(bearerFormat=bearerFormat, description=description)
+ self.scheme_name = scheme_name or self.__class__.__name__
+ self.auto_error = auto_error
+
+ async def __call__(
+ self, request: Request
+ ) -> Optional[HTTPAuthorizationCredentials]:
+ authorization = request.headers.get("Authorization")
+ scheme, credentials = get_authorization_scheme_param(authorization)
+ if not (authorization and scheme and credentials):
+ if self.auto_error:
+ raise HTTPException(
+ status_code=HTTP_403_FORBIDDEN, detail="Not authenticated"
+ )
+ else:
+ return None
+ if scheme.lower() != "bearer":
+ if self.auto_error:
+ raise HTTPException(
+ status_code=HTTP_403_FORBIDDEN,
+ detail="Invalid authentication credentials",
+ )
+ else:
+ return None
+ return HTTPAuthorizationCredentials(scheme=scheme, credentials=credentials)
+
+
+class HTTPDigest(HTTPBase):
+ """
+ HTTP Digest authentication.
+
+ ## Usage
+
+ Create an instance object and use that object as the dependency in `Depends()`.
+
+ The dependency result will be an `HTTPAuthorizationCredentials` object containing
+ the `scheme` and the `credentials`.
+
+ ## Example
+
+ ```python
+ from typing import Annotated
+
+ from fastapi import Depends, FastAPI
+ from fastapi.security import HTTPAuthorizationCredentials, HTTPDigest
+
+ app = FastAPI()
+
+ security = HTTPDigest()
+
+
+ @app.get("/users/me")
+ def read_current_user(
+ credentials: Annotated[HTTPAuthorizationCredentials, Depends(security)]
+ ):
+ return {"scheme": credentials.scheme, "credentials": credentials.credentials}
+ ```
+ """
+
+ def __init__(
+ self,
+ *,
+ scheme_name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme name.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme description.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ auto_error: Annotated[
+ bool,
+ Doc(
+ """
+ By default, if the HTTP Digest is not provided, `HTTPDigest` will
+ automatically cancel the request and send the client an error.
+
+ If `auto_error` is set to `False`, when the HTTP Digest is not
+ available, instead of erroring out, the dependency result will
+ be `None`.
+
+ This is useful when you want to have optional authentication.
+
+ It is also useful when you want to have authentication that can be
+ provided in one of multiple optional ways (for example, in HTTP
+ Digest or in a cookie).
+ """
+ ),
+ ] = True,
+ ):
+ self.model = HTTPBaseModel(scheme="digest", description=description)
+ self.scheme_name = scheme_name or self.__class__.__name__
+ self.auto_error = auto_error
+
+ async def __call__(
+ self, request: Request
+ ) -> Optional[HTTPAuthorizationCredentials]:
+ authorization = request.headers.get("Authorization")
+ scheme, credentials = get_authorization_scheme_param(authorization)
+ if not (authorization and scheme and credentials):
+ if self.auto_error:
+ raise HTTPException(
+ status_code=HTTP_403_FORBIDDEN, detail="Not authenticated"
+ )
+ else:
+ return None
+ if scheme.lower() != "digest":
+ if self.auto_error:
+ raise HTTPException(
+ status_code=HTTP_403_FORBIDDEN,
+ detail="Invalid authentication credentials",
+ )
+ else:
+ return None
+ return HTTPAuthorizationCredentials(scheme=scheme, credentials=credentials)
diff --git a/venv/Lib/site-packages/fastapi/security/oauth2.py b/venv/Lib/site-packages/fastapi/security/oauth2.py
new file mode 100644
index 00000000..88e394db
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/security/oauth2.py
@@ -0,0 +1,653 @@
+from typing import Any, Dict, List, Optional, Union, cast
+
+from fastapi.exceptions import HTTPException
+from fastapi.openapi.models import OAuth2 as OAuth2Model
+from fastapi.openapi.models import OAuthFlows as OAuthFlowsModel
+from fastapi.param_functions import Form
+from fastapi.security.base import SecurityBase
+from fastapi.security.utils import get_authorization_scheme_param
+from starlette.requests import Request
+from starlette.status import HTTP_401_UNAUTHORIZED, HTTP_403_FORBIDDEN
+
+# TODO: import from typing when deprecating Python 3.9
+from typing_extensions import Annotated, Doc
+
+
+class OAuth2PasswordRequestForm:
+ """
+ This is a dependency class to collect the `username` and `password` as form data
+ for an OAuth2 password flow.
+
+ The OAuth2 specification dictates that for a password flow the data should be
+ collected using form data (instead of JSON) and that it should have the specific
+ fields `username` and `password`.
+
+ All the initialization parameters are extracted from the request.
+
+ Read more about it in the
+ [FastAPI docs for Simple OAuth2 with Password and Bearer](https://fastapi.tiangolo.com/tutorial/security/simple-oauth2/).
+
+ ## Example
+
+ ```python
+ from typing import Annotated
+
+ from fastapi import Depends, FastAPI
+ from fastapi.security import OAuth2PasswordRequestForm
+
+ app = FastAPI()
+
+
+ @app.post("/login")
+ def login(form_data: Annotated[OAuth2PasswordRequestForm, Depends()]):
+ data = {}
+ data["scopes"] = []
+ for scope in form_data.scopes:
+ data["scopes"].append(scope)
+ if form_data.client_id:
+ data["client_id"] = form_data.client_id
+ if form_data.client_secret:
+ data["client_secret"] = form_data.client_secret
+ return data
+ ```
+
+ Note that for OAuth2 the scope `items:read` is a single scope in an opaque string.
+ You could have custom internal logic to separate it by colon characters (`:`) or
+ similar, and get the two parts `items` and `read`. Many applications do that to
+ group and organize permissions, you could do it as well in your application, just
+ know that that it is application specific, it's not part of the specification.
+ """
+
+ def __init__(
+ self,
+ *,
+ grant_type: Annotated[
+ Union[str, None],
+ Form(pattern="^password$"),
+ Doc(
+ """
+ The OAuth2 spec says it is required and MUST be the fixed string
+ "password". Nevertheless, this dependency class is permissive and
+ allows not passing it. If you want to enforce it, use instead the
+ `OAuth2PasswordRequestFormStrict` dependency.
+ """
+ ),
+ ] = None,
+ username: Annotated[
+ str,
+ Form(),
+ Doc(
+ """
+ `username` string. The OAuth2 spec requires the exact field name
+ `username`.
+ """
+ ),
+ ],
+ password: Annotated[
+ str,
+ Form(json_schema_extra={"format": "password"}),
+ Doc(
+ """
+ `password` string. The OAuth2 spec requires the exact field name
+ `password".
+ """
+ ),
+ ],
+ scope: Annotated[
+ str,
+ Form(),
+ Doc(
+ """
+ A single string with actually several scopes separated by spaces. Each
+ scope is also a string.
+
+ For example, a single string with:
+
+ ```python
+ "items:read items:write users:read profile openid"
+ ````
+
+ would represent the scopes:
+
+ * `items:read`
+ * `items:write`
+ * `users:read`
+ * `profile`
+ * `openid`
+ """
+ ),
+ ] = "",
+ client_id: Annotated[
+ Union[str, None],
+ Form(),
+ Doc(
+ """
+ If there's a `client_id`, it can be sent as part of the form fields.
+ But the OAuth2 specification recommends sending the `client_id` and
+ `client_secret` (if any) using HTTP Basic auth.
+ """
+ ),
+ ] = None,
+ client_secret: Annotated[
+ Union[str, None],
+ Form(json_schema_extra={"format": "password"}),
+ Doc(
+ """
+ If there's a `client_password` (and a `client_id`), they can be sent
+ as part of the form fields. But the OAuth2 specification recommends
+ sending the `client_id` and `client_secret` (if any) using HTTP Basic
+ auth.
+ """
+ ),
+ ] = None,
+ ):
+ self.grant_type = grant_type
+ self.username = username
+ self.password = password
+ self.scopes = scope.split()
+ self.client_id = client_id
+ self.client_secret = client_secret
+
+
+class OAuth2PasswordRequestFormStrict(OAuth2PasswordRequestForm):
+ """
+ This is a dependency class to collect the `username` and `password` as form data
+ for an OAuth2 password flow.
+
+ The OAuth2 specification dictates that for a password flow the data should be
+ collected using form data (instead of JSON) and that it should have the specific
+ fields `username` and `password`.
+
+ All the initialization parameters are extracted from the request.
+
+ The only difference between `OAuth2PasswordRequestFormStrict` and
+ `OAuth2PasswordRequestForm` is that `OAuth2PasswordRequestFormStrict` requires the
+ client to send the form field `grant_type` with the value `"password"`, which
+ is required in the OAuth2 specification (it seems that for no particular reason),
+ while for `OAuth2PasswordRequestForm` `grant_type` is optional.
+
+ Read more about it in the
+ [FastAPI docs for Simple OAuth2 with Password and Bearer](https://fastapi.tiangolo.com/tutorial/security/simple-oauth2/).
+
+ ## Example
+
+ ```python
+ from typing import Annotated
+
+ from fastapi import Depends, FastAPI
+ from fastapi.security import OAuth2PasswordRequestForm
+
+ app = FastAPI()
+
+
+ @app.post("/login")
+ def login(form_data: Annotated[OAuth2PasswordRequestFormStrict, Depends()]):
+ data = {}
+ data["scopes"] = []
+ for scope in form_data.scopes:
+ data["scopes"].append(scope)
+ if form_data.client_id:
+ data["client_id"] = form_data.client_id
+ if form_data.client_secret:
+ data["client_secret"] = form_data.client_secret
+ return data
+ ```
+
+ Note that for OAuth2 the scope `items:read` is a single scope in an opaque string.
+ You could have custom internal logic to separate it by colon characters (`:`) or
+ similar, and get the two parts `items` and `read`. Many applications do that to
+ group and organize permissions, you could do it as well in your application, just
+ know that that it is application specific, it's not part of the specification.
+
+
+ grant_type: the OAuth2 spec says it is required and MUST be the fixed string "password".
+ This dependency is strict about it. If you want to be permissive, use instead the
+ OAuth2PasswordRequestForm dependency class.
+ username: username string. The OAuth2 spec requires the exact field name "username".
+ password: password string. The OAuth2 spec requires the exact field name "password".
+ scope: Optional string. Several scopes (each one a string) separated by spaces. E.g.
+ "items:read items:write users:read profile openid"
+ client_id: optional string. OAuth2 recommends sending the client_id and client_secret (if any)
+ using HTTP Basic auth, as: client_id:client_secret
+ client_secret: optional string. OAuth2 recommends sending the client_id and client_secret (if any)
+ using HTTP Basic auth, as: client_id:client_secret
+ """
+
+ def __init__(
+ self,
+ grant_type: Annotated[
+ str,
+ Form(pattern="^password$"),
+ Doc(
+ """
+ The OAuth2 spec says it is required and MUST be the fixed string
+ "password". This dependency is strict about it. If you want to be
+ permissive, use instead the `OAuth2PasswordRequestForm` dependency
+ class.
+ """
+ ),
+ ],
+ username: Annotated[
+ str,
+ Form(),
+ Doc(
+ """
+ `username` string. The OAuth2 spec requires the exact field name
+ `username`.
+ """
+ ),
+ ],
+ password: Annotated[
+ str,
+ Form(),
+ Doc(
+ """
+ `password` string. The OAuth2 spec requires the exact field name
+ `password".
+ """
+ ),
+ ],
+ scope: Annotated[
+ str,
+ Form(),
+ Doc(
+ """
+ A single string with actually several scopes separated by spaces. Each
+ scope is also a string.
+
+ For example, a single string with:
+
+ ```python
+ "items:read items:write users:read profile openid"
+ ````
+
+ would represent the scopes:
+
+ * `items:read`
+ * `items:write`
+ * `users:read`
+ * `profile`
+ * `openid`
+ """
+ ),
+ ] = "",
+ client_id: Annotated[
+ Union[str, None],
+ Form(),
+ Doc(
+ """
+ If there's a `client_id`, it can be sent as part of the form fields.
+ But the OAuth2 specification recommends sending the `client_id` and
+ `client_secret` (if any) using HTTP Basic auth.
+ """
+ ),
+ ] = None,
+ client_secret: Annotated[
+ Union[str, None],
+ Form(),
+ Doc(
+ """
+ If there's a `client_password` (and a `client_id`), they can be sent
+ as part of the form fields. But the OAuth2 specification recommends
+ sending the `client_id` and `client_secret` (if any) using HTTP Basic
+ auth.
+ """
+ ),
+ ] = None,
+ ):
+ super().__init__(
+ grant_type=grant_type,
+ username=username,
+ password=password,
+ scope=scope,
+ client_id=client_id,
+ client_secret=client_secret,
+ )
+
+
+class OAuth2(SecurityBase):
+ """
+ This is the base class for OAuth2 authentication, an instance of it would be used
+ as a dependency. All other OAuth2 classes inherit from it and customize it for
+ each OAuth2 flow.
+
+ You normally would not create a new class inheriting from it but use one of the
+ existing subclasses, and maybe compose them if you want to support multiple flows.
+
+ Read more about it in the
+ [FastAPI docs for Security](https://fastapi.tiangolo.com/tutorial/security/).
+ """
+
+ def __init__(
+ self,
+ *,
+ flows: Annotated[
+ Union[OAuthFlowsModel, Dict[str, Dict[str, Any]]],
+ Doc(
+ """
+ The dictionary of OAuth2 flows.
+ """
+ ),
+ ] = OAuthFlowsModel(),
+ scheme_name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme name.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme description.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ auto_error: Annotated[
+ bool,
+ Doc(
+ """
+ By default, if no HTTP Authorization header is provided, required for
+ OAuth2 authentication, it will automatically cancel the request and
+ send the client an error.
+
+ If `auto_error` is set to `False`, when the HTTP Authorization header
+ is not available, instead of erroring out, the dependency result will
+ be `None`.
+
+ This is useful when you want to have optional authentication.
+
+ It is also useful when you want to have authentication that can be
+ provided in one of multiple optional ways (for example, with OAuth2
+ or in a cookie).
+ """
+ ),
+ ] = True,
+ ):
+ self.model = OAuth2Model(
+ flows=cast(OAuthFlowsModel, flows), description=description
+ )
+ self.scheme_name = scheme_name or self.__class__.__name__
+ self.auto_error = auto_error
+
+ async def __call__(self, request: Request) -> Optional[str]:
+ authorization = request.headers.get("Authorization")
+ if not authorization:
+ if self.auto_error:
+ raise HTTPException(
+ status_code=HTTP_403_FORBIDDEN, detail="Not authenticated"
+ )
+ else:
+ return None
+ return authorization
+
+
+class OAuth2PasswordBearer(OAuth2):
+ """
+ OAuth2 flow for authentication using a bearer token obtained with a password.
+ An instance of it would be used as a dependency.
+
+ Read more about it in the
+ [FastAPI docs for Simple OAuth2 with Password and Bearer](https://fastapi.tiangolo.com/tutorial/security/simple-oauth2/).
+ """
+
+ def __init__(
+ self,
+ tokenUrl: Annotated[
+ str,
+ Doc(
+ """
+ The URL to obtain the OAuth2 token. This would be the *path operation*
+ that has `OAuth2PasswordRequestForm` as a dependency.
+ """
+ ),
+ ],
+ scheme_name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme name.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ scopes: Annotated[
+ Optional[Dict[str, str]],
+ Doc(
+ """
+ The OAuth2 scopes that would be required by the *path operations* that
+ use this dependency.
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme description.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ auto_error: Annotated[
+ bool,
+ Doc(
+ """
+ By default, if no HTTP Authorization header is provided, required for
+ OAuth2 authentication, it will automatically cancel the request and
+ send the client an error.
+
+ If `auto_error` is set to `False`, when the HTTP Authorization header
+ is not available, instead of erroring out, the dependency result will
+ be `None`.
+
+ This is useful when you want to have optional authentication.
+
+ It is also useful when you want to have authentication that can be
+ provided in one of multiple optional ways (for example, with OAuth2
+ or in a cookie).
+ """
+ ),
+ ] = True,
+ refreshUrl: Annotated[
+ Optional[str],
+ Doc(
+ """
+ The URL to refresh the token and obtain a new one.
+ """
+ ),
+ ] = None,
+ ):
+ if not scopes:
+ scopes = {}
+ flows = OAuthFlowsModel(
+ password=cast(
+ Any,
+ {
+ "tokenUrl": tokenUrl,
+ "refreshUrl": refreshUrl,
+ "scopes": scopes,
+ },
+ )
+ )
+ super().__init__(
+ flows=flows,
+ scheme_name=scheme_name,
+ description=description,
+ auto_error=auto_error,
+ )
+
+ async def __call__(self, request: Request) -> Optional[str]:
+ authorization = request.headers.get("Authorization")
+ scheme, param = get_authorization_scheme_param(authorization)
+ if not authorization or scheme.lower() != "bearer":
+ if self.auto_error:
+ raise HTTPException(
+ status_code=HTTP_401_UNAUTHORIZED,
+ detail="Not authenticated",
+ headers={"WWW-Authenticate": "Bearer"},
+ )
+ else:
+ return None
+ return param
+
+
+class OAuth2AuthorizationCodeBearer(OAuth2):
+ """
+ OAuth2 flow for authentication using a bearer token obtained with an OAuth2 code
+ flow. An instance of it would be used as a dependency.
+ """
+
+ def __init__(
+ self,
+ authorizationUrl: str,
+ tokenUrl: Annotated[
+ str,
+ Doc(
+ """
+ The URL to obtain the OAuth2 token.
+ """
+ ),
+ ],
+ refreshUrl: Annotated[
+ Optional[str],
+ Doc(
+ """
+ The URL to refresh the token and obtain a new one.
+ """
+ ),
+ ] = None,
+ scheme_name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme name.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ scopes: Annotated[
+ Optional[Dict[str, str]],
+ Doc(
+ """
+ The OAuth2 scopes that would be required by the *path operations* that
+ use this dependency.
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme description.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ auto_error: Annotated[
+ bool,
+ Doc(
+ """
+ By default, if no HTTP Authorization header is provided, required for
+ OAuth2 authentication, it will automatically cancel the request and
+ send the client an error.
+
+ If `auto_error` is set to `False`, when the HTTP Authorization header
+ is not available, instead of erroring out, the dependency result will
+ be `None`.
+
+ This is useful when you want to have optional authentication.
+
+ It is also useful when you want to have authentication that can be
+ provided in one of multiple optional ways (for example, with OAuth2
+ or in a cookie).
+ """
+ ),
+ ] = True,
+ ):
+ if not scopes:
+ scopes = {}
+ flows = OAuthFlowsModel(
+ authorizationCode=cast(
+ Any,
+ {
+ "authorizationUrl": authorizationUrl,
+ "tokenUrl": tokenUrl,
+ "refreshUrl": refreshUrl,
+ "scopes": scopes,
+ },
+ )
+ )
+ super().__init__(
+ flows=flows,
+ scheme_name=scheme_name,
+ description=description,
+ auto_error=auto_error,
+ )
+
+ async def __call__(self, request: Request) -> Optional[str]:
+ authorization = request.headers.get("Authorization")
+ scheme, param = get_authorization_scheme_param(authorization)
+ if not authorization or scheme.lower() != "bearer":
+ if self.auto_error:
+ raise HTTPException(
+ status_code=HTTP_401_UNAUTHORIZED,
+ detail="Not authenticated",
+ headers={"WWW-Authenticate": "Bearer"},
+ )
+ else:
+ return None # pragma: nocover
+ return param
+
+
+class SecurityScopes:
+ """
+ This is a special class that you can define in a parameter in a dependency to
+ obtain the OAuth2 scopes required by all the dependencies in the same chain.
+
+ This way, multiple dependencies can have different scopes, even when used in the
+ same *path operation*. And with this, you can access all the scopes required in
+ all those dependencies in a single place.
+
+ Read more about it in the
+ [FastAPI docs for OAuth2 scopes](https://fastapi.tiangolo.com/advanced/security/oauth2-scopes/).
+ """
+
+ def __init__(
+ self,
+ scopes: Annotated[
+ Optional[List[str]],
+ Doc(
+ """
+ This will be filled by FastAPI.
+ """
+ ),
+ ] = None,
+ ):
+ self.scopes: Annotated[
+ List[str],
+ Doc(
+ """
+ The list of all the scopes required by dependencies.
+ """
+ ),
+ ] = scopes or []
+ self.scope_str: Annotated[
+ str,
+ Doc(
+ """
+ All the scopes required by all the dependencies in a single string
+ separated by spaces, as defined in the OAuth2 specification.
+ """
+ ),
+ ] = " ".join(self.scopes)
diff --git a/venv/Lib/site-packages/fastapi/security/open_id_connect_url.py b/venv/Lib/site-packages/fastapi/security/open_id_connect_url.py
new file mode 100644
index 00000000..c8cceb91
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/security/open_id_connect_url.py
@@ -0,0 +1,84 @@
+from typing import Optional
+
+from fastapi.openapi.models import OpenIdConnect as OpenIdConnectModel
+from fastapi.security.base import SecurityBase
+from starlette.exceptions import HTTPException
+from starlette.requests import Request
+from starlette.status import HTTP_403_FORBIDDEN
+from typing_extensions import Annotated, Doc
+
+
+class OpenIdConnect(SecurityBase):
+ """
+ OpenID Connect authentication class. An instance of it would be used as a
+ dependency.
+ """
+
+ def __init__(
+ self,
+ *,
+ openIdConnectUrl: Annotated[
+ str,
+ Doc(
+ """
+ The OpenID Connect URL.
+ """
+ ),
+ ],
+ scheme_name: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme name.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ description: Annotated[
+ Optional[str],
+ Doc(
+ """
+ Security scheme description.
+
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
+ """
+ ),
+ ] = None,
+ auto_error: Annotated[
+ bool,
+ Doc(
+ """
+ By default, if no HTTP Authorization header is provided, required for
+ OpenID Connect authentication, it will automatically cancel the request
+ and send the client an error.
+
+ If `auto_error` is set to `False`, when the HTTP Authorization header
+ is not available, instead of erroring out, the dependency result will
+ be `None`.
+
+ This is useful when you want to have optional authentication.
+
+ It is also useful when you want to have authentication that can be
+ provided in one of multiple optional ways (for example, with OpenID
+ Connect or in a cookie).
+ """
+ ),
+ ] = True,
+ ):
+ self.model = OpenIdConnectModel(
+ openIdConnectUrl=openIdConnectUrl, description=description
+ )
+ self.scheme_name = scheme_name or self.__class__.__name__
+ self.auto_error = auto_error
+
+ async def __call__(self, request: Request) -> Optional[str]:
+ authorization = request.headers.get("Authorization")
+ if not authorization:
+ if self.auto_error:
+ raise HTTPException(
+ status_code=HTTP_403_FORBIDDEN, detail="Not authenticated"
+ )
+ else:
+ return None
+ return authorization
diff --git a/venv/Lib/site-packages/fastapi/security/utils.py b/venv/Lib/site-packages/fastapi/security/utils.py
new file mode 100644
index 00000000..fa7a450b
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/security/utils.py
@@ -0,0 +1,10 @@
+from typing import Optional, Tuple
+
+
+def get_authorization_scheme_param(
+ authorization_header_value: Optional[str],
+) -> Tuple[str, str]:
+ if not authorization_header_value:
+ return "", ""
+ scheme, _, param = authorization_header_value.partition(" ")
+ return scheme, param
diff --git a/venv/Lib/site-packages/fastapi/staticfiles.py b/venv/Lib/site-packages/fastapi/staticfiles.py
new file mode 100644
index 00000000..299015d4
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/staticfiles.py
@@ -0,0 +1 @@
+from starlette.staticfiles import StaticFiles as StaticFiles # noqa
diff --git a/venv/Lib/site-packages/fastapi/templating.py b/venv/Lib/site-packages/fastapi/templating.py
new file mode 100644
index 00000000..0cb86848
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/templating.py
@@ -0,0 +1 @@
+from starlette.templating import Jinja2Templates as Jinja2Templates # noqa
diff --git a/venv/Lib/site-packages/fastapi/testclient.py b/venv/Lib/site-packages/fastapi/testclient.py
new file mode 100644
index 00000000..4012406a
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/testclient.py
@@ -0,0 +1 @@
+from starlette.testclient import TestClient as TestClient # noqa
diff --git a/venv/Lib/site-packages/fastapi/types.py b/venv/Lib/site-packages/fastapi/types.py
new file mode 100644
index 00000000..3205654c
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/types.py
@@ -0,0 +1,10 @@
+import types
+from enum import Enum
+from typing import Any, Callable, Dict, Set, Type, TypeVar, Union
+
+from pydantic import BaseModel
+
+DecoratedCallable = TypeVar("DecoratedCallable", bound=Callable[..., Any])
+UnionType = getattr(types, "UnionType", Union)
+ModelNameMap = Dict[Union[Type[BaseModel], Type[Enum]], str]
+IncEx = Union[Set[int], Set[str], Dict[int, Any], Dict[str, Any]]
diff --git a/venv/Lib/site-packages/fastapi/utils.py b/venv/Lib/site-packages/fastapi/utils.py
new file mode 100644
index 00000000..4c7350fe
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/utils.py
@@ -0,0 +1,220 @@
+import re
+import warnings
+from dataclasses import is_dataclass
+from typing import (
+ TYPE_CHECKING,
+ Any,
+ Dict,
+ MutableMapping,
+ Optional,
+ Set,
+ Type,
+ Union,
+ cast,
+)
+from weakref import WeakKeyDictionary
+
+import fastapi
+from fastapi._compat import (
+ PYDANTIC_V2,
+ BaseConfig,
+ ModelField,
+ PydanticSchemaGenerationError,
+ Undefined,
+ UndefinedType,
+ Validator,
+ lenient_issubclass,
+)
+from fastapi.datastructures import DefaultPlaceholder, DefaultType
+from pydantic import BaseModel, create_model
+from pydantic.fields import FieldInfo
+from typing_extensions import Literal
+
+if TYPE_CHECKING: # pragma: nocover
+ from .routing import APIRoute
+
+# Cache for `create_cloned_field`
+_CLONED_TYPES_CACHE: MutableMapping[Type[BaseModel], Type[BaseModel]] = (
+ WeakKeyDictionary()
+)
+
+
+def is_body_allowed_for_status_code(status_code: Union[int, str, None]) -> bool:
+ if status_code is None:
+ return True
+ # Ref: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#patterned-fields-1
+ if status_code in {
+ "default",
+ "1XX",
+ "2XX",
+ "3XX",
+ "4XX",
+ "5XX",
+ }:
+ return True
+ current_status_code = int(status_code)
+ return not (current_status_code < 200 or current_status_code in {204, 205, 304})
+
+
+def get_path_param_names(path: str) -> Set[str]:
+ return set(re.findall("{(.*?)}", path))
+
+
+def create_model_field(
+ name: str,
+ type_: Any,
+ class_validators: Optional[Dict[str, Validator]] = None,
+ default: Optional[Any] = Undefined,
+ required: Union[bool, UndefinedType] = Undefined,
+ model_config: Type[BaseConfig] = BaseConfig,
+ field_info: Optional[FieldInfo] = None,
+ alias: Optional[str] = None,
+ mode: Literal["validation", "serialization"] = "validation",
+) -> ModelField:
+ class_validators = class_validators or {}
+ if PYDANTIC_V2:
+ field_info = field_info or FieldInfo(
+ annotation=type_, default=default, alias=alias
+ )
+ else:
+ field_info = field_info or FieldInfo()
+ kwargs = {"name": name, "field_info": field_info}
+ if PYDANTIC_V2:
+ kwargs.update({"mode": mode})
+ else:
+ kwargs.update(
+ {
+ "type_": type_,
+ "class_validators": class_validators,
+ "default": default,
+ "required": required,
+ "model_config": model_config,
+ "alias": alias,
+ }
+ )
+ try:
+ return ModelField(**kwargs) # type: ignore[arg-type]
+ except (RuntimeError, PydanticSchemaGenerationError):
+ raise fastapi.exceptions.FastAPIError(
+ "Invalid args for response field! Hint: "
+ f"check that {type_} is a valid Pydantic field type. "
+ "If you are using a return type annotation that is not a valid Pydantic "
+ "field (e.g. Union[Response, dict, None]) you can disable generating the "
+ "response model from the type annotation with the path operation decorator "
+ "parameter response_model=None. Read more: "
+ "https://fastapi.tiangolo.com/tutorial/response-model/"
+ ) from None
+
+
+def create_cloned_field(
+ field: ModelField,
+ *,
+ cloned_types: Optional[MutableMapping[Type[BaseModel], Type[BaseModel]]] = None,
+) -> ModelField:
+ if PYDANTIC_V2:
+ return field
+ # cloned_types caches already cloned types to support recursive models and improve
+ # performance by avoiding unnecessary cloning
+ if cloned_types is None:
+ cloned_types = _CLONED_TYPES_CACHE
+
+ original_type = field.type_
+ if is_dataclass(original_type) and hasattr(original_type, "__pydantic_model__"):
+ original_type = original_type.__pydantic_model__
+ use_type = original_type
+ if lenient_issubclass(original_type, BaseModel):
+ original_type = cast(Type[BaseModel], original_type)
+ use_type = cloned_types.get(original_type)
+ if use_type is None:
+ use_type = create_model(original_type.__name__, __base__=original_type)
+ cloned_types[original_type] = use_type
+ for f in original_type.__fields__.values():
+ use_type.__fields__[f.name] = create_cloned_field(
+ f, cloned_types=cloned_types
+ )
+ new_field = create_model_field(name=field.name, type_=use_type)
+ new_field.has_alias = field.has_alias # type: ignore[attr-defined]
+ new_field.alias = field.alias # type: ignore[misc]
+ new_field.class_validators = field.class_validators # type: ignore[attr-defined]
+ new_field.default = field.default # type: ignore[misc]
+ new_field.required = field.required # type: ignore[misc]
+ new_field.model_config = field.model_config # type: ignore[attr-defined]
+ new_field.field_info = field.field_info
+ new_field.allow_none = field.allow_none # type: ignore[attr-defined]
+ new_field.validate_always = field.validate_always # type: ignore[attr-defined]
+ if field.sub_fields: # type: ignore[attr-defined]
+ new_field.sub_fields = [ # type: ignore[attr-defined]
+ create_cloned_field(sub_field, cloned_types=cloned_types)
+ for sub_field in field.sub_fields # type: ignore[attr-defined]
+ ]
+ if field.key_field: # type: ignore[attr-defined]
+ new_field.key_field = create_cloned_field( # type: ignore[attr-defined]
+ field.key_field, # type: ignore[attr-defined]
+ cloned_types=cloned_types,
+ )
+ new_field.validators = field.validators # type: ignore[attr-defined]
+ new_field.pre_validators = field.pre_validators # type: ignore[attr-defined]
+ new_field.post_validators = field.post_validators # type: ignore[attr-defined]
+ new_field.parse_json = field.parse_json # type: ignore[attr-defined]
+ new_field.shape = field.shape # type: ignore[attr-defined]
+ new_field.populate_validators() # type: ignore[attr-defined]
+ return new_field
+
+
+def generate_operation_id_for_path(
+ *, name: str, path: str, method: str
+) -> str: # pragma: nocover
+ warnings.warn(
+ "fastapi.utils.generate_operation_id_for_path() was deprecated, "
+ "it is not used internally, and will be removed soon",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ operation_id = f"{name}{path}"
+ operation_id = re.sub(r"\W", "_", operation_id)
+ operation_id = f"{operation_id}_{method.lower()}"
+ return operation_id
+
+
+def generate_unique_id(route: "APIRoute") -> str:
+ operation_id = f"{route.name}{route.path_format}"
+ operation_id = re.sub(r"\W", "_", operation_id)
+ assert route.methods
+ operation_id = f"{operation_id}_{list(route.methods)[0].lower()}"
+ return operation_id
+
+
+def deep_dict_update(main_dict: Dict[Any, Any], update_dict: Dict[Any, Any]) -> None:
+ for key, value in update_dict.items():
+ if (
+ key in main_dict
+ and isinstance(main_dict[key], dict)
+ and isinstance(value, dict)
+ ):
+ deep_dict_update(main_dict[key], value)
+ elif (
+ key in main_dict
+ and isinstance(main_dict[key], list)
+ and isinstance(update_dict[key], list)
+ ):
+ main_dict[key] = main_dict[key] + update_dict[key]
+ else:
+ main_dict[key] = value
+
+
+def get_value_or_default(
+ first_item: Union[DefaultPlaceholder, DefaultType],
+ *extra_items: Union[DefaultPlaceholder, DefaultType],
+) -> Union[DefaultPlaceholder, DefaultType]:
+ """
+ Pass items or `DefaultPlaceholder`s by descending priority.
+
+ The first one to _not_ be a `DefaultPlaceholder` will be returned.
+
+ Otherwise, the first item (a `DefaultPlaceholder`) will be returned.
+ """
+ items = (first_item,) + extra_items
+ for item in items:
+ if not isinstance(item, DefaultPlaceholder):
+ return item
+ return first_item
diff --git a/venv/Lib/site-packages/fastapi/websockets.py b/venv/Lib/site-packages/fastapi/websockets.py
new file mode 100644
index 00000000..55a4ac4a
--- /dev/null
+++ b/venv/Lib/site-packages/fastapi/websockets.py
@@ -0,0 +1,3 @@
+from starlette.websockets import WebSocket as WebSocket # noqa
+from starlette.websockets import WebSocketDisconnect as WebSocketDisconnect # noqa
+from starlette.websockets import WebSocketState as WebSocketState # noqa
diff --git a/venv/Lib/site-packages/frozenlist/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/frozenlist/__pycache__/__init__.cpython-312.pyc
index ab7c3113..fbfe40ff 100644
Binary files a/venv/Lib/site-packages/frozenlist/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/frozenlist/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/google/protobuf/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/google/protobuf/__pycache__/__init__.cpython-312.pyc
index 4cec3467..acbff829 100644
Binary files a/venv/Lib/site-packages/google/protobuf/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/google/protobuf/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/google/protobuf/__pycache__/descriptor.cpython-312.pyc b/venv/Lib/site-packages/google/protobuf/__pycache__/descriptor.cpython-312.pyc
index dc4d89f4..b35453a5 100644
Binary files a/venv/Lib/site-packages/google/protobuf/__pycache__/descriptor.cpython-312.pyc and b/venv/Lib/site-packages/google/protobuf/__pycache__/descriptor.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/google/protobuf/__pycache__/descriptor_database.cpython-312.pyc b/venv/Lib/site-packages/google/protobuf/__pycache__/descriptor_database.cpython-312.pyc
index 005b53da..02e675cf 100644
Binary files a/venv/Lib/site-packages/google/protobuf/__pycache__/descriptor_database.cpython-312.pyc and b/venv/Lib/site-packages/google/protobuf/__pycache__/descriptor_database.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/google/protobuf/__pycache__/descriptor_pool.cpython-312.pyc b/venv/Lib/site-packages/google/protobuf/__pycache__/descriptor_pool.cpython-312.pyc
index c7bf79f4..ad3ddde4 100644
Binary files a/venv/Lib/site-packages/google/protobuf/__pycache__/descriptor_pool.cpython-312.pyc and b/venv/Lib/site-packages/google/protobuf/__pycache__/descriptor_pool.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/google/protobuf/__pycache__/duration_pb2.cpython-312.pyc b/venv/Lib/site-packages/google/protobuf/__pycache__/duration_pb2.cpython-312.pyc
index 31aaa6b9..27ff694c 100644
Binary files a/venv/Lib/site-packages/google/protobuf/__pycache__/duration_pb2.cpython-312.pyc and b/venv/Lib/site-packages/google/protobuf/__pycache__/duration_pb2.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/google/protobuf/__pycache__/empty_pb2.cpython-312.pyc b/venv/Lib/site-packages/google/protobuf/__pycache__/empty_pb2.cpython-312.pyc
index bbc81cfa..bda40a1e 100644
Binary files a/venv/Lib/site-packages/google/protobuf/__pycache__/empty_pb2.cpython-312.pyc and b/venv/Lib/site-packages/google/protobuf/__pycache__/empty_pb2.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/google/protobuf/__pycache__/json_format.cpython-312.pyc b/venv/Lib/site-packages/google/protobuf/__pycache__/json_format.cpython-312.pyc
index 3d74a6e0..a48c287d 100644
Binary files a/venv/Lib/site-packages/google/protobuf/__pycache__/json_format.cpython-312.pyc and b/venv/Lib/site-packages/google/protobuf/__pycache__/json_format.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/google/protobuf/__pycache__/message.cpython-312.pyc b/venv/Lib/site-packages/google/protobuf/__pycache__/message.cpython-312.pyc
index 6a044949..8db29042 100644
Binary files a/venv/Lib/site-packages/google/protobuf/__pycache__/message.cpython-312.pyc and b/venv/Lib/site-packages/google/protobuf/__pycache__/message.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/google/protobuf/__pycache__/message_factory.cpython-312.pyc b/venv/Lib/site-packages/google/protobuf/__pycache__/message_factory.cpython-312.pyc
index 89f8f494..cb0a2f06 100644
Binary files a/venv/Lib/site-packages/google/protobuf/__pycache__/message_factory.cpython-312.pyc and b/venv/Lib/site-packages/google/protobuf/__pycache__/message_factory.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/google/protobuf/__pycache__/reflection.cpython-312.pyc b/venv/Lib/site-packages/google/protobuf/__pycache__/reflection.cpython-312.pyc
index e07ff188..f1634060 100644
Binary files a/venv/Lib/site-packages/google/protobuf/__pycache__/reflection.cpython-312.pyc and b/venv/Lib/site-packages/google/protobuf/__pycache__/reflection.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/google/protobuf/__pycache__/runtime_version.cpython-312.pyc b/venv/Lib/site-packages/google/protobuf/__pycache__/runtime_version.cpython-312.pyc
index 6caf8027..feaa2e96 100644
Binary files a/venv/Lib/site-packages/google/protobuf/__pycache__/runtime_version.cpython-312.pyc and b/venv/Lib/site-packages/google/protobuf/__pycache__/runtime_version.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/google/protobuf/__pycache__/symbol_database.cpython-312.pyc b/venv/Lib/site-packages/google/protobuf/__pycache__/symbol_database.cpython-312.pyc
index 3baf061f..2318fcec 100644
Binary files a/venv/Lib/site-packages/google/protobuf/__pycache__/symbol_database.cpython-312.pyc and b/venv/Lib/site-packages/google/protobuf/__pycache__/symbol_database.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/google/protobuf/__pycache__/text_encoding.cpython-312.pyc b/venv/Lib/site-packages/google/protobuf/__pycache__/text_encoding.cpython-312.pyc
index 0d4a0aa5..b0fff9bc 100644
Binary files a/venv/Lib/site-packages/google/protobuf/__pycache__/text_encoding.cpython-312.pyc and b/venv/Lib/site-packages/google/protobuf/__pycache__/text_encoding.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/google/protobuf/__pycache__/text_format.cpython-312.pyc b/venv/Lib/site-packages/google/protobuf/__pycache__/text_format.cpython-312.pyc
index 6eacd6c2..58dfeb3d 100644
Binary files a/venv/Lib/site-packages/google/protobuf/__pycache__/text_format.cpython-312.pyc and b/venv/Lib/site-packages/google/protobuf/__pycache__/text_format.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/google/protobuf/__pycache__/timestamp_pb2.cpython-312.pyc b/venv/Lib/site-packages/google/protobuf/__pycache__/timestamp_pb2.cpython-312.pyc
index c84504dc..7643bbb7 100644
Binary files a/venv/Lib/site-packages/google/protobuf/__pycache__/timestamp_pb2.cpython-312.pyc and b/venv/Lib/site-packages/google/protobuf/__pycache__/timestamp_pb2.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/google/protobuf/__pycache__/unknown_fields.cpython-312.pyc b/venv/Lib/site-packages/google/protobuf/__pycache__/unknown_fields.cpython-312.pyc
index 9f5d95b8..3db00309 100644
Binary files a/venv/Lib/site-packages/google/protobuf/__pycache__/unknown_fields.cpython-312.pyc and b/venv/Lib/site-packages/google/protobuf/__pycache__/unknown_fields.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/google/protobuf/internal/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/google/protobuf/internal/__pycache__/__init__.cpython-312.pyc
index 1dd68a21..e1c22b85 100644
Binary files a/venv/Lib/site-packages/google/protobuf/internal/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/google/protobuf/internal/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/google/protobuf/internal/__pycache__/api_implementation.cpython-312.pyc b/venv/Lib/site-packages/google/protobuf/internal/__pycache__/api_implementation.cpython-312.pyc
index 4d963975..60f48eef 100644
Binary files a/venv/Lib/site-packages/google/protobuf/internal/__pycache__/api_implementation.cpython-312.pyc and b/venv/Lib/site-packages/google/protobuf/internal/__pycache__/api_implementation.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/google/protobuf/internal/__pycache__/builder.cpython-312.pyc b/venv/Lib/site-packages/google/protobuf/internal/__pycache__/builder.cpython-312.pyc
index 6f42d514..931855d8 100644
Binary files a/venv/Lib/site-packages/google/protobuf/internal/__pycache__/builder.cpython-312.pyc and b/venv/Lib/site-packages/google/protobuf/internal/__pycache__/builder.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/google/protobuf/internal/__pycache__/containers.cpython-312.pyc b/venv/Lib/site-packages/google/protobuf/internal/__pycache__/containers.cpython-312.pyc
index eba8d290..0c672332 100644
Binary files a/venv/Lib/site-packages/google/protobuf/internal/__pycache__/containers.cpython-312.pyc and b/venv/Lib/site-packages/google/protobuf/internal/__pycache__/containers.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/google/protobuf/internal/__pycache__/decoder.cpython-312.pyc b/venv/Lib/site-packages/google/protobuf/internal/__pycache__/decoder.cpython-312.pyc
index 464f6475..4f4c82c1 100644
Binary files a/venv/Lib/site-packages/google/protobuf/internal/__pycache__/decoder.cpython-312.pyc and b/venv/Lib/site-packages/google/protobuf/internal/__pycache__/decoder.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/google/protobuf/internal/__pycache__/encoder.cpython-312.pyc b/venv/Lib/site-packages/google/protobuf/internal/__pycache__/encoder.cpython-312.pyc
index 46c5303b..346940be 100644
Binary files a/venv/Lib/site-packages/google/protobuf/internal/__pycache__/encoder.cpython-312.pyc and b/venv/Lib/site-packages/google/protobuf/internal/__pycache__/encoder.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/google/protobuf/internal/__pycache__/enum_type_wrapper.cpython-312.pyc b/venv/Lib/site-packages/google/protobuf/internal/__pycache__/enum_type_wrapper.cpython-312.pyc
index aa73bda5..6287b9db 100644
Binary files a/venv/Lib/site-packages/google/protobuf/internal/__pycache__/enum_type_wrapper.cpython-312.pyc and b/venv/Lib/site-packages/google/protobuf/internal/__pycache__/enum_type_wrapper.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/google/protobuf/internal/__pycache__/extension_dict.cpython-312.pyc b/venv/Lib/site-packages/google/protobuf/internal/__pycache__/extension_dict.cpython-312.pyc
index 910ebb75..45d196ce 100644
Binary files a/venv/Lib/site-packages/google/protobuf/internal/__pycache__/extension_dict.cpython-312.pyc and b/venv/Lib/site-packages/google/protobuf/internal/__pycache__/extension_dict.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/google/protobuf/internal/__pycache__/field_mask.cpython-312.pyc b/venv/Lib/site-packages/google/protobuf/internal/__pycache__/field_mask.cpython-312.pyc
index e9af34a9..89cd011d 100644
Binary files a/venv/Lib/site-packages/google/protobuf/internal/__pycache__/field_mask.cpython-312.pyc and b/venv/Lib/site-packages/google/protobuf/internal/__pycache__/field_mask.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/google/protobuf/internal/__pycache__/message_listener.cpython-312.pyc b/venv/Lib/site-packages/google/protobuf/internal/__pycache__/message_listener.cpython-312.pyc
index 01a946a7..13bd47c2 100644
Binary files a/venv/Lib/site-packages/google/protobuf/internal/__pycache__/message_listener.cpython-312.pyc and b/venv/Lib/site-packages/google/protobuf/internal/__pycache__/message_listener.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/google/protobuf/internal/__pycache__/python_edition_defaults.cpython-312.pyc b/venv/Lib/site-packages/google/protobuf/internal/__pycache__/python_edition_defaults.cpython-312.pyc
index 148fec00..dcbe5719 100644
Binary files a/venv/Lib/site-packages/google/protobuf/internal/__pycache__/python_edition_defaults.cpython-312.pyc and b/venv/Lib/site-packages/google/protobuf/internal/__pycache__/python_edition_defaults.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/google/protobuf/internal/__pycache__/python_message.cpython-312.pyc b/venv/Lib/site-packages/google/protobuf/internal/__pycache__/python_message.cpython-312.pyc
index 54f79047..3d82241e 100644
Binary files a/venv/Lib/site-packages/google/protobuf/internal/__pycache__/python_message.cpython-312.pyc and b/venv/Lib/site-packages/google/protobuf/internal/__pycache__/python_message.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/google/protobuf/internal/__pycache__/type_checkers.cpython-312.pyc b/venv/Lib/site-packages/google/protobuf/internal/__pycache__/type_checkers.cpython-312.pyc
index f10e21be..dc37f5b3 100644
Binary files a/venv/Lib/site-packages/google/protobuf/internal/__pycache__/type_checkers.cpython-312.pyc and b/venv/Lib/site-packages/google/protobuf/internal/__pycache__/type_checkers.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/google/protobuf/internal/__pycache__/well_known_types.cpython-312.pyc b/venv/Lib/site-packages/google/protobuf/internal/__pycache__/well_known_types.cpython-312.pyc
index c56b7d67..529b1d9a 100644
Binary files a/venv/Lib/site-packages/google/protobuf/internal/__pycache__/well_known_types.cpython-312.pyc and b/venv/Lib/site-packages/google/protobuf/internal/__pycache__/well_known_types.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/google/protobuf/internal/__pycache__/wire_format.cpython-312.pyc b/venv/Lib/site-packages/google/protobuf/internal/__pycache__/wire_format.cpython-312.pyc
index 478158e8..18588d38 100644
Binary files a/venv/Lib/site-packages/google/protobuf/internal/__pycache__/wire_format.cpython-312.pyc and b/venv/Lib/site-packages/google/protobuf/internal/__pycache__/wire_format.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/google/protobuf/pyext/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/google/protobuf/pyext/__pycache__/__init__.cpython-312.pyc
index 8acaef3b..d9239b94 100644
Binary files a/venv/Lib/site-packages/google/protobuf/pyext/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/google/protobuf/pyext/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/google/protobuf/pyext/__pycache__/cpp_message.cpython-312.pyc b/venv/Lib/site-packages/google/protobuf/pyext/__pycache__/cpp_message.cpython-312.pyc
index 74c5d9d5..e48e123d 100644
Binary files a/venv/Lib/site-packages/google/protobuf/pyext/__pycache__/cpp_message.cpython-312.pyc and b/venv/Lib/site-packages/google/protobuf/pyext/__pycache__/cpp_message.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/h11/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/h11/__pycache__/__init__.cpython-312.pyc
index e6e0b3a1..1a57fd0d 100644
Binary files a/venv/Lib/site-packages/h11/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/h11/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/h11/__pycache__/_abnf.cpython-312.pyc b/venv/Lib/site-packages/h11/__pycache__/_abnf.cpython-312.pyc
index 61b5aa53..71dd85fc 100644
Binary files a/venv/Lib/site-packages/h11/__pycache__/_abnf.cpython-312.pyc and b/venv/Lib/site-packages/h11/__pycache__/_abnf.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/h11/__pycache__/_connection.cpython-312.pyc b/venv/Lib/site-packages/h11/__pycache__/_connection.cpython-312.pyc
index 21f15fe9..3af04d3c 100644
Binary files a/venv/Lib/site-packages/h11/__pycache__/_connection.cpython-312.pyc and b/venv/Lib/site-packages/h11/__pycache__/_connection.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/h11/__pycache__/_events.cpython-312.pyc b/venv/Lib/site-packages/h11/__pycache__/_events.cpython-312.pyc
index dd454e97..65cfe71e 100644
Binary files a/venv/Lib/site-packages/h11/__pycache__/_events.cpython-312.pyc and b/venv/Lib/site-packages/h11/__pycache__/_events.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/h11/__pycache__/_headers.cpython-312.pyc b/venv/Lib/site-packages/h11/__pycache__/_headers.cpython-312.pyc
index 1c7ef164..b9cdc53f 100644
Binary files a/venv/Lib/site-packages/h11/__pycache__/_headers.cpython-312.pyc and b/venv/Lib/site-packages/h11/__pycache__/_headers.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/h11/__pycache__/_readers.cpython-312.pyc b/venv/Lib/site-packages/h11/__pycache__/_readers.cpython-312.pyc
index 84745bbb..95acb44f 100644
Binary files a/venv/Lib/site-packages/h11/__pycache__/_readers.cpython-312.pyc and b/venv/Lib/site-packages/h11/__pycache__/_readers.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/h11/__pycache__/_receivebuffer.cpython-312.pyc b/venv/Lib/site-packages/h11/__pycache__/_receivebuffer.cpython-312.pyc
index 28826197..d27d6e78 100644
Binary files a/venv/Lib/site-packages/h11/__pycache__/_receivebuffer.cpython-312.pyc and b/venv/Lib/site-packages/h11/__pycache__/_receivebuffer.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/h11/__pycache__/_state.cpython-312.pyc b/venv/Lib/site-packages/h11/__pycache__/_state.cpython-312.pyc
index 1602c623..63f583b8 100644
Binary files a/venv/Lib/site-packages/h11/__pycache__/_state.cpython-312.pyc and b/venv/Lib/site-packages/h11/__pycache__/_state.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/h11/__pycache__/_util.cpython-312.pyc b/venv/Lib/site-packages/h11/__pycache__/_util.cpython-312.pyc
index 87e3b470..e51952bc 100644
Binary files a/venv/Lib/site-packages/h11/__pycache__/_util.cpython-312.pyc and b/venv/Lib/site-packages/h11/__pycache__/_util.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/h11/__pycache__/_version.cpython-312.pyc b/venv/Lib/site-packages/h11/__pycache__/_version.cpython-312.pyc
index f948d9c8..cc2a69a4 100644
Binary files a/venv/Lib/site-packages/h11/__pycache__/_version.cpython-312.pyc and b/venv/Lib/site-packages/h11/__pycache__/_version.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/h11/__pycache__/_writers.cpython-312.pyc b/venv/Lib/site-packages/h11/__pycache__/_writers.cpython-312.pyc
index e7538f10..1fa94c44 100644
Binary files a/venv/Lib/site-packages/h11/__pycache__/_writers.cpython-312.pyc and b/venv/Lib/site-packages/h11/__pycache__/_writers.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpcore/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/httpcore/__pycache__/__init__.cpython-312.pyc
index 55a826cf..87c31c25 100644
Binary files a/venv/Lib/site-packages/httpcore/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/httpcore/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpcore/__pycache__/_api.cpython-312.pyc b/venv/Lib/site-packages/httpcore/__pycache__/_api.cpython-312.pyc
index 8f48a618..ce5d1d6b 100644
Binary files a/venv/Lib/site-packages/httpcore/__pycache__/_api.cpython-312.pyc and b/venv/Lib/site-packages/httpcore/__pycache__/_api.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpcore/__pycache__/_exceptions.cpython-312.pyc b/venv/Lib/site-packages/httpcore/__pycache__/_exceptions.cpython-312.pyc
index ea6c953a..473b886a 100644
Binary files a/venv/Lib/site-packages/httpcore/__pycache__/_exceptions.cpython-312.pyc and b/venv/Lib/site-packages/httpcore/__pycache__/_exceptions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpcore/__pycache__/_models.cpython-312.pyc b/venv/Lib/site-packages/httpcore/__pycache__/_models.cpython-312.pyc
index e1ef7b1e..7776d9b2 100644
Binary files a/venv/Lib/site-packages/httpcore/__pycache__/_models.cpython-312.pyc and b/venv/Lib/site-packages/httpcore/__pycache__/_models.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpcore/__pycache__/_ssl.cpython-312.pyc b/venv/Lib/site-packages/httpcore/__pycache__/_ssl.cpython-312.pyc
index cd0b9ba9..b1875ace 100644
Binary files a/venv/Lib/site-packages/httpcore/__pycache__/_ssl.cpython-312.pyc and b/venv/Lib/site-packages/httpcore/__pycache__/_ssl.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpcore/__pycache__/_synchronization.cpython-312.pyc b/venv/Lib/site-packages/httpcore/__pycache__/_synchronization.cpython-312.pyc
index a8e6f670..0a72721f 100644
Binary files a/venv/Lib/site-packages/httpcore/__pycache__/_synchronization.cpython-312.pyc and b/venv/Lib/site-packages/httpcore/__pycache__/_synchronization.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpcore/__pycache__/_trace.cpython-312.pyc b/venv/Lib/site-packages/httpcore/__pycache__/_trace.cpython-312.pyc
index fdb518ff..b75086a1 100644
Binary files a/venv/Lib/site-packages/httpcore/__pycache__/_trace.cpython-312.pyc and b/venv/Lib/site-packages/httpcore/__pycache__/_trace.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpcore/__pycache__/_utils.cpython-312.pyc b/venv/Lib/site-packages/httpcore/__pycache__/_utils.cpython-312.pyc
index 6bc68b29..b461dd07 100644
Binary files a/venv/Lib/site-packages/httpcore/__pycache__/_utils.cpython-312.pyc and b/venv/Lib/site-packages/httpcore/__pycache__/_utils.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpcore/_async/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/httpcore/_async/__pycache__/__init__.cpython-312.pyc
index b9a94f26..69cd0978 100644
Binary files a/venv/Lib/site-packages/httpcore/_async/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/httpcore/_async/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpcore/_async/__pycache__/connection.cpython-312.pyc b/venv/Lib/site-packages/httpcore/_async/__pycache__/connection.cpython-312.pyc
index 5b26db49..442eb81a 100644
Binary files a/venv/Lib/site-packages/httpcore/_async/__pycache__/connection.cpython-312.pyc and b/venv/Lib/site-packages/httpcore/_async/__pycache__/connection.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpcore/_async/__pycache__/connection_pool.cpython-312.pyc b/venv/Lib/site-packages/httpcore/_async/__pycache__/connection_pool.cpython-312.pyc
index 09ebd7ed..d123747f 100644
Binary files a/venv/Lib/site-packages/httpcore/_async/__pycache__/connection_pool.cpython-312.pyc and b/venv/Lib/site-packages/httpcore/_async/__pycache__/connection_pool.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpcore/_async/__pycache__/http11.cpython-312.pyc b/venv/Lib/site-packages/httpcore/_async/__pycache__/http11.cpython-312.pyc
index 5bd5bfbb..bde7a8d3 100644
Binary files a/venv/Lib/site-packages/httpcore/_async/__pycache__/http11.cpython-312.pyc and b/venv/Lib/site-packages/httpcore/_async/__pycache__/http11.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpcore/_async/__pycache__/http2.cpython-312.pyc b/venv/Lib/site-packages/httpcore/_async/__pycache__/http2.cpython-312.pyc
index ccc28a97..a79f6995 100644
Binary files a/venv/Lib/site-packages/httpcore/_async/__pycache__/http2.cpython-312.pyc and b/venv/Lib/site-packages/httpcore/_async/__pycache__/http2.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpcore/_async/__pycache__/http_proxy.cpython-312.pyc b/venv/Lib/site-packages/httpcore/_async/__pycache__/http_proxy.cpython-312.pyc
index 5dbd7164..6d1c773f 100644
Binary files a/venv/Lib/site-packages/httpcore/_async/__pycache__/http_proxy.cpython-312.pyc and b/venv/Lib/site-packages/httpcore/_async/__pycache__/http_proxy.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpcore/_async/__pycache__/interfaces.cpython-312.pyc b/venv/Lib/site-packages/httpcore/_async/__pycache__/interfaces.cpython-312.pyc
index 61d9d01c..703935ed 100644
Binary files a/venv/Lib/site-packages/httpcore/_async/__pycache__/interfaces.cpython-312.pyc and b/venv/Lib/site-packages/httpcore/_async/__pycache__/interfaces.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpcore/_async/__pycache__/socks_proxy.cpython-312.pyc b/venv/Lib/site-packages/httpcore/_async/__pycache__/socks_proxy.cpython-312.pyc
index 43a2aaf6..86d04f92 100644
Binary files a/venv/Lib/site-packages/httpcore/_async/__pycache__/socks_proxy.cpython-312.pyc and b/venv/Lib/site-packages/httpcore/_async/__pycache__/socks_proxy.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpcore/_backends/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/httpcore/_backends/__pycache__/__init__.cpython-312.pyc
index 894437d8..9ae64c6f 100644
Binary files a/venv/Lib/site-packages/httpcore/_backends/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/httpcore/_backends/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpcore/_backends/__pycache__/anyio.cpython-312.pyc b/venv/Lib/site-packages/httpcore/_backends/__pycache__/anyio.cpython-312.pyc
index 7ed9d0b0..bd7dc66d 100644
Binary files a/venv/Lib/site-packages/httpcore/_backends/__pycache__/anyio.cpython-312.pyc and b/venv/Lib/site-packages/httpcore/_backends/__pycache__/anyio.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpcore/_backends/__pycache__/auto.cpython-312.pyc b/venv/Lib/site-packages/httpcore/_backends/__pycache__/auto.cpython-312.pyc
index 529d97cf..6b0bcdfa 100644
Binary files a/venv/Lib/site-packages/httpcore/_backends/__pycache__/auto.cpython-312.pyc and b/venv/Lib/site-packages/httpcore/_backends/__pycache__/auto.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpcore/_backends/__pycache__/base.cpython-312.pyc b/venv/Lib/site-packages/httpcore/_backends/__pycache__/base.cpython-312.pyc
index c77e153c..403e62cc 100644
Binary files a/venv/Lib/site-packages/httpcore/_backends/__pycache__/base.cpython-312.pyc and b/venv/Lib/site-packages/httpcore/_backends/__pycache__/base.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpcore/_backends/__pycache__/mock.cpython-312.pyc b/venv/Lib/site-packages/httpcore/_backends/__pycache__/mock.cpython-312.pyc
index 9fd9c8d0..e1d323c2 100644
Binary files a/venv/Lib/site-packages/httpcore/_backends/__pycache__/mock.cpython-312.pyc and b/venv/Lib/site-packages/httpcore/_backends/__pycache__/mock.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpcore/_backends/__pycache__/sync.cpython-312.pyc b/venv/Lib/site-packages/httpcore/_backends/__pycache__/sync.cpython-312.pyc
index a3500bc6..049ed0b8 100644
Binary files a/venv/Lib/site-packages/httpcore/_backends/__pycache__/sync.cpython-312.pyc and b/venv/Lib/site-packages/httpcore/_backends/__pycache__/sync.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpcore/_backends/__pycache__/trio.cpython-312.pyc b/venv/Lib/site-packages/httpcore/_backends/__pycache__/trio.cpython-312.pyc
index 16429032..2fe24ad7 100644
Binary files a/venv/Lib/site-packages/httpcore/_backends/__pycache__/trio.cpython-312.pyc and b/venv/Lib/site-packages/httpcore/_backends/__pycache__/trio.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpcore/_sync/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/httpcore/_sync/__pycache__/__init__.cpython-312.pyc
index dbf24c7a..ef09017b 100644
Binary files a/venv/Lib/site-packages/httpcore/_sync/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/httpcore/_sync/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpcore/_sync/__pycache__/connection.cpython-312.pyc b/venv/Lib/site-packages/httpcore/_sync/__pycache__/connection.cpython-312.pyc
index 7dd24cd5..fb743a67 100644
Binary files a/venv/Lib/site-packages/httpcore/_sync/__pycache__/connection.cpython-312.pyc and b/venv/Lib/site-packages/httpcore/_sync/__pycache__/connection.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpcore/_sync/__pycache__/connection_pool.cpython-312.pyc b/venv/Lib/site-packages/httpcore/_sync/__pycache__/connection_pool.cpython-312.pyc
index 6084e5c7..081cfc3c 100644
Binary files a/venv/Lib/site-packages/httpcore/_sync/__pycache__/connection_pool.cpython-312.pyc and b/venv/Lib/site-packages/httpcore/_sync/__pycache__/connection_pool.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpcore/_sync/__pycache__/http11.cpython-312.pyc b/venv/Lib/site-packages/httpcore/_sync/__pycache__/http11.cpython-312.pyc
index 8d2629a7..45607510 100644
Binary files a/venv/Lib/site-packages/httpcore/_sync/__pycache__/http11.cpython-312.pyc and b/venv/Lib/site-packages/httpcore/_sync/__pycache__/http11.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpcore/_sync/__pycache__/http2.cpython-312.pyc b/venv/Lib/site-packages/httpcore/_sync/__pycache__/http2.cpython-312.pyc
index fa2d17d3..a014fef8 100644
Binary files a/venv/Lib/site-packages/httpcore/_sync/__pycache__/http2.cpython-312.pyc and b/venv/Lib/site-packages/httpcore/_sync/__pycache__/http2.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpcore/_sync/__pycache__/http_proxy.cpython-312.pyc b/venv/Lib/site-packages/httpcore/_sync/__pycache__/http_proxy.cpython-312.pyc
index f0d1fcea..4e668fd9 100644
Binary files a/venv/Lib/site-packages/httpcore/_sync/__pycache__/http_proxy.cpython-312.pyc and b/venv/Lib/site-packages/httpcore/_sync/__pycache__/http_proxy.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpcore/_sync/__pycache__/interfaces.cpython-312.pyc b/venv/Lib/site-packages/httpcore/_sync/__pycache__/interfaces.cpython-312.pyc
index 30364159..be87defb 100644
Binary files a/venv/Lib/site-packages/httpcore/_sync/__pycache__/interfaces.cpython-312.pyc and b/venv/Lib/site-packages/httpcore/_sync/__pycache__/interfaces.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpcore/_sync/__pycache__/socks_proxy.cpython-312.pyc b/venv/Lib/site-packages/httpcore/_sync/__pycache__/socks_proxy.cpython-312.pyc
index 4b9c364d..9609bb46 100644
Binary files a/venv/Lib/site-packages/httpcore/_sync/__pycache__/socks_proxy.cpython-312.pyc and b/venv/Lib/site-packages/httpcore/_sync/__pycache__/socks_proxy.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpx/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/httpx/__pycache__/__init__.cpython-312.pyc
index fca42c0c..48d4c896 100644
Binary files a/venv/Lib/site-packages/httpx/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/httpx/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpx/__pycache__/__version__.cpython-312.pyc b/venv/Lib/site-packages/httpx/__pycache__/__version__.cpython-312.pyc
index c25dcaf3..c7618fa7 100644
Binary files a/venv/Lib/site-packages/httpx/__pycache__/__version__.cpython-312.pyc and b/venv/Lib/site-packages/httpx/__pycache__/__version__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpx/__pycache__/_api.cpython-312.pyc b/venv/Lib/site-packages/httpx/__pycache__/_api.cpython-312.pyc
index 59bbd01e..4d4c2ff2 100644
Binary files a/venv/Lib/site-packages/httpx/__pycache__/_api.cpython-312.pyc and b/venv/Lib/site-packages/httpx/__pycache__/_api.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpx/__pycache__/_auth.cpython-312.pyc b/venv/Lib/site-packages/httpx/__pycache__/_auth.cpython-312.pyc
index c4413bcd..083f90aa 100644
Binary files a/venv/Lib/site-packages/httpx/__pycache__/_auth.cpython-312.pyc and b/venv/Lib/site-packages/httpx/__pycache__/_auth.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpx/__pycache__/_client.cpython-312.pyc b/venv/Lib/site-packages/httpx/__pycache__/_client.cpython-312.pyc
index 1bf3ba12..8b48e1e6 100644
Binary files a/venv/Lib/site-packages/httpx/__pycache__/_client.cpython-312.pyc and b/venv/Lib/site-packages/httpx/__pycache__/_client.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpx/__pycache__/_config.cpython-312.pyc b/venv/Lib/site-packages/httpx/__pycache__/_config.cpython-312.pyc
index a17d5693..649a10b4 100644
Binary files a/venv/Lib/site-packages/httpx/__pycache__/_config.cpython-312.pyc and b/venv/Lib/site-packages/httpx/__pycache__/_config.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpx/__pycache__/_content.cpython-312.pyc b/venv/Lib/site-packages/httpx/__pycache__/_content.cpython-312.pyc
index a2d08e4c..ab6afbe0 100644
Binary files a/venv/Lib/site-packages/httpx/__pycache__/_content.cpython-312.pyc and b/venv/Lib/site-packages/httpx/__pycache__/_content.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpx/__pycache__/_decoders.cpython-312.pyc b/venv/Lib/site-packages/httpx/__pycache__/_decoders.cpython-312.pyc
index 1106f61b..8bc5daa6 100644
Binary files a/venv/Lib/site-packages/httpx/__pycache__/_decoders.cpython-312.pyc and b/venv/Lib/site-packages/httpx/__pycache__/_decoders.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpx/__pycache__/_exceptions.cpython-312.pyc b/venv/Lib/site-packages/httpx/__pycache__/_exceptions.cpython-312.pyc
index 2bcc0f5d..61e61b76 100644
Binary files a/venv/Lib/site-packages/httpx/__pycache__/_exceptions.cpython-312.pyc and b/venv/Lib/site-packages/httpx/__pycache__/_exceptions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpx/__pycache__/_main.cpython-312.pyc b/venv/Lib/site-packages/httpx/__pycache__/_main.cpython-312.pyc
index 9a820a7c..a88a19f2 100644
Binary files a/venv/Lib/site-packages/httpx/__pycache__/_main.cpython-312.pyc and b/venv/Lib/site-packages/httpx/__pycache__/_main.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpx/__pycache__/_models.cpython-312.pyc b/venv/Lib/site-packages/httpx/__pycache__/_models.cpython-312.pyc
index 18a99338..0ebb5779 100644
Binary files a/venv/Lib/site-packages/httpx/__pycache__/_models.cpython-312.pyc and b/venv/Lib/site-packages/httpx/__pycache__/_models.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpx/__pycache__/_multipart.cpython-312.pyc b/venv/Lib/site-packages/httpx/__pycache__/_multipart.cpython-312.pyc
index d5b9d187..41f186ec 100644
Binary files a/venv/Lib/site-packages/httpx/__pycache__/_multipart.cpython-312.pyc and b/venv/Lib/site-packages/httpx/__pycache__/_multipart.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpx/__pycache__/_status_codes.cpython-312.pyc b/venv/Lib/site-packages/httpx/__pycache__/_status_codes.cpython-312.pyc
index 3c882f26..be2c4c5a 100644
Binary files a/venv/Lib/site-packages/httpx/__pycache__/_status_codes.cpython-312.pyc and b/venv/Lib/site-packages/httpx/__pycache__/_status_codes.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpx/__pycache__/_types.cpython-312.pyc b/venv/Lib/site-packages/httpx/__pycache__/_types.cpython-312.pyc
index bc008da7..edc7f666 100644
Binary files a/venv/Lib/site-packages/httpx/__pycache__/_types.cpython-312.pyc and b/venv/Lib/site-packages/httpx/__pycache__/_types.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpx/__pycache__/_urlparse.cpython-312.pyc b/venv/Lib/site-packages/httpx/__pycache__/_urlparse.cpython-312.pyc
index 613f89a6..79e844b6 100644
Binary files a/venv/Lib/site-packages/httpx/__pycache__/_urlparse.cpython-312.pyc and b/venv/Lib/site-packages/httpx/__pycache__/_urlparse.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpx/__pycache__/_urls.cpython-312.pyc b/venv/Lib/site-packages/httpx/__pycache__/_urls.cpython-312.pyc
index a0033f9a..1a139a53 100644
Binary files a/venv/Lib/site-packages/httpx/__pycache__/_urls.cpython-312.pyc and b/venv/Lib/site-packages/httpx/__pycache__/_urls.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpx/__pycache__/_utils.cpython-312.pyc b/venv/Lib/site-packages/httpx/__pycache__/_utils.cpython-312.pyc
index 68d53fa0..a1575771 100644
Binary files a/venv/Lib/site-packages/httpx/__pycache__/_utils.cpython-312.pyc and b/venv/Lib/site-packages/httpx/__pycache__/_utils.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpx/_transports/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/httpx/_transports/__pycache__/__init__.cpython-312.pyc
index 2f689500..2603e5cd 100644
Binary files a/venv/Lib/site-packages/httpx/_transports/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/httpx/_transports/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpx/_transports/__pycache__/asgi.cpython-312.pyc b/venv/Lib/site-packages/httpx/_transports/__pycache__/asgi.cpython-312.pyc
index 57b04808..88f3a7c8 100644
Binary files a/venv/Lib/site-packages/httpx/_transports/__pycache__/asgi.cpython-312.pyc and b/venv/Lib/site-packages/httpx/_transports/__pycache__/asgi.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpx/_transports/__pycache__/base.cpython-312.pyc b/venv/Lib/site-packages/httpx/_transports/__pycache__/base.cpython-312.pyc
index 6f903175..8923a961 100644
Binary files a/venv/Lib/site-packages/httpx/_transports/__pycache__/base.cpython-312.pyc and b/venv/Lib/site-packages/httpx/_transports/__pycache__/base.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpx/_transports/__pycache__/default.cpython-312.pyc b/venv/Lib/site-packages/httpx/_transports/__pycache__/default.cpython-312.pyc
index 2d757e63..67129ca5 100644
Binary files a/venv/Lib/site-packages/httpx/_transports/__pycache__/default.cpython-312.pyc and b/venv/Lib/site-packages/httpx/_transports/__pycache__/default.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpx/_transports/__pycache__/mock.cpython-312.pyc b/venv/Lib/site-packages/httpx/_transports/__pycache__/mock.cpython-312.pyc
index 6b8bb16e..52482ee0 100644
Binary files a/venv/Lib/site-packages/httpx/_transports/__pycache__/mock.cpython-312.pyc and b/venv/Lib/site-packages/httpx/_transports/__pycache__/mock.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/httpx/_transports/__pycache__/wsgi.cpython-312.pyc b/venv/Lib/site-packages/httpx/_transports/__pycache__/wsgi.cpython-312.pyc
index 6dcb055b..e0f2a854 100644
Binary files a/venv/Lib/site-packages/httpx/_transports/__pycache__/wsgi.cpython-312.pyc and b/venv/Lib/site-packages/httpx/_transports/__pycache__/wsgi.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/idna/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/idna/__pycache__/__init__.cpython-312.pyc
index b741a48c..863466ea 100644
Binary files a/venv/Lib/site-packages/idna/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/idna/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/idna/__pycache__/core.cpython-312.pyc b/venv/Lib/site-packages/idna/__pycache__/core.cpython-312.pyc
index f2791514..6f0a4907 100644
Binary files a/venv/Lib/site-packages/idna/__pycache__/core.cpython-312.pyc and b/venv/Lib/site-packages/idna/__pycache__/core.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/idna/__pycache__/idnadata.cpython-312.pyc b/venv/Lib/site-packages/idna/__pycache__/idnadata.cpython-312.pyc
index 1ac20710..003adc0e 100644
Binary files a/venv/Lib/site-packages/idna/__pycache__/idnadata.cpython-312.pyc and b/venv/Lib/site-packages/idna/__pycache__/idnadata.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/idna/__pycache__/intranges.cpython-312.pyc b/venv/Lib/site-packages/idna/__pycache__/intranges.cpython-312.pyc
index a66af7ad..4a199b38 100644
Binary files a/venv/Lib/site-packages/idna/__pycache__/intranges.cpython-312.pyc and b/venv/Lib/site-packages/idna/__pycache__/intranges.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/idna/__pycache__/package_data.cpython-312.pyc b/venv/Lib/site-packages/idna/__pycache__/package_data.cpython-312.pyc
index 9488a73a..73d556b0 100644
Binary files a/venv/Lib/site-packages/idna/__pycache__/package_data.cpython-312.pyc and b/venv/Lib/site-packages/idna/__pycache__/package_data.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/jiter/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/jiter/__pycache__/__init__.cpython-312.pyc
index fdd55e34..7c9b1c50 100644
Binary files a/venv/Lib/site-packages/jiter/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/jiter/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/jwt/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/jwt/__pycache__/__init__.cpython-312.pyc
index 884231fc..e91692ff 100644
Binary files a/venv/Lib/site-packages/jwt/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/jwt/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/jwt/__pycache__/algorithms.cpython-312.pyc b/venv/Lib/site-packages/jwt/__pycache__/algorithms.cpython-312.pyc
index 25cc12a3..b5453f1d 100644
Binary files a/venv/Lib/site-packages/jwt/__pycache__/algorithms.cpython-312.pyc and b/venv/Lib/site-packages/jwt/__pycache__/algorithms.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/jwt/__pycache__/api_jwk.cpython-312.pyc b/venv/Lib/site-packages/jwt/__pycache__/api_jwk.cpython-312.pyc
index 95dba171..e5c9884b 100644
Binary files a/venv/Lib/site-packages/jwt/__pycache__/api_jwk.cpython-312.pyc and b/venv/Lib/site-packages/jwt/__pycache__/api_jwk.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/jwt/__pycache__/api_jws.cpython-312.pyc b/venv/Lib/site-packages/jwt/__pycache__/api_jws.cpython-312.pyc
index eb5783da..e063e89c 100644
Binary files a/venv/Lib/site-packages/jwt/__pycache__/api_jws.cpython-312.pyc and b/venv/Lib/site-packages/jwt/__pycache__/api_jws.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/jwt/__pycache__/api_jwt.cpython-312.pyc b/venv/Lib/site-packages/jwt/__pycache__/api_jwt.cpython-312.pyc
index aa1b05d8..15f0d03f 100644
Binary files a/venv/Lib/site-packages/jwt/__pycache__/api_jwt.cpython-312.pyc and b/venv/Lib/site-packages/jwt/__pycache__/api_jwt.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/jwt/__pycache__/exceptions.cpython-312.pyc b/venv/Lib/site-packages/jwt/__pycache__/exceptions.cpython-312.pyc
index d1684f8f..b88a60ac 100644
Binary files a/venv/Lib/site-packages/jwt/__pycache__/exceptions.cpython-312.pyc and b/venv/Lib/site-packages/jwt/__pycache__/exceptions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/jwt/__pycache__/jwk_set_cache.cpython-312.pyc b/venv/Lib/site-packages/jwt/__pycache__/jwk_set_cache.cpython-312.pyc
index 0940b80d..e923b5a5 100644
Binary files a/venv/Lib/site-packages/jwt/__pycache__/jwk_set_cache.cpython-312.pyc and b/venv/Lib/site-packages/jwt/__pycache__/jwk_set_cache.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/jwt/__pycache__/jwks_client.cpython-312.pyc b/venv/Lib/site-packages/jwt/__pycache__/jwks_client.cpython-312.pyc
index 1e475ff0..db37ae61 100644
Binary files a/venv/Lib/site-packages/jwt/__pycache__/jwks_client.cpython-312.pyc and b/venv/Lib/site-packages/jwt/__pycache__/jwks_client.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/jwt/__pycache__/types.cpython-312.pyc b/venv/Lib/site-packages/jwt/__pycache__/types.cpython-312.pyc
index 3b573fbe..aef58581 100644
Binary files a/venv/Lib/site-packages/jwt/__pycache__/types.cpython-312.pyc and b/venv/Lib/site-packages/jwt/__pycache__/types.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/jwt/__pycache__/utils.cpython-312.pyc b/venv/Lib/site-packages/jwt/__pycache__/utils.cpython-312.pyc
index 0cd57b3e..d719c33b 100644
Binary files a/venv/Lib/site-packages/jwt/__pycache__/utils.cpython-312.pyc and b/venv/Lib/site-packages/jwt/__pycache__/utils.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/jwt/__pycache__/warnings.cpython-312.pyc b/venv/Lib/site-packages/jwt/__pycache__/warnings.cpython-312.pyc
index 3f21c9c4..94f380fb 100644
Binary files a/venv/Lib/site-packages/jwt/__pycache__/warnings.cpython-312.pyc and b/venv/Lib/site-packages/jwt/__pycache__/warnings.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/__pycache__/__init__.cpython-312.pyc
index 54718518..ce346daf 100644
Binary files a/venv/Lib/site-packages/livekit/agents/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/__pycache__/_exceptions.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/__pycache__/_exceptions.cpython-312.pyc
index 94ce46f0..d570cee8 100644
Binary files a/venv/Lib/site-packages/livekit/agents/__pycache__/_exceptions.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/__pycache__/_exceptions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/__pycache__/http_server.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/__pycache__/http_server.cpython-312.pyc
index b6eeb119..7d10acdc 100644
Binary files a/venv/Lib/site-packages/livekit/agents/__pycache__/http_server.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/__pycache__/http_server.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/__pycache__/inference_runner.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/__pycache__/inference_runner.cpython-312.pyc
index d648e83a..1fec5e08 100644
Binary files a/venv/Lib/site-packages/livekit/agents/__pycache__/inference_runner.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/__pycache__/inference_runner.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/__pycache__/job.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/__pycache__/job.cpython-312.pyc
index 6300e88f..42261acb 100644
Binary files a/venv/Lib/site-packages/livekit/agents/__pycache__/job.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/__pycache__/job.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/__pycache__/log.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/__pycache__/log.cpython-312.pyc
index ad29163d..8f3e57af 100644
Binary files a/venv/Lib/site-packages/livekit/agents/__pycache__/log.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/__pycache__/log.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/__pycache__/plugin.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/__pycache__/plugin.cpython-312.pyc
index 608a6989..a2d9da68 100644
Binary files a/venv/Lib/site-packages/livekit/agents/__pycache__/plugin.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/__pycache__/plugin.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/__pycache__/types.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/__pycache__/types.cpython-312.pyc
index 29b60f45..9bf73f10 100644
Binary files a/venv/Lib/site-packages/livekit/agents/__pycache__/types.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/__pycache__/types.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/__pycache__/vad.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/__pycache__/vad.cpython-312.pyc
index 62c606b2..e73ee63d 100644
Binary files a/venv/Lib/site-packages/livekit/agents/__pycache__/vad.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/__pycache__/vad.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/__pycache__/version.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/__pycache__/version.cpython-312.pyc
index d16ced18..59d65bb0 100644
Binary files a/venv/Lib/site-packages/livekit/agents/__pycache__/version.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/__pycache__/version.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/__pycache__/worker.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/__pycache__/worker.cpython-312.pyc
index 58d20f4e..9d2f965f 100644
Binary files a/venv/Lib/site-packages/livekit/agents/__pycache__/worker.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/__pycache__/worker.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/cli/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/cli/__pycache__/__init__.cpython-312.pyc
index 2be00816..5f31a92e 100644
Binary files a/venv/Lib/site-packages/livekit/agents/cli/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/cli/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/cli/__pycache__/_run.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/cli/__pycache__/_run.cpython-312.pyc
index 661fdbf0..9ea93a9b 100644
Binary files a/venv/Lib/site-packages/livekit/agents/cli/__pycache__/_run.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/cli/__pycache__/_run.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/cli/__pycache__/cli.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/cli/__pycache__/cli.cpython-312.pyc
index 7aa3680b..7e53c687 100644
Binary files a/venv/Lib/site-packages/livekit/agents/cli/__pycache__/cli.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/cli/__pycache__/cli.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/cli/__pycache__/log.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/cli/__pycache__/log.cpython-312.pyc
index dff74e14..2e8347ef 100644
Binary files a/venv/Lib/site-packages/livekit/agents/cli/__pycache__/log.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/cli/__pycache__/log.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/cli/__pycache__/proto.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/cli/__pycache__/proto.cpython-312.pyc
index 98f87cdc..b7794fff 100644
Binary files a/venv/Lib/site-packages/livekit/agents/cli/__pycache__/proto.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/cli/__pycache__/proto.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/debug/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/debug/__pycache__/__init__.cpython-312.pyc
index 01221af9..58f7a6b2 100644
Binary files a/venv/Lib/site-packages/livekit/agents/debug/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/debug/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/debug/__pycache__/tracing.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/debug/__pycache__/tracing.cpython-312.pyc
index 6b0c9664..efdba5a9 100644
Binary files a/venv/Lib/site-packages/livekit/agents/debug/__pycache__/tracing.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/debug/__pycache__/tracing.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/__init__.cpython-312.pyc
index c5412a43..d31f1dd5 100644
Binary files a/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/channel.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/channel.cpython-312.pyc
index cbedd69b..5a72a03b 100644
Binary files a/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/channel.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/channel.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/inference_executor.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/inference_executor.cpython-312.pyc
index fe5bc183..5a186095 100644
Binary files a/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/inference_executor.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/inference_executor.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/inference_proc_executor.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/inference_proc_executor.cpython-312.pyc
index ec26bd29..877b6baf 100644
Binary files a/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/inference_proc_executor.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/inference_proc_executor.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/inference_proc_lazy_main.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/inference_proc_lazy_main.cpython-312.pyc
index b56aa93c..5eff6ba7 100644
Binary files a/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/inference_proc_lazy_main.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/inference_proc_lazy_main.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/job_executor.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/job_executor.cpython-312.pyc
index be0a7446..46b94171 100644
Binary files a/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/job_executor.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/job_executor.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/job_proc_executor.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/job_proc_executor.cpython-312.pyc
index d140a631..e91569fb 100644
Binary files a/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/job_proc_executor.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/job_proc_executor.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/job_proc_lazy_main.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/job_proc_lazy_main.cpython-312.pyc
index f3173aba..42a3e544 100644
Binary files a/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/job_proc_lazy_main.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/job_proc_lazy_main.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/job_thread_executor.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/job_thread_executor.cpython-312.pyc
index 7122b7af..ce1225e5 100644
Binary files a/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/job_thread_executor.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/job_thread_executor.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/log_queue.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/log_queue.cpython-312.pyc
index 16a90185..f59fc696 100644
Binary files a/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/log_queue.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/log_queue.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/proc_client.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/proc_client.cpython-312.pyc
index 5e65567c..87b3e479 100644
Binary files a/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/proc_client.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/proc_client.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/proc_pool.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/proc_pool.cpython-312.pyc
index b710e500..6516c522 100644
Binary files a/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/proc_pool.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/proc_pool.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/proto.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/proto.cpython-312.pyc
index 1115ab5d..b4b51ec8 100644
Binary files a/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/proto.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/proto.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/supervised_proc.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/supervised_proc.cpython-312.pyc
index 7a5d1b5e..046865a5 100644
Binary files a/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/supervised_proc.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/ipc/__pycache__/supervised_proc.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/llm/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/llm/__pycache__/__init__.cpython-312.pyc
index 3462db80..e46008cc 100644
Binary files a/venv/Lib/site-packages/livekit/agents/llm/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/llm/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/llm/__pycache__/_strict.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/llm/__pycache__/_strict.cpython-312.pyc
index 644fdaff..ae8c4408 100644
Binary files a/venv/Lib/site-packages/livekit/agents/llm/__pycache__/_strict.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/llm/__pycache__/_strict.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/llm/__pycache__/chat_context.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/llm/__pycache__/chat_context.cpython-312.pyc
index 0d18be07..9a3b7443 100644
Binary files a/venv/Lib/site-packages/livekit/agents/llm/__pycache__/chat_context.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/llm/__pycache__/chat_context.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/llm/__pycache__/fallback_adapter.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/llm/__pycache__/fallback_adapter.cpython-312.pyc
index ad663215..adadd888 100644
Binary files a/venv/Lib/site-packages/livekit/agents/llm/__pycache__/fallback_adapter.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/llm/__pycache__/fallback_adapter.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/llm/__pycache__/llm.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/llm/__pycache__/llm.cpython-312.pyc
index c42d6878..0061d2eb 100644
Binary files a/venv/Lib/site-packages/livekit/agents/llm/__pycache__/llm.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/llm/__pycache__/llm.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/llm/__pycache__/realtime.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/llm/__pycache__/realtime.cpython-312.pyc
index d18e1aa6..52ca60be 100644
Binary files a/venv/Lib/site-packages/livekit/agents/llm/__pycache__/realtime.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/llm/__pycache__/realtime.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/llm/__pycache__/remote_chat_context.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/llm/__pycache__/remote_chat_context.cpython-312.pyc
index 92a64281..b26d86f7 100644
Binary files a/venv/Lib/site-packages/livekit/agents/llm/__pycache__/remote_chat_context.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/llm/__pycache__/remote_chat_context.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/llm/__pycache__/tool_context.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/llm/__pycache__/tool_context.cpython-312.pyc
index af641594..352733f5 100644
Binary files a/venv/Lib/site-packages/livekit/agents/llm/__pycache__/tool_context.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/llm/__pycache__/tool_context.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/llm/__pycache__/utils.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/llm/__pycache__/utils.cpython-312.pyc
index b6fcf74f..0045216c 100644
Binary files a/venv/Lib/site-packages/livekit/agents/llm/__pycache__/utils.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/llm/__pycache__/utils.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/metrics/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/metrics/__pycache__/__init__.cpython-312.pyc
index 950f1a1b..491c6705 100644
Binary files a/venv/Lib/site-packages/livekit/agents/metrics/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/metrics/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/metrics/__pycache__/base.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/metrics/__pycache__/base.cpython-312.pyc
index fde7d3ec..61e21049 100644
Binary files a/venv/Lib/site-packages/livekit/agents/metrics/__pycache__/base.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/metrics/__pycache__/base.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/metrics/__pycache__/usage_collector.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/metrics/__pycache__/usage_collector.cpython-312.pyc
index bcc6d70c..b5e28dae 100644
Binary files a/venv/Lib/site-packages/livekit/agents/metrics/__pycache__/usage_collector.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/metrics/__pycache__/usage_collector.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/metrics/__pycache__/utils.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/metrics/__pycache__/utils.cpython-312.pyc
index d495c04f..c81398bd 100644
Binary files a/venv/Lib/site-packages/livekit/agents/metrics/__pycache__/utils.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/metrics/__pycache__/utils.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/stt/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/stt/__pycache__/__init__.cpython-312.pyc
index e95ea2c1..d05969f9 100644
Binary files a/venv/Lib/site-packages/livekit/agents/stt/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/stt/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/stt/__pycache__/fallback_adapter.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/stt/__pycache__/fallback_adapter.cpython-312.pyc
index ce72394d..cd978960 100644
Binary files a/venv/Lib/site-packages/livekit/agents/stt/__pycache__/fallback_adapter.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/stt/__pycache__/fallback_adapter.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/stt/__pycache__/stream_adapter.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/stt/__pycache__/stream_adapter.cpython-312.pyc
index b904dd3f..e247f69a 100644
Binary files a/venv/Lib/site-packages/livekit/agents/stt/__pycache__/stream_adapter.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/stt/__pycache__/stream_adapter.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/stt/__pycache__/stt.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/stt/__pycache__/stt.cpython-312.pyc
index 8fb3c332..3c3c744a 100644
Binary files a/venv/Lib/site-packages/livekit/agents/stt/__pycache__/stt.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/stt/__pycache__/stt.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/tokenize/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/tokenize/__pycache__/__init__.cpython-312.pyc
index 6418cea1..547abf0f 100644
Binary files a/venv/Lib/site-packages/livekit/agents/tokenize/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/tokenize/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/tokenize/__pycache__/_basic_hyphenator.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/tokenize/__pycache__/_basic_hyphenator.cpython-312.pyc
index f0a2be8e..4a8500ab 100644
Binary files a/venv/Lib/site-packages/livekit/agents/tokenize/__pycache__/_basic_hyphenator.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/tokenize/__pycache__/_basic_hyphenator.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/tokenize/__pycache__/_basic_paragraph.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/tokenize/__pycache__/_basic_paragraph.cpython-312.pyc
index f0cc844c..752c0972 100644
Binary files a/venv/Lib/site-packages/livekit/agents/tokenize/__pycache__/_basic_paragraph.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/tokenize/__pycache__/_basic_paragraph.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/tokenize/__pycache__/_basic_sent.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/tokenize/__pycache__/_basic_sent.cpython-312.pyc
index 7dc9c017..19a64800 100644
Binary files a/venv/Lib/site-packages/livekit/agents/tokenize/__pycache__/_basic_sent.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/tokenize/__pycache__/_basic_sent.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/tokenize/__pycache__/_basic_word.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/tokenize/__pycache__/_basic_word.cpython-312.pyc
index 8107019e..44d8d041 100644
Binary files a/venv/Lib/site-packages/livekit/agents/tokenize/__pycache__/_basic_word.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/tokenize/__pycache__/_basic_word.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/tokenize/__pycache__/basic.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/tokenize/__pycache__/basic.cpython-312.pyc
index e9571349..bc07536b 100644
Binary files a/venv/Lib/site-packages/livekit/agents/tokenize/__pycache__/basic.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/tokenize/__pycache__/basic.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/tokenize/__pycache__/token_stream.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/tokenize/__pycache__/token_stream.cpython-312.pyc
index cad51c1c..1de28416 100644
Binary files a/venv/Lib/site-packages/livekit/agents/tokenize/__pycache__/token_stream.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/tokenize/__pycache__/token_stream.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/tokenize/__pycache__/tokenizer.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/tokenize/__pycache__/tokenizer.cpython-312.pyc
index 0a869612..df4cd40b 100644
Binary files a/venv/Lib/site-packages/livekit/agents/tokenize/__pycache__/tokenizer.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/tokenize/__pycache__/tokenizer.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/tokenize/__pycache__/utils.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/tokenize/__pycache__/utils.cpython-312.pyc
index 5665c8b4..861bad2c 100644
Binary files a/venv/Lib/site-packages/livekit/agents/tokenize/__pycache__/utils.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/tokenize/__pycache__/utils.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/tts/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/tts/__pycache__/__init__.cpython-312.pyc
index 1e783520..076ec5fd 100644
Binary files a/venv/Lib/site-packages/livekit/agents/tts/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/tts/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/tts/__pycache__/fallback_adapter.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/tts/__pycache__/fallback_adapter.cpython-312.pyc
index 922c2479..341dd1a5 100644
Binary files a/venv/Lib/site-packages/livekit/agents/tts/__pycache__/fallback_adapter.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/tts/__pycache__/fallback_adapter.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/tts/__pycache__/stream_adapter.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/tts/__pycache__/stream_adapter.cpython-312.pyc
index 4c37a589..af96da80 100644
Binary files a/venv/Lib/site-packages/livekit/agents/tts/__pycache__/stream_adapter.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/tts/__pycache__/stream_adapter.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/tts/__pycache__/tts.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/tts/__pycache__/tts.cpython-312.pyc
index a97dd622..028b4539 100644
Binary files a/venv/Lib/site-packages/livekit/agents/tts/__pycache__/tts.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/tts/__pycache__/tts.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/utils/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/utils/__pycache__/__init__.cpython-312.pyc
index db38b8fd..806f2df6 100644
Binary files a/venv/Lib/site-packages/livekit/agents/utils/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/utils/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/utils/__pycache__/audio.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/utils/__pycache__/audio.cpython-312.pyc
index c76e4487..8f53c3c6 100644
Binary files a/venv/Lib/site-packages/livekit/agents/utils/__pycache__/audio.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/utils/__pycache__/audio.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/utils/__pycache__/connection_pool.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/utils/__pycache__/connection_pool.cpython-312.pyc
index cb28c0b0..1ac35421 100644
Binary files a/venv/Lib/site-packages/livekit/agents/utils/__pycache__/connection_pool.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/utils/__pycache__/connection_pool.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/utils/__pycache__/exp_filter.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/utils/__pycache__/exp_filter.cpython-312.pyc
index 60cf5e98..db5e3a61 100644
Binary files a/venv/Lib/site-packages/livekit/agents/utils/__pycache__/exp_filter.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/utils/__pycache__/exp_filter.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/utils/__pycache__/http_context.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/utils/__pycache__/http_context.cpython-312.pyc
index f2ade4c5..ebf970eb 100644
Binary files a/venv/Lib/site-packages/livekit/agents/utils/__pycache__/http_context.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/utils/__pycache__/http_context.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/utils/__pycache__/log.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/utils/__pycache__/log.cpython-312.pyc
index b7a82bc4..860832c0 100644
Binary files a/venv/Lib/site-packages/livekit/agents/utils/__pycache__/log.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/utils/__pycache__/log.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/utils/__pycache__/misc.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/utils/__pycache__/misc.cpython-312.pyc
index 9c6b9aae..f4fe0ae0 100644
Binary files a/venv/Lib/site-packages/livekit/agents/utils/__pycache__/misc.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/utils/__pycache__/misc.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/utils/__pycache__/moving_average.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/utils/__pycache__/moving_average.cpython-312.pyc
index 20cd2906..14651dc1 100644
Binary files a/venv/Lib/site-packages/livekit/agents/utils/__pycache__/moving_average.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/utils/__pycache__/moving_average.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/utils/__pycache__/participant.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/utils/__pycache__/participant.cpython-312.pyc
index 820b6103..5f850008 100644
Binary files a/venv/Lib/site-packages/livekit/agents/utils/__pycache__/participant.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/utils/__pycache__/participant.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/__init__.cpython-312.pyc
index 09229118..c7220c4f 100644
Binary files a/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/channel.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/channel.cpython-312.pyc
index 128decb2..afa4a6f0 100644
Binary files a/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/channel.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/channel.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/debug.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/debug.cpython-312.pyc
index c6f4fd2f..baeb7909 100644
Binary files a/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/debug.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/debug.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/duplex_unix.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/duplex_unix.cpython-312.pyc
index 069bf7b1..4b994df5 100644
Binary files a/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/duplex_unix.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/duplex_unix.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/interval.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/interval.cpython-312.pyc
index 6f9b3987..55e103bc 100644
Binary files a/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/interval.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/interval.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/itertools.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/itertools.cpython-312.pyc
index a8ba4704..52dc640d 100644
Binary files a/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/itertools.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/itertools.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/sleep.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/sleep.cpython-312.pyc
index 393fff36..0c4b37ed 100644
Binary files a/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/sleep.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/sleep.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/task_set.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/task_set.cpython-312.pyc
index 3526c6f0..b8ce3697 100644
Binary files a/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/task_set.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/task_set.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/utils.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/utils.cpython-312.pyc
index 1822030b..56c57673 100644
Binary files a/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/utils.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/utils.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/wait_group.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/wait_group.cpython-312.pyc
index a91b5a83..f903c243 100644
Binary files a/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/wait_group.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/utils/aio/__pycache__/wait_group.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/utils/codecs/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/utils/codecs/__pycache__/__init__.cpython-312.pyc
index 91f85ea1..150a6109 100644
Binary files a/venv/Lib/site-packages/livekit/agents/utils/codecs/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/utils/codecs/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/utils/codecs/__pycache__/decoder.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/utils/codecs/__pycache__/decoder.cpython-312.pyc
index 150d741a..2ee1a002 100644
Binary files a/venv/Lib/site-packages/livekit/agents/utils/codecs/__pycache__/decoder.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/utils/codecs/__pycache__/decoder.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/utils/hw/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/utils/hw/__pycache__/__init__.cpython-312.pyc
index a16bfc69..4109e73c 100644
Binary files a/venv/Lib/site-packages/livekit/agents/utils/hw/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/utils/hw/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/utils/hw/__pycache__/cpu.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/utils/hw/__pycache__/cpu.cpython-312.pyc
index 0f4b6af9..11222650 100644
Binary files a/venv/Lib/site-packages/livekit/agents/utils/hw/__pycache__/cpu.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/utils/hw/__pycache__/cpu.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/utils/images/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/utils/images/__pycache__/__init__.cpython-312.pyc
index 544ec851..cfd7ba6d 100644
Binary files a/venv/Lib/site-packages/livekit/agents/utils/images/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/utils/images/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/utils/images/__pycache__/image.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/utils/images/__pycache__/image.cpython-312.pyc
index 39ef8fa7..b9b405c2 100644
Binary files a/venv/Lib/site-packages/livekit/agents/utils/images/__pycache__/image.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/utils/images/__pycache__/image.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/voice/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/voice/__pycache__/__init__.cpython-312.pyc
index 2b3ef0f8..d14112a7 100644
Binary files a/venv/Lib/site-packages/livekit/agents/voice/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/voice/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/voice/__pycache__/agent.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/voice/__pycache__/agent.cpython-312.pyc
index 93f02f18..3618c7a9 100644
Binary files a/venv/Lib/site-packages/livekit/agents/voice/__pycache__/agent.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/voice/__pycache__/agent.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/voice/__pycache__/agent_activity.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/voice/__pycache__/agent_activity.cpython-312.pyc
index 8719cc87..f96e3223 100644
Binary files a/venv/Lib/site-packages/livekit/agents/voice/__pycache__/agent_activity.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/voice/__pycache__/agent_activity.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/voice/__pycache__/agent_session.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/voice/__pycache__/agent_session.cpython-312.pyc
index b0fd9f56..7a24128e 100644
Binary files a/venv/Lib/site-packages/livekit/agents/voice/__pycache__/agent_session.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/voice/__pycache__/agent_session.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/voice/__pycache__/audio_recognition.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/voice/__pycache__/audio_recognition.cpython-312.pyc
index 62f47a7b..c94c0bfa 100644
Binary files a/venv/Lib/site-packages/livekit/agents/voice/__pycache__/audio_recognition.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/voice/__pycache__/audio_recognition.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/voice/__pycache__/background_audio.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/voice/__pycache__/background_audio.cpython-312.pyc
index 4030780e..87842463 100644
Binary files a/venv/Lib/site-packages/livekit/agents/voice/__pycache__/background_audio.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/voice/__pycache__/background_audio.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/voice/__pycache__/chat_cli.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/voice/__pycache__/chat_cli.cpython-312.pyc
index 1df56606..4cd4c851 100644
Binary files a/venv/Lib/site-packages/livekit/agents/voice/__pycache__/chat_cli.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/voice/__pycache__/chat_cli.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/voice/__pycache__/events.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/voice/__pycache__/events.cpython-312.pyc
index 6dca784b..47673744 100644
Binary files a/venv/Lib/site-packages/livekit/agents/voice/__pycache__/events.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/voice/__pycache__/events.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/voice/__pycache__/generation.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/voice/__pycache__/generation.cpython-312.pyc
index f00184a3..3d5bd03d 100644
Binary files a/venv/Lib/site-packages/livekit/agents/voice/__pycache__/generation.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/voice/__pycache__/generation.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/voice/__pycache__/io.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/voice/__pycache__/io.cpython-312.pyc
index d11bfa0d..4a1bbdbe 100644
Binary files a/venv/Lib/site-packages/livekit/agents/voice/__pycache__/io.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/voice/__pycache__/io.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/voice/__pycache__/speech_handle.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/voice/__pycache__/speech_handle.cpython-312.pyc
index 325f7728..3b9d0b5f 100644
Binary files a/venv/Lib/site-packages/livekit/agents/voice/__pycache__/speech_handle.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/voice/__pycache__/speech_handle.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/voice/avatar/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/voice/avatar/__pycache__/__init__.cpython-312.pyc
index 5cff87d9..4f6c2104 100644
Binary files a/venv/Lib/site-packages/livekit/agents/voice/avatar/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/voice/avatar/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/voice/avatar/__pycache__/_datastream_io.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/voice/avatar/__pycache__/_datastream_io.cpython-312.pyc
index 0d674164..a4682271 100644
Binary files a/venv/Lib/site-packages/livekit/agents/voice/avatar/__pycache__/_datastream_io.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/voice/avatar/__pycache__/_datastream_io.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/voice/avatar/__pycache__/_queue_io.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/voice/avatar/__pycache__/_queue_io.cpython-312.pyc
index 0654185d..4ccc7c2e 100644
Binary files a/venv/Lib/site-packages/livekit/agents/voice/avatar/__pycache__/_queue_io.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/voice/avatar/__pycache__/_queue_io.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/voice/avatar/__pycache__/_runner.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/voice/avatar/__pycache__/_runner.cpython-312.pyc
index e0a57990..d563458c 100644
Binary files a/venv/Lib/site-packages/livekit/agents/voice/avatar/__pycache__/_runner.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/voice/avatar/__pycache__/_runner.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/voice/avatar/__pycache__/_types.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/voice/avatar/__pycache__/_types.cpython-312.pyc
index c12bbf3c..538a258e 100644
Binary files a/venv/Lib/site-packages/livekit/agents/voice/avatar/__pycache__/_types.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/voice/avatar/__pycache__/_types.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/voice/room_io/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/voice/room_io/__pycache__/__init__.cpython-312.pyc
index 022d2b39..fb948982 100644
Binary files a/venv/Lib/site-packages/livekit/agents/voice/room_io/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/voice/room_io/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/voice/room_io/__pycache__/_input.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/voice/room_io/__pycache__/_input.cpython-312.pyc
index 4f65bb26..7a19f8ad 100644
Binary files a/venv/Lib/site-packages/livekit/agents/voice/room_io/__pycache__/_input.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/voice/room_io/__pycache__/_input.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/voice/room_io/__pycache__/_output.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/voice/room_io/__pycache__/_output.cpython-312.pyc
index 513757c6..f8a52329 100644
Binary files a/venv/Lib/site-packages/livekit/agents/voice/room_io/__pycache__/_output.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/voice/room_io/__pycache__/_output.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/voice/room_io/__pycache__/_pre_connect_audio.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/voice/room_io/__pycache__/_pre_connect_audio.cpython-312.pyc
index 1c4739be..dc0e3810 100644
Binary files a/venv/Lib/site-packages/livekit/agents/voice/room_io/__pycache__/_pre_connect_audio.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/voice/room_io/__pycache__/_pre_connect_audio.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/voice/room_io/__pycache__/room_io.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/voice/room_io/__pycache__/room_io.cpython-312.pyc
index b84ef19b..ed66c582 100644
Binary files a/venv/Lib/site-packages/livekit/agents/voice/room_io/__pycache__/room_io.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/voice/room_io/__pycache__/room_io.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/voice/transcription/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/voice/transcription/__pycache__/__init__.cpython-312.pyc
index 5b190445..8ea2b321 100644
Binary files a/venv/Lib/site-packages/livekit/agents/voice/transcription/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/voice/transcription/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/voice/transcription/__pycache__/_speaking_rate.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/voice/transcription/__pycache__/_speaking_rate.cpython-312.pyc
index 9c71f2ae..200c9e49 100644
Binary files a/venv/Lib/site-packages/livekit/agents/voice/transcription/__pycache__/_speaking_rate.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/voice/transcription/__pycache__/_speaking_rate.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/voice/transcription/__pycache__/_utils.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/voice/transcription/__pycache__/_utils.cpython-312.pyc
index fca0e850..be4639bd 100644
Binary files a/venv/Lib/site-packages/livekit/agents/voice/transcription/__pycache__/_utils.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/voice/transcription/__pycache__/_utils.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/agents/voice/transcription/__pycache__/synchronizer.cpython-312.pyc b/venv/Lib/site-packages/livekit/agents/voice/transcription/__pycache__/synchronizer.cpython-312.pyc
index 0cee511e..1175bebf 100644
Binary files a/venv/Lib/site-packages/livekit/agents/voice/transcription/__pycache__/synchronizer.cpython-312.pyc and b/venv/Lib/site-packages/livekit/agents/voice/transcription/__pycache__/synchronizer.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/api/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/livekit/api/__pycache__/__init__.cpython-312.pyc
index 5438a7c8..693d3937 100644
Binary files a/venv/Lib/site-packages/livekit/api/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/livekit/api/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/api/__pycache__/_service.cpython-312.pyc b/venv/Lib/site-packages/livekit/api/__pycache__/_service.cpython-312.pyc
index 9779916c..99cc2989 100644
Binary files a/venv/Lib/site-packages/livekit/api/__pycache__/_service.cpython-312.pyc and b/venv/Lib/site-packages/livekit/api/__pycache__/_service.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/api/__pycache__/access_token.cpython-312.pyc b/venv/Lib/site-packages/livekit/api/__pycache__/access_token.cpython-312.pyc
index a880b59f..54feeb67 100644
Binary files a/venv/Lib/site-packages/livekit/api/__pycache__/access_token.cpython-312.pyc and b/venv/Lib/site-packages/livekit/api/__pycache__/access_token.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/api/__pycache__/agent_dispatch_service.cpython-312.pyc b/venv/Lib/site-packages/livekit/api/__pycache__/agent_dispatch_service.cpython-312.pyc
index aa5631e3..ddcf5a24 100644
Binary files a/venv/Lib/site-packages/livekit/api/__pycache__/agent_dispatch_service.cpython-312.pyc and b/venv/Lib/site-packages/livekit/api/__pycache__/agent_dispatch_service.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/api/__pycache__/egress_service.cpython-312.pyc b/venv/Lib/site-packages/livekit/api/__pycache__/egress_service.cpython-312.pyc
index 2bee8f85..9c34ee90 100644
Binary files a/venv/Lib/site-packages/livekit/api/__pycache__/egress_service.cpython-312.pyc and b/venv/Lib/site-packages/livekit/api/__pycache__/egress_service.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/api/__pycache__/ingress_service.cpython-312.pyc b/venv/Lib/site-packages/livekit/api/__pycache__/ingress_service.cpython-312.pyc
index f59b904e..0f81fdd0 100644
Binary files a/venv/Lib/site-packages/livekit/api/__pycache__/ingress_service.cpython-312.pyc and b/venv/Lib/site-packages/livekit/api/__pycache__/ingress_service.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/api/__pycache__/livekit_api.cpython-312.pyc b/venv/Lib/site-packages/livekit/api/__pycache__/livekit_api.cpython-312.pyc
index 7e39cd87..91f9b198 100644
Binary files a/venv/Lib/site-packages/livekit/api/__pycache__/livekit_api.cpython-312.pyc and b/venv/Lib/site-packages/livekit/api/__pycache__/livekit_api.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/api/__pycache__/room_service.cpython-312.pyc b/venv/Lib/site-packages/livekit/api/__pycache__/room_service.cpython-312.pyc
index 5b351149..6596b8b7 100644
Binary files a/venv/Lib/site-packages/livekit/api/__pycache__/room_service.cpython-312.pyc and b/venv/Lib/site-packages/livekit/api/__pycache__/room_service.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/api/__pycache__/sip_service.cpython-312.pyc b/venv/Lib/site-packages/livekit/api/__pycache__/sip_service.cpython-312.pyc
index db320762..008b0a90 100644
Binary files a/venv/Lib/site-packages/livekit/api/__pycache__/sip_service.cpython-312.pyc and b/venv/Lib/site-packages/livekit/api/__pycache__/sip_service.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/api/__pycache__/twirp_client.cpython-312.pyc b/venv/Lib/site-packages/livekit/api/__pycache__/twirp_client.cpython-312.pyc
index a3786c77..8316d5c4 100644
Binary files a/venv/Lib/site-packages/livekit/api/__pycache__/twirp_client.cpython-312.pyc and b/venv/Lib/site-packages/livekit/api/__pycache__/twirp_client.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/api/__pycache__/version.cpython-312.pyc b/venv/Lib/site-packages/livekit/api/__pycache__/version.cpython-312.pyc
index 2d722e9f..ec38065a 100644
Binary files a/venv/Lib/site-packages/livekit/api/__pycache__/version.cpython-312.pyc and b/venv/Lib/site-packages/livekit/api/__pycache__/version.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/api/__pycache__/webhook.cpython-312.pyc b/venv/Lib/site-packages/livekit/api/__pycache__/webhook.cpython-312.pyc
index f49666e2..b226e9fd 100644
Binary files a/venv/Lib/site-packages/livekit/api/__pycache__/webhook.cpython-312.pyc and b/venv/Lib/site-packages/livekit/api/__pycache__/webhook.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/plugins/deepgram/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/livekit/plugins/deepgram/__pycache__/__init__.cpython-312.pyc
index fb4d8ac3..cd8879c2 100644
Binary files a/venv/Lib/site-packages/livekit/plugins/deepgram/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/livekit/plugins/deepgram/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/plugins/deepgram/__pycache__/_utils.cpython-312.pyc b/venv/Lib/site-packages/livekit/plugins/deepgram/__pycache__/_utils.cpython-312.pyc
index f976ea7d..86774e5d 100644
Binary files a/venv/Lib/site-packages/livekit/plugins/deepgram/__pycache__/_utils.cpython-312.pyc and b/venv/Lib/site-packages/livekit/plugins/deepgram/__pycache__/_utils.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/plugins/deepgram/__pycache__/log.cpython-312.pyc b/venv/Lib/site-packages/livekit/plugins/deepgram/__pycache__/log.cpython-312.pyc
index 0374d101..5b673a69 100644
Binary files a/venv/Lib/site-packages/livekit/plugins/deepgram/__pycache__/log.cpython-312.pyc and b/venv/Lib/site-packages/livekit/plugins/deepgram/__pycache__/log.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/plugins/deepgram/__pycache__/models.cpython-312.pyc b/venv/Lib/site-packages/livekit/plugins/deepgram/__pycache__/models.cpython-312.pyc
index e32c35fc..c5746a93 100644
Binary files a/venv/Lib/site-packages/livekit/plugins/deepgram/__pycache__/models.cpython-312.pyc and b/venv/Lib/site-packages/livekit/plugins/deepgram/__pycache__/models.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/plugins/deepgram/__pycache__/stt.cpython-312.pyc b/venv/Lib/site-packages/livekit/plugins/deepgram/__pycache__/stt.cpython-312.pyc
index a3db768c..2e7e52bb 100644
Binary files a/venv/Lib/site-packages/livekit/plugins/deepgram/__pycache__/stt.cpython-312.pyc and b/venv/Lib/site-packages/livekit/plugins/deepgram/__pycache__/stt.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/plugins/deepgram/__pycache__/tts.cpython-312.pyc b/venv/Lib/site-packages/livekit/plugins/deepgram/__pycache__/tts.cpython-312.pyc
index 8042c6eb..90ac0773 100644
Binary files a/venv/Lib/site-packages/livekit/plugins/deepgram/__pycache__/tts.cpython-312.pyc and b/venv/Lib/site-packages/livekit/plugins/deepgram/__pycache__/tts.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/plugins/deepgram/__pycache__/version.cpython-312.pyc b/venv/Lib/site-packages/livekit/plugins/deepgram/__pycache__/version.cpython-312.pyc
index f1c9e3dc..6d49270a 100644
Binary files a/venv/Lib/site-packages/livekit/plugins/deepgram/__pycache__/version.cpython-312.pyc and b/venv/Lib/site-packages/livekit/plugins/deepgram/__pycache__/version.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/plugins/elevenlabs/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/livekit/plugins/elevenlabs/__pycache__/__init__.cpython-312.pyc
index 328a6f14..3f4adc5f 100644
Binary files a/venv/Lib/site-packages/livekit/plugins/elevenlabs/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/livekit/plugins/elevenlabs/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/plugins/elevenlabs/__pycache__/log.cpython-312.pyc b/venv/Lib/site-packages/livekit/plugins/elevenlabs/__pycache__/log.cpython-312.pyc
index 22a0770e..a0d5aecd 100644
Binary files a/venv/Lib/site-packages/livekit/plugins/elevenlabs/__pycache__/log.cpython-312.pyc and b/venv/Lib/site-packages/livekit/plugins/elevenlabs/__pycache__/log.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/plugins/elevenlabs/__pycache__/models.cpython-312.pyc b/venv/Lib/site-packages/livekit/plugins/elevenlabs/__pycache__/models.cpython-312.pyc
index decd96ab..95f0d6aa 100644
Binary files a/venv/Lib/site-packages/livekit/plugins/elevenlabs/__pycache__/models.cpython-312.pyc and b/venv/Lib/site-packages/livekit/plugins/elevenlabs/__pycache__/models.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/plugins/elevenlabs/__pycache__/stt.cpython-312.pyc b/venv/Lib/site-packages/livekit/plugins/elevenlabs/__pycache__/stt.cpython-312.pyc
index 85109a69..d7a410ec 100644
Binary files a/venv/Lib/site-packages/livekit/plugins/elevenlabs/__pycache__/stt.cpython-312.pyc and b/venv/Lib/site-packages/livekit/plugins/elevenlabs/__pycache__/stt.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/plugins/elevenlabs/__pycache__/tts.cpython-312.pyc b/venv/Lib/site-packages/livekit/plugins/elevenlabs/__pycache__/tts.cpython-312.pyc
index 37b0fed4..9519ade6 100644
Binary files a/venv/Lib/site-packages/livekit/plugins/elevenlabs/__pycache__/tts.cpython-312.pyc and b/venv/Lib/site-packages/livekit/plugins/elevenlabs/__pycache__/tts.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/plugins/elevenlabs/__pycache__/version.cpython-312.pyc b/venv/Lib/site-packages/livekit/plugins/elevenlabs/__pycache__/version.cpython-312.pyc
index 93fcc9a1..5d2a3e07 100644
Binary files a/venv/Lib/site-packages/livekit/plugins/elevenlabs/__pycache__/version.cpython-312.pyc and b/venv/Lib/site-packages/livekit/plugins/elevenlabs/__pycache__/version.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/plugins/groq/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/livekit/plugins/groq/__pycache__/__init__.cpython-312.pyc
index 6eba53d1..f254185f 100644
Binary files a/venv/Lib/site-packages/livekit/plugins/groq/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/livekit/plugins/groq/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/plugins/groq/__pycache__/log.cpython-312.pyc b/venv/Lib/site-packages/livekit/plugins/groq/__pycache__/log.cpython-312.pyc
index 7645690b..6af6bcf6 100644
Binary files a/venv/Lib/site-packages/livekit/plugins/groq/__pycache__/log.cpython-312.pyc and b/venv/Lib/site-packages/livekit/plugins/groq/__pycache__/log.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/plugins/groq/__pycache__/models.cpython-312.pyc b/venv/Lib/site-packages/livekit/plugins/groq/__pycache__/models.cpython-312.pyc
index 84e332ec..1c474c5e 100644
Binary files a/venv/Lib/site-packages/livekit/plugins/groq/__pycache__/models.cpython-312.pyc and b/venv/Lib/site-packages/livekit/plugins/groq/__pycache__/models.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/plugins/groq/__pycache__/services.cpython-312.pyc b/venv/Lib/site-packages/livekit/plugins/groq/__pycache__/services.cpython-312.pyc
index 7ec1ff2b..3c9681f7 100644
Binary files a/venv/Lib/site-packages/livekit/plugins/groq/__pycache__/services.cpython-312.pyc and b/venv/Lib/site-packages/livekit/plugins/groq/__pycache__/services.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/plugins/groq/__pycache__/tts.cpython-312.pyc b/venv/Lib/site-packages/livekit/plugins/groq/__pycache__/tts.cpython-312.pyc
index 87fe8f5a..76e665fe 100644
Binary files a/venv/Lib/site-packages/livekit/plugins/groq/__pycache__/tts.cpython-312.pyc and b/venv/Lib/site-packages/livekit/plugins/groq/__pycache__/tts.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/plugins/groq/__pycache__/version.cpython-312.pyc b/venv/Lib/site-packages/livekit/plugins/groq/__pycache__/version.cpython-312.pyc
index 6cadfeda..c464dbb3 100644
Binary files a/venv/Lib/site-packages/livekit/plugins/groq/__pycache__/version.cpython-312.pyc and b/venv/Lib/site-packages/livekit/plugins/groq/__pycache__/version.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/plugins/openai/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/livekit/plugins/openai/__pycache__/__init__.cpython-312.pyc
index 14845957..c4289be4 100644
Binary files a/venv/Lib/site-packages/livekit/plugins/openai/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/livekit/plugins/openai/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/plugins/openai/__pycache__/embeddings.cpython-312.pyc b/venv/Lib/site-packages/livekit/plugins/openai/__pycache__/embeddings.cpython-312.pyc
index 7372ae7d..5d3f24bb 100644
Binary files a/venv/Lib/site-packages/livekit/plugins/openai/__pycache__/embeddings.cpython-312.pyc and b/venv/Lib/site-packages/livekit/plugins/openai/__pycache__/embeddings.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/plugins/openai/__pycache__/llm.cpython-312.pyc b/venv/Lib/site-packages/livekit/plugins/openai/__pycache__/llm.cpython-312.pyc
index 0d086a00..9ff2711f 100644
Binary files a/venv/Lib/site-packages/livekit/plugins/openai/__pycache__/llm.cpython-312.pyc and b/venv/Lib/site-packages/livekit/plugins/openai/__pycache__/llm.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/plugins/openai/__pycache__/log.cpython-312.pyc b/venv/Lib/site-packages/livekit/plugins/openai/__pycache__/log.cpython-312.pyc
index bb43e7ad..1ed2a314 100644
Binary files a/venv/Lib/site-packages/livekit/plugins/openai/__pycache__/log.cpython-312.pyc and b/venv/Lib/site-packages/livekit/plugins/openai/__pycache__/log.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/plugins/openai/__pycache__/models.cpython-312.pyc b/venv/Lib/site-packages/livekit/plugins/openai/__pycache__/models.cpython-312.pyc
index c9e81045..92f2590e 100644
Binary files a/venv/Lib/site-packages/livekit/plugins/openai/__pycache__/models.cpython-312.pyc and b/venv/Lib/site-packages/livekit/plugins/openai/__pycache__/models.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/plugins/openai/__pycache__/stt.cpython-312.pyc b/venv/Lib/site-packages/livekit/plugins/openai/__pycache__/stt.cpython-312.pyc
index cca65e1a..fd945eb0 100644
Binary files a/venv/Lib/site-packages/livekit/plugins/openai/__pycache__/stt.cpython-312.pyc and b/venv/Lib/site-packages/livekit/plugins/openai/__pycache__/stt.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/plugins/openai/__pycache__/tts.cpython-312.pyc b/venv/Lib/site-packages/livekit/plugins/openai/__pycache__/tts.cpython-312.pyc
index 98eb4a93..145c71de 100644
Binary files a/venv/Lib/site-packages/livekit/plugins/openai/__pycache__/tts.cpython-312.pyc and b/venv/Lib/site-packages/livekit/plugins/openai/__pycache__/tts.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/plugins/openai/__pycache__/utils.cpython-312.pyc b/venv/Lib/site-packages/livekit/plugins/openai/__pycache__/utils.cpython-312.pyc
index eaddc0bf..84b9d78b 100644
Binary files a/venv/Lib/site-packages/livekit/plugins/openai/__pycache__/utils.cpython-312.pyc and b/venv/Lib/site-packages/livekit/plugins/openai/__pycache__/utils.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/plugins/openai/__pycache__/version.cpython-312.pyc b/venv/Lib/site-packages/livekit/plugins/openai/__pycache__/version.cpython-312.pyc
index 3ec6f901..161ba076 100644
Binary files a/venv/Lib/site-packages/livekit/plugins/openai/__pycache__/version.cpython-312.pyc and b/venv/Lib/site-packages/livekit/plugins/openai/__pycache__/version.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/plugins/openai/realtime/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/livekit/plugins/openai/realtime/__pycache__/__init__.cpython-312.pyc
index dd315f0c..b2f2ce04 100644
Binary files a/venv/Lib/site-packages/livekit/plugins/openai/realtime/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/livekit/plugins/openai/realtime/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/plugins/openai/realtime/__pycache__/realtime_model.cpython-312.pyc b/venv/Lib/site-packages/livekit/plugins/openai/realtime/__pycache__/realtime_model.cpython-312.pyc
index 35b4e694..353aee7e 100644
Binary files a/venv/Lib/site-packages/livekit/plugins/openai/realtime/__pycache__/realtime_model.cpython-312.pyc and b/venv/Lib/site-packages/livekit/plugins/openai/realtime/__pycache__/realtime_model.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/plugins/silero/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/livekit/plugins/silero/__pycache__/__init__.cpython-312.pyc
index 5105335d..eae97fdf 100644
Binary files a/venv/Lib/site-packages/livekit/plugins/silero/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/livekit/plugins/silero/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/plugins/silero/__pycache__/log.cpython-312.pyc b/venv/Lib/site-packages/livekit/plugins/silero/__pycache__/log.cpython-312.pyc
index 9688848e..527b8c99 100644
Binary files a/venv/Lib/site-packages/livekit/plugins/silero/__pycache__/log.cpython-312.pyc and b/venv/Lib/site-packages/livekit/plugins/silero/__pycache__/log.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/plugins/silero/__pycache__/onnx_model.cpython-312.pyc b/venv/Lib/site-packages/livekit/plugins/silero/__pycache__/onnx_model.cpython-312.pyc
index d8d8b240..164a6a63 100644
Binary files a/venv/Lib/site-packages/livekit/plugins/silero/__pycache__/onnx_model.cpython-312.pyc and b/venv/Lib/site-packages/livekit/plugins/silero/__pycache__/onnx_model.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/plugins/silero/__pycache__/vad.cpython-312.pyc b/venv/Lib/site-packages/livekit/plugins/silero/__pycache__/vad.cpython-312.pyc
index 18acdc12..db6888e6 100644
Binary files a/venv/Lib/site-packages/livekit/plugins/silero/__pycache__/vad.cpython-312.pyc and b/venv/Lib/site-packages/livekit/plugins/silero/__pycache__/vad.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/plugins/silero/__pycache__/version.cpython-312.pyc b/venv/Lib/site-packages/livekit/plugins/silero/__pycache__/version.cpython-312.pyc
index 23c46d39..652faa3c 100644
Binary files a/venv/Lib/site-packages/livekit/plugins/silero/__pycache__/version.cpython-312.pyc and b/venv/Lib/site-packages/livekit/plugins/silero/__pycache__/version.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/plugins/silero/resources/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/livekit/plugins/silero/resources/__pycache__/__init__.cpython-312.pyc
index 8a59e61d..f6d78cb8 100644
Binary files a/venv/Lib/site-packages/livekit/plugins/silero/resources/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/livekit/plugins/silero/resources/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/protocol/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/livekit/protocol/__pycache__/__init__.cpython-312.pyc
index e986bb28..5563f066 100644
Binary files a/venv/Lib/site-packages/livekit/protocol/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/livekit/protocol/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/protocol/__pycache__/agent.cpython-312.pyc b/venv/Lib/site-packages/livekit/protocol/__pycache__/agent.cpython-312.pyc
index c3ebad4f..27d14336 100644
Binary files a/venv/Lib/site-packages/livekit/protocol/__pycache__/agent.cpython-312.pyc and b/venv/Lib/site-packages/livekit/protocol/__pycache__/agent.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/protocol/__pycache__/agent_dispatch.cpython-312.pyc b/venv/Lib/site-packages/livekit/protocol/__pycache__/agent_dispatch.cpython-312.pyc
index e31f02e7..a3de961f 100644
Binary files a/venv/Lib/site-packages/livekit/protocol/__pycache__/agent_dispatch.cpython-312.pyc and b/venv/Lib/site-packages/livekit/protocol/__pycache__/agent_dispatch.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/protocol/__pycache__/analytics.cpython-312.pyc b/venv/Lib/site-packages/livekit/protocol/__pycache__/analytics.cpython-312.pyc
index 4937e3a7..2cefd298 100644
Binary files a/venv/Lib/site-packages/livekit/protocol/__pycache__/analytics.cpython-312.pyc and b/venv/Lib/site-packages/livekit/protocol/__pycache__/analytics.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/protocol/__pycache__/egress.cpython-312.pyc b/venv/Lib/site-packages/livekit/protocol/__pycache__/egress.cpython-312.pyc
index 7c5e3092..f283fe5c 100644
Binary files a/venv/Lib/site-packages/livekit/protocol/__pycache__/egress.cpython-312.pyc and b/venv/Lib/site-packages/livekit/protocol/__pycache__/egress.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/protocol/__pycache__/ingress.cpython-312.pyc b/venv/Lib/site-packages/livekit/protocol/__pycache__/ingress.cpython-312.pyc
index ede2c896..092f1fed 100644
Binary files a/venv/Lib/site-packages/livekit/protocol/__pycache__/ingress.cpython-312.pyc and b/venv/Lib/site-packages/livekit/protocol/__pycache__/ingress.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/protocol/__pycache__/metrics.cpython-312.pyc b/venv/Lib/site-packages/livekit/protocol/__pycache__/metrics.cpython-312.pyc
index 10029e99..39e0e64e 100644
Binary files a/venv/Lib/site-packages/livekit/protocol/__pycache__/metrics.cpython-312.pyc and b/venv/Lib/site-packages/livekit/protocol/__pycache__/metrics.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/protocol/__pycache__/models.cpython-312.pyc b/venv/Lib/site-packages/livekit/protocol/__pycache__/models.cpython-312.pyc
index abf3e54f..f788825b 100644
Binary files a/venv/Lib/site-packages/livekit/protocol/__pycache__/models.cpython-312.pyc and b/venv/Lib/site-packages/livekit/protocol/__pycache__/models.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/protocol/__pycache__/room.cpython-312.pyc b/venv/Lib/site-packages/livekit/protocol/__pycache__/room.cpython-312.pyc
index fc41ec98..eb960883 100644
Binary files a/venv/Lib/site-packages/livekit/protocol/__pycache__/room.cpython-312.pyc and b/venv/Lib/site-packages/livekit/protocol/__pycache__/room.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/protocol/__pycache__/sip.cpython-312.pyc b/venv/Lib/site-packages/livekit/protocol/__pycache__/sip.cpython-312.pyc
index 50b11947..f40d7d26 100644
Binary files a/venv/Lib/site-packages/livekit/protocol/__pycache__/sip.cpython-312.pyc and b/venv/Lib/site-packages/livekit/protocol/__pycache__/sip.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/protocol/__pycache__/version.cpython-312.pyc b/venv/Lib/site-packages/livekit/protocol/__pycache__/version.cpython-312.pyc
index 2abca779..0d3733d1 100644
Binary files a/venv/Lib/site-packages/livekit/protocol/__pycache__/version.cpython-312.pyc and b/venv/Lib/site-packages/livekit/protocol/__pycache__/version.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/protocol/__pycache__/webhook.cpython-312.pyc b/venv/Lib/site-packages/livekit/protocol/__pycache__/webhook.cpython-312.pyc
index b5171eb1..8569661d 100644
Binary files a/venv/Lib/site-packages/livekit/protocol/__pycache__/webhook.cpython-312.pyc and b/venv/Lib/site-packages/livekit/protocol/__pycache__/webhook.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/__pycache__/__init__.cpython-312.pyc
index fd2f2eac..723727e6 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/__pycache__/_ffi_client.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/__pycache__/_ffi_client.cpython-312.pyc
index 1317b9be..56fc72af 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/__pycache__/_ffi_client.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/__pycache__/_ffi_client.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/__pycache__/_utils.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/__pycache__/_utils.cpython-312.pyc
index 4a172f5d..54f0e79c 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/__pycache__/_utils.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/__pycache__/_utils.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/__pycache__/apm.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/__pycache__/apm.cpython-312.pyc
index 26fdaa11..c737f4c1 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/__pycache__/apm.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/__pycache__/apm.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/__pycache__/audio_filter.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/__pycache__/audio_filter.cpython-312.pyc
index 3dade8d3..54263a1a 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/__pycache__/audio_filter.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/__pycache__/audio_filter.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/__pycache__/audio_frame.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/__pycache__/audio_frame.cpython-312.pyc
index 805b0677..0cccf714 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/__pycache__/audio_frame.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/__pycache__/audio_frame.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/__pycache__/audio_mixer.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/__pycache__/audio_mixer.cpython-312.pyc
index 2a5326b1..43c2441b 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/__pycache__/audio_mixer.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/__pycache__/audio_mixer.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/__pycache__/audio_resampler.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/__pycache__/audio_resampler.cpython-312.pyc
index 3316db3e..f793d796 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/__pycache__/audio_resampler.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/__pycache__/audio_resampler.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/__pycache__/audio_source.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/__pycache__/audio_source.cpython-312.pyc
index 678d0b5c..bcf9c235 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/__pycache__/audio_source.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/__pycache__/audio_source.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/__pycache__/audio_stream.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/__pycache__/audio_stream.cpython-312.pyc
index 74f0ba5c..c5254f2b 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/__pycache__/audio_stream.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/__pycache__/audio_stream.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/__pycache__/data_stream.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/__pycache__/data_stream.cpython-312.pyc
index 4a990df4..67c97d95 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/__pycache__/data_stream.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/__pycache__/data_stream.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/__pycache__/e2ee.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/__pycache__/e2ee.cpython-312.pyc
index 7ffbf8be..9cb47d89 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/__pycache__/e2ee.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/__pycache__/e2ee.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/__pycache__/event_emitter.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/__pycache__/event_emitter.cpython-312.pyc
index 154263d3..9f0096ca 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/__pycache__/event_emitter.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/__pycache__/event_emitter.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/__pycache__/log.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/__pycache__/log.cpython-312.pyc
index 60dc292a..aeefaeef 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/__pycache__/log.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/__pycache__/log.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/__pycache__/participant.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/__pycache__/participant.cpython-312.pyc
index c12d9727..9f7a8f8a 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/__pycache__/participant.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/__pycache__/participant.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/__pycache__/room.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/__pycache__/room.cpython-312.pyc
index 2cbf34c0..1c781152 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/__pycache__/room.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/__pycache__/room.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/__pycache__/rpc.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/__pycache__/rpc.cpython-312.pyc
index bd291fc1..b18d4e12 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/__pycache__/rpc.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/__pycache__/rpc.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/__pycache__/synchronizer.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/__pycache__/synchronizer.cpython-312.pyc
index 91125d51..3d4a7115 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/__pycache__/synchronizer.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/__pycache__/synchronizer.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/__pycache__/track.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/__pycache__/track.cpython-312.pyc
index 56d478dc..9da438c9 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/__pycache__/track.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/__pycache__/track.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/__pycache__/track_publication.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/__pycache__/track_publication.cpython-312.pyc
index 4d9d80d5..72968906 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/__pycache__/track_publication.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/__pycache__/track_publication.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/__pycache__/transcription.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/__pycache__/transcription.cpython-312.pyc
index 29eefdad..b39aaf97 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/__pycache__/transcription.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/__pycache__/transcription.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/__pycache__/utils.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/__pycache__/utils.cpython-312.pyc
index fa4a26a8..97c99cef 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/__pycache__/utils.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/__pycache__/utils.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/__pycache__/version.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/__pycache__/version.cpython-312.pyc
index d99ef351..23287457 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/__pycache__/version.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/__pycache__/version.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/__pycache__/video_frame.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/__pycache__/video_frame.cpython-312.pyc
index 1164bafb..8c71b117 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/__pycache__/video_frame.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/__pycache__/video_frame.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/__pycache__/video_source.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/__pycache__/video_source.cpython-312.pyc
index 09c09dff..433c965d 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/__pycache__/video_source.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/__pycache__/video_source.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/__pycache__/video_stream.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/__pycache__/video_stream.cpython-312.pyc
index c0926105..9a0e8a38 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/__pycache__/video_stream.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/__pycache__/video_stream.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/__init__.cpython-312.pyc
index 73337100..8e877f01 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/audio_frame_pb2.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/audio_frame_pb2.cpython-312.pyc
index 0a5b21a3..13db3bcd 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/audio_frame_pb2.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/audio_frame_pb2.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/data_stream_pb2.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/data_stream_pb2.cpython-312.pyc
index cfa78e98..757fc23b 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/data_stream_pb2.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/data_stream_pb2.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/e2ee_pb2.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/e2ee_pb2.cpython-312.pyc
index dea885b2..f2ed4490 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/e2ee_pb2.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/e2ee_pb2.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/ffi_pb2.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/ffi_pb2.cpython-312.pyc
index afcf05fb..2d3dd94d 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/ffi_pb2.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/ffi_pb2.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/handle_pb2.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/handle_pb2.cpython-312.pyc
index acec456f..74b0038a 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/handle_pb2.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/handle_pb2.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/participant_pb2.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/participant_pb2.cpython-312.pyc
index abafb964..ffa81175 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/participant_pb2.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/participant_pb2.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/room_pb2.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/room_pb2.cpython-312.pyc
index 71177624..93aa4a76 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/room_pb2.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/room_pb2.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/rpc_pb2.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/rpc_pb2.cpython-312.pyc
index 86f247f2..ee727736 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/rpc_pb2.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/rpc_pb2.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/stats_pb2.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/stats_pb2.cpython-312.pyc
index 71d16665..6cf8f41c 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/stats_pb2.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/stats_pb2.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/track_pb2.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/track_pb2.cpython-312.pyc
index bd826208..61c08403 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/track_pb2.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/track_pb2.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/track_publication_pb2.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/track_publication_pb2.cpython-312.pyc
index c368e0ae..f804b3a5 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/track_publication_pb2.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/track_publication_pb2.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/video_frame_pb2.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/video_frame_pb2.cpython-312.pyc
index 711968d2..556ad5e0 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/video_frame_pb2.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/_proto/__pycache__/video_frame_pb2.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/livekit/rtc/resources/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/livekit/rtc/resources/__pycache__/__init__.cpython-312.pyc
index be640f34..c54aacb9 100644
Binary files a/venv/Lib/site-packages/livekit/rtc/resources/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/livekit/rtc/resources/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/marshmallow/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/marshmallow/__pycache__/__init__.cpython-312.pyc
index e4667ca6..8d18c073 100644
Binary files a/venv/Lib/site-packages/marshmallow/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/marshmallow/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/marshmallow/__pycache__/base.cpython-312.pyc b/venv/Lib/site-packages/marshmallow/__pycache__/base.cpython-312.pyc
index 2737a356..af47f7c4 100644
Binary files a/venv/Lib/site-packages/marshmallow/__pycache__/base.cpython-312.pyc and b/venv/Lib/site-packages/marshmallow/__pycache__/base.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/marshmallow/__pycache__/class_registry.cpython-312.pyc b/venv/Lib/site-packages/marshmallow/__pycache__/class_registry.cpython-312.pyc
index 7ad18c1f..5f878b73 100644
Binary files a/venv/Lib/site-packages/marshmallow/__pycache__/class_registry.cpython-312.pyc and b/venv/Lib/site-packages/marshmallow/__pycache__/class_registry.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/marshmallow/__pycache__/decorators.cpython-312.pyc b/venv/Lib/site-packages/marshmallow/__pycache__/decorators.cpython-312.pyc
index 4da8b33c..035ba138 100644
Binary files a/venv/Lib/site-packages/marshmallow/__pycache__/decorators.cpython-312.pyc and b/venv/Lib/site-packages/marshmallow/__pycache__/decorators.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/marshmallow/__pycache__/error_store.cpython-312.pyc b/venv/Lib/site-packages/marshmallow/__pycache__/error_store.cpython-312.pyc
index 4ab6f61c..8cb4b16b 100644
Binary files a/venv/Lib/site-packages/marshmallow/__pycache__/error_store.cpython-312.pyc and b/venv/Lib/site-packages/marshmallow/__pycache__/error_store.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/marshmallow/__pycache__/exceptions.cpython-312.pyc b/venv/Lib/site-packages/marshmallow/__pycache__/exceptions.cpython-312.pyc
index 60a9b8b7..d8d563de 100644
Binary files a/venv/Lib/site-packages/marshmallow/__pycache__/exceptions.cpython-312.pyc and b/venv/Lib/site-packages/marshmallow/__pycache__/exceptions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/marshmallow/__pycache__/fields.cpython-312.pyc b/venv/Lib/site-packages/marshmallow/__pycache__/fields.cpython-312.pyc
index 5b8c4ab1..1b2c9971 100644
Binary files a/venv/Lib/site-packages/marshmallow/__pycache__/fields.cpython-312.pyc and b/venv/Lib/site-packages/marshmallow/__pycache__/fields.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/marshmallow/__pycache__/orderedset.cpython-312.pyc b/venv/Lib/site-packages/marshmallow/__pycache__/orderedset.cpython-312.pyc
index 38e12b58..619d4f6c 100644
Binary files a/venv/Lib/site-packages/marshmallow/__pycache__/orderedset.cpython-312.pyc and b/venv/Lib/site-packages/marshmallow/__pycache__/orderedset.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/marshmallow/__pycache__/schema.cpython-312.pyc b/venv/Lib/site-packages/marshmallow/__pycache__/schema.cpython-312.pyc
index 4d18ebd4..715dc20c 100644
Binary files a/venv/Lib/site-packages/marshmallow/__pycache__/schema.cpython-312.pyc and b/venv/Lib/site-packages/marshmallow/__pycache__/schema.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/marshmallow/__pycache__/types.cpython-312.pyc b/venv/Lib/site-packages/marshmallow/__pycache__/types.cpython-312.pyc
index aadd55e2..c4b10741 100644
Binary files a/venv/Lib/site-packages/marshmallow/__pycache__/types.cpython-312.pyc and b/venv/Lib/site-packages/marshmallow/__pycache__/types.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/marshmallow/__pycache__/utils.cpython-312.pyc b/venv/Lib/site-packages/marshmallow/__pycache__/utils.cpython-312.pyc
index 5aa9afb7..7b81e24d 100644
Binary files a/venv/Lib/site-packages/marshmallow/__pycache__/utils.cpython-312.pyc and b/venv/Lib/site-packages/marshmallow/__pycache__/utils.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/marshmallow/__pycache__/validate.cpython-312.pyc b/venv/Lib/site-packages/marshmallow/__pycache__/validate.cpython-312.pyc
index 967f5faf..1b70836b 100644
Binary files a/venv/Lib/site-packages/marshmallow/__pycache__/validate.cpython-312.pyc and b/venv/Lib/site-packages/marshmallow/__pycache__/validate.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/marshmallow/__pycache__/warnings.cpython-312.pyc b/venv/Lib/site-packages/marshmallow/__pycache__/warnings.cpython-312.pyc
index acd03b0c..f922d601 100644
Binary files a/venv/Lib/site-packages/marshmallow/__pycache__/warnings.cpython-312.pyc and b/venv/Lib/site-packages/marshmallow/__pycache__/warnings.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/multidict/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/multidict/__pycache__/__init__.cpython-312.pyc
index d309a38b..05df2b4e 100644
Binary files a/venv/Lib/site-packages/multidict/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/multidict/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/multidict/__pycache__/_abc.cpython-312.pyc b/venv/Lib/site-packages/multidict/__pycache__/_abc.cpython-312.pyc
index 5b08ccd6..e24a57b4 100644
Binary files a/venv/Lib/site-packages/multidict/__pycache__/_abc.cpython-312.pyc and b/venv/Lib/site-packages/multidict/__pycache__/_abc.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/multidict/__pycache__/_compat.cpython-312.pyc b/venv/Lib/site-packages/multidict/__pycache__/_compat.cpython-312.pyc
index 08262129..3166251b 100644
Binary files a/venv/Lib/site-packages/multidict/__pycache__/_compat.cpython-312.pyc and b/venv/Lib/site-packages/multidict/__pycache__/_compat.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/multipart/__init__.py b/venv/Lib/site-packages/multipart/__init__.py
new file mode 100644
index 00000000..67f0e5bb
--- /dev/null
+++ b/venv/Lib/site-packages/multipart/__init__.py
@@ -0,0 +1,24 @@
+# This only works if using a file system, other loaders not implemented.
+
+import importlib.util
+import sys
+import warnings
+from pathlib import Path
+
+for p in sys.path:
+ file_path = Path(p, "multipart.py")
+ try:
+ if file_path.is_file():
+ spec = importlib.util.spec_from_file_location("multipart", file_path)
+ assert spec is not None, f"{file_path} found but not loadable!"
+ module = importlib.util.module_from_spec(spec)
+ sys.modules["multipart"] = module
+ assert spec.loader is not None, f"{file_path} must be loadable!"
+ spec.loader.exec_module(module)
+ break
+ except PermissionError:
+ pass
+else:
+ warnings.warn("Please use `import python_multipart` instead.", PendingDeprecationWarning, stacklevel=2)
+ from python_multipart import *
+ from python_multipart import __all__, __author__, __copyright__, __license__, __version__
diff --git a/venv/Lib/site-packages/multipart/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/multipart/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 00000000..9f6d0f47
Binary files /dev/null and b/venv/Lib/site-packages/multipart/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/multipart/__pycache__/decoders.cpython-312.pyc b/venv/Lib/site-packages/multipart/__pycache__/decoders.cpython-312.pyc
new file mode 100644
index 00000000..aa1ef546
Binary files /dev/null and b/venv/Lib/site-packages/multipart/__pycache__/decoders.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/multipart/__pycache__/exceptions.cpython-312.pyc b/venv/Lib/site-packages/multipart/__pycache__/exceptions.cpython-312.pyc
new file mode 100644
index 00000000..fbc2f8ab
Binary files /dev/null and b/venv/Lib/site-packages/multipart/__pycache__/exceptions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/multipart/__pycache__/multipart.cpython-312.pyc b/venv/Lib/site-packages/multipart/__pycache__/multipart.cpython-312.pyc
new file mode 100644
index 00000000..ac8b6466
Binary files /dev/null and b/venv/Lib/site-packages/multipart/__pycache__/multipart.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/multipart/decoders.py b/venv/Lib/site-packages/multipart/decoders.py
new file mode 100644
index 00000000..31acdfbf
--- /dev/null
+++ b/venv/Lib/site-packages/multipart/decoders.py
@@ -0,0 +1 @@
+from python_multipart.decoders import *
diff --git a/venv/Lib/site-packages/multipart/exceptions.py b/venv/Lib/site-packages/multipart/exceptions.py
new file mode 100644
index 00000000..36815d19
--- /dev/null
+++ b/venv/Lib/site-packages/multipart/exceptions.py
@@ -0,0 +1 @@
+from python_multipart.exceptions import *
diff --git a/venv/Lib/site-packages/multipart/multipart.py b/venv/Lib/site-packages/multipart/multipart.py
new file mode 100644
index 00000000..7bf567df
--- /dev/null
+++ b/venv/Lib/site-packages/multipart/multipart.py
@@ -0,0 +1 @@
+from python_multipart.multipart import *
diff --git a/venv/Lib/site-packages/numpy/__pycache__/__config__.cpython-312.pyc b/venv/Lib/site-packages/numpy/__pycache__/__config__.cpython-312.pyc
index d376b59c..061d4ead 100644
Binary files a/venv/Lib/site-packages/numpy/__pycache__/__config__.cpython-312.pyc and b/venv/Lib/site-packages/numpy/__pycache__/__config__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/numpy/__pycache__/__init__.cpython-312.pyc
index 380e5abd..ba72520e 100644
Binary files a/venv/Lib/site-packages/numpy/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/numpy/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/__pycache__/_array_api_info.cpython-312.pyc b/venv/Lib/site-packages/numpy/__pycache__/_array_api_info.cpython-312.pyc
index f89a6c25..5a4ac402 100644
Binary files a/venv/Lib/site-packages/numpy/__pycache__/_array_api_info.cpython-312.pyc and b/venv/Lib/site-packages/numpy/__pycache__/_array_api_info.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/__pycache__/_distributor_init.cpython-312.pyc b/venv/Lib/site-packages/numpy/__pycache__/_distributor_init.cpython-312.pyc
index d8ae2e55..ab53c3c8 100644
Binary files a/venv/Lib/site-packages/numpy/__pycache__/_distributor_init.cpython-312.pyc and b/venv/Lib/site-packages/numpy/__pycache__/_distributor_init.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/__pycache__/_expired_attrs_2_0.cpython-312.pyc b/venv/Lib/site-packages/numpy/__pycache__/_expired_attrs_2_0.cpython-312.pyc
index 8a26236f..91b1ebf2 100644
Binary files a/venv/Lib/site-packages/numpy/__pycache__/_expired_attrs_2_0.cpython-312.pyc and b/venv/Lib/site-packages/numpy/__pycache__/_expired_attrs_2_0.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/__pycache__/_globals.cpython-312.pyc b/venv/Lib/site-packages/numpy/__pycache__/_globals.cpython-312.pyc
index f8af03d8..616b5219 100644
Binary files a/venv/Lib/site-packages/numpy/__pycache__/_globals.cpython-312.pyc and b/venv/Lib/site-packages/numpy/__pycache__/_globals.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/__pycache__/_pytesttester.cpython-312.pyc b/venv/Lib/site-packages/numpy/__pycache__/_pytesttester.cpython-312.pyc
index 17d32d68..30965b32 100644
Binary files a/venv/Lib/site-packages/numpy/__pycache__/_pytesttester.cpython-312.pyc and b/venv/Lib/site-packages/numpy/__pycache__/_pytesttester.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/__pycache__/dtypes.cpython-312.pyc b/venv/Lib/site-packages/numpy/__pycache__/dtypes.cpython-312.pyc
index 0e7760ea..7da0011d 100644
Binary files a/venv/Lib/site-packages/numpy/__pycache__/dtypes.cpython-312.pyc and b/venv/Lib/site-packages/numpy/__pycache__/dtypes.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/__pycache__/exceptions.cpython-312.pyc b/venv/Lib/site-packages/numpy/__pycache__/exceptions.cpython-312.pyc
index 655a7e43..620696f7 100644
Binary files a/venv/Lib/site-packages/numpy/__pycache__/exceptions.cpython-312.pyc and b/venv/Lib/site-packages/numpy/__pycache__/exceptions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/__pycache__/version.cpython-312.pyc b/venv/Lib/site-packages/numpy/__pycache__/version.cpython-312.pyc
index 6894cc39..73971925 100644
Binary files a/venv/Lib/site-packages/numpy/__pycache__/version.cpython-312.pyc and b/venv/Lib/site-packages/numpy/__pycache__/version.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_core/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/numpy/_core/__pycache__/__init__.cpython-312.pyc
index 9a520392..5c335132 100644
Binary files a/venv/Lib/site-packages/numpy/_core/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_core/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_core/__pycache__/_add_newdocs.cpython-312.pyc b/venv/Lib/site-packages/numpy/_core/__pycache__/_add_newdocs.cpython-312.pyc
index 3f7e1b31..2de3c4bb 100644
Binary files a/venv/Lib/site-packages/numpy/_core/__pycache__/_add_newdocs.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_core/__pycache__/_add_newdocs.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_core/__pycache__/_add_newdocs_scalars.cpython-312.pyc b/venv/Lib/site-packages/numpy/_core/__pycache__/_add_newdocs_scalars.cpython-312.pyc
index 83248221..5704ee5a 100644
Binary files a/venv/Lib/site-packages/numpy/_core/__pycache__/_add_newdocs_scalars.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_core/__pycache__/_add_newdocs_scalars.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_core/__pycache__/_asarray.cpython-312.pyc b/venv/Lib/site-packages/numpy/_core/__pycache__/_asarray.cpython-312.pyc
index 266aeafb..99e32b9c 100644
Binary files a/venv/Lib/site-packages/numpy/_core/__pycache__/_asarray.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_core/__pycache__/_asarray.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_core/__pycache__/_dtype.cpython-312.pyc b/venv/Lib/site-packages/numpy/_core/__pycache__/_dtype.cpython-312.pyc
index 702bbced..7916a0d5 100644
Binary files a/venv/Lib/site-packages/numpy/_core/__pycache__/_dtype.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_core/__pycache__/_dtype.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_core/__pycache__/_dtype_ctypes.cpython-312.pyc b/venv/Lib/site-packages/numpy/_core/__pycache__/_dtype_ctypes.cpython-312.pyc
index 204eff45..be46d2f2 100644
Binary files a/venv/Lib/site-packages/numpy/_core/__pycache__/_dtype_ctypes.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_core/__pycache__/_dtype_ctypes.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_core/__pycache__/_exceptions.cpython-312.pyc b/venv/Lib/site-packages/numpy/_core/__pycache__/_exceptions.cpython-312.pyc
index 275755a8..bd6cd700 100644
Binary files a/venv/Lib/site-packages/numpy/_core/__pycache__/_exceptions.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_core/__pycache__/_exceptions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_core/__pycache__/_internal.cpython-312.pyc b/venv/Lib/site-packages/numpy/_core/__pycache__/_internal.cpython-312.pyc
index e1cb5786..4e0d60a5 100644
Binary files a/venv/Lib/site-packages/numpy/_core/__pycache__/_internal.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_core/__pycache__/_internal.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_core/__pycache__/_machar.cpython-312.pyc b/venv/Lib/site-packages/numpy/_core/__pycache__/_machar.cpython-312.pyc
index 49017d64..f2bc06d6 100644
Binary files a/venv/Lib/site-packages/numpy/_core/__pycache__/_machar.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_core/__pycache__/_machar.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_core/__pycache__/_methods.cpython-312.pyc b/venv/Lib/site-packages/numpy/_core/__pycache__/_methods.cpython-312.pyc
index fc8d35ce..bb1071be 100644
Binary files a/venv/Lib/site-packages/numpy/_core/__pycache__/_methods.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_core/__pycache__/_methods.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_core/__pycache__/_string_helpers.cpython-312.pyc b/venv/Lib/site-packages/numpy/_core/__pycache__/_string_helpers.cpython-312.pyc
index b0e796e0..b5c60e04 100644
Binary files a/venv/Lib/site-packages/numpy/_core/__pycache__/_string_helpers.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_core/__pycache__/_string_helpers.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_core/__pycache__/_type_aliases.cpython-312.pyc b/venv/Lib/site-packages/numpy/_core/__pycache__/_type_aliases.cpython-312.pyc
index 5a91fb4d..4b250267 100644
Binary files a/venv/Lib/site-packages/numpy/_core/__pycache__/_type_aliases.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_core/__pycache__/_type_aliases.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_core/__pycache__/_ufunc_config.cpython-312.pyc b/venv/Lib/site-packages/numpy/_core/__pycache__/_ufunc_config.cpython-312.pyc
index 7e30db22..60686339 100644
Binary files a/venv/Lib/site-packages/numpy/_core/__pycache__/_ufunc_config.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_core/__pycache__/_ufunc_config.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_core/__pycache__/arrayprint.cpython-312.pyc b/venv/Lib/site-packages/numpy/_core/__pycache__/arrayprint.cpython-312.pyc
index eb5753eb..9a79d89c 100644
Binary files a/venv/Lib/site-packages/numpy/_core/__pycache__/arrayprint.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_core/__pycache__/arrayprint.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_core/__pycache__/einsumfunc.cpython-312.pyc b/venv/Lib/site-packages/numpy/_core/__pycache__/einsumfunc.cpython-312.pyc
index 86242603..5eb700b9 100644
Binary files a/venv/Lib/site-packages/numpy/_core/__pycache__/einsumfunc.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_core/__pycache__/einsumfunc.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_core/__pycache__/fromnumeric.cpython-312.pyc b/venv/Lib/site-packages/numpy/_core/__pycache__/fromnumeric.cpython-312.pyc
index 6008c054..0b34ebc9 100644
Binary files a/venv/Lib/site-packages/numpy/_core/__pycache__/fromnumeric.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_core/__pycache__/fromnumeric.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_core/__pycache__/function_base.cpython-312.pyc b/venv/Lib/site-packages/numpy/_core/__pycache__/function_base.cpython-312.pyc
index d63d7a21..5da77aa8 100644
Binary files a/venv/Lib/site-packages/numpy/_core/__pycache__/function_base.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_core/__pycache__/function_base.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_core/__pycache__/getlimits.cpython-312.pyc b/venv/Lib/site-packages/numpy/_core/__pycache__/getlimits.cpython-312.pyc
index f942e8bb..feb4ae79 100644
Binary files a/venv/Lib/site-packages/numpy/_core/__pycache__/getlimits.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_core/__pycache__/getlimits.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_core/__pycache__/memmap.cpython-312.pyc b/venv/Lib/site-packages/numpy/_core/__pycache__/memmap.cpython-312.pyc
index 7477906a..7ffbf017 100644
Binary files a/venv/Lib/site-packages/numpy/_core/__pycache__/memmap.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_core/__pycache__/memmap.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_core/__pycache__/multiarray.cpython-312.pyc b/venv/Lib/site-packages/numpy/_core/__pycache__/multiarray.cpython-312.pyc
index 9597eff3..7d2a42bb 100644
Binary files a/venv/Lib/site-packages/numpy/_core/__pycache__/multiarray.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_core/__pycache__/multiarray.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_core/__pycache__/numeric.cpython-312.pyc b/venv/Lib/site-packages/numpy/_core/__pycache__/numeric.cpython-312.pyc
index f755580b..7b3c1d5b 100644
Binary files a/venv/Lib/site-packages/numpy/_core/__pycache__/numeric.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_core/__pycache__/numeric.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_core/__pycache__/numerictypes.cpython-312.pyc b/venv/Lib/site-packages/numpy/_core/__pycache__/numerictypes.cpython-312.pyc
index 615e5a65..22338c85 100644
Binary files a/venv/Lib/site-packages/numpy/_core/__pycache__/numerictypes.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_core/__pycache__/numerictypes.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_core/__pycache__/overrides.cpython-312.pyc b/venv/Lib/site-packages/numpy/_core/__pycache__/overrides.cpython-312.pyc
index 62063bf1..f81ac6bf 100644
Binary files a/venv/Lib/site-packages/numpy/_core/__pycache__/overrides.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_core/__pycache__/overrides.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_core/__pycache__/printoptions.cpython-312.pyc b/venv/Lib/site-packages/numpy/_core/__pycache__/printoptions.cpython-312.pyc
index 900f1e40..7b603860 100644
Binary files a/venv/Lib/site-packages/numpy/_core/__pycache__/printoptions.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_core/__pycache__/printoptions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_core/__pycache__/records.cpython-312.pyc b/venv/Lib/site-packages/numpy/_core/__pycache__/records.cpython-312.pyc
index 9c4ffb21..7fedca8e 100644
Binary files a/venv/Lib/site-packages/numpy/_core/__pycache__/records.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_core/__pycache__/records.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_core/__pycache__/shape_base.cpython-312.pyc b/venv/Lib/site-packages/numpy/_core/__pycache__/shape_base.cpython-312.pyc
index b8a6c875..c5e8187e 100644
Binary files a/venv/Lib/site-packages/numpy/_core/__pycache__/shape_base.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_core/__pycache__/shape_base.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_core/__pycache__/umath.cpython-312.pyc b/venv/Lib/site-packages/numpy/_core/__pycache__/umath.cpython-312.pyc
index 8e8a2456..61788866 100644
Binary files a/venv/Lib/site-packages/numpy/_core/__pycache__/umath.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_core/__pycache__/umath.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_typing/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/numpy/_typing/__pycache__/__init__.cpython-312.pyc
index 71f974a7..df691658 100644
Binary files a/venv/Lib/site-packages/numpy/_typing/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_typing/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_typing/__pycache__/_array_like.cpython-312.pyc b/venv/Lib/site-packages/numpy/_typing/__pycache__/_array_like.cpython-312.pyc
index 0b0dc87d..bbed1857 100644
Binary files a/venv/Lib/site-packages/numpy/_typing/__pycache__/_array_like.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_typing/__pycache__/_array_like.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_typing/__pycache__/_char_codes.cpython-312.pyc b/venv/Lib/site-packages/numpy/_typing/__pycache__/_char_codes.cpython-312.pyc
index 87c212ae..3d897bfe 100644
Binary files a/venv/Lib/site-packages/numpy/_typing/__pycache__/_char_codes.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_typing/__pycache__/_char_codes.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_typing/__pycache__/_dtype_like.cpython-312.pyc b/venv/Lib/site-packages/numpy/_typing/__pycache__/_dtype_like.cpython-312.pyc
index feb63728..7dc22108 100644
Binary files a/venv/Lib/site-packages/numpy/_typing/__pycache__/_dtype_like.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_typing/__pycache__/_dtype_like.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_typing/__pycache__/_nbit.cpython-312.pyc b/venv/Lib/site-packages/numpy/_typing/__pycache__/_nbit.cpython-312.pyc
index 00a21566..28e3b557 100644
Binary files a/venv/Lib/site-packages/numpy/_typing/__pycache__/_nbit.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_typing/__pycache__/_nbit.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_typing/__pycache__/_nbit_base.cpython-312.pyc b/venv/Lib/site-packages/numpy/_typing/__pycache__/_nbit_base.cpython-312.pyc
index 44723c3f..8d39c126 100644
Binary files a/venv/Lib/site-packages/numpy/_typing/__pycache__/_nbit_base.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_typing/__pycache__/_nbit_base.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_typing/__pycache__/_nested_sequence.cpython-312.pyc b/venv/Lib/site-packages/numpy/_typing/__pycache__/_nested_sequence.cpython-312.pyc
index adb2da60..f888e607 100644
Binary files a/venv/Lib/site-packages/numpy/_typing/__pycache__/_nested_sequence.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_typing/__pycache__/_nested_sequence.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_typing/__pycache__/_scalars.cpython-312.pyc b/venv/Lib/site-packages/numpy/_typing/__pycache__/_scalars.cpython-312.pyc
index 853ed171..97df2ebe 100644
Binary files a/venv/Lib/site-packages/numpy/_typing/__pycache__/_scalars.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_typing/__pycache__/_scalars.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_typing/__pycache__/_shape.cpython-312.pyc b/venv/Lib/site-packages/numpy/_typing/__pycache__/_shape.cpython-312.pyc
index b3189608..16eca63f 100644
Binary files a/venv/Lib/site-packages/numpy/_typing/__pycache__/_shape.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_typing/__pycache__/_shape.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_typing/__pycache__/_ufunc.cpython-312.pyc b/venv/Lib/site-packages/numpy/_typing/__pycache__/_ufunc.cpython-312.pyc
index 8f253f2f..fc8c9f74 100644
Binary files a/venv/Lib/site-packages/numpy/_typing/__pycache__/_ufunc.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_typing/__pycache__/_ufunc.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_utils/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/numpy/_utils/__pycache__/__init__.cpython-312.pyc
index ae32e1c6..b7385736 100644
Binary files a/venv/Lib/site-packages/numpy/_utils/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_utils/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_utils/__pycache__/_convertions.cpython-312.pyc b/venv/Lib/site-packages/numpy/_utils/__pycache__/_convertions.cpython-312.pyc
index a7a8d5e1..037cb335 100644
Binary files a/venv/Lib/site-packages/numpy/_utils/__pycache__/_convertions.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_utils/__pycache__/_convertions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/_utils/__pycache__/_inspect.cpython-312.pyc b/venv/Lib/site-packages/numpy/_utils/__pycache__/_inspect.cpython-312.pyc
index 3b5cc640..fb286fa3 100644
Binary files a/venv/Lib/site-packages/numpy/_utils/__pycache__/_inspect.cpython-312.pyc and b/venv/Lib/site-packages/numpy/_utils/__pycache__/_inspect.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/fft/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/numpy/fft/__pycache__/__init__.cpython-312.pyc
index b0a2c42b..ba480a0d 100644
Binary files a/venv/Lib/site-packages/numpy/fft/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/numpy/fft/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/fft/__pycache__/_helper.cpython-312.pyc b/venv/Lib/site-packages/numpy/fft/__pycache__/_helper.cpython-312.pyc
index b00a7be4..bf66f11e 100644
Binary files a/venv/Lib/site-packages/numpy/fft/__pycache__/_helper.cpython-312.pyc and b/venv/Lib/site-packages/numpy/fft/__pycache__/_helper.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/fft/__pycache__/_pocketfft.cpython-312.pyc b/venv/Lib/site-packages/numpy/fft/__pycache__/_pocketfft.cpython-312.pyc
index 0975c82c..0217e7e9 100644
Binary files a/venv/Lib/site-packages/numpy/fft/__pycache__/_pocketfft.cpython-312.pyc and b/venv/Lib/site-packages/numpy/fft/__pycache__/_pocketfft.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/fft/__pycache__/helper.cpython-312.pyc b/venv/Lib/site-packages/numpy/fft/__pycache__/helper.cpython-312.pyc
index fc33dc35..64632f96 100644
Binary files a/venv/Lib/site-packages/numpy/fft/__pycache__/helper.cpython-312.pyc and b/venv/Lib/site-packages/numpy/fft/__pycache__/helper.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/lib/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/numpy/lib/__pycache__/__init__.cpython-312.pyc
index 2a9b08c0..ed1a68f1 100644
Binary files a/venv/Lib/site-packages/numpy/lib/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/numpy/lib/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/lib/__pycache__/_array_utils_impl.cpython-312.pyc b/venv/Lib/site-packages/numpy/lib/__pycache__/_array_utils_impl.cpython-312.pyc
index 9d404cc1..a5f21142 100644
Binary files a/venv/Lib/site-packages/numpy/lib/__pycache__/_array_utils_impl.cpython-312.pyc and b/venv/Lib/site-packages/numpy/lib/__pycache__/_array_utils_impl.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/lib/__pycache__/_arraypad_impl.cpython-312.pyc b/venv/Lib/site-packages/numpy/lib/__pycache__/_arraypad_impl.cpython-312.pyc
index 28c5c345..1cac7873 100644
Binary files a/venv/Lib/site-packages/numpy/lib/__pycache__/_arraypad_impl.cpython-312.pyc and b/venv/Lib/site-packages/numpy/lib/__pycache__/_arraypad_impl.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/lib/__pycache__/_arraysetops_impl.cpython-312.pyc b/venv/Lib/site-packages/numpy/lib/__pycache__/_arraysetops_impl.cpython-312.pyc
index 687abdaf..1a47e2d8 100644
Binary files a/venv/Lib/site-packages/numpy/lib/__pycache__/_arraysetops_impl.cpython-312.pyc and b/venv/Lib/site-packages/numpy/lib/__pycache__/_arraysetops_impl.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/lib/__pycache__/_arrayterator_impl.cpython-312.pyc b/venv/Lib/site-packages/numpy/lib/__pycache__/_arrayterator_impl.cpython-312.pyc
index 50ba51ec..353bea5e 100644
Binary files a/venv/Lib/site-packages/numpy/lib/__pycache__/_arrayterator_impl.cpython-312.pyc and b/venv/Lib/site-packages/numpy/lib/__pycache__/_arrayterator_impl.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/lib/__pycache__/_datasource.cpython-312.pyc b/venv/Lib/site-packages/numpy/lib/__pycache__/_datasource.cpython-312.pyc
index 28d5ae2e..88c9d2e0 100644
Binary files a/venv/Lib/site-packages/numpy/lib/__pycache__/_datasource.cpython-312.pyc and b/venv/Lib/site-packages/numpy/lib/__pycache__/_datasource.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/lib/__pycache__/_format_impl.cpython-312.pyc b/venv/Lib/site-packages/numpy/lib/__pycache__/_format_impl.cpython-312.pyc
index 6cb1fa1a..8f3bb439 100644
Binary files a/venv/Lib/site-packages/numpy/lib/__pycache__/_format_impl.cpython-312.pyc and b/venv/Lib/site-packages/numpy/lib/__pycache__/_format_impl.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/lib/__pycache__/_function_base_impl.cpython-312.pyc b/venv/Lib/site-packages/numpy/lib/__pycache__/_function_base_impl.cpython-312.pyc
index 8980791f..57e9f520 100644
Binary files a/venv/Lib/site-packages/numpy/lib/__pycache__/_function_base_impl.cpython-312.pyc and b/venv/Lib/site-packages/numpy/lib/__pycache__/_function_base_impl.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/lib/__pycache__/_histograms_impl.cpython-312.pyc b/venv/Lib/site-packages/numpy/lib/__pycache__/_histograms_impl.cpython-312.pyc
index bd82cbfe..f297fda0 100644
Binary files a/venv/Lib/site-packages/numpy/lib/__pycache__/_histograms_impl.cpython-312.pyc and b/venv/Lib/site-packages/numpy/lib/__pycache__/_histograms_impl.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/lib/__pycache__/_index_tricks_impl.cpython-312.pyc b/venv/Lib/site-packages/numpy/lib/__pycache__/_index_tricks_impl.cpython-312.pyc
index 33aba798..8e91e441 100644
Binary files a/venv/Lib/site-packages/numpy/lib/__pycache__/_index_tricks_impl.cpython-312.pyc and b/venv/Lib/site-packages/numpy/lib/__pycache__/_index_tricks_impl.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/lib/__pycache__/_iotools.cpython-312.pyc b/venv/Lib/site-packages/numpy/lib/__pycache__/_iotools.cpython-312.pyc
index 70044500..9c85bc58 100644
Binary files a/venv/Lib/site-packages/numpy/lib/__pycache__/_iotools.cpython-312.pyc and b/venv/Lib/site-packages/numpy/lib/__pycache__/_iotools.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/lib/__pycache__/_nanfunctions_impl.cpython-312.pyc b/venv/Lib/site-packages/numpy/lib/__pycache__/_nanfunctions_impl.cpython-312.pyc
index 5208c54b..261fe4be 100644
Binary files a/venv/Lib/site-packages/numpy/lib/__pycache__/_nanfunctions_impl.cpython-312.pyc and b/venv/Lib/site-packages/numpy/lib/__pycache__/_nanfunctions_impl.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/lib/__pycache__/_npyio_impl.cpython-312.pyc b/venv/Lib/site-packages/numpy/lib/__pycache__/_npyio_impl.cpython-312.pyc
index e78ccdc2..86fe4aae 100644
Binary files a/venv/Lib/site-packages/numpy/lib/__pycache__/_npyio_impl.cpython-312.pyc and b/venv/Lib/site-packages/numpy/lib/__pycache__/_npyio_impl.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/lib/__pycache__/_polynomial_impl.cpython-312.pyc b/venv/Lib/site-packages/numpy/lib/__pycache__/_polynomial_impl.cpython-312.pyc
index 19cff001..30ed43aa 100644
Binary files a/venv/Lib/site-packages/numpy/lib/__pycache__/_polynomial_impl.cpython-312.pyc and b/venv/Lib/site-packages/numpy/lib/__pycache__/_polynomial_impl.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/lib/__pycache__/_scimath_impl.cpython-312.pyc b/venv/Lib/site-packages/numpy/lib/__pycache__/_scimath_impl.cpython-312.pyc
index beb4ee97..29737a27 100644
Binary files a/venv/Lib/site-packages/numpy/lib/__pycache__/_scimath_impl.cpython-312.pyc and b/venv/Lib/site-packages/numpy/lib/__pycache__/_scimath_impl.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/lib/__pycache__/_shape_base_impl.cpython-312.pyc b/venv/Lib/site-packages/numpy/lib/__pycache__/_shape_base_impl.cpython-312.pyc
index 7ac8be2f..084a6213 100644
Binary files a/venv/Lib/site-packages/numpy/lib/__pycache__/_shape_base_impl.cpython-312.pyc and b/venv/Lib/site-packages/numpy/lib/__pycache__/_shape_base_impl.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/lib/__pycache__/_stride_tricks_impl.cpython-312.pyc b/venv/Lib/site-packages/numpy/lib/__pycache__/_stride_tricks_impl.cpython-312.pyc
index 80d5d58c..b032f213 100644
Binary files a/venv/Lib/site-packages/numpy/lib/__pycache__/_stride_tricks_impl.cpython-312.pyc and b/venv/Lib/site-packages/numpy/lib/__pycache__/_stride_tricks_impl.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/lib/__pycache__/_twodim_base_impl.cpython-312.pyc b/venv/Lib/site-packages/numpy/lib/__pycache__/_twodim_base_impl.cpython-312.pyc
index 628ec4d6..8e3c5750 100644
Binary files a/venv/Lib/site-packages/numpy/lib/__pycache__/_twodim_base_impl.cpython-312.pyc and b/venv/Lib/site-packages/numpy/lib/__pycache__/_twodim_base_impl.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/lib/__pycache__/_type_check_impl.cpython-312.pyc b/venv/Lib/site-packages/numpy/lib/__pycache__/_type_check_impl.cpython-312.pyc
index 0216f65e..59898017 100644
Binary files a/venv/Lib/site-packages/numpy/lib/__pycache__/_type_check_impl.cpython-312.pyc and b/venv/Lib/site-packages/numpy/lib/__pycache__/_type_check_impl.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/lib/__pycache__/_ufunclike_impl.cpython-312.pyc b/venv/Lib/site-packages/numpy/lib/__pycache__/_ufunclike_impl.cpython-312.pyc
index 0ce90c87..a0c45000 100644
Binary files a/venv/Lib/site-packages/numpy/lib/__pycache__/_ufunclike_impl.cpython-312.pyc and b/venv/Lib/site-packages/numpy/lib/__pycache__/_ufunclike_impl.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/lib/__pycache__/_utils_impl.cpython-312.pyc b/venv/Lib/site-packages/numpy/lib/__pycache__/_utils_impl.cpython-312.pyc
index 0b6fc0c7..3a0baf82 100644
Binary files a/venv/Lib/site-packages/numpy/lib/__pycache__/_utils_impl.cpython-312.pyc and b/venv/Lib/site-packages/numpy/lib/__pycache__/_utils_impl.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/lib/__pycache__/_version.cpython-312.pyc b/venv/Lib/site-packages/numpy/lib/__pycache__/_version.cpython-312.pyc
index c287ef24..675b2628 100644
Binary files a/venv/Lib/site-packages/numpy/lib/__pycache__/_version.cpython-312.pyc and b/venv/Lib/site-packages/numpy/lib/__pycache__/_version.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/lib/__pycache__/array_utils.cpython-312.pyc b/venv/Lib/site-packages/numpy/lib/__pycache__/array_utils.cpython-312.pyc
index 5feb17ea..a2fcc88f 100644
Binary files a/venv/Lib/site-packages/numpy/lib/__pycache__/array_utils.cpython-312.pyc and b/venv/Lib/site-packages/numpy/lib/__pycache__/array_utils.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/lib/__pycache__/format.cpython-312.pyc b/venv/Lib/site-packages/numpy/lib/__pycache__/format.cpython-312.pyc
index b5af0581..7204b9af 100644
Binary files a/venv/Lib/site-packages/numpy/lib/__pycache__/format.cpython-312.pyc and b/venv/Lib/site-packages/numpy/lib/__pycache__/format.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/lib/__pycache__/introspect.cpython-312.pyc b/venv/Lib/site-packages/numpy/lib/__pycache__/introspect.cpython-312.pyc
index e5e6daec..33996aeb 100644
Binary files a/venv/Lib/site-packages/numpy/lib/__pycache__/introspect.cpython-312.pyc and b/venv/Lib/site-packages/numpy/lib/__pycache__/introspect.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/lib/__pycache__/mixins.cpython-312.pyc b/venv/Lib/site-packages/numpy/lib/__pycache__/mixins.cpython-312.pyc
index 7a286af3..f280e2cf 100644
Binary files a/venv/Lib/site-packages/numpy/lib/__pycache__/mixins.cpython-312.pyc and b/venv/Lib/site-packages/numpy/lib/__pycache__/mixins.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/lib/__pycache__/npyio.cpython-312.pyc b/venv/Lib/site-packages/numpy/lib/__pycache__/npyio.cpython-312.pyc
index 2f5f4572..52450a02 100644
Binary files a/venv/Lib/site-packages/numpy/lib/__pycache__/npyio.cpython-312.pyc and b/venv/Lib/site-packages/numpy/lib/__pycache__/npyio.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/lib/__pycache__/scimath.cpython-312.pyc b/venv/Lib/site-packages/numpy/lib/__pycache__/scimath.cpython-312.pyc
index a635a262..4d45829d 100644
Binary files a/venv/Lib/site-packages/numpy/lib/__pycache__/scimath.cpython-312.pyc and b/venv/Lib/site-packages/numpy/lib/__pycache__/scimath.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/lib/__pycache__/stride_tricks.cpython-312.pyc b/venv/Lib/site-packages/numpy/lib/__pycache__/stride_tricks.cpython-312.pyc
index a2a6a5bf..1923f3bf 100644
Binary files a/venv/Lib/site-packages/numpy/lib/__pycache__/stride_tricks.cpython-312.pyc and b/venv/Lib/site-packages/numpy/lib/__pycache__/stride_tricks.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/linalg/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/numpy/linalg/__pycache__/__init__.cpython-312.pyc
index 7c8bc8b4..4db3aee1 100644
Binary files a/venv/Lib/site-packages/numpy/linalg/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/numpy/linalg/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/linalg/__pycache__/_linalg.cpython-312.pyc b/venv/Lib/site-packages/numpy/linalg/__pycache__/_linalg.cpython-312.pyc
index 13b7cf0c..f0f7f8e7 100644
Binary files a/venv/Lib/site-packages/numpy/linalg/__pycache__/_linalg.cpython-312.pyc and b/venv/Lib/site-packages/numpy/linalg/__pycache__/_linalg.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/linalg/__pycache__/linalg.cpython-312.pyc b/venv/Lib/site-packages/numpy/linalg/__pycache__/linalg.cpython-312.pyc
index 7c5454d5..5388825d 100644
Binary files a/venv/Lib/site-packages/numpy/linalg/__pycache__/linalg.cpython-312.pyc and b/venv/Lib/site-packages/numpy/linalg/__pycache__/linalg.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/ma/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/numpy/ma/__pycache__/__init__.cpython-312.pyc
index 7b197fe0..92df85ce 100644
Binary files a/venv/Lib/site-packages/numpy/ma/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/numpy/ma/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/ma/__pycache__/core.cpython-312.pyc b/venv/Lib/site-packages/numpy/ma/__pycache__/core.cpython-312.pyc
index 6e6eff8b..e54b1bf5 100644
Binary files a/venv/Lib/site-packages/numpy/ma/__pycache__/core.cpython-312.pyc and b/venv/Lib/site-packages/numpy/ma/__pycache__/core.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/ma/__pycache__/extras.cpython-312.pyc b/venv/Lib/site-packages/numpy/ma/__pycache__/extras.cpython-312.pyc
index 92185a4c..1fc7e427 100644
Binary files a/venv/Lib/site-packages/numpy/ma/__pycache__/extras.cpython-312.pyc and b/venv/Lib/site-packages/numpy/ma/__pycache__/extras.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/matrixlib/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/numpy/matrixlib/__pycache__/__init__.cpython-312.pyc
index 4ab9b1dd..fbbc1c04 100644
Binary files a/venv/Lib/site-packages/numpy/matrixlib/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/numpy/matrixlib/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/matrixlib/__pycache__/defmatrix.cpython-312.pyc b/venv/Lib/site-packages/numpy/matrixlib/__pycache__/defmatrix.cpython-312.pyc
index 309e6730..5c7b1f2e 100644
Binary files a/venv/Lib/site-packages/numpy/matrixlib/__pycache__/defmatrix.cpython-312.pyc and b/venv/Lib/site-packages/numpy/matrixlib/__pycache__/defmatrix.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/random/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/numpy/random/__pycache__/__init__.cpython-312.pyc
index 81d25835..d8de0019 100644
Binary files a/venv/Lib/site-packages/numpy/random/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/numpy/random/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/random/__pycache__/_pickle.cpython-312.pyc b/venv/Lib/site-packages/numpy/random/__pycache__/_pickle.cpython-312.pyc
index 5bec08d7..8cc77dea 100644
Binary files a/venv/Lib/site-packages/numpy/random/__pycache__/_pickle.cpython-312.pyc and b/venv/Lib/site-packages/numpy/random/__pycache__/_pickle.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/numpy/rec/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/numpy/rec/__pycache__/__init__.cpython-312.pyc
index bff65ebc..5a35a0d5 100644
Binary files a/venv/Lib/site-packages/numpy/rec/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/numpy/rec/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/onnxruntime/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/onnxruntime/__pycache__/__init__.cpython-312.pyc
index 6b629f8d..58e56d89 100644
Binary files a/venv/Lib/site-packages/onnxruntime/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/onnxruntime/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/onnxruntime/capi/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/onnxruntime/capi/__pycache__/__init__.cpython-312.pyc
index c1d7d12a..a2bf241b 100644
Binary files a/venv/Lib/site-packages/onnxruntime/capi/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/onnxruntime/capi/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/onnxruntime/capi/__pycache__/_ld_preload.cpython-312.pyc b/venv/Lib/site-packages/onnxruntime/capi/__pycache__/_ld_preload.cpython-312.pyc
index 2b706612..bf5eb49b 100644
Binary files a/venv/Lib/site-packages/onnxruntime/capi/__pycache__/_ld_preload.cpython-312.pyc and b/venv/Lib/site-packages/onnxruntime/capi/__pycache__/_ld_preload.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/onnxruntime/capi/__pycache__/_pybind_state.cpython-312.pyc b/venv/Lib/site-packages/onnxruntime/capi/__pycache__/_pybind_state.cpython-312.pyc
index 0c2e1205..41d71d9b 100644
Binary files a/venv/Lib/site-packages/onnxruntime/capi/__pycache__/_pybind_state.cpython-312.pyc and b/venv/Lib/site-packages/onnxruntime/capi/__pycache__/_pybind_state.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/onnxruntime/capi/__pycache__/build_and_package_info.cpython-312.pyc b/venv/Lib/site-packages/onnxruntime/capi/__pycache__/build_and_package_info.cpython-312.pyc
index f0e89ec4..6e756653 100644
Binary files a/venv/Lib/site-packages/onnxruntime/capi/__pycache__/build_and_package_info.cpython-312.pyc and b/venv/Lib/site-packages/onnxruntime/capi/__pycache__/build_and_package_info.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/onnxruntime/capi/__pycache__/onnxruntime_inference_collection.cpython-312.pyc b/venv/Lib/site-packages/onnxruntime/capi/__pycache__/onnxruntime_inference_collection.cpython-312.pyc
index 04a81f28..a8a6a938 100644
Binary files a/venv/Lib/site-packages/onnxruntime/capi/__pycache__/onnxruntime_inference_collection.cpython-312.pyc and b/venv/Lib/site-packages/onnxruntime/capi/__pycache__/onnxruntime_inference_collection.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/onnxruntime/capi/__pycache__/onnxruntime_validation.cpython-312.pyc b/venv/Lib/site-packages/onnxruntime/capi/__pycache__/onnxruntime_validation.cpython-312.pyc
index 14ff3784..13eb1345 100644
Binary files a/venv/Lib/site-packages/onnxruntime/capi/__pycache__/onnxruntime_validation.cpython-312.pyc and b/venv/Lib/site-packages/onnxruntime/capi/__pycache__/onnxruntime_validation.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/onnxruntime/capi/__pycache__/version_info.cpython-312.pyc b/venv/Lib/site-packages/onnxruntime/capi/__pycache__/version_info.cpython-312.pyc
index f5ffd8e2..c863d53a 100644
Binary files a/venv/Lib/site-packages/onnxruntime/capi/__pycache__/version_info.cpython-312.pyc and b/venv/Lib/site-packages/onnxruntime/capi/__pycache__/version_info.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/__pycache__/__init__.cpython-312.pyc
index 1e4153f5..153c459a 100644
Binary files a/venv/Lib/site-packages/openai/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/__pycache__/_base_client.cpython-312.pyc b/venv/Lib/site-packages/openai/__pycache__/_base_client.cpython-312.pyc
index 45f9b4ca..b61f8786 100644
Binary files a/venv/Lib/site-packages/openai/__pycache__/_base_client.cpython-312.pyc and b/venv/Lib/site-packages/openai/__pycache__/_base_client.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/__pycache__/_client.cpython-312.pyc b/venv/Lib/site-packages/openai/__pycache__/_client.cpython-312.pyc
index 974f5190..dac8bfbf 100644
Binary files a/venv/Lib/site-packages/openai/__pycache__/_client.cpython-312.pyc and b/venv/Lib/site-packages/openai/__pycache__/_client.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/__pycache__/_compat.cpython-312.pyc b/venv/Lib/site-packages/openai/__pycache__/_compat.cpython-312.pyc
index 8961c563..7fefc7c8 100644
Binary files a/venv/Lib/site-packages/openai/__pycache__/_compat.cpython-312.pyc and b/venv/Lib/site-packages/openai/__pycache__/_compat.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/__pycache__/_constants.cpython-312.pyc b/venv/Lib/site-packages/openai/__pycache__/_constants.cpython-312.pyc
index d289d6c1..3a551cc2 100644
Binary files a/venv/Lib/site-packages/openai/__pycache__/_constants.cpython-312.pyc and b/venv/Lib/site-packages/openai/__pycache__/_constants.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/__pycache__/_exceptions.cpython-312.pyc b/venv/Lib/site-packages/openai/__pycache__/_exceptions.cpython-312.pyc
index 6ff14680..a632004d 100644
Binary files a/venv/Lib/site-packages/openai/__pycache__/_exceptions.cpython-312.pyc and b/venv/Lib/site-packages/openai/__pycache__/_exceptions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/__pycache__/_files.cpython-312.pyc b/venv/Lib/site-packages/openai/__pycache__/_files.cpython-312.pyc
index a97f4272..018cf509 100644
Binary files a/venv/Lib/site-packages/openai/__pycache__/_files.cpython-312.pyc and b/venv/Lib/site-packages/openai/__pycache__/_files.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/__pycache__/_legacy_response.cpython-312.pyc b/venv/Lib/site-packages/openai/__pycache__/_legacy_response.cpython-312.pyc
index 4b6d383c..41fd9cdb 100644
Binary files a/venv/Lib/site-packages/openai/__pycache__/_legacy_response.cpython-312.pyc and b/venv/Lib/site-packages/openai/__pycache__/_legacy_response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/__pycache__/_models.cpython-312.pyc b/venv/Lib/site-packages/openai/__pycache__/_models.cpython-312.pyc
index 8d944a43..2ccaba6b 100644
Binary files a/venv/Lib/site-packages/openai/__pycache__/_models.cpython-312.pyc and b/venv/Lib/site-packages/openai/__pycache__/_models.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/__pycache__/_module_client.cpython-312.pyc b/venv/Lib/site-packages/openai/__pycache__/_module_client.cpython-312.pyc
index 98af929a..ae3ccc4d 100644
Binary files a/venv/Lib/site-packages/openai/__pycache__/_module_client.cpython-312.pyc and b/venv/Lib/site-packages/openai/__pycache__/_module_client.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/__pycache__/_qs.cpython-312.pyc b/venv/Lib/site-packages/openai/__pycache__/_qs.cpython-312.pyc
index 90ec7e5a..746e45dd 100644
Binary files a/venv/Lib/site-packages/openai/__pycache__/_qs.cpython-312.pyc and b/venv/Lib/site-packages/openai/__pycache__/_qs.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/__pycache__/_resource.cpython-312.pyc b/venv/Lib/site-packages/openai/__pycache__/_resource.cpython-312.pyc
index 4b7d2ec9..fdf4d532 100644
Binary files a/venv/Lib/site-packages/openai/__pycache__/_resource.cpython-312.pyc and b/venv/Lib/site-packages/openai/__pycache__/_resource.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/__pycache__/_response.cpython-312.pyc b/venv/Lib/site-packages/openai/__pycache__/_response.cpython-312.pyc
index f952a99e..15b7bb99 100644
Binary files a/venv/Lib/site-packages/openai/__pycache__/_response.cpython-312.pyc and b/venv/Lib/site-packages/openai/__pycache__/_response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/__pycache__/_streaming.cpython-312.pyc b/venv/Lib/site-packages/openai/__pycache__/_streaming.cpython-312.pyc
index f0716dd8..5cd87df2 100644
Binary files a/venv/Lib/site-packages/openai/__pycache__/_streaming.cpython-312.pyc and b/venv/Lib/site-packages/openai/__pycache__/_streaming.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/__pycache__/_types.cpython-312.pyc b/venv/Lib/site-packages/openai/__pycache__/_types.cpython-312.pyc
index 152ac03e..a5a0de57 100644
Binary files a/venv/Lib/site-packages/openai/__pycache__/_types.cpython-312.pyc and b/venv/Lib/site-packages/openai/__pycache__/_types.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/__pycache__/_version.cpython-312.pyc b/venv/Lib/site-packages/openai/__pycache__/_version.cpython-312.pyc
index 9aa90c79..3ac4730f 100644
Binary files a/venv/Lib/site-packages/openai/__pycache__/_version.cpython-312.pyc and b/venv/Lib/site-packages/openai/__pycache__/_version.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/__pycache__/pagination.cpython-312.pyc b/venv/Lib/site-packages/openai/__pycache__/pagination.cpython-312.pyc
index ac80b8dd..998601b7 100644
Binary files a/venv/Lib/site-packages/openai/__pycache__/pagination.cpython-312.pyc and b/venv/Lib/site-packages/openai/__pycache__/pagination.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/__pycache__/version.cpython-312.pyc b/venv/Lib/site-packages/openai/__pycache__/version.cpython-312.pyc
index 47ba1e07..db4d1d0e 100644
Binary files a/venv/Lib/site-packages/openai/__pycache__/version.cpython-312.pyc and b/venv/Lib/site-packages/openai/__pycache__/version.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/_extras/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/_extras/__pycache__/__init__.cpython-312.pyc
index bbfe9f12..984d06fb 100644
Binary files a/venv/Lib/site-packages/openai/_extras/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/_extras/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/_extras/__pycache__/_common.cpython-312.pyc b/venv/Lib/site-packages/openai/_extras/__pycache__/_common.cpython-312.pyc
index 16e2c6ed..8431c9cd 100644
Binary files a/venv/Lib/site-packages/openai/_extras/__pycache__/_common.cpython-312.pyc and b/venv/Lib/site-packages/openai/_extras/__pycache__/_common.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/_extras/__pycache__/numpy_proxy.cpython-312.pyc b/venv/Lib/site-packages/openai/_extras/__pycache__/numpy_proxy.cpython-312.pyc
index 91a826b9..7c6e65f9 100644
Binary files a/venv/Lib/site-packages/openai/_extras/__pycache__/numpy_proxy.cpython-312.pyc and b/venv/Lib/site-packages/openai/_extras/__pycache__/numpy_proxy.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/_extras/__pycache__/pandas_proxy.cpython-312.pyc b/venv/Lib/site-packages/openai/_extras/__pycache__/pandas_proxy.cpython-312.pyc
index ac6a4fdb..777b8d68 100644
Binary files a/venv/Lib/site-packages/openai/_extras/__pycache__/pandas_proxy.cpython-312.pyc and b/venv/Lib/site-packages/openai/_extras/__pycache__/pandas_proxy.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/_extras/__pycache__/sounddevice_proxy.cpython-312.pyc b/venv/Lib/site-packages/openai/_extras/__pycache__/sounddevice_proxy.cpython-312.pyc
index 3030465d..eb4ebbf2 100644
Binary files a/venv/Lib/site-packages/openai/_extras/__pycache__/sounddevice_proxy.cpython-312.pyc and b/venv/Lib/site-packages/openai/_extras/__pycache__/sounddevice_proxy.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/_utils/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/_utils/__pycache__/__init__.cpython-312.pyc
index f9c3fc8b..da07d679 100644
Binary files a/venv/Lib/site-packages/openai/_utils/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/_utils/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/_utils/__pycache__/_logs.cpython-312.pyc b/venv/Lib/site-packages/openai/_utils/__pycache__/_logs.cpython-312.pyc
index eed7c516..0ca9ec6b 100644
Binary files a/venv/Lib/site-packages/openai/_utils/__pycache__/_logs.cpython-312.pyc and b/venv/Lib/site-packages/openai/_utils/__pycache__/_logs.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/_utils/__pycache__/_proxy.cpython-312.pyc b/venv/Lib/site-packages/openai/_utils/__pycache__/_proxy.cpython-312.pyc
index 97cf220c..2a81cbe7 100644
Binary files a/venv/Lib/site-packages/openai/_utils/__pycache__/_proxy.cpython-312.pyc and b/venv/Lib/site-packages/openai/_utils/__pycache__/_proxy.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/_utils/__pycache__/_reflection.cpython-312.pyc b/venv/Lib/site-packages/openai/_utils/__pycache__/_reflection.cpython-312.pyc
index 9f7881a6..3e3dde65 100644
Binary files a/venv/Lib/site-packages/openai/_utils/__pycache__/_reflection.cpython-312.pyc and b/venv/Lib/site-packages/openai/_utils/__pycache__/_reflection.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/_utils/__pycache__/_resources_proxy.cpython-312.pyc b/venv/Lib/site-packages/openai/_utils/__pycache__/_resources_proxy.cpython-312.pyc
index ba4d55d0..a592fbf5 100644
Binary files a/venv/Lib/site-packages/openai/_utils/__pycache__/_resources_proxy.cpython-312.pyc and b/venv/Lib/site-packages/openai/_utils/__pycache__/_resources_proxy.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/_utils/__pycache__/_streams.cpython-312.pyc b/venv/Lib/site-packages/openai/_utils/__pycache__/_streams.cpython-312.pyc
index 51e93c9f..88734b3b 100644
Binary files a/venv/Lib/site-packages/openai/_utils/__pycache__/_streams.cpython-312.pyc and b/venv/Lib/site-packages/openai/_utils/__pycache__/_streams.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/_utils/__pycache__/_sync.cpython-312.pyc b/venv/Lib/site-packages/openai/_utils/__pycache__/_sync.cpython-312.pyc
index 8668ab46..67345964 100644
Binary files a/venv/Lib/site-packages/openai/_utils/__pycache__/_sync.cpython-312.pyc and b/venv/Lib/site-packages/openai/_utils/__pycache__/_sync.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/_utils/__pycache__/_transform.cpython-312.pyc b/venv/Lib/site-packages/openai/_utils/__pycache__/_transform.cpython-312.pyc
index f0fec663..f1bb5b90 100644
Binary files a/venv/Lib/site-packages/openai/_utils/__pycache__/_transform.cpython-312.pyc and b/venv/Lib/site-packages/openai/_utils/__pycache__/_transform.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/_utils/__pycache__/_typing.cpython-312.pyc b/venv/Lib/site-packages/openai/_utils/__pycache__/_typing.cpython-312.pyc
index 46326397..ae6b2025 100644
Binary files a/venv/Lib/site-packages/openai/_utils/__pycache__/_typing.cpython-312.pyc and b/venv/Lib/site-packages/openai/_utils/__pycache__/_typing.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/_utils/__pycache__/_utils.cpython-312.pyc b/venv/Lib/site-packages/openai/_utils/__pycache__/_utils.cpython-312.pyc
index 4c525f9a..fc4f041c 100644
Binary files a/venv/Lib/site-packages/openai/_utils/__pycache__/_utils.cpython-312.pyc and b/venv/Lib/site-packages/openai/_utils/__pycache__/_utils.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/lib/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/lib/__pycache__/__init__.cpython-312.pyc
index 75f53aa5..782d8c92 100644
Binary files a/venv/Lib/site-packages/openai/lib/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/lib/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/lib/__pycache__/_old_api.cpython-312.pyc b/venv/Lib/site-packages/openai/lib/__pycache__/_old_api.cpython-312.pyc
index 1391b519..22c06433 100644
Binary files a/venv/Lib/site-packages/openai/lib/__pycache__/_old_api.cpython-312.pyc and b/venv/Lib/site-packages/openai/lib/__pycache__/_old_api.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/lib/__pycache__/_pydantic.cpython-312.pyc b/venv/Lib/site-packages/openai/lib/__pycache__/_pydantic.cpython-312.pyc
index 39258f46..b7c0c0c2 100644
Binary files a/venv/Lib/site-packages/openai/lib/__pycache__/_pydantic.cpython-312.pyc and b/venv/Lib/site-packages/openai/lib/__pycache__/_pydantic.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/lib/__pycache__/_tools.cpython-312.pyc b/venv/Lib/site-packages/openai/lib/__pycache__/_tools.cpython-312.pyc
index 870470de..0dd435fc 100644
Binary files a/venv/Lib/site-packages/openai/lib/__pycache__/_tools.cpython-312.pyc and b/venv/Lib/site-packages/openai/lib/__pycache__/_tools.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/lib/__pycache__/azure.cpython-312.pyc b/venv/Lib/site-packages/openai/lib/__pycache__/azure.cpython-312.pyc
index eeacefd4..b134e21d 100644
Binary files a/venv/Lib/site-packages/openai/lib/__pycache__/azure.cpython-312.pyc and b/venv/Lib/site-packages/openai/lib/__pycache__/azure.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/lib/_parsing/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/lib/_parsing/__pycache__/__init__.cpython-312.pyc
index 59e70e1f..634581d2 100644
Binary files a/venv/Lib/site-packages/openai/lib/_parsing/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/lib/_parsing/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/lib/_parsing/__pycache__/_completions.cpython-312.pyc b/venv/Lib/site-packages/openai/lib/_parsing/__pycache__/_completions.cpython-312.pyc
index 70816ba8..a670d0e8 100644
Binary files a/venv/Lib/site-packages/openai/lib/_parsing/__pycache__/_completions.cpython-312.pyc and b/venv/Lib/site-packages/openai/lib/_parsing/__pycache__/_completions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/lib/streaming/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/lib/streaming/__pycache__/__init__.cpython-312.pyc
index e17a5947..ea5b0d1b 100644
Binary files a/venv/Lib/site-packages/openai/lib/streaming/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/lib/streaming/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/lib/streaming/__pycache__/_assistants.cpython-312.pyc b/venv/Lib/site-packages/openai/lib/streaming/__pycache__/_assistants.cpython-312.pyc
index d23ef650..d403a6b8 100644
Binary files a/venv/Lib/site-packages/openai/lib/streaming/__pycache__/_assistants.cpython-312.pyc and b/venv/Lib/site-packages/openai/lib/streaming/__pycache__/_assistants.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/lib/streaming/__pycache__/_deltas.cpython-312.pyc b/venv/Lib/site-packages/openai/lib/streaming/__pycache__/_deltas.cpython-312.pyc
index b8fc8076..91946405 100644
Binary files a/venv/Lib/site-packages/openai/lib/streaming/__pycache__/_deltas.cpython-312.pyc and b/venv/Lib/site-packages/openai/lib/streaming/__pycache__/_deltas.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/lib/streaming/chat/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/lib/streaming/chat/__pycache__/__init__.cpython-312.pyc
index e5d7cfe5..8a206cb9 100644
Binary files a/venv/Lib/site-packages/openai/lib/streaming/chat/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/lib/streaming/chat/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/lib/streaming/chat/__pycache__/_completions.cpython-312.pyc b/venv/Lib/site-packages/openai/lib/streaming/chat/__pycache__/_completions.cpython-312.pyc
index 0b69ae36..7e44b67e 100644
Binary files a/venv/Lib/site-packages/openai/lib/streaming/chat/__pycache__/_completions.cpython-312.pyc and b/venv/Lib/site-packages/openai/lib/streaming/chat/__pycache__/_completions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/lib/streaming/chat/__pycache__/_events.cpython-312.pyc b/venv/Lib/site-packages/openai/lib/streaming/chat/__pycache__/_events.cpython-312.pyc
index a0f33412..0ad7d0ff 100644
Binary files a/venv/Lib/site-packages/openai/lib/streaming/chat/__pycache__/_events.cpython-312.pyc and b/venv/Lib/site-packages/openai/lib/streaming/chat/__pycache__/_events.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/lib/streaming/chat/__pycache__/_types.cpython-312.pyc b/venv/Lib/site-packages/openai/lib/streaming/chat/__pycache__/_types.cpython-312.pyc
index d49eb692..50d2997d 100644
Binary files a/venv/Lib/site-packages/openai/lib/streaming/chat/__pycache__/_types.cpython-312.pyc and b/venv/Lib/site-packages/openai/lib/streaming/chat/__pycache__/_types.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/__pycache__/__init__.cpython-312.pyc
index b4d8e0d3..16fa001e 100644
Binary files a/venv/Lib/site-packages/openai/resources/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/__pycache__/batches.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/__pycache__/batches.cpython-312.pyc
index 50f03cdf..77bb6204 100644
Binary files a/venv/Lib/site-packages/openai/resources/__pycache__/batches.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/__pycache__/batches.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/__pycache__/completions.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/__pycache__/completions.cpython-312.pyc
index df5abd8f..499da7f9 100644
Binary files a/venv/Lib/site-packages/openai/resources/__pycache__/completions.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/__pycache__/completions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/__pycache__/embeddings.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/__pycache__/embeddings.cpython-312.pyc
index 77857a6c..3560e804 100644
Binary files a/venv/Lib/site-packages/openai/resources/__pycache__/embeddings.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/__pycache__/embeddings.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/__pycache__/files.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/__pycache__/files.cpython-312.pyc
index 7cb2d717..4ca3897f 100644
Binary files a/venv/Lib/site-packages/openai/resources/__pycache__/files.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/__pycache__/files.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/__pycache__/images.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/__pycache__/images.cpython-312.pyc
index a0cded74..3b4e93d5 100644
Binary files a/venv/Lib/site-packages/openai/resources/__pycache__/images.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/__pycache__/images.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/__pycache__/models.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/__pycache__/models.cpython-312.pyc
index 2f2d6595..1558ebeb 100644
Binary files a/venv/Lib/site-packages/openai/resources/__pycache__/models.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/__pycache__/models.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/__pycache__/moderations.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/__pycache__/moderations.cpython-312.pyc
index 018a35b0..0156513a 100644
Binary files a/venv/Lib/site-packages/openai/resources/__pycache__/moderations.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/__pycache__/moderations.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/audio/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/audio/__pycache__/__init__.cpython-312.pyc
index ff87f916..3826d0e7 100644
Binary files a/venv/Lib/site-packages/openai/resources/audio/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/audio/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/audio/__pycache__/audio.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/audio/__pycache__/audio.cpython-312.pyc
index 556c04e4..e7c303b7 100644
Binary files a/venv/Lib/site-packages/openai/resources/audio/__pycache__/audio.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/audio/__pycache__/audio.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/audio/__pycache__/speech.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/audio/__pycache__/speech.cpython-312.pyc
index 6c5fbbc7..14dc9d7e 100644
Binary files a/venv/Lib/site-packages/openai/resources/audio/__pycache__/speech.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/audio/__pycache__/speech.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/audio/__pycache__/transcriptions.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/audio/__pycache__/transcriptions.cpython-312.pyc
index d9805122..00d8d23c 100644
Binary files a/venv/Lib/site-packages/openai/resources/audio/__pycache__/transcriptions.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/audio/__pycache__/transcriptions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/audio/__pycache__/translations.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/audio/__pycache__/translations.cpython-312.pyc
index d637c1b8..aab5c31b 100644
Binary files a/venv/Lib/site-packages/openai/resources/audio/__pycache__/translations.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/audio/__pycache__/translations.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/beta/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/beta/__pycache__/__init__.cpython-312.pyc
index 546169eb..d2f9fdbb 100644
Binary files a/venv/Lib/site-packages/openai/resources/beta/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/beta/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/beta/__pycache__/assistants.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/beta/__pycache__/assistants.cpython-312.pyc
index eb851777..2fb1f26c 100644
Binary files a/venv/Lib/site-packages/openai/resources/beta/__pycache__/assistants.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/beta/__pycache__/assistants.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/beta/__pycache__/beta.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/beta/__pycache__/beta.cpython-312.pyc
index fc59ebaf..41d6520a 100644
Binary files a/venv/Lib/site-packages/openai/resources/beta/__pycache__/beta.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/beta/__pycache__/beta.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/beta/chat/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/beta/chat/__pycache__/__init__.cpython-312.pyc
index 71ceac37..b0bc5c43 100644
Binary files a/venv/Lib/site-packages/openai/resources/beta/chat/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/beta/chat/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/beta/chat/__pycache__/chat.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/beta/chat/__pycache__/chat.cpython-312.pyc
index f0af8069..6512f29e 100644
Binary files a/venv/Lib/site-packages/openai/resources/beta/chat/__pycache__/chat.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/beta/chat/__pycache__/chat.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/beta/chat/__pycache__/completions.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/beta/chat/__pycache__/completions.cpython-312.pyc
index 130c6fae..7dc4a046 100644
Binary files a/venv/Lib/site-packages/openai/resources/beta/chat/__pycache__/completions.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/beta/chat/__pycache__/completions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/beta/realtime/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/beta/realtime/__pycache__/__init__.cpython-312.pyc
index fb659674..be419920 100644
Binary files a/venv/Lib/site-packages/openai/resources/beta/realtime/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/beta/realtime/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/beta/realtime/__pycache__/realtime.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/beta/realtime/__pycache__/realtime.cpython-312.pyc
index 0ff9f792..4e29d25e 100644
Binary files a/venv/Lib/site-packages/openai/resources/beta/realtime/__pycache__/realtime.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/beta/realtime/__pycache__/realtime.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/beta/realtime/__pycache__/sessions.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/beta/realtime/__pycache__/sessions.cpython-312.pyc
index f7df4313..132a98b7 100644
Binary files a/venv/Lib/site-packages/openai/resources/beta/realtime/__pycache__/sessions.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/beta/realtime/__pycache__/sessions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/beta/realtime/__pycache__/transcription_sessions.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/beta/realtime/__pycache__/transcription_sessions.cpython-312.pyc
index 904a49ed..97c7a640 100644
Binary files a/venv/Lib/site-packages/openai/resources/beta/realtime/__pycache__/transcription_sessions.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/beta/realtime/__pycache__/transcription_sessions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/beta/threads/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/beta/threads/__pycache__/__init__.cpython-312.pyc
index abdf1488..8d55a4c8 100644
Binary files a/venv/Lib/site-packages/openai/resources/beta/threads/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/beta/threads/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/beta/threads/__pycache__/messages.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/beta/threads/__pycache__/messages.cpython-312.pyc
index 28ec3fda..a135e8ec 100644
Binary files a/venv/Lib/site-packages/openai/resources/beta/threads/__pycache__/messages.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/beta/threads/__pycache__/messages.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/beta/threads/__pycache__/threads.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/beta/threads/__pycache__/threads.cpython-312.pyc
index ec1a43bc..7f2150d0 100644
Binary files a/venv/Lib/site-packages/openai/resources/beta/threads/__pycache__/threads.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/beta/threads/__pycache__/threads.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/beta/threads/runs/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/beta/threads/runs/__pycache__/__init__.cpython-312.pyc
index 275c6efd..83970d37 100644
Binary files a/venv/Lib/site-packages/openai/resources/beta/threads/runs/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/beta/threads/runs/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/beta/threads/runs/__pycache__/runs.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/beta/threads/runs/__pycache__/runs.cpython-312.pyc
index b03afc8d..31f7de98 100644
Binary files a/venv/Lib/site-packages/openai/resources/beta/threads/runs/__pycache__/runs.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/beta/threads/runs/__pycache__/runs.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/beta/threads/runs/__pycache__/steps.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/beta/threads/runs/__pycache__/steps.cpython-312.pyc
index 9ce2cb94..ef31e170 100644
Binary files a/venv/Lib/site-packages/openai/resources/beta/threads/runs/__pycache__/steps.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/beta/threads/runs/__pycache__/steps.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/chat/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/chat/__pycache__/__init__.cpython-312.pyc
index 4ba5539a..f5c67d33 100644
Binary files a/venv/Lib/site-packages/openai/resources/chat/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/chat/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/chat/__pycache__/chat.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/chat/__pycache__/chat.cpython-312.pyc
index fcf792e7..cfd3bf62 100644
Binary files a/venv/Lib/site-packages/openai/resources/chat/__pycache__/chat.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/chat/__pycache__/chat.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/chat/completions/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/chat/completions/__pycache__/__init__.cpython-312.pyc
index fde4b7c9..be7585e7 100644
Binary files a/venv/Lib/site-packages/openai/resources/chat/completions/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/chat/completions/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/chat/completions/__pycache__/completions.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/chat/completions/__pycache__/completions.cpython-312.pyc
index 8603abef..0802fbdf 100644
Binary files a/venv/Lib/site-packages/openai/resources/chat/completions/__pycache__/completions.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/chat/completions/__pycache__/completions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/chat/completions/__pycache__/messages.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/chat/completions/__pycache__/messages.cpython-312.pyc
index 4c1df7b7..0248dd51 100644
Binary files a/venv/Lib/site-packages/openai/resources/chat/completions/__pycache__/messages.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/chat/completions/__pycache__/messages.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/containers/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/containers/__pycache__/__init__.cpython-312.pyc
index e28996db..5e07b2f5 100644
Binary files a/venv/Lib/site-packages/openai/resources/containers/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/containers/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/containers/__pycache__/containers.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/containers/__pycache__/containers.cpython-312.pyc
index e0d96217..4e27bcd1 100644
Binary files a/venv/Lib/site-packages/openai/resources/containers/__pycache__/containers.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/containers/__pycache__/containers.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/containers/files/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/containers/files/__pycache__/__init__.cpython-312.pyc
index f2caaa2d..1f1bd38e 100644
Binary files a/venv/Lib/site-packages/openai/resources/containers/files/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/containers/files/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/containers/files/__pycache__/content.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/containers/files/__pycache__/content.cpython-312.pyc
index 0c5d65c4..bb70234c 100644
Binary files a/venv/Lib/site-packages/openai/resources/containers/files/__pycache__/content.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/containers/files/__pycache__/content.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/containers/files/__pycache__/files.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/containers/files/__pycache__/files.cpython-312.pyc
index 9c6d88e3..f35056be 100644
Binary files a/venv/Lib/site-packages/openai/resources/containers/files/__pycache__/files.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/containers/files/__pycache__/files.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/evals/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/evals/__pycache__/__init__.cpython-312.pyc
index a5bb28e2..b5fae06f 100644
Binary files a/venv/Lib/site-packages/openai/resources/evals/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/evals/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/evals/__pycache__/evals.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/evals/__pycache__/evals.cpython-312.pyc
index 49c5410c..4e970f09 100644
Binary files a/venv/Lib/site-packages/openai/resources/evals/__pycache__/evals.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/evals/__pycache__/evals.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/evals/runs/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/evals/runs/__pycache__/__init__.cpython-312.pyc
index 4e56fec3..e040b1ff 100644
Binary files a/venv/Lib/site-packages/openai/resources/evals/runs/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/evals/runs/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/evals/runs/__pycache__/output_items.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/evals/runs/__pycache__/output_items.cpython-312.pyc
index 51339a30..2ad827db 100644
Binary files a/venv/Lib/site-packages/openai/resources/evals/runs/__pycache__/output_items.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/evals/runs/__pycache__/output_items.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/evals/runs/__pycache__/runs.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/evals/runs/__pycache__/runs.cpython-312.pyc
index f501b834..8ab551be 100644
Binary files a/venv/Lib/site-packages/openai/resources/evals/runs/__pycache__/runs.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/evals/runs/__pycache__/runs.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/fine_tuning/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/fine_tuning/__pycache__/__init__.cpython-312.pyc
index 32de1a1c..51c55230 100644
Binary files a/venv/Lib/site-packages/openai/resources/fine_tuning/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/fine_tuning/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/fine_tuning/__pycache__/fine_tuning.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/fine_tuning/__pycache__/fine_tuning.cpython-312.pyc
index 64e2dbda..006ae711 100644
Binary files a/venv/Lib/site-packages/openai/resources/fine_tuning/__pycache__/fine_tuning.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/fine_tuning/__pycache__/fine_tuning.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/fine_tuning/alpha/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/fine_tuning/alpha/__pycache__/__init__.cpython-312.pyc
index 3651cde3..a36b61f4 100644
Binary files a/venv/Lib/site-packages/openai/resources/fine_tuning/alpha/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/fine_tuning/alpha/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/fine_tuning/alpha/__pycache__/alpha.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/fine_tuning/alpha/__pycache__/alpha.cpython-312.pyc
index acf2da4d..7fdf69f3 100644
Binary files a/venv/Lib/site-packages/openai/resources/fine_tuning/alpha/__pycache__/alpha.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/fine_tuning/alpha/__pycache__/alpha.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/fine_tuning/alpha/__pycache__/graders.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/fine_tuning/alpha/__pycache__/graders.cpython-312.pyc
index 7c92c68b..1cfbee4e 100644
Binary files a/venv/Lib/site-packages/openai/resources/fine_tuning/alpha/__pycache__/graders.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/fine_tuning/alpha/__pycache__/graders.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/fine_tuning/checkpoints/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/fine_tuning/checkpoints/__pycache__/__init__.cpython-312.pyc
index 9010377a..54fc6b30 100644
Binary files a/venv/Lib/site-packages/openai/resources/fine_tuning/checkpoints/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/fine_tuning/checkpoints/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/fine_tuning/checkpoints/__pycache__/checkpoints.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/fine_tuning/checkpoints/__pycache__/checkpoints.cpython-312.pyc
index e4a4e4d6..245f8b5e 100644
Binary files a/venv/Lib/site-packages/openai/resources/fine_tuning/checkpoints/__pycache__/checkpoints.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/fine_tuning/checkpoints/__pycache__/checkpoints.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/fine_tuning/checkpoints/__pycache__/permissions.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/fine_tuning/checkpoints/__pycache__/permissions.cpython-312.pyc
index edecbdc7..0524f46f 100644
Binary files a/venv/Lib/site-packages/openai/resources/fine_tuning/checkpoints/__pycache__/permissions.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/fine_tuning/checkpoints/__pycache__/permissions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/fine_tuning/jobs/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/fine_tuning/jobs/__pycache__/__init__.cpython-312.pyc
index d6119544..551d1177 100644
Binary files a/venv/Lib/site-packages/openai/resources/fine_tuning/jobs/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/fine_tuning/jobs/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/fine_tuning/jobs/__pycache__/checkpoints.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/fine_tuning/jobs/__pycache__/checkpoints.cpython-312.pyc
index 3f2ebe8c..ab5733ef 100644
Binary files a/venv/Lib/site-packages/openai/resources/fine_tuning/jobs/__pycache__/checkpoints.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/fine_tuning/jobs/__pycache__/checkpoints.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/fine_tuning/jobs/__pycache__/jobs.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/fine_tuning/jobs/__pycache__/jobs.cpython-312.pyc
index e767a7ce..94c791a0 100644
Binary files a/venv/Lib/site-packages/openai/resources/fine_tuning/jobs/__pycache__/jobs.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/fine_tuning/jobs/__pycache__/jobs.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/uploads/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/uploads/__pycache__/__init__.cpython-312.pyc
index 179aa0d5..6f7be8c8 100644
Binary files a/venv/Lib/site-packages/openai/resources/uploads/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/uploads/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/uploads/__pycache__/parts.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/uploads/__pycache__/parts.cpython-312.pyc
index 44257870..a5741a90 100644
Binary files a/venv/Lib/site-packages/openai/resources/uploads/__pycache__/parts.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/uploads/__pycache__/parts.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/uploads/__pycache__/uploads.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/uploads/__pycache__/uploads.cpython-312.pyc
index fb809f3a..fc50d829 100644
Binary files a/venv/Lib/site-packages/openai/resources/uploads/__pycache__/uploads.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/uploads/__pycache__/uploads.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/vector_stores/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/vector_stores/__pycache__/__init__.cpython-312.pyc
index a6e738bb..502c0fe3 100644
Binary files a/venv/Lib/site-packages/openai/resources/vector_stores/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/vector_stores/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/vector_stores/__pycache__/file_batches.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/vector_stores/__pycache__/file_batches.cpython-312.pyc
index 537044ec..04d0ab6d 100644
Binary files a/venv/Lib/site-packages/openai/resources/vector_stores/__pycache__/file_batches.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/vector_stores/__pycache__/file_batches.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/vector_stores/__pycache__/files.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/vector_stores/__pycache__/files.cpython-312.pyc
index db77c6d8..bff7b74e 100644
Binary files a/venv/Lib/site-packages/openai/resources/vector_stores/__pycache__/files.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/vector_stores/__pycache__/files.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/resources/vector_stores/__pycache__/vector_stores.cpython-312.pyc b/venv/Lib/site-packages/openai/resources/vector_stores/__pycache__/vector_stores.cpython-312.pyc
index 0d1467d8..5481af25 100644
Binary files a/venv/Lib/site-packages/openai/resources/vector_stores/__pycache__/vector_stores.cpython-312.pyc and b/venv/Lib/site-packages/openai/resources/vector_stores/__pycache__/vector_stores.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/__init__.cpython-312.pyc
index 8561964d..ce80ff20 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/audio_model.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/audio_model.cpython-312.pyc
index 2d7fe17b..1beb9ef7 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/audio_model.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/audio_model.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/audio_response_format.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/audio_response_format.cpython-312.pyc
index 40dc665a..0bcfb34a 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/audio_response_format.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/audio_response_format.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/auto_file_chunking_strategy_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/auto_file_chunking_strategy_param.cpython-312.pyc
index 923d1b1f..106c7e1f 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/auto_file_chunking_strategy_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/auto_file_chunking_strategy_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/batch.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/batch.cpython-312.pyc
index e94b0e1b..a1db9e0c 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/batch.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/batch.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/batch_create_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/batch_create_params.cpython-312.pyc
index aba2c197..7d7f7e47 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/batch_create_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/batch_create_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/batch_error.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/batch_error.cpython-312.pyc
index 4e368b4f..3654da94 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/batch_error.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/batch_error.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/batch_list_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/batch_list_params.cpython-312.pyc
index 3e72134d..c73166c4 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/batch_list_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/batch_list_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/batch_request_counts.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/batch_request_counts.cpython-312.pyc
index d599b825..1618161c 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/batch_request_counts.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/batch_request_counts.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/chat_model.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/chat_model.cpython-312.pyc
index e1f4ce17..f93dfaf9 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/chat_model.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/chat_model.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/completion.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/completion.cpython-312.pyc
index 64c9bff7..cdf1d9ea 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/completion.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/completion.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/completion_choice.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/completion_choice.cpython-312.pyc
index 29a66eef..7abef67e 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/completion_choice.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/completion_choice.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/completion_create_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/completion_create_params.cpython-312.pyc
index aa11263d..e5a82ba3 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/completion_create_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/completion_create_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/completion_usage.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/completion_usage.cpython-312.pyc
index 1d8a24d1..56db1642 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/completion_usage.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/completion_usage.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/container_create_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/container_create_params.cpython-312.pyc
index 4f983182..df0b89cc 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/container_create_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/container_create_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/container_create_response.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/container_create_response.cpython-312.pyc
index 72992a00..af3f41e6 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/container_create_response.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/container_create_response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/container_list_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/container_list_params.cpython-312.pyc
index c4371751..4069c565 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/container_list_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/container_list_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/container_list_response.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/container_list_response.cpython-312.pyc
index 293cc6a6..86a0e5b8 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/container_list_response.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/container_list_response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/container_retrieve_response.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/container_retrieve_response.cpython-312.pyc
index f6c4b31d..617be090 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/container_retrieve_response.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/container_retrieve_response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/create_embedding_response.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/create_embedding_response.cpython-312.pyc
index eb0faf09..d54a9ea2 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/create_embedding_response.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/create_embedding_response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/embedding.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/embedding.cpython-312.pyc
index 2dea6f4e..2d770c5d 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/embedding.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/embedding.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/embedding_create_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/embedding_create_params.cpython-312.pyc
index e2644985..751e0fd4 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/embedding_create_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/embedding_create_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/embedding_model.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/embedding_model.cpython-312.pyc
index 702f6d9a..6503639e 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/embedding_model.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/embedding_model.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/eval_create_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/eval_create_params.cpython-312.pyc
index 54d8ef5d..665a89ee 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/eval_create_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/eval_create_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/eval_create_response.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/eval_create_response.cpython-312.pyc
index 99b013a2..36c8c74b 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/eval_create_response.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/eval_create_response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/eval_custom_data_source_config.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/eval_custom_data_source_config.cpython-312.pyc
index e041545c..fa4caaaf 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/eval_custom_data_source_config.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/eval_custom_data_source_config.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/eval_delete_response.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/eval_delete_response.cpython-312.pyc
index b8e0485e..18bca7ae 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/eval_delete_response.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/eval_delete_response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/eval_list_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/eval_list_params.cpython-312.pyc
index 098bc420..62ab12f6 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/eval_list_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/eval_list_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/eval_list_response.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/eval_list_response.cpython-312.pyc
index a0c6610e..07be1a28 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/eval_list_response.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/eval_list_response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/eval_retrieve_response.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/eval_retrieve_response.cpython-312.pyc
index 9bc0b642..738c542e 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/eval_retrieve_response.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/eval_retrieve_response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/eval_stored_completions_data_source_config.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/eval_stored_completions_data_source_config.cpython-312.pyc
index 4daafb66..05dd0b7a 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/eval_stored_completions_data_source_config.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/eval_stored_completions_data_source_config.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/eval_update_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/eval_update_params.cpython-312.pyc
index edb7fdd7..6fdd537a 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/eval_update_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/eval_update_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/eval_update_response.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/eval_update_response.cpython-312.pyc
index d9088e02..79d2ed1c 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/eval_update_response.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/eval_update_response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/file_chunking_strategy.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/file_chunking_strategy.cpython-312.pyc
index 08568a01..45cc16f2 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/file_chunking_strategy.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/file_chunking_strategy.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/file_chunking_strategy_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/file_chunking_strategy_param.cpython-312.pyc
index be30e00d..4cc8462c 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/file_chunking_strategy_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/file_chunking_strategy_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/file_content.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/file_content.cpython-312.pyc
index 2f724425..80cb2a10 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/file_content.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/file_content.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/file_create_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/file_create_params.cpython-312.pyc
index f11a4a15..509a09cc 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/file_create_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/file_create_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/file_deleted.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/file_deleted.cpython-312.pyc
index 017c600b..81e90415 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/file_deleted.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/file_deleted.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/file_list_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/file_list_params.cpython-312.pyc
index f02e7465..fcde798b 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/file_list_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/file_list_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/file_object.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/file_object.cpython-312.pyc
index b8a742a8..a0310208 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/file_object.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/file_object.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/file_purpose.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/file_purpose.cpython-312.pyc
index 40e2e110..4542cc43 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/file_purpose.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/file_purpose.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/image.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/image.cpython-312.pyc
index ddddbfc8..f82935ab 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/image.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/image.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/image_create_variation_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/image_create_variation_params.cpython-312.pyc
index 845d0c6d..553b2ca0 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/image_create_variation_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/image_create_variation_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/image_edit_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/image_edit_params.cpython-312.pyc
index a3c1fd14..97d3ff2b 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/image_edit_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/image_edit_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/image_generate_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/image_generate_params.cpython-312.pyc
index 16437daa..f996a699 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/image_generate_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/image_generate_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/image_model.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/image_model.cpython-312.pyc
index 9fc69650..e7f32b04 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/image_model.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/image_model.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/images_response.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/images_response.cpython-312.pyc
index f1a31552..6c07d4a6 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/images_response.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/images_response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/model.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/model.cpython-312.pyc
index e11f0d6e..7a62c87d 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/model.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/model.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/model_deleted.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/model_deleted.cpython-312.pyc
index 2e4463d1..cecb1535 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/model_deleted.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/model_deleted.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/moderation.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/moderation.cpython-312.pyc
index 19fa6ad4..cb0f0efe 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/moderation.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/moderation.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/moderation_create_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/moderation_create_params.cpython-312.pyc
index 96446ec6..c7172737 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/moderation_create_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/moderation_create_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/moderation_create_response.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/moderation_create_response.cpython-312.pyc
index 3d5699cf..fefae7f3 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/moderation_create_response.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/moderation_create_response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/moderation_image_url_input_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/moderation_image_url_input_param.cpython-312.pyc
index 97e37285..90eacf06 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/moderation_image_url_input_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/moderation_image_url_input_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/moderation_model.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/moderation_model.cpython-312.pyc
index 11a9f180..c51bbfa7 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/moderation_model.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/moderation_model.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/moderation_multi_modal_input_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/moderation_multi_modal_input_param.cpython-312.pyc
index f165544e..732ada5e 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/moderation_multi_modal_input_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/moderation_multi_modal_input_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/moderation_text_input_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/moderation_text_input_param.cpython-312.pyc
index d0ac10ce..c532cea2 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/moderation_text_input_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/moderation_text_input_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/other_file_chunking_strategy_object.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/other_file_chunking_strategy_object.cpython-312.pyc
index 21555a14..f401665b 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/other_file_chunking_strategy_object.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/other_file_chunking_strategy_object.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/static_file_chunking_strategy.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/static_file_chunking_strategy.cpython-312.pyc
index e9c6cd39..1aecfa3d 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/static_file_chunking_strategy.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/static_file_chunking_strategy.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/static_file_chunking_strategy_object.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/static_file_chunking_strategy_object.cpython-312.pyc
index 395558be..2b6483c4 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/static_file_chunking_strategy_object.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/static_file_chunking_strategy_object.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/static_file_chunking_strategy_object_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/static_file_chunking_strategy_object_param.cpython-312.pyc
index a51e1016..d2f2f535 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/static_file_chunking_strategy_object_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/static_file_chunking_strategy_object_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/static_file_chunking_strategy_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/static_file_chunking_strategy_param.cpython-312.pyc
index 07c364a6..7b9cdaff 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/static_file_chunking_strategy_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/static_file_chunking_strategy_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/upload.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/upload.cpython-312.pyc
index 3b14bf60..87918d36 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/upload.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/upload.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/upload_complete_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/upload_complete_params.cpython-312.pyc
index 2b4a98f9..08013504 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/upload_complete_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/upload_complete_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/upload_create_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/upload_create_params.cpython-312.pyc
index 5714552e..3a02df91 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/upload_create_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/upload_create_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/vector_store.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/vector_store.cpython-312.pyc
index 31e11192..2572ea81 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/vector_store.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/vector_store.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/vector_store_create_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/vector_store_create_params.cpython-312.pyc
index c37f1299..0f7d3070 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/vector_store_create_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/vector_store_create_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/vector_store_deleted.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/vector_store_deleted.cpython-312.pyc
index ee5310b9..8e473f4c 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/vector_store_deleted.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/vector_store_deleted.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/vector_store_list_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/vector_store_list_params.cpython-312.pyc
index 39cd5d17..be14e532 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/vector_store_list_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/vector_store_list_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/vector_store_search_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/vector_store_search_params.cpython-312.pyc
index 4c203b4f..fb45e4c9 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/vector_store_search_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/vector_store_search_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/vector_store_search_response.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/vector_store_search_response.cpython-312.pyc
index e3c47859..ef84d710 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/vector_store_search_response.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/vector_store_search_response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/vector_store_update_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/vector_store_update_params.cpython-312.pyc
index 8591d64b..5c955265 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/vector_store_update_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/vector_store_update_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/__pycache__/websocket_connection_options.cpython-312.pyc b/venv/Lib/site-packages/openai/types/__pycache__/websocket_connection_options.cpython-312.pyc
index 6b01d469..941b1228 100644
Binary files a/venv/Lib/site-packages/openai/types/__pycache__/websocket_connection_options.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/__pycache__/websocket_connection_options.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/audio/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/types/audio/__pycache__/__init__.cpython-312.pyc
index 684ff5fe..d9a72c2a 100644
Binary files a/venv/Lib/site-packages/openai/types/audio/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/audio/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/audio/__pycache__/speech_create_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/audio/__pycache__/speech_create_params.cpython-312.pyc
index da04b1bb..1dc226b7 100644
Binary files a/venv/Lib/site-packages/openai/types/audio/__pycache__/speech_create_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/audio/__pycache__/speech_create_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/audio/__pycache__/speech_model.cpython-312.pyc b/venv/Lib/site-packages/openai/types/audio/__pycache__/speech_model.cpython-312.pyc
index b86f8197..c8a607a2 100644
Binary files a/venv/Lib/site-packages/openai/types/audio/__pycache__/speech_model.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/audio/__pycache__/speech_model.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription.cpython-312.pyc b/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription.cpython-312.pyc
index 04470d05..8c507d2d 100644
Binary files a/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription_create_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription_create_params.cpython-312.pyc
index efbd5592..c7f24d92 100644
Binary files a/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription_create_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription_create_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription_create_response.cpython-312.pyc b/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription_create_response.cpython-312.pyc
index 5aabd19a..96c0b819 100644
Binary files a/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription_create_response.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription_create_response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription_include.cpython-312.pyc b/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription_include.cpython-312.pyc
index 8b879f7b..522415ee 100644
Binary files a/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription_include.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription_include.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription_segment.cpython-312.pyc b/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription_segment.cpython-312.pyc
index cbd3adec..bd314104 100644
Binary files a/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription_segment.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription_segment.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription_stream_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription_stream_event.cpython-312.pyc
index 385d6f32..133cf149 100644
Binary files a/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription_stream_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription_stream_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription_text_delta_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription_text_delta_event.cpython-312.pyc
index ee9e4196..0a3cb380 100644
Binary files a/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription_text_delta_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription_text_delta_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription_text_done_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription_text_done_event.cpython-312.pyc
index 8d858689..00aa3090 100644
Binary files a/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription_text_done_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription_text_done_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription_verbose.cpython-312.pyc b/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription_verbose.cpython-312.pyc
index 9c92091e..77b264c6 100644
Binary files a/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription_verbose.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription_verbose.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription_word.cpython-312.pyc b/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription_word.cpython-312.pyc
index acf738d1..e55b3ee7 100644
Binary files a/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription_word.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/audio/__pycache__/transcription_word.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/audio/__pycache__/translation.cpython-312.pyc b/venv/Lib/site-packages/openai/types/audio/__pycache__/translation.cpython-312.pyc
index 866ce01f..d8c12194 100644
Binary files a/venv/Lib/site-packages/openai/types/audio/__pycache__/translation.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/audio/__pycache__/translation.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/audio/__pycache__/translation_create_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/audio/__pycache__/translation_create_params.cpython-312.pyc
index 6c17c6d3..4035d5d6 100644
Binary files a/venv/Lib/site-packages/openai/types/audio/__pycache__/translation_create_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/audio/__pycache__/translation_create_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/audio/__pycache__/translation_create_response.cpython-312.pyc b/venv/Lib/site-packages/openai/types/audio/__pycache__/translation_create_response.cpython-312.pyc
index c44a70af..2920ab20 100644
Binary files a/venv/Lib/site-packages/openai/types/audio/__pycache__/translation_create_response.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/audio/__pycache__/translation_create_response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/audio/__pycache__/translation_verbose.cpython-312.pyc b/venv/Lib/site-packages/openai/types/audio/__pycache__/translation_verbose.cpython-312.pyc
index e0c71388..d13e92fa 100644
Binary files a/venv/Lib/site-packages/openai/types/audio/__pycache__/translation_verbose.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/audio/__pycache__/translation_verbose.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/__pycache__/__init__.cpython-312.pyc
index 31d5a2e9..d72e7df7 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant.cpython-312.pyc
index bc099d4b..60f563f6 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_create_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_create_params.cpython-312.pyc
index 7884ab1e..cc488502 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_create_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_create_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_deleted.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_deleted.cpython-312.pyc
index ad0224d9..bc522b4a 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_deleted.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_deleted.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_list_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_list_params.cpython-312.pyc
index b01298ac..a611a17d 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_list_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_list_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_response_format_option.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_response_format_option.cpython-312.pyc
index ace3d813..83104035 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_response_format_option.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_response_format_option.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_response_format_option_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_response_format_option_param.cpython-312.pyc
index ecce9b9e..72145540 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_response_format_option_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_response_format_option_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_stream_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_stream_event.cpython-312.pyc
index 9e1a7706..b10a6e29 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_stream_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_stream_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_tool.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_tool.cpython-312.pyc
index 81dd40c0..b82cd0de 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_tool.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_tool.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_tool_choice.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_tool_choice.cpython-312.pyc
index 31d7d617..37b46b97 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_tool_choice.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_tool_choice.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_tool_choice_function.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_tool_choice_function.cpython-312.pyc
index 62621fe4..45d02555 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_tool_choice_function.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_tool_choice_function.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_tool_choice_function_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_tool_choice_function_param.cpython-312.pyc
index d9af1f92..ccd8365f 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_tool_choice_function_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_tool_choice_function_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_tool_choice_option.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_tool_choice_option.cpython-312.pyc
index adaaaef1..a269171e 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_tool_choice_option.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_tool_choice_option.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_tool_choice_option_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_tool_choice_option_param.cpython-312.pyc
index d4d90eb1..1062a4eb 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_tool_choice_option_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_tool_choice_option_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_tool_choice_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_tool_choice_param.cpython-312.pyc
index ef981898..3ea048d4 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_tool_choice_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_tool_choice_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_tool_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_tool_param.cpython-312.pyc
index 08e4417b..b76a8edf 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_tool_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_tool_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_update_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_update_params.cpython-312.pyc
index d5579296..687ad1b6 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_update_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/__pycache__/assistant_update_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/__pycache__/code_interpreter_tool.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/__pycache__/code_interpreter_tool.cpython-312.pyc
index 049c13db..bee9ebff 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/__pycache__/code_interpreter_tool.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/__pycache__/code_interpreter_tool.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/__pycache__/code_interpreter_tool_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/__pycache__/code_interpreter_tool_param.cpython-312.pyc
index 19229c10..1eb19cde 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/__pycache__/code_interpreter_tool_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/__pycache__/code_interpreter_tool_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/__pycache__/file_search_tool.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/__pycache__/file_search_tool.cpython-312.pyc
index aa7712b3..38f06eac 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/__pycache__/file_search_tool.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/__pycache__/file_search_tool.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/__pycache__/file_search_tool_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/__pycache__/file_search_tool_param.cpython-312.pyc
index e409e0a3..af60b124 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/__pycache__/file_search_tool_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/__pycache__/file_search_tool_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/__pycache__/function_tool.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/__pycache__/function_tool.cpython-312.pyc
index 11526718..6afb10c9 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/__pycache__/function_tool.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/__pycache__/function_tool.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/__pycache__/function_tool_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/__pycache__/function_tool_param.cpython-312.pyc
index 2f816780..2465b737 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/__pycache__/function_tool_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/__pycache__/function_tool_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/__pycache__/thread.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/__pycache__/thread.cpython-312.pyc
index c759a591..1520893c 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/__pycache__/thread.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/__pycache__/thread.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/__pycache__/thread_create_and_run_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/__pycache__/thread_create_and_run_params.cpython-312.pyc
index 3f7d3807..5a1467ec 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/__pycache__/thread_create_and_run_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/__pycache__/thread_create_and_run_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/__pycache__/thread_create_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/__pycache__/thread_create_params.cpython-312.pyc
index 1fdb85ed..ef0c8de6 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/__pycache__/thread_create_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/__pycache__/thread_create_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/__pycache__/thread_deleted.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/__pycache__/thread_deleted.cpython-312.pyc
index 1a9455d7..1f9c67f2 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/__pycache__/thread_deleted.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/__pycache__/thread_deleted.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/__pycache__/thread_update_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/__pycache__/thread_update_params.cpython-312.pyc
index 76c7617f..1f031ae9 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/__pycache__/thread_update_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/__pycache__/thread_update_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/__init__.cpython-312.pyc
index 263ada7e..444ae9bc 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_created_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_created_event.cpython-312.pyc
index 91bebfb4..041f6a7e 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_created_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_created_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item.cpython-312.pyc
index b9ee61e5..b3dd1c63 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_content.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_content.cpython-312.pyc
index 7eaa8532..46146a3b 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_content.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_content.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_content_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_content_param.cpython-312.pyc
index d84aa417..cb199dbc 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_content_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_content_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_create_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_create_event.cpython-312.pyc
index 91a62f8b..ff9ecf4a 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_create_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_create_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_create_event_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_create_event_param.cpython-312.pyc
index f4a06b6f..4c271876 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_create_event_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_create_event_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_created_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_created_event.cpython-312.pyc
index 7c5fcc57..4346aa05 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_created_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_created_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_delete_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_delete_event.cpython-312.pyc
index 3e79d206..12050cf2 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_delete_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_delete_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_delete_event_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_delete_event_param.cpython-312.pyc
index e68d72a9..9167232c 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_delete_event_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_delete_event_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_deleted_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_deleted_event.cpython-312.pyc
index 923c8d9d..b3122ff0 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_deleted_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_deleted_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_input_audio_transcription_completed_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_input_audio_transcription_completed_event.cpython-312.pyc
index 3e8a0260..9a8bab80 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_input_audio_transcription_completed_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_input_audio_transcription_completed_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_input_audio_transcription_delta_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_input_audio_transcription_delta_event.cpython-312.pyc
index b0a54df5..ee453302 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_input_audio_transcription_delta_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_input_audio_transcription_delta_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_input_audio_transcription_failed_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_input_audio_transcription_failed_event.cpython-312.pyc
index 4ba9f4cb..48fa09bc 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_input_audio_transcription_failed_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_input_audio_transcription_failed_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_param.cpython-312.pyc
index 2309c336..53b1d41f 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_retrieve_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_retrieve_event.cpython-312.pyc
index 8b562acf..467a6561 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_retrieve_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_retrieve_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_retrieve_event_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_retrieve_event_param.cpython-312.pyc
index d5d2d3d0..1ff8f081 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_retrieve_event_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_retrieve_event_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_truncate_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_truncate_event.cpython-312.pyc
index 64ff9e70..1659d1c7 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_truncate_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_truncate_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_truncate_event_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_truncate_event_param.cpython-312.pyc
index 7669b527..64cdf762 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_truncate_event_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_truncate_event_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_truncated_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_truncated_event.cpython-312.pyc
index aee4c54c..6b1c9baf 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_truncated_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_truncated_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_with_reference.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_with_reference.cpython-312.pyc
index 51df7a24..404aa87d 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_with_reference.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_with_reference.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_with_reference_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_with_reference_param.cpython-312.pyc
index a3c87722..cd7dd144 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_with_reference_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/conversation_item_with_reference_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/error_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/error_event.cpython-312.pyc
index 51d8ae76..4a60e36b 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/error_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/error_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_append_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_append_event.cpython-312.pyc
index ea4e74da..26bb4634 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_append_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_append_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_append_event_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_append_event_param.cpython-312.pyc
index 134cb85e..8de541be 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_append_event_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_append_event_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_clear_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_clear_event.cpython-312.pyc
index 023f79a0..8d375490 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_clear_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_clear_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_clear_event_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_clear_event_param.cpython-312.pyc
index bc8f975c..7d32a524 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_clear_event_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_clear_event_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_cleared_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_cleared_event.cpython-312.pyc
index 91498053..36030f59 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_cleared_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_cleared_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_commit_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_commit_event.cpython-312.pyc
index ec435d5b..f304e5bd 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_commit_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_commit_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_commit_event_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_commit_event_param.cpython-312.pyc
index 1960d5e0..c7c35966 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_commit_event_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_commit_event_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_committed_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_committed_event.cpython-312.pyc
index d7006a1f..f852448b 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_committed_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_committed_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_speech_started_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_speech_started_event.cpython-312.pyc
index dc65f736..6a069f60 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_speech_started_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_speech_started_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_speech_stopped_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_speech_stopped_event.cpython-312.pyc
index 2174fec5..5fa24715 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_speech_stopped_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/input_audio_buffer_speech_stopped_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/rate_limits_updated_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/rate_limits_updated_event.cpython-312.pyc
index 063e0110..4ef4927a 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/rate_limits_updated_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/rate_limits_updated_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/realtime_client_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/realtime_client_event.cpython-312.pyc
index 3d2b23da..6502c474 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/realtime_client_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/realtime_client_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/realtime_client_event_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/realtime_client_event_param.cpython-312.pyc
index 158b3a21..8f2e6b2c 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/realtime_client_event_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/realtime_client_event_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/realtime_connect_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/realtime_connect_params.cpython-312.pyc
index 0a748daa..caed9cab 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/realtime_connect_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/realtime_connect_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/realtime_response.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/realtime_response.cpython-312.pyc
index 3d107693..1586d58a 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/realtime_response.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/realtime_response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/realtime_response_status.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/realtime_response_status.cpython-312.pyc
index 0483d423..2b6f4c91 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/realtime_response_status.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/realtime_response_status.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/realtime_response_usage.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/realtime_response_usage.cpython-312.pyc
index 6c01b7d0..f006cb72 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/realtime_response_usage.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/realtime_response_usage.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/realtime_server_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/realtime_server_event.cpython-312.pyc
index 70863629..2ce492ac 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/realtime_server_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/realtime_server_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_audio_delta_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_audio_delta_event.cpython-312.pyc
index 8de5d17c..4462f4b8 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_audio_delta_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_audio_delta_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_audio_done_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_audio_done_event.cpython-312.pyc
index 2ca6dcd1..d3fba8a6 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_audio_done_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_audio_done_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_audio_transcript_delta_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_audio_transcript_delta_event.cpython-312.pyc
index d7d819ab..23c209da 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_audio_transcript_delta_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_audio_transcript_delta_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_audio_transcript_done_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_audio_transcript_done_event.cpython-312.pyc
index 698d0296..2c8c351d 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_audio_transcript_done_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_audio_transcript_done_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_cancel_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_cancel_event.cpython-312.pyc
index 3a7e903e..79ff7409 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_cancel_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_cancel_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_cancel_event_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_cancel_event_param.cpython-312.pyc
index 2ddcda2c..a3e4e716 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_cancel_event_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_cancel_event_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_content_part_added_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_content_part_added_event.cpython-312.pyc
index f83f974f..d0c3c203 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_content_part_added_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_content_part_added_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_content_part_done_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_content_part_done_event.cpython-312.pyc
index d92fbf63..9a814946 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_content_part_done_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_content_part_done_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_create_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_create_event.cpython-312.pyc
index f3f4149e..96c4a39c 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_create_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_create_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_create_event_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_create_event_param.cpython-312.pyc
index f33b9981..1075faaa 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_create_event_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_create_event_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_created_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_created_event.cpython-312.pyc
index ac95303d..989b824c 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_created_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_created_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_done_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_done_event.cpython-312.pyc
index 4bcf08cf..eb933c90 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_done_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_done_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_function_call_arguments_delta_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_function_call_arguments_delta_event.cpython-312.pyc
index 4902ff37..a8c5d639 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_function_call_arguments_delta_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_function_call_arguments_delta_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_function_call_arguments_done_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_function_call_arguments_done_event.cpython-312.pyc
index 94ecc73a..24b2c3b1 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_function_call_arguments_done_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_function_call_arguments_done_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_output_item_added_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_output_item_added_event.cpython-312.pyc
index 90c1a680..42dc8070 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_output_item_added_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_output_item_added_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_output_item_done_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_output_item_done_event.cpython-312.pyc
index e384cdf3..184cd205 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_output_item_done_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_output_item_done_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_text_delta_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_text_delta_event.cpython-312.pyc
index 6e9e9164..03983783 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_text_delta_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_text_delta_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_text_done_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_text_done_event.cpython-312.pyc
index dd956dd7..c60dd2cc 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_text_done_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/response_text_done_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/session.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/session.cpython-312.pyc
index cc1766ef..4e6b33b9 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/session.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/session.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/session_create_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/session_create_params.cpython-312.pyc
index d05433ec..64c9ef9f 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/session_create_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/session_create_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/session_create_response.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/session_create_response.cpython-312.pyc
index ba2bbce4..0912082b 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/session_create_response.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/session_create_response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/session_created_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/session_created_event.cpython-312.pyc
index bfff311b..1a63cdd1 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/session_created_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/session_created_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/session_update_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/session_update_event.cpython-312.pyc
index 88a3103a..8339d788 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/session_update_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/session_update_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/session_update_event_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/session_update_event_param.cpython-312.pyc
index 316cdcff..6aaa9fca 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/session_update_event_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/session_update_event_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/session_updated_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/session_updated_event.cpython-312.pyc
index 173fa8ca..4edb2d46 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/session_updated_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/session_updated_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/transcription_session.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/transcription_session.cpython-312.pyc
index 1d8798d6..27ad0188 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/transcription_session.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/transcription_session.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/transcription_session_create_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/transcription_session_create_params.cpython-312.pyc
index cde6f7f4..0309bdcd 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/transcription_session_create_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/transcription_session_create_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/transcription_session_update.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/transcription_session_update.cpython-312.pyc
index a4adf1cf..a5fa8289 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/transcription_session_update.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/transcription_session_update.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/transcription_session_update_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/transcription_session_update_param.cpython-312.pyc
index 93b18a7e..cd383a28 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/transcription_session_update_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/transcription_session_update_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/transcription_session_updated_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/transcription_session_updated_event.cpython-312.pyc
index 9d1acc3c..da6d0d5b 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/transcription_session_updated_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/realtime/__pycache__/transcription_session_updated_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/__init__.cpython-312.pyc
index ea60fc6c..9cde883d 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/annotation.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/annotation.cpython-312.pyc
index 55e9ac68..d705ba08 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/annotation.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/annotation.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/annotation_delta.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/annotation_delta.cpython-312.pyc
index ccdc45d4..4f44bbf7 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/annotation_delta.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/annotation_delta.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/file_citation_annotation.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/file_citation_annotation.cpython-312.pyc
index 80f697ae..edc638dd 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/file_citation_annotation.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/file_citation_annotation.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/file_citation_delta_annotation.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/file_citation_delta_annotation.cpython-312.pyc
index 98c4e313..03ca34e5 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/file_citation_delta_annotation.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/file_citation_delta_annotation.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/file_path_annotation.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/file_path_annotation.cpython-312.pyc
index 10d0cb77..3b36997b 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/file_path_annotation.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/file_path_annotation.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/file_path_delta_annotation.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/file_path_delta_annotation.cpython-312.pyc
index 86535b94..70933fe2 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/file_path_delta_annotation.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/file_path_delta_annotation.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_file.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_file.cpython-312.pyc
index 34dae78c..f640f584 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_file.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_file.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_file_content_block.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_file_content_block.cpython-312.pyc
index ef7fb7f4..d6a0c2f1 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_file_content_block.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_file_content_block.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_file_content_block_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_file_content_block_param.cpython-312.pyc
index 48e9af28..ce666466 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_file_content_block_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_file_content_block_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_file_delta.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_file_delta.cpython-312.pyc
index 1473f127..a45da30f 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_file_delta.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_file_delta.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_file_delta_block.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_file_delta_block.cpython-312.pyc
index 556191d6..8fba3a08 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_file_delta_block.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_file_delta_block.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_file_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_file_param.cpython-312.pyc
index f672b1ad..d31a088c 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_file_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_file_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_url.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_url.cpython-312.pyc
index 6513355b..c5aceef1 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_url.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_url.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_url_content_block.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_url_content_block.cpython-312.pyc
index e365b552..50b1e5fd 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_url_content_block.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_url_content_block.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_url_content_block_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_url_content_block_param.cpython-312.pyc
index 83c29a51..f10f491e 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_url_content_block_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_url_content_block_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_url_delta.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_url_delta.cpython-312.pyc
index 6cff6dce..64ddc8ed 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_url_delta.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_url_delta.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_url_delta_block.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_url_delta_block.cpython-312.pyc
index 6990ed3d..9b5ffb2c 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_url_delta_block.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_url_delta_block.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_url_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_url_param.cpython-312.pyc
index dc10f890..e8eec185 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_url_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/image_url_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message.cpython-312.pyc
index adc18165..82d63faa 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message_content.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message_content.cpython-312.pyc
index e28cfa73..6c47a3b6 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message_content.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message_content.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message_content_delta.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message_content_delta.cpython-312.pyc
index b33c3176..a1a864d6 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message_content_delta.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message_content_delta.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message_content_part_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message_content_part_param.cpython-312.pyc
index afe60e0e..94ae17d3 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message_content_part_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message_content_part_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message_create_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message_create_params.cpython-312.pyc
index 4aab46d9..1dc5a3e7 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message_create_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message_create_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message_deleted.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message_deleted.cpython-312.pyc
index ad7b61f8..f31f980e 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message_deleted.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message_deleted.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message_delta.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message_delta.cpython-312.pyc
index fabd306c..4245607b 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message_delta.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message_delta.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message_delta_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message_delta_event.cpython-312.pyc
index 0cf29c78..3d4ededc 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message_delta_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message_delta_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message_list_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message_list_params.cpython-312.pyc
index ca87488e..e0f9cf95 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message_list_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message_list_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message_update_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message_update_params.cpython-312.pyc
index d773bd06..07fe026b 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message_update_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/message_update_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/refusal_content_block.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/refusal_content_block.cpython-312.pyc
index 575095a0..78570730 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/refusal_content_block.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/refusal_content_block.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/refusal_delta_block.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/refusal_delta_block.cpython-312.pyc
index df389756..0c22cc67 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/refusal_delta_block.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/refusal_delta_block.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/required_action_function_tool_call.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/required_action_function_tool_call.cpython-312.pyc
index b5e49755..88284775 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/required_action_function_tool_call.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/required_action_function_tool_call.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/run.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/run.cpython-312.pyc
index 35f7d88f..e148513e 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/run.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/run.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/run_create_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/run_create_params.cpython-312.pyc
index 8c4849b9..a7aaac52 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/run_create_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/run_create_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/run_list_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/run_list_params.cpython-312.pyc
index e846b319..8dc9a7eb 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/run_list_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/run_list_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/run_status.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/run_status.cpython-312.pyc
index 624c7bee..44ba9447 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/run_status.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/run_status.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/run_submit_tool_outputs_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/run_submit_tool_outputs_params.cpython-312.pyc
index 5af02e0f..f183c875 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/run_submit_tool_outputs_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/run_submit_tool_outputs_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/run_update_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/run_update_params.cpython-312.pyc
index 86eb708b..7cbe922d 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/run_update_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/run_update_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/text.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/text.cpython-312.pyc
index 0e7f368b..71981cf0 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/text.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/text.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/text_content_block.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/text_content_block.cpython-312.pyc
index 66fd00a6..e98eafa9 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/text_content_block.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/text_content_block.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/text_content_block_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/text_content_block_param.cpython-312.pyc
index bbb15df5..5492b14f 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/text_content_block_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/text_content_block_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/text_delta.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/text_delta.cpython-312.pyc
index 7b828dc0..7884a142 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/text_delta.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/text_delta.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/text_delta_block.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/text_delta_block.cpython-312.pyc
index 69ca20ae..a29f72b9 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/text_delta_block.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/__pycache__/text_delta_block.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/__init__.cpython-312.pyc
index a68c6c23..d6f0f2fb 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/code_interpreter_logs.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/code_interpreter_logs.cpython-312.pyc
index 69699f28..ebba2088 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/code_interpreter_logs.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/code_interpreter_logs.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/code_interpreter_output_image.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/code_interpreter_output_image.cpython-312.pyc
index 0cb2ba78..cb6a0edf 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/code_interpreter_output_image.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/code_interpreter_output_image.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/code_interpreter_tool_call.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/code_interpreter_tool_call.cpython-312.pyc
index 6a824c9e..cee409bf 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/code_interpreter_tool_call.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/code_interpreter_tool_call.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/code_interpreter_tool_call_delta.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/code_interpreter_tool_call_delta.cpython-312.pyc
index ba467574..de6ab7dc 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/code_interpreter_tool_call_delta.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/code_interpreter_tool_call_delta.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/file_search_tool_call.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/file_search_tool_call.cpython-312.pyc
index 7ee89fac..2cfe7d9a 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/file_search_tool_call.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/file_search_tool_call.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/file_search_tool_call_delta.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/file_search_tool_call_delta.cpython-312.pyc
index 5235a70d..fb8d14cb 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/file_search_tool_call_delta.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/file_search_tool_call_delta.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/function_tool_call.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/function_tool_call.cpython-312.pyc
index 47f5d06c..9bf757af 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/function_tool_call.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/function_tool_call.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/function_tool_call_delta.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/function_tool_call_delta.cpython-312.pyc
index dc760619..2dee8c9d 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/function_tool_call_delta.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/function_tool_call_delta.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/message_creation_step_details.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/message_creation_step_details.cpython-312.pyc
index 6ce72e0b..325fd824 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/message_creation_step_details.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/message_creation_step_details.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/run_step.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/run_step.cpython-312.pyc
index 6c7ea537..91261e06 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/run_step.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/run_step.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/run_step_delta.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/run_step_delta.cpython-312.pyc
index 76bde8c9..3677ffe4 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/run_step_delta.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/run_step_delta.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/run_step_delta_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/run_step_delta_event.cpython-312.pyc
index 5db5b50e..df628f3c 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/run_step_delta_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/run_step_delta_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/run_step_delta_message_delta.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/run_step_delta_message_delta.cpython-312.pyc
index dfa2aabe..7c7e979d 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/run_step_delta_message_delta.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/run_step_delta_message_delta.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/run_step_include.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/run_step_include.cpython-312.pyc
index 7104aaa2..b42bf144 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/run_step_include.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/run_step_include.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/step_list_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/step_list_params.cpython-312.pyc
index 5f7f0166..8dc4e97f 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/step_list_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/step_list_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/step_retrieve_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/step_retrieve_params.cpython-312.pyc
index 5b8414b7..f24d8e88 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/step_retrieve_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/step_retrieve_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/tool_call.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/tool_call.cpython-312.pyc
index 34beb3e6..b0c3a88e 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/tool_call.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/tool_call.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/tool_call_delta.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/tool_call_delta.cpython-312.pyc
index f516c445..3b7c8828 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/tool_call_delta.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/tool_call_delta.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/tool_call_delta_object.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/tool_call_delta_object.cpython-312.pyc
index 1e24491c..2c21f464 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/tool_call_delta_object.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/tool_call_delta_object.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/tool_calls_step_details.cpython-312.pyc b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/tool_calls_step_details.cpython-312.pyc
index 0c6437cc..c170e085 100644
Binary files a/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/tool_calls_step_details.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/beta/threads/runs/__pycache__/tool_calls_step_details.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/__pycache__/__init__.cpython-312.pyc
index 2e47f7ec..ec981fff 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion.cpython-312.pyc
index ee9045b2..1f13640b 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_assistant_message_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_assistant_message_param.cpython-312.pyc
index de82e4e0..a81221b9 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_assistant_message_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_assistant_message_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_audio.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_audio.cpython-312.pyc
index 27b21979..5d2954ba 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_audio.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_audio.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_audio_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_audio_param.cpython-312.pyc
index 6e210939..ccfe1d64 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_audio_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_audio_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_chunk.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_chunk.cpython-312.pyc
index 620757b1..a2a6326c 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_chunk.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_chunk.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_content_part_image_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_content_part_image_param.cpython-312.pyc
index a3c67d22..8f6bc356 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_content_part_image_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_content_part_image_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_content_part_input_audio_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_content_part_input_audio_param.cpython-312.pyc
index dc42441e..f30a6ed8 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_content_part_input_audio_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_content_part_input_audio_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_content_part_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_content_part_param.cpython-312.pyc
index a0c79931..f0096b54 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_content_part_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_content_part_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_content_part_refusal_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_content_part_refusal_param.cpython-312.pyc
index 95564856..df410a43 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_content_part_refusal_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_content_part_refusal_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_content_part_text_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_content_part_text_param.cpython-312.pyc
index 6c6f3244..b375307a 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_content_part_text_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_content_part_text_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_deleted.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_deleted.cpython-312.pyc
index 963851a8..c7650dd1 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_deleted.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_deleted.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_developer_message_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_developer_message_param.cpython-312.pyc
index 4554f314..6f9f66b2 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_developer_message_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_developer_message_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_function_call_option_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_function_call_option_param.cpython-312.pyc
index 693b384d..4d4f1590 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_function_call_option_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_function_call_option_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_function_message_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_function_message_param.cpython-312.pyc
index 76d40337..6a3e5e07 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_function_message_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_function_message_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_message.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_message.cpython-312.pyc
index dd842de7..e41e14fc 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_message.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_message.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_message_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_message_param.cpython-312.pyc
index 53530ae6..ad001b99 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_message_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_message_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_message_tool_call.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_message_tool_call.cpython-312.pyc
index 33ea1549..cbe6e323 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_message_tool_call.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_message_tool_call.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_message_tool_call_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_message_tool_call_param.cpython-312.pyc
index 8235b220..6ebca4c4 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_message_tool_call_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_message_tool_call_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_modality.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_modality.cpython-312.pyc
index 8ca80406..30933fec 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_modality.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_modality.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_named_tool_choice_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_named_tool_choice_param.cpython-312.pyc
index 297e94c2..63a341c4 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_named_tool_choice_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_named_tool_choice_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_prediction_content_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_prediction_content_param.cpython-312.pyc
index a67906a9..a19d84e6 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_prediction_content_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_prediction_content_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_reasoning_effort.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_reasoning_effort.cpython-312.pyc
index d292f2ef..06eb5ab7 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_reasoning_effort.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_reasoning_effort.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_role.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_role.cpython-312.pyc
index 1d8c29dd..33f311fd 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_role.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_role.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_store_message.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_store_message.cpython-312.pyc
index a9846ea0..fa8cfef0 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_store_message.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_store_message.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_stream_options_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_stream_options_param.cpython-312.pyc
index 4e7423d4..da95e232 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_stream_options_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_stream_options_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_system_message_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_system_message_param.cpython-312.pyc
index ae37d581..fe8bb688 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_system_message_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_system_message_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_token_logprob.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_token_logprob.cpython-312.pyc
index b5c78fc5..7f80fbce 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_token_logprob.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_token_logprob.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_tool_choice_option_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_tool_choice_option_param.cpython-312.pyc
index 5b08a497..19037650 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_tool_choice_option_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_tool_choice_option_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_tool_message_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_tool_message_param.cpython-312.pyc
index 43517e1b..325ef122 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_tool_message_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_tool_message_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_tool_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_tool_param.cpython-312.pyc
index 1b2cc300..ce3b7cea 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_tool_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_tool_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_user_message_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_user_message_param.cpython-312.pyc
index 5f899c91..f714bb26 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_user_message_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/__pycache__/chat_completion_user_message_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/__pycache__/completion_create_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/__pycache__/completion_create_params.cpython-312.pyc
index 4ab65aaa..59faa219 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/__pycache__/completion_create_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/__pycache__/completion_create_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/__pycache__/completion_list_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/__pycache__/completion_list_params.cpython-312.pyc
index b6ac11a5..b1e7f49c 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/__pycache__/completion_list_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/__pycache__/completion_list_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/__pycache__/completion_update_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/__pycache__/completion_update_params.cpython-312.pyc
index 76639768..445802f1 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/__pycache__/completion_update_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/__pycache__/completion_update_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/__pycache__/parsed_chat_completion.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/__pycache__/parsed_chat_completion.cpython-312.pyc
index db08b21d..70394e85 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/__pycache__/parsed_chat_completion.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/__pycache__/parsed_chat_completion.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/__pycache__/parsed_function_tool_call.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/__pycache__/parsed_function_tool_call.cpython-312.pyc
index 5284b3ab..7d241e2a 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/__pycache__/parsed_function_tool_call.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/__pycache__/parsed_function_tool_call.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/completions/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/completions/__pycache__/__init__.cpython-312.pyc
index 91fc34e0..34eca900 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/completions/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/completions/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/chat/completions/__pycache__/message_list_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/chat/completions/__pycache__/message_list_params.cpython-312.pyc
index b638f27d..08ad435f 100644
Binary files a/venv/Lib/site-packages/openai/types/chat/completions/__pycache__/message_list_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/chat/completions/__pycache__/message_list_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/containers/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/types/containers/__pycache__/__init__.cpython-312.pyc
index 425073f3..bf147170 100644
Binary files a/venv/Lib/site-packages/openai/types/containers/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/containers/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/containers/__pycache__/file_create_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/containers/__pycache__/file_create_params.cpython-312.pyc
index 5c7d1491..a46bec1a 100644
Binary files a/venv/Lib/site-packages/openai/types/containers/__pycache__/file_create_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/containers/__pycache__/file_create_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/containers/__pycache__/file_create_response.cpython-312.pyc b/venv/Lib/site-packages/openai/types/containers/__pycache__/file_create_response.cpython-312.pyc
index dcd71039..00bac2f8 100644
Binary files a/venv/Lib/site-packages/openai/types/containers/__pycache__/file_create_response.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/containers/__pycache__/file_create_response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/containers/__pycache__/file_list_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/containers/__pycache__/file_list_params.cpython-312.pyc
index 77ab63c5..2abcfb0c 100644
Binary files a/venv/Lib/site-packages/openai/types/containers/__pycache__/file_list_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/containers/__pycache__/file_list_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/containers/__pycache__/file_list_response.cpython-312.pyc b/venv/Lib/site-packages/openai/types/containers/__pycache__/file_list_response.cpython-312.pyc
index d6fb570a..42d6cf1e 100644
Binary files a/venv/Lib/site-packages/openai/types/containers/__pycache__/file_list_response.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/containers/__pycache__/file_list_response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/containers/__pycache__/file_retrieve_response.cpython-312.pyc b/venv/Lib/site-packages/openai/types/containers/__pycache__/file_retrieve_response.cpython-312.pyc
index 9e67ddba..a9124f51 100644
Binary files a/venv/Lib/site-packages/openai/types/containers/__pycache__/file_retrieve_response.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/containers/__pycache__/file_retrieve_response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/evals/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/types/evals/__pycache__/__init__.cpython-312.pyc
index fe7dd9ff..6112c049 100644
Binary files a/venv/Lib/site-packages/openai/types/evals/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/evals/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/evals/__pycache__/create_eval_completions_run_data_source.cpython-312.pyc b/venv/Lib/site-packages/openai/types/evals/__pycache__/create_eval_completions_run_data_source.cpython-312.pyc
index 05cadd2c..9bd94695 100644
Binary files a/venv/Lib/site-packages/openai/types/evals/__pycache__/create_eval_completions_run_data_source.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/evals/__pycache__/create_eval_completions_run_data_source.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/evals/__pycache__/create_eval_completions_run_data_source_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/evals/__pycache__/create_eval_completions_run_data_source_param.cpython-312.pyc
index 5afda967..6c997e75 100644
Binary files a/venv/Lib/site-packages/openai/types/evals/__pycache__/create_eval_completions_run_data_source_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/evals/__pycache__/create_eval_completions_run_data_source_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/evals/__pycache__/create_eval_jsonl_run_data_source.cpython-312.pyc b/venv/Lib/site-packages/openai/types/evals/__pycache__/create_eval_jsonl_run_data_source.cpython-312.pyc
index 486b0a3d..6fde6c97 100644
Binary files a/venv/Lib/site-packages/openai/types/evals/__pycache__/create_eval_jsonl_run_data_source.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/evals/__pycache__/create_eval_jsonl_run_data_source.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/evals/__pycache__/create_eval_jsonl_run_data_source_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/evals/__pycache__/create_eval_jsonl_run_data_source_param.cpython-312.pyc
index bdf68491..97bd7c08 100644
Binary files a/venv/Lib/site-packages/openai/types/evals/__pycache__/create_eval_jsonl_run_data_source_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/evals/__pycache__/create_eval_jsonl_run_data_source_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/evals/__pycache__/eval_api_error.cpython-312.pyc b/venv/Lib/site-packages/openai/types/evals/__pycache__/eval_api_error.cpython-312.pyc
index 6f3904d6..d46e7f2c 100644
Binary files a/venv/Lib/site-packages/openai/types/evals/__pycache__/eval_api_error.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/evals/__pycache__/eval_api_error.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/evals/__pycache__/run_cancel_response.cpython-312.pyc b/venv/Lib/site-packages/openai/types/evals/__pycache__/run_cancel_response.cpython-312.pyc
index 3aa28f9f..5e0b1834 100644
Binary files a/venv/Lib/site-packages/openai/types/evals/__pycache__/run_cancel_response.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/evals/__pycache__/run_cancel_response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/evals/__pycache__/run_create_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/evals/__pycache__/run_create_params.cpython-312.pyc
index 903b954f..3f51630e 100644
Binary files a/venv/Lib/site-packages/openai/types/evals/__pycache__/run_create_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/evals/__pycache__/run_create_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/evals/__pycache__/run_create_response.cpython-312.pyc b/venv/Lib/site-packages/openai/types/evals/__pycache__/run_create_response.cpython-312.pyc
index 7ab324da..8b51f673 100644
Binary files a/venv/Lib/site-packages/openai/types/evals/__pycache__/run_create_response.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/evals/__pycache__/run_create_response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/evals/__pycache__/run_delete_response.cpython-312.pyc b/venv/Lib/site-packages/openai/types/evals/__pycache__/run_delete_response.cpython-312.pyc
index d19ffbf0..89c7aeb8 100644
Binary files a/venv/Lib/site-packages/openai/types/evals/__pycache__/run_delete_response.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/evals/__pycache__/run_delete_response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/evals/__pycache__/run_list_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/evals/__pycache__/run_list_params.cpython-312.pyc
index f984e3e0..a49976bb 100644
Binary files a/venv/Lib/site-packages/openai/types/evals/__pycache__/run_list_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/evals/__pycache__/run_list_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/evals/__pycache__/run_list_response.cpython-312.pyc b/venv/Lib/site-packages/openai/types/evals/__pycache__/run_list_response.cpython-312.pyc
index 48ed45db..be199d39 100644
Binary files a/venv/Lib/site-packages/openai/types/evals/__pycache__/run_list_response.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/evals/__pycache__/run_list_response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/evals/__pycache__/run_retrieve_response.cpython-312.pyc b/venv/Lib/site-packages/openai/types/evals/__pycache__/run_retrieve_response.cpython-312.pyc
index a467edea..e45e4d15 100644
Binary files a/venv/Lib/site-packages/openai/types/evals/__pycache__/run_retrieve_response.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/evals/__pycache__/run_retrieve_response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/evals/runs/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/types/evals/runs/__pycache__/__init__.cpython-312.pyc
index cd7ebcef..12ede1ce 100644
Binary files a/venv/Lib/site-packages/openai/types/evals/runs/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/evals/runs/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/evals/runs/__pycache__/output_item_list_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/evals/runs/__pycache__/output_item_list_params.cpython-312.pyc
index b9f360f5..cbab48b9 100644
Binary files a/venv/Lib/site-packages/openai/types/evals/runs/__pycache__/output_item_list_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/evals/runs/__pycache__/output_item_list_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/evals/runs/__pycache__/output_item_list_response.cpython-312.pyc b/venv/Lib/site-packages/openai/types/evals/runs/__pycache__/output_item_list_response.cpython-312.pyc
index ea419610..5762ccea 100644
Binary files a/venv/Lib/site-packages/openai/types/evals/runs/__pycache__/output_item_list_response.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/evals/runs/__pycache__/output_item_list_response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/evals/runs/__pycache__/output_item_retrieve_response.cpython-312.pyc b/venv/Lib/site-packages/openai/types/evals/runs/__pycache__/output_item_retrieve_response.cpython-312.pyc
index c4ea0729..b5f64760 100644
Binary files a/venv/Lib/site-packages/openai/types/evals/runs/__pycache__/output_item_retrieve_response.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/evals/runs/__pycache__/output_item_retrieve_response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/__init__.cpython-312.pyc
index a57b8c73..4b2ed18e 100644
Binary files a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/dpo_hyperparameters.cpython-312.pyc b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/dpo_hyperparameters.cpython-312.pyc
index f19217a8..cb228774 100644
Binary files a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/dpo_hyperparameters.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/dpo_hyperparameters.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/dpo_hyperparameters_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/dpo_hyperparameters_param.cpython-312.pyc
index f456fdfe..541e1efd 100644
Binary files a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/dpo_hyperparameters_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/dpo_hyperparameters_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/dpo_method.cpython-312.pyc b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/dpo_method.cpython-312.pyc
index e0deb357..7b75c3a0 100644
Binary files a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/dpo_method.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/dpo_method.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/dpo_method_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/dpo_method_param.cpython-312.pyc
index 984780bf..c3bfe407 100644
Binary files a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/dpo_method_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/dpo_method_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/fine_tuning_job.cpython-312.pyc b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/fine_tuning_job.cpython-312.pyc
index 583bbc49..af6c84e3 100644
Binary files a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/fine_tuning_job.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/fine_tuning_job.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/fine_tuning_job_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/fine_tuning_job_event.cpython-312.pyc
index e7fd61f4..a1f2470e 100644
Binary files a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/fine_tuning_job_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/fine_tuning_job_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/fine_tuning_job_integration.cpython-312.pyc b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/fine_tuning_job_integration.cpython-312.pyc
index a8398406..c75cc453 100644
Binary files a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/fine_tuning_job_integration.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/fine_tuning_job_integration.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/fine_tuning_job_wandb_integration.cpython-312.pyc b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/fine_tuning_job_wandb_integration.cpython-312.pyc
index d2522e1f..a5550834 100644
Binary files a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/fine_tuning_job_wandb_integration.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/fine_tuning_job_wandb_integration.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/fine_tuning_job_wandb_integration_object.cpython-312.pyc b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/fine_tuning_job_wandb_integration_object.cpython-312.pyc
index ca733529..973cb6d0 100644
Binary files a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/fine_tuning_job_wandb_integration_object.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/fine_tuning_job_wandb_integration_object.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/job_create_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/job_create_params.cpython-312.pyc
index b2dc4149..4960b156 100644
Binary files a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/job_create_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/job_create_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/job_list_events_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/job_list_events_params.cpython-312.pyc
index 23e909d1..5deeee11 100644
Binary files a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/job_list_events_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/job_list_events_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/job_list_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/job_list_params.cpython-312.pyc
index 4b4236cf..218846dd 100644
Binary files a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/job_list_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/job_list_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/reinforcement_hyperparameters.cpython-312.pyc b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/reinforcement_hyperparameters.cpython-312.pyc
index 6c9add2f..889a1c7a 100644
Binary files a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/reinforcement_hyperparameters.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/reinforcement_hyperparameters.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/reinforcement_hyperparameters_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/reinforcement_hyperparameters_param.cpython-312.pyc
index 27f3b822..c94ef2a1 100644
Binary files a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/reinforcement_hyperparameters_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/reinforcement_hyperparameters_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/reinforcement_method.cpython-312.pyc b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/reinforcement_method.cpython-312.pyc
index 3b86ef92..116d9ed6 100644
Binary files a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/reinforcement_method.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/reinforcement_method.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/reinforcement_method_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/reinforcement_method_param.cpython-312.pyc
index 1adaefe5..e774d27d 100644
Binary files a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/reinforcement_method_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/reinforcement_method_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/supervised_hyperparameters.cpython-312.pyc b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/supervised_hyperparameters.cpython-312.pyc
index 82de440e..37d73b35 100644
Binary files a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/supervised_hyperparameters.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/supervised_hyperparameters.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/supervised_hyperparameters_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/supervised_hyperparameters_param.cpython-312.pyc
index 829a75c7..a4bc6550 100644
Binary files a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/supervised_hyperparameters_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/supervised_hyperparameters_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/supervised_method.cpython-312.pyc b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/supervised_method.cpython-312.pyc
index 9c47b06e..a20a209a 100644
Binary files a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/supervised_method.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/supervised_method.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/supervised_method_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/supervised_method_param.cpython-312.pyc
index cf596fa5..4d1864eb 100644
Binary files a/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/supervised_method_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/fine_tuning/__pycache__/supervised_method_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/fine_tuning/alpha/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/types/fine_tuning/alpha/__pycache__/__init__.cpython-312.pyc
index e10c051d..59efcd60 100644
Binary files a/venv/Lib/site-packages/openai/types/fine_tuning/alpha/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/fine_tuning/alpha/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/fine_tuning/alpha/__pycache__/grader_run_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/fine_tuning/alpha/__pycache__/grader_run_params.cpython-312.pyc
index cedfc3c3..b5b63dec 100644
Binary files a/venv/Lib/site-packages/openai/types/fine_tuning/alpha/__pycache__/grader_run_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/fine_tuning/alpha/__pycache__/grader_run_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/fine_tuning/alpha/__pycache__/grader_run_response.cpython-312.pyc b/venv/Lib/site-packages/openai/types/fine_tuning/alpha/__pycache__/grader_run_response.cpython-312.pyc
index a43fb1db..bdef61ce 100644
Binary files a/venv/Lib/site-packages/openai/types/fine_tuning/alpha/__pycache__/grader_run_response.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/fine_tuning/alpha/__pycache__/grader_run_response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/fine_tuning/alpha/__pycache__/grader_validate_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/fine_tuning/alpha/__pycache__/grader_validate_params.cpython-312.pyc
index eff05593..dfc3c906 100644
Binary files a/venv/Lib/site-packages/openai/types/fine_tuning/alpha/__pycache__/grader_validate_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/fine_tuning/alpha/__pycache__/grader_validate_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/fine_tuning/alpha/__pycache__/grader_validate_response.cpython-312.pyc b/venv/Lib/site-packages/openai/types/fine_tuning/alpha/__pycache__/grader_validate_response.cpython-312.pyc
index 48588fa2..17150581 100644
Binary files a/venv/Lib/site-packages/openai/types/fine_tuning/alpha/__pycache__/grader_validate_response.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/fine_tuning/alpha/__pycache__/grader_validate_response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/fine_tuning/checkpoints/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/types/fine_tuning/checkpoints/__pycache__/__init__.cpython-312.pyc
index 63ad08e1..b70497d8 100644
Binary files a/venv/Lib/site-packages/openai/types/fine_tuning/checkpoints/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/fine_tuning/checkpoints/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/fine_tuning/checkpoints/__pycache__/permission_create_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/fine_tuning/checkpoints/__pycache__/permission_create_params.cpython-312.pyc
index e88a6756..adaca66a 100644
Binary files a/venv/Lib/site-packages/openai/types/fine_tuning/checkpoints/__pycache__/permission_create_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/fine_tuning/checkpoints/__pycache__/permission_create_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/fine_tuning/checkpoints/__pycache__/permission_create_response.cpython-312.pyc b/venv/Lib/site-packages/openai/types/fine_tuning/checkpoints/__pycache__/permission_create_response.cpython-312.pyc
index caac0687..4349e207 100644
Binary files a/venv/Lib/site-packages/openai/types/fine_tuning/checkpoints/__pycache__/permission_create_response.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/fine_tuning/checkpoints/__pycache__/permission_create_response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/fine_tuning/checkpoints/__pycache__/permission_delete_response.cpython-312.pyc b/venv/Lib/site-packages/openai/types/fine_tuning/checkpoints/__pycache__/permission_delete_response.cpython-312.pyc
index 85af888a..705c61c2 100644
Binary files a/venv/Lib/site-packages/openai/types/fine_tuning/checkpoints/__pycache__/permission_delete_response.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/fine_tuning/checkpoints/__pycache__/permission_delete_response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/fine_tuning/checkpoints/__pycache__/permission_retrieve_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/fine_tuning/checkpoints/__pycache__/permission_retrieve_params.cpython-312.pyc
index 1c94b9af..582d91b4 100644
Binary files a/venv/Lib/site-packages/openai/types/fine_tuning/checkpoints/__pycache__/permission_retrieve_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/fine_tuning/checkpoints/__pycache__/permission_retrieve_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/fine_tuning/checkpoints/__pycache__/permission_retrieve_response.cpython-312.pyc b/venv/Lib/site-packages/openai/types/fine_tuning/checkpoints/__pycache__/permission_retrieve_response.cpython-312.pyc
index b3ee8fda..9b54ccfa 100644
Binary files a/venv/Lib/site-packages/openai/types/fine_tuning/checkpoints/__pycache__/permission_retrieve_response.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/fine_tuning/checkpoints/__pycache__/permission_retrieve_response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/fine_tuning/jobs/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/types/fine_tuning/jobs/__pycache__/__init__.cpython-312.pyc
index 354deb7c..9edfb8e6 100644
Binary files a/venv/Lib/site-packages/openai/types/fine_tuning/jobs/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/fine_tuning/jobs/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/fine_tuning/jobs/__pycache__/checkpoint_list_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/fine_tuning/jobs/__pycache__/checkpoint_list_params.cpython-312.pyc
index 6ded6b13..54f1cac0 100644
Binary files a/venv/Lib/site-packages/openai/types/fine_tuning/jobs/__pycache__/checkpoint_list_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/fine_tuning/jobs/__pycache__/checkpoint_list_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/fine_tuning/jobs/__pycache__/fine_tuning_job_checkpoint.cpython-312.pyc b/venv/Lib/site-packages/openai/types/fine_tuning/jobs/__pycache__/fine_tuning_job_checkpoint.cpython-312.pyc
index 7ac873f2..09042d4d 100644
Binary files a/venv/Lib/site-packages/openai/types/fine_tuning/jobs/__pycache__/fine_tuning_job_checkpoint.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/fine_tuning/jobs/__pycache__/fine_tuning_job_checkpoint.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/graders/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/types/graders/__pycache__/__init__.cpython-312.pyc
index 3996184a..c8203f10 100644
Binary files a/venv/Lib/site-packages/openai/types/graders/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/graders/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/graders/__pycache__/label_model_grader.cpython-312.pyc b/venv/Lib/site-packages/openai/types/graders/__pycache__/label_model_grader.cpython-312.pyc
index 03237b65..51f28478 100644
Binary files a/venv/Lib/site-packages/openai/types/graders/__pycache__/label_model_grader.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/graders/__pycache__/label_model_grader.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/graders/__pycache__/label_model_grader_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/graders/__pycache__/label_model_grader_param.cpython-312.pyc
index e999f870..1d18d08d 100644
Binary files a/venv/Lib/site-packages/openai/types/graders/__pycache__/label_model_grader_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/graders/__pycache__/label_model_grader_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/graders/__pycache__/multi_grader.cpython-312.pyc b/venv/Lib/site-packages/openai/types/graders/__pycache__/multi_grader.cpython-312.pyc
index 1f43d876..2da05ed1 100644
Binary files a/venv/Lib/site-packages/openai/types/graders/__pycache__/multi_grader.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/graders/__pycache__/multi_grader.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/graders/__pycache__/multi_grader_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/graders/__pycache__/multi_grader_param.cpython-312.pyc
index f96f8719..36933602 100644
Binary files a/venv/Lib/site-packages/openai/types/graders/__pycache__/multi_grader_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/graders/__pycache__/multi_grader_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/graders/__pycache__/python_grader.cpython-312.pyc b/venv/Lib/site-packages/openai/types/graders/__pycache__/python_grader.cpython-312.pyc
index 91480898..236a2f89 100644
Binary files a/venv/Lib/site-packages/openai/types/graders/__pycache__/python_grader.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/graders/__pycache__/python_grader.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/graders/__pycache__/python_grader_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/graders/__pycache__/python_grader_param.cpython-312.pyc
index 31ac8615..1b4ffcb9 100644
Binary files a/venv/Lib/site-packages/openai/types/graders/__pycache__/python_grader_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/graders/__pycache__/python_grader_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/graders/__pycache__/score_model_grader.cpython-312.pyc b/venv/Lib/site-packages/openai/types/graders/__pycache__/score_model_grader.cpython-312.pyc
index 6751f4e1..630298d2 100644
Binary files a/venv/Lib/site-packages/openai/types/graders/__pycache__/score_model_grader.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/graders/__pycache__/score_model_grader.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/graders/__pycache__/score_model_grader_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/graders/__pycache__/score_model_grader_param.cpython-312.pyc
index f72d721e..78b68588 100644
Binary files a/venv/Lib/site-packages/openai/types/graders/__pycache__/score_model_grader_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/graders/__pycache__/score_model_grader_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/graders/__pycache__/string_check_grader.cpython-312.pyc b/venv/Lib/site-packages/openai/types/graders/__pycache__/string_check_grader.cpython-312.pyc
index 4a3ad019..c8f51411 100644
Binary files a/venv/Lib/site-packages/openai/types/graders/__pycache__/string_check_grader.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/graders/__pycache__/string_check_grader.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/graders/__pycache__/string_check_grader_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/graders/__pycache__/string_check_grader_param.cpython-312.pyc
index cb393983..7a97b06c 100644
Binary files a/venv/Lib/site-packages/openai/types/graders/__pycache__/string_check_grader_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/graders/__pycache__/string_check_grader_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/graders/__pycache__/text_similarity_grader.cpython-312.pyc b/venv/Lib/site-packages/openai/types/graders/__pycache__/text_similarity_grader.cpython-312.pyc
index 0e07d1ee..f74a4b29 100644
Binary files a/venv/Lib/site-packages/openai/types/graders/__pycache__/text_similarity_grader.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/graders/__pycache__/text_similarity_grader.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/graders/__pycache__/text_similarity_grader_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/graders/__pycache__/text_similarity_grader_param.cpython-312.pyc
index ccf68fe6..8826c5d5 100644
Binary files a/venv/Lib/site-packages/openai/types/graders/__pycache__/text_similarity_grader_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/graders/__pycache__/text_similarity_grader_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/__init__.cpython-312.pyc
index 9e4f5440..436c077c 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/computer_tool.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/computer_tool.cpython-312.pyc
index 112716be..fc092346 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/computer_tool.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/computer_tool.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/computer_tool_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/computer_tool_param.cpython-312.pyc
index 52fa5171..56113d86 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/computer_tool_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/computer_tool_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/easy_input_message.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/easy_input_message.cpython-312.pyc
index f7dbd1c0..d1e060e6 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/easy_input_message.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/easy_input_message.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/easy_input_message_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/easy_input_message_param.cpython-312.pyc
index 687e768b..5aba9fa7 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/easy_input_message_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/easy_input_message_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/file_search_tool.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/file_search_tool.cpython-312.pyc
index 506d1f64..7d573daa 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/file_search_tool.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/file_search_tool.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/file_search_tool_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/file_search_tool_param.cpython-312.pyc
index 61b26351..8f23c39d 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/file_search_tool_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/file_search_tool_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/function_tool.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/function_tool.cpython-312.pyc
index a0fa3027..e2eebfbb 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/function_tool.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/function_tool.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/function_tool_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/function_tool_param.cpython-312.pyc
index 10787262..e8e6e19d 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/function_tool_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/function_tool_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/input_item_list_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/input_item_list_params.cpython-312.pyc
index 7ac4d927..45a443b9 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/input_item_list_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/input_item_list_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/parsed_response.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/parsed_response.cpython-312.pyc
index b4faf1b8..f5d6aa45 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/parsed_response.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/parsed_response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response.cpython-312.pyc
index 01dac2f6..e3c6fbe9 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_audio_delta_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_audio_delta_event.cpython-312.pyc
index 248763bc..a8b84a62 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_audio_delta_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_audio_delta_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_audio_done_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_audio_done_event.cpython-312.pyc
index 3c36e0b1..1fc3f2d7 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_audio_done_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_audio_done_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_audio_transcript_delta_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_audio_transcript_delta_event.cpython-312.pyc
index b15c5e8d..fb5d31be 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_audio_transcript_delta_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_audio_transcript_delta_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_audio_transcript_done_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_audio_transcript_done_event.cpython-312.pyc
index 5995888c..3d02ba42 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_audio_transcript_done_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_audio_transcript_done_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_code_interpreter_call_code_delta_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_code_interpreter_call_code_delta_event.cpython-312.pyc
index 3c9342ee..30dcf9b9 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_code_interpreter_call_code_delta_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_code_interpreter_call_code_delta_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_code_interpreter_call_code_done_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_code_interpreter_call_code_done_event.cpython-312.pyc
index 1f7d4a1d..86baa5e5 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_code_interpreter_call_code_done_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_code_interpreter_call_code_done_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_code_interpreter_call_completed_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_code_interpreter_call_completed_event.cpython-312.pyc
index 1afc1a94..103f9b39 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_code_interpreter_call_completed_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_code_interpreter_call_completed_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_code_interpreter_call_in_progress_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_code_interpreter_call_in_progress_event.cpython-312.pyc
index 723986d1..b7176ac4 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_code_interpreter_call_in_progress_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_code_interpreter_call_in_progress_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_code_interpreter_call_interpreting_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_code_interpreter_call_interpreting_event.cpython-312.pyc
index a01d6d07..63e33728 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_code_interpreter_call_interpreting_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_code_interpreter_call_interpreting_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_code_interpreter_tool_call.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_code_interpreter_tool_call.cpython-312.pyc
index 1e135560..27f0336e 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_code_interpreter_tool_call.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_code_interpreter_tool_call.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_code_interpreter_tool_call_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_code_interpreter_tool_call_param.cpython-312.pyc
index 0e252c10..8ee66734 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_code_interpreter_tool_call_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_code_interpreter_tool_call_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_completed_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_completed_event.cpython-312.pyc
index 88a66845..f56f8767 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_completed_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_completed_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_computer_tool_call.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_computer_tool_call.cpython-312.pyc
index 51ced2d7..80c8bb05 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_computer_tool_call.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_computer_tool_call.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_computer_tool_call_output_item.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_computer_tool_call_output_item.cpython-312.pyc
index 79c7e9a3..6c49b883 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_computer_tool_call_output_item.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_computer_tool_call_output_item.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_computer_tool_call_output_screenshot.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_computer_tool_call_output_screenshot.cpython-312.pyc
index 6084f81e..4d3d17e3 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_computer_tool_call_output_screenshot.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_computer_tool_call_output_screenshot.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_computer_tool_call_output_screenshot_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_computer_tool_call_output_screenshot_param.cpython-312.pyc
index 5a348396..d7191ef7 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_computer_tool_call_output_screenshot_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_computer_tool_call_output_screenshot_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_computer_tool_call_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_computer_tool_call_param.cpython-312.pyc
index ad5c305d..046432d2 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_computer_tool_call_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_computer_tool_call_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_content_part_added_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_content_part_added_event.cpython-312.pyc
index 3933af10..3ecacf5c 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_content_part_added_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_content_part_added_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_content_part_done_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_content_part_done_event.cpython-312.pyc
index df313d78..fb17f244 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_content_part_done_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_content_part_done_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_create_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_create_params.cpython-312.pyc
index 4b3ecfdc..5de3b75a 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_create_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_create_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_created_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_created_event.cpython-312.pyc
index d2217023..0a1ddd73 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_created_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_created_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_error.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_error.cpython-312.pyc
index 05dec651..41abfcb1 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_error.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_error.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_error_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_error_event.cpython-312.pyc
index a79724ab..26f38938 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_error_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_error_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_failed_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_failed_event.cpython-312.pyc
index 3a58d347..149b3264 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_failed_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_failed_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_file_search_call_completed_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_file_search_call_completed_event.cpython-312.pyc
index 5bb789f2..a0480dc3 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_file_search_call_completed_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_file_search_call_completed_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_file_search_call_in_progress_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_file_search_call_in_progress_event.cpython-312.pyc
index 752d5ec9..01da1dcd 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_file_search_call_in_progress_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_file_search_call_in_progress_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_file_search_call_searching_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_file_search_call_searching_event.cpython-312.pyc
index ff3d75d8..e8100c70 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_file_search_call_searching_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_file_search_call_searching_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_file_search_tool_call.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_file_search_tool_call.cpython-312.pyc
index 0a03ac38..79f1d64f 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_file_search_tool_call.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_file_search_tool_call.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_file_search_tool_call_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_file_search_tool_call_param.cpython-312.pyc
index f52a8148..61cd8862 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_file_search_tool_call_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_file_search_tool_call_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_format_text_config.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_format_text_config.cpython-312.pyc
index 4c3a3402..b2682249 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_format_text_config.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_format_text_config.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_format_text_config_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_format_text_config_param.cpython-312.pyc
index cba151fc..a71bb89b 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_format_text_config_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_format_text_config_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_format_text_json_schema_config.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_format_text_json_schema_config.cpython-312.pyc
index 41b9bf9f..d075f841 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_format_text_json_schema_config.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_format_text_json_schema_config.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_format_text_json_schema_config_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_format_text_json_schema_config_param.cpython-312.pyc
index 2792a60c..823aab5a 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_format_text_json_schema_config_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_format_text_json_schema_config_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_function_call_arguments_delta_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_function_call_arguments_delta_event.cpython-312.pyc
index e6a86c87..f6f15352 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_function_call_arguments_delta_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_function_call_arguments_delta_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_function_call_arguments_done_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_function_call_arguments_done_event.cpython-312.pyc
index af18a1f2..fb60a298 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_function_call_arguments_done_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_function_call_arguments_done_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_function_tool_call.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_function_tool_call.cpython-312.pyc
index bf1b62c1..b6135a98 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_function_tool_call.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_function_tool_call.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_function_tool_call_item.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_function_tool_call_item.cpython-312.pyc
index 1ba710c7..7670161b 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_function_tool_call_item.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_function_tool_call_item.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_function_tool_call_output_item.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_function_tool_call_output_item.cpython-312.pyc
index 0fdfead8..cc73e619 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_function_tool_call_output_item.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_function_tool_call_output_item.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_function_tool_call_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_function_tool_call_param.cpython-312.pyc
index b525a7b7..b9994d67 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_function_tool_call_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_function_tool_call_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_function_web_search.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_function_web_search.cpython-312.pyc
index 5a01bd8d..b0a7260c 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_function_web_search.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_function_web_search.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_function_web_search_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_function_web_search_param.cpython-312.pyc
index a92ae57a..3a58e5bb 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_function_web_search_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_function_web_search_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_image_gen_call_completed_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_image_gen_call_completed_event.cpython-312.pyc
index b08a5851..e89abfc6 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_image_gen_call_completed_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_image_gen_call_completed_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_image_gen_call_generating_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_image_gen_call_generating_event.cpython-312.pyc
index 226cfb4c..2a10b4e0 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_image_gen_call_generating_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_image_gen_call_generating_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_image_gen_call_in_progress_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_image_gen_call_in_progress_event.cpython-312.pyc
index a379a96b..85dcfbff 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_image_gen_call_in_progress_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_image_gen_call_in_progress_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_image_gen_call_partial_image_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_image_gen_call_partial_image_event.cpython-312.pyc
index 49bced25..1a1eac87 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_image_gen_call_partial_image_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_image_gen_call_partial_image_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_in_progress_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_in_progress_event.cpython-312.pyc
index a33b9ef1..a3afef1e 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_in_progress_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_in_progress_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_includable.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_includable.cpython-312.pyc
index 883d5089..a5f22560 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_includable.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_includable.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_incomplete_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_incomplete_event.cpython-312.pyc
index b120f8e0..e38b94af 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_incomplete_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_incomplete_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_content.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_content.cpython-312.pyc
index a3fe0f0b..b0b85300 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_content.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_content.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_content_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_content_param.cpython-312.pyc
index 68f84bec..2e5956a8 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_content_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_content_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_file.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_file.cpython-312.pyc
index 72718e1f..8e8e66f2 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_file.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_file.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_file_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_file_param.cpython-312.pyc
index bd3eabb9..d6f1117d 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_file_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_file_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_image.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_image.cpython-312.pyc
index f0f462a0..8ec313d7 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_image.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_image.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_image_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_image_param.cpython-312.pyc
index 6d8fcac3..56c51502 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_image_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_image_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_item_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_item_param.cpython-312.pyc
index 2fafb074..15e4e028 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_item_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_item_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_message_content_list.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_message_content_list.cpython-312.pyc
index e22697ae..5fabbb38 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_message_content_list.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_message_content_list.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_message_content_list_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_message_content_list_param.cpython-312.pyc
index 0e650472..091095d9 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_message_content_list_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_message_content_list_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_message_item.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_message_item.cpython-312.pyc
index 3b62a9ce..63d9ebdd 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_message_item.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_message_item.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_param.cpython-312.pyc
index a3fd0b15..13177a38 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_text.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_text.cpython-312.pyc
index 509c9617..dfb18e6a 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_text.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_text.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_text_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_text_param.cpython-312.pyc
index 36b29e57..d28b613a 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_text_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_input_text_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_item.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_item.cpython-312.pyc
index 7ac266ee..81ab8ebf 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_item.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_item.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_item_list.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_item_list.cpython-312.pyc
index 2c41a8dd..267dabc5 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_item_list.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_item_list.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_mcp_call_arguments_delta_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_mcp_call_arguments_delta_event.cpython-312.pyc
index c910131f..bf90f668 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_mcp_call_arguments_delta_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_mcp_call_arguments_delta_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_mcp_call_arguments_done_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_mcp_call_arguments_done_event.cpython-312.pyc
index c67aab3a..0523dc46 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_mcp_call_arguments_done_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_mcp_call_arguments_done_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_mcp_call_completed_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_mcp_call_completed_event.cpython-312.pyc
index 35d09eb1..2e9e59eb 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_mcp_call_completed_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_mcp_call_completed_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_mcp_call_failed_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_mcp_call_failed_event.cpython-312.pyc
index d050d21c..a0a1aee6 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_mcp_call_failed_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_mcp_call_failed_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_mcp_call_in_progress_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_mcp_call_in_progress_event.cpython-312.pyc
index 8169deea..01e5c1be 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_mcp_call_in_progress_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_mcp_call_in_progress_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_mcp_list_tools_completed_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_mcp_list_tools_completed_event.cpython-312.pyc
index e5b0e5ce..7e017735 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_mcp_list_tools_completed_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_mcp_list_tools_completed_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_mcp_list_tools_failed_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_mcp_list_tools_failed_event.cpython-312.pyc
index cb9e14e7..62561be9 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_mcp_list_tools_failed_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_mcp_list_tools_failed_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_mcp_list_tools_in_progress_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_mcp_list_tools_in_progress_event.cpython-312.pyc
index 5ce2b3c1..8210c504 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_mcp_list_tools_in_progress_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_mcp_list_tools_in_progress_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_item.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_item.cpython-312.pyc
index d21a5228..8d3a0e91 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_item.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_item.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_item_added_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_item_added_event.cpython-312.pyc
index 56b3ac04..2ecec0fc 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_item_added_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_item_added_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_item_done_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_item_done_event.cpython-312.pyc
index 721e1d67..a473afd9 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_item_done_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_item_done_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_message.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_message.cpython-312.pyc
index eb91d0a6..5de48874 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_message.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_message.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_message_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_message_param.cpython-312.pyc
index 765aae78..527d7f5a 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_message_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_message_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_refusal.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_refusal.cpython-312.pyc
index 1a17e06b..0060ac60 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_refusal.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_refusal.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_refusal_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_refusal_param.cpython-312.pyc
index d2a3c8c6..90cc5d5b 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_refusal_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_refusal_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_text.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_text.cpython-312.pyc
index 8e4852b9..412e732e 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_text.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_text.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_text_annotation_added_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_text_annotation_added_event.cpython-312.pyc
index 7219295d..8f13227e 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_text_annotation_added_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_text_annotation_added_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_text_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_text_param.cpython-312.pyc
index 299dc85b..d089e185 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_text_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_output_text_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_queued_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_queued_event.cpython-312.pyc
index 89b17faa..925f435a 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_queued_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_queued_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_delta_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_delta_event.cpython-312.pyc
index 5688bcb9..9c10bebb 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_delta_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_delta_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_done_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_done_event.cpython-312.pyc
index 1e9fec9b..a228a405 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_done_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_done_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_item.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_item.cpython-312.pyc
index 70f95f3c..9d8bb3b0 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_item.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_item.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_item_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_item_param.cpython-312.pyc
index 931dcde4..3d712b27 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_item_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_item_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_summary_delta_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_summary_delta_event.cpython-312.pyc
index a68fd7c0..7bc31292 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_summary_delta_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_summary_delta_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_summary_done_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_summary_done_event.cpython-312.pyc
index d2166154..178802fe 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_summary_done_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_summary_done_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_summary_part_added_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_summary_part_added_event.cpython-312.pyc
index 1343f368..56e9bfd4 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_summary_part_added_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_summary_part_added_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_summary_part_done_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_summary_part_done_event.cpython-312.pyc
index 133516f4..7f99cdb1 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_summary_part_done_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_summary_part_done_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_summary_text_delta_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_summary_text_delta_event.cpython-312.pyc
index 20145e0c..1f69ec0f 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_summary_text_delta_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_summary_text_delta_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_summary_text_done_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_summary_text_done_event.cpython-312.pyc
index f12a82fe..016b6d1d 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_summary_text_done_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_reasoning_summary_text_done_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_refusal_delta_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_refusal_delta_event.cpython-312.pyc
index 2e551929..8da6764f 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_refusal_delta_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_refusal_delta_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_refusal_done_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_refusal_done_event.cpython-312.pyc
index 6534bf5b..7382fabf 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_refusal_done_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_refusal_done_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_retrieve_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_retrieve_params.cpython-312.pyc
index 3f58bbbd..bd979bd1 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_retrieve_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_retrieve_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_status.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_status.cpython-312.pyc
index 07b4d1f0..d49d9eda 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_status.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_status.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_stream_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_stream_event.cpython-312.pyc
index aa0208f4..576957a6 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_stream_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_stream_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_text_config.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_text_config.cpython-312.pyc
index 32bbf9c2..f3d1a47f 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_text_config.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_text_config.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_text_config_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_text_config_param.cpython-312.pyc
index 07f675ad..07c81e98 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_text_config_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_text_config_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_text_delta_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_text_delta_event.cpython-312.pyc
index d34ee3a1..dd33d03b 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_text_delta_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_text_delta_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_text_done_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_text_done_event.cpython-312.pyc
index 0cd6b847..505ff730 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_text_done_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_text_done_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_usage.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_usage.cpython-312.pyc
index 608df305..1aa45664 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_usage.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_usage.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_web_search_call_completed_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_web_search_call_completed_event.cpython-312.pyc
index f423c928..82da85b3 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_web_search_call_completed_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_web_search_call_completed_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_web_search_call_in_progress_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_web_search_call_in_progress_event.cpython-312.pyc
index d38623cc..d1d16ddd 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_web_search_call_in_progress_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_web_search_call_in_progress_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_web_search_call_searching_event.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_web_search_call_searching_event.cpython-312.pyc
index eeceeaf5..dd1ef923 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/response_web_search_call_searching_event.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/response_web_search_call_searching_event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/tool.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/tool.cpython-312.pyc
index 9623a62e..9b992b82 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/tool.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/tool.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/tool_choice_function.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/tool_choice_function.cpython-312.pyc
index 197cbf4a..b93c1dfa 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/tool_choice_function.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/tool_choice_function.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/tool_choice_function_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/tool_choice_function_param.cpython-312.pyc
index 9cf2bb80..ef2e8dba 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/tool_choice_function_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/tool_choice_function_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/tool_choice_options.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/tool_choice_options.cpython-312.pyc
index 71f63da6..bf19a4ad 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/tool_choice_options.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/tool_choice_options.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/tool_choice_types.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/tool_choice_types.cpython-312.pyc
index de4cf5f6..5ced58b9 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/tool_choice_types.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/tool_choice_types.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/tool_choice_types_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/tool_choice_types_param.cpython-312.pyc
index bc76c0e0..3939847c 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/tool_choice_types_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/tool_choice_types_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/tool_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/tool_param.cpython-312.pyc
index a58f2f50..34281def 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/tool_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/tool_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/web_search_tool.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/web_search_tool.cpython-312.pyc
index af13e43d..56b41da8 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/web_search_tool.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/web_search_tool.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/responses/__pycache__/web_search_tool_param.cpython-312.pyc b/venv/Lib/site-packages/openai/types/responses/__pycache__/web_search_tool_param.cpython-312.pyc
index 4bd92e3e..f88052f6 100644
Binary files a/venv/Lib/site-packages/openai/types/responses/__pycache__/web_search_tool_param.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/responses/__pycache__/web_search_tool_param.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/shared/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/types/shared/__pycache__/__init__.cpython-312.pyc
index 7295cad9..037d8bae 100644
Binary files a/venv/Lib/site-packages/openai/types/shared/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/shared/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/shared/__pycache__/all_models.cpython-312.pyc b/venv/Lib/site-packages/openai/types/shared/__pycache__/all_models.cpython-312.pyc
index 3a6dc889..b6f9e022 100644
Binary files a/venv/Lib/site-packages/openai/types/shared/__pycache__/all_models.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/shared/__pycache__/all_models.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/shared/__pycache__/chat_model.cpython-312.pyc b/venv/Lib/site-packages/openai/types/shared/__pycache__/chat_model.cpython-312.pyc
index 94c412b8..8ec6c9f1 100644
Binary files a/venv/Lib/site-packages/openai/types/shared/__pycache__/chat_model.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/shared/__pycache__/chat_model.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/shared/__pycache__/comparison_filter.cpython-312.pyc b/venv/Lib/site-packages/openai/types/shared/__pycache__/comparison_filter.cpython-312.pyc
index 8577c98e..851338c3 100644
Binary files a/venv/Lib/site-packages/openai/types/shared/__pycache__/comparison_filter.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/shared/__pycache__/comparison_filter.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/shared/__pycache__/compound_filter.cpython-312.pyc b/venv/Lib/site-packages/openai/types/shared/__pycache__/compound_filter.cpython-312.pyc
index 3b509d29..06aa87bd 100644
Binary files a/venv/Lib/site-packages/openai/types/shared/__pycache__/compound_filter.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/shared/__pycache__/compound_filter.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/shared/__pycache__/error_object.cpython-312.pyc b/venv/Lib/site-packages/openai/types/shared/__pycache__/error_object.cpython-312.pyc
index 3cde6951..102a0010 100644
Binary files a/venv/Lib/site-packages/openai/types/shared/__pycache__/error_object.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/shared/__pycache__/error_object.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/shared/__pycache__/function_definition.cpython-312.pyc b/venv/Lib/site-packages/openai/types/shared/__pycache__/function_definition.cpython-312.pyc
index 020c1279..4ddcd306 100644
Binary files a/venv/Lib/site-packages/openai/types/shared/__pycache__/function_definition.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/shared/__pycache__/function_definition.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/shared/__pycache__/function_parameters.cpython-312.pyc b/venv/Lib/site-packages/openai/types/shared/__pycache__/function_parameters.cpython-312.pyc
index 65fb310e..0c92f64e 100644
Binary files a/venv/Lib/site-packages/openai/types/shared/__pycache__/function_parameters.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/shared/__pycache__/function_parameters.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/shared/__pycache__/metadata.cpython-312.pyc b/venv/Lib/site-packages/openai/types/shared/__pycache__/metadata.cpython-312.pyc
index b589371d..833d2369 100644
Binary files a/venv/Lib/site-packages/openai/types/shared/__pycache__/metadata.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/shared/__pycache__/metadata.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/shared/__pycache__/reasoning.cpython-312.pyc b/venv/Lib/site-packages/openai/types/shared/__pycache__/reasoning.cpython-312.pyc
index 4b7809f7..f2e7c480 100644
Binary files a/venv/Lib/site-packages/openai/types/shared/__pycache__/reasoning.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/shared/__pycache__/reasoning.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/shared/__pycache__/reasoning_effort.cpython-312.pyc b/venv/Lib/site-packages/openai/types/shared/__pycache__/reasoning_effort.cpython-312.pyc
index 3fa28a22..7058df28 100644
Binary files a/venv/Lib/site-packages/openai/types/shared/__pycache__/reasoning_effort.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/shared/__pycache__/reasoning_effort.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/shared/__pycache__/response_format_json_object.cpython-312.pyc b/venv/Lib/site-packages/openai/types/shared/__pycache__/response_format_json_object.cpython-312.pyc
index fd9a7428..d67c2dbb 100644
Binary files a/venv/Lib/site-packages/openai/types/shared/__pycache__/response_format_json_object.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/shared/__pycache__/response_format_json_object.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/shared/__pycache__/response_format_json_schema.cpython-312.pyc b/venv/Lib/site-packages/openai/types/shared/__pycache__/response_format_json_schema.cpython-312.pyc
index cd689f86..c9539c9c 100644
Binary files a/venv/Lib/site-packages/openai/types/shared/__pycache__/response_format_json_schema.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/shared/__pycache__/response_format_json_schema.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/shared/__pycache__/response_format_text.cpython-312.pyc b/venv/Lib/site-packages/openai/types/shared/__pycache__/response_format_text.cpython-312.pyc
index cb6ae23f..c21e709b 100644
Binary files a/venv/Lib/site-packages/openai/types/shared/__pycache__/response_format_text.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/shared/__pycache__/response_format_text.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/shared/__pycache__/responses_model.cpython-312.pyc b/venv/Lib/site-packages/openai/types/shared/__pycache__/responses_model.cpython-312.pyc
index 98fcc658..15a29b33 100644
Binary files a/venv/Lib/site-packages/openai/types/shared/__pycache__/responses_model.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/shared/__pycache__/responses_model.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/shared_params/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/types/shared_params/__pycache__/__init__.cpython-312.pyc
index 8073afca..01f111d5 100644
Binary files a/venv/Lib/site-packages/openai/types/shared_params/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/shared_params/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/shared_params/__pycache__/chat_model.cpython-312.pyc b/venv/Lib/site-packages/openai/types/shared_params/__pycache__/chat_model.cpython-312.pyc
index 2a1e4adc..19632f45 100644
Binary files a/venv/Lib/site-packages/openai/types/shared_params/__pycache__/chat_model.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/shared_params/__pycache__/chat_model.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/shared_params/__pycache__/comparison_filter.cpython-312.pyc b/venv/Lib/site-packages/openai/types/shared_params/__pycache__/comparison_filter.cpython-312.pyc
index b00087a1..6267da94 100644
Binary files a/venv/Lib/site-packages/openai/types/shared_params/__pycache__/comparison_filter.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/shared_params/__pycache__/comparison_filter.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/shared_params/__pycache__/compound_filter.cpython-312.pyc b/venv/Lib/site-packages/openai/types/shared_params/__pycache__/compound_filter.cpython-312.pyc
index d74f5e8a..9d47495c 100644
Binary files a/venv/Lib/site-packages/openai/types/shared_params/__pycache__/compound_filter.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/shared_params/__pycache__/compound_filter.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/shared_params/__pycache__/function_definition.cpython-312.pyc b/venv/Lib/site-packages/openai/types/shared_params/__pycache__/function_definition.cpython-312.pyc
index a5a817bd..aa541c24 100644
Binary files a/venv/Lib/site-packages/openai/types/shared_params/__pycache__/function_definition.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/shared_params/__pycache__/function_definition.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/shared_params/__pycache__/function_parameters.cpython-312.pyc b/venv/Lib/site-packages/openai/types/shared_params/__pycache__/function_parameters.cpython-312.pyc
index e4deea59..6e421dd8 100644
Binary files a/venv/Lib/site-packages/openai/types/shared_params/__pycache__/function_parameters.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/shared_params/__pycache__/function_parameters.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/shared_params/__pycache__/metadata.cpython-312.pyc b/venv/Lib/site-packages/openai/types/shared_params/__pycache__/metadata.cpython-312.pyc
index 4722340c..c52ff181 100644
Binary files a/venv/Lib/site-packages/openai/types/shared_params/__pycache__/metadata.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/shared_params/__pycache__/metadata.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/shared_params/__pycache__/reasoning.cpython-312.pyc b/venv/Lib/site-packages/openai/types/shared_params/__pycache__/reasoning.cpython-312.pyc
index 1670fbf7..bbf7e97c 100644
Binary files a/venv/Lib/site-packages/openai/types/shared_params/__pycache__/reasoning.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/shared_params/__pycache__/reasoning.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/shared_params/__pycache__/reasoning_effort.cpython-312.pyc b/venv/Lib/site-packages/openai/types/shared_params/__pycache__/reasoning_effort.cpython-312.pyc
index 237da206..c869582b 100644
Binary files a/venv/Lib/site-packages/openai/types/shared_params/__pycache__/reasoning_effort.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/shared_params/__pycache__/reasoning_effort.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/shared_params/__pycache__/response_format_json_object.cpython-312.pyc b/venv/Lib/site-packages/openai/types/shared_params/__pycache__/response_format_json_object.cpython-312.pyc
index 97498231..e1bd57a5 100644
Binary files a/venv/Lib/site-packages/openai/types/shared_params/__pycache__/response_format_json_object.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/shared_params/__pycache__/response_format_json_object.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/shared_params/__pycache__/response_format_json_schema.cpython-312.pyc b/venv/Lib/site-packages/openai/types/shared_params/__pycache__/response_format_json_schema.cpython-312.pyc
index 3f1b54c1..95b8718b 100644
Binary files a/venv/Lib/site-packages/openai/types/shared_params/__pycache__/response_format_json_schema.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/shared_params/__pycache__/response_format_json_schema.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/shared_params/__pycache__/response_format_text.cpython-312.pyc b/venv/Lib/site-packages/openai/types/shared_params/__pycache__/response_format_text.cpython-312.pyc
index 7ca3b511..c303beb1 100644
Binary files a/venv/Lib/site-packages/openai/types/shared_params/__pycache__/response_format_text.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/shared_params/__pycache__/response_format_text.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/shared_params/__pycache__/responses_model.cpython-312.pyc b/venv/Lib/site-packages/openai/types/shared_params/__pycache__/responses_model.cpython-312.pyc
index d7225936..9ce8120f 100644
Binary files a/venv/Lib/site-packages/openai/types/shared_params/__pycache__/responses_model.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/shared_params/__pycache__/responses_model.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/uploads/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/types/uploads/__pycache__/__init__.cpython-312.pyc
index e5096c45..81d5eca8 100644
Binary files a/venv/Lib/site-packages/openai/types/uploads/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/uploads/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/uploads/__pycache__/part_create_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/uploads/__pycache__/part_create_params.cpython-312.pyc
index 98b5a115..f97a976c 100644
Binary files a/venv/Lib/site-packages/openai/types/uploads/__pycache__/part_create_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/uploads/__pycache__/part_create_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/uploads/__pycache__/upload_part.cpython-312.pyc b/venv/Lib/site-packages/openai/types/uploads/__pycache__/upload_part.cpython-312.pyc
index cb9e26d2..e52499a9 100644
Binary files a/venv/Lib/site-packages/openai/types/uploads/__pycache__/upload_part.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/uploads/__pycache__/upload_part.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/__init__.cpython-312.pyc
index fe61fa4c..9e0f6680 100644
Binary files a/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/file_batch_create_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/file_batch_create_params.cpython-312.pyc
index f7754025..9a600457 100644
Binary files a/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/file_batch_create_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/file_batch_create_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/file_batch_list_files_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/file_batch_list_files_params.cpython-312.pyc
index f767950a..66a65024 100644
Binary files a/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/file_batch_list_files_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/file_batch_list_files_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/file_content_response.cpython-312.pyc b/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/file_content_response.cpython-312.pyc
index 741cc21f..bfa2ddcf 100644
Binary files a/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/file_content_response.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/file_content_response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/file_create_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/file_create_params.cpython-312.pyc
index 7989e832..19680e42 100644
Binary files a/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/file_create_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/file_create_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/file_list_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/file_list_params.cpython-312.pyc
index 87a3b8d7..3cdaf375 100644
Binary files a/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/file_list_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/file_list_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/file_update_params.cpython-312.pyc b/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/file_update_params.cpython-312.pyc
index ff11a986..aaba781c 100644
Binary files a/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/file_update_params.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/file_update_params.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/vector_store_file.cpython-312.pyc b/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/vector_store_file.cpython-312.pyc
index 7515ea4d..ab259f79 100644
Binary files a/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/vector_store_file.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/vector_store_file.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/vector_store_file_batch.cpython-312.pyc b/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/vector_store_file_batch.cpython-312.pyc
index f541ab3b..845f3308 100644
Binary files a/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/vector_store_file_batch.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/vector_store_file_batch.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/vector_store_file_deleted.cpython-312.pyc b/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/vector_store_file_deleted.cpython-312.pyc
index c6fdfac4..98df5bbd 100644
Binary files a/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/vector_store_file_deleted.cpython-312.pyc and b/venv/Lib/site-packages/openai/types/vector_stores/__pycache__/vector_store_file_deleted.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/packaging/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/packaging/__pycache__/__init__.cpython-312.pyc
index dbd9c7a6..ae13cb4e 100644
Binary files a/venv/Lib/site-packages/packaging/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/packaging/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/packaging/__pycache__/_structures.cpython-312.pyc b/venv/Lib/site-packages/packaging/__pycache__/_structures.cpython-312.pyc
index 674dbe74..9588c2aa 100644
Binary files a/venv/Lib/site-packages/packaging/__pycache__/_structures.cpython-312.pyc and b/venv/Lib/site-packages/packaging/__pycache__/_structures.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/packaging/__pycache__/version.cpython-312.pyc b/venv/Lib/site-packages/packaging/__pycache__/version.cpython-312.pyc
index c60ee08f..a8af9f8f 100644
Binary files a/venv/Lib/site-packages/packaging/__pycache__/version.cpython-312.pyc and b/venv/Lib/site-packages/packaging/__pycache__/version.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/__pycache__/__init__.cpython-312.pyc
index a8dabe00..27f1294a 100644
Binary files a/venv/Lib/site-packages/pandas/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/__pycache__/_typing.cpython-312.pyc b/venv/Lib/site-packages/pandas/__pycache__/_typing.cpython-312.pyc
index 1430b631..e54db573 100644
Binary files a/venv/Lib/site-packages/pandas/__pycache__/_typing.cpython-312.pyc and b/venv/Lib/site-packages/pandas/__pycache__/_typing.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/__pycache__/_version_meson.cpython-312.pyc b/venv/Lib/site-packages/pandas/__pycache__/_version_meson.cpython-312.pyc
index afcac67d..b59aa769 100644
Binary files a/venv/Lib/site-packages/pandas/__pycache__/_version_meson.cpython-312.pyc and b/venv/Lib/site-packages/pandas/__pycache__/_version_meson.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/__pycache__/testing.cpython-312.pyc b/venv/Lib/site-packages/pandas/__pycache__/testing.cpython-312.pyc
index f9f656c9..a9328e9d 100644
Binary files a/venv/Lib/site-packages/pandas/__pycache__/testing.cpython-312.pyc and b/venv/Lib/site-packages/pandas/__pycache__/testing.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/_config/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/_config/__pycache__/__init__.cpython-312.pyc
index ee08b98b..84703e2b 100644
Binary files a/venv/Lib/site-packages/pandas/_config/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/_config/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/_config/__pycache__/config.cpython-312.pyc b/venv/Lib/site-packages/pandas/_config/__pycache__/config.cpython-312.pyc
index 3be9ab92..0a08428d 100644
Binary files a/venv/Lib/site-packages/pandas/_config/__pycache__/config.cpython-312.pyc and b/venv/Lib/site-packages/pandas/_config/__pycache__/config.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/_config/__pycache__/dates.cpython-312.pyc b/venv/Lib/site-packages/pandas/_config/__pycache__/dates.cpython-312.pyc
index 3825eaac..8e89e4b7 100644
Binary files a/venv/Lib/site-packages/pandas/_config/__pycache__/dates.cpython-312.pyc and b/venv/Lib/site-packages/pandas/_config/__pycache__/dates.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/_config/__pycache__/display.cpython-312.pyc b/venv/Lib/site-packages/pandas/_config/__pycache__/display.cpython-312.pyc
index 0ab740c4..0a38f161 100644
Binary files a/venv/Lib/site-packages/pandas/_config/__pycache__/display.cpython-312.pyc and b/venv/Lib/site-packages/pandas/_config/__pycache__/display.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/_config/__pycache__/localization.cpython-312.pyc b/venv/Lib/site-packages/pandas/_config/__pycache__/localization.cpython-312.pyc
index 82cf4b26..34e7d82a 100644
Binary files a/venv/Lib/site-packages/pandas/_config/__pycache__/localization.cpython-312.pyc and b/venv/Lib/site-packages/pandas/_config/__pycache__/localization.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/_libs/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/_libs/__pycache__/__init__.cpython-312.pyc
index 2086eb9a..5e5c7cd0 100644
Binary files a/venv/Lib/site-packages/pandas/_libs/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/_libs/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/_libs/tslibs/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/_libs/tslibs/__pycache__/__init__.cpython-312.pyc
index 1ce01fa4..f12df524 100644
Binary files a/venv/Lib/site-packages/pandas/_libs/tslibs/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/_libs/tslibs/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/_libs/window/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/_libs/window/__pycache__/__init__.cpython-312.pyc
index 2d11dfb4..050bd761 100644
Binary files a/venv/Lib/site-packages/pandas/_libs/window/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/_libs/window/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/_testing/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/_testing/__pycache__/__init__.cpython-312.pyc
index 0de7880b..36a920a7 100644
Binary files a/venv/Lib/site-packages/pandas/_testing/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/_testing/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/_testing/__pycache__/_io.cpython-312.pyc b/venv/Lib/site-packages/pandas/_testing/__pycache__/_io.cpython-312.pyc
index 25a20da0..24c95524 100644
Binary files a/venv/Lib/site-packages/pandas/_testing/__pycache__/_io.cpython-312.pyc and b/venv/Lib/site-packages/pandas/_testing/__pycache__/_io.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/_testing/__pycache__/_warnings.cpython-312.pyc b/venv/Lib/site-packages/pandas/_testing/__pycache__/_warnings.cpython-312.pyc
index 6331d191..59bf535a 100644
Binary files a/venv/Lib/site-packages/pandas/_testing/__pycache__/_warnings.cpython-312.pyc and b/venv/Lib/site-packages/pandas/_testing/__pycache__/_warnings.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/_testing/__pycache__/asserters.cpython-312.pyc b/venv/Lib/site-packages/pandas/_testing/__pycache__/asserters.cpython-312.pyc
index 0565e3d5..bc73ecd2 100644
Binary files a/venv/Lib/site-packages/pandas/_testing/__pycache__/asserters.cpython-312.pyc and b/venv/Lib/site-packages/pandas/_testing/__pycache__/asserters.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/_testing/__pycache__/compat.cpython-312.pyc b/venv/Lib/site-packages/pandas/_testing/__pycache__/compat.cpython-312.pyc
index b6ce6cdf..2db98e40 100644
Binary files a/venv/Lib/site-packages/pandas/_testing/__pycache__/compat.cpython-312.pyc and b/venv/Lib/site-packages/pandas/_testing/__pycache__/compat.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/_testing/__pycache__/contexts.cpython-312.pyc b/venv/Lib/site-packages/pandas/_testing/__pycache__/contexts.cpython-312.pyc
index 3cbaba23..8b78e02a 100644
Binary files a/venv/Lib/site-packages/pandas/_testing/__pycache__/contexts.cpython-312.pyc and b/venv/Lib/site-packages/pandas/_testing/__pycache__/contexts.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/api/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/api/__pycache__/__init__.cpython-312.pyc
index 11283710..ead76063 100644
Binary files a/venv/Lib/site-packages/pandas/api/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/api/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/api/extensions/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/api/extensions/__pycache__/__init__.cpython-312.pyc
index 5afc5b44..451a185a 100644
Binary files a/venv/Lib/site-packages/pandas/api/extensions/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/api/extensions/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/api/indexers/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/api/indexers/__pycache__/__init__.cpython-312.pyc
index c087ed09..335e7abc 100644
Binary files a/venv/Lib/site-packages/pandas/api/indexers/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/api/indexers/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/api/interchange/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/api/interchange/__pycache__/__init__.cpython-312.pyc
index 2fc9c4c6..c99238f1 100644
Binary files a/venv/Lib/site-packages/pandas/api/interchange/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/api/interchange/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/api/types/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/api/types/__pycache__/__init__.cpython-312.pyc
index bcd1b7fc..ebfca396 100644
Binary files a/venv/Lib/site-packages/pandas/api/types/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/api/types/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/api/typing/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/api/typing/__pycache__/__init__.cpython-312.pyc
index ca94794d..769c34cd 100644
Binary files a/venv/Lib/site-packages/pandas/api/typing/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/api/typing/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/arrays/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/arrays/__pycache__/__init__.cpython-312.pyc
index 18f145a8..7c2d4c29 100644
Binary files a/venv/Lib/site-packages/pandas/arrays/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/arrays/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/compat/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/compat/__pycache__/__init__.cpython-312.pyc
index 88be73eb..8f1fb9b9 100644
Binary files a/venv/Lib/site-packages/pandas/compat/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/compat/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/compat/__pycache__/_constants.cpython-312.pyc b/venv/Lib/site-packages/pandas/compat/__pycache__/_constants.cpython-312.pyc
index 7ea94844..27fde434 100644
Binary files a/venv/Lib/site-packages/pandas/compat/__pycache__/_constants.cpython-312.pyc and b/venv/Lib/site-packages/pandas/compat/__pycache__/_constants.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/compat/__pycache__/_optional.cpython-312.pyc b/venv/Lib/site-packages/pandas/compat/__pycache__/_optional.cpython-312.pyc
index 9f63f6c1..997eda23 100644
Binary files a/venv/Lib/site-packages/pandas/compat/__pycache__/_optional.cpython-312.pyc and b/venv/Lib/site-packages/pandas/compat/__pycache__/_optional.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/compat/__pycache__/compressors.cpython-312.pyc b/venv/Lib/site-packages/pandas/compat/__pycache__/compressors.cpython-312.pyc
index 9c1fea6f..7fce2535 100644
Binary files a/venv/Lib/site-packages/pandas/compat/__pycache__/compressors.cpython-312.pyc and b/venv/Lib/site-packages/pandas/compat/__pycache__/compressors.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/compat/__pycache__/pickle_compat.cpython-312.pyc b/venv/Lib/site-packages/pandas/compat/__pycache__/pickle_compat.cpython-312.pyc
index 2e7c71c6..325e4c67 100644
Binary files a/venv/Lib/site-packages/pandas/compat/__pycache__/pickle_compat.cpython-312.pyc and b/venv/Lib/site-packages/pandas/compat/__pycache__/pickle_compat.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/compat/__pycache__/pyarrow.cpython-312.pyc b/venv/Lib/site-packages/pandas/compat/__pycache__/pyarrow.cpython-312.pyc
index 31ee405c..886100bc 100644
Binary files a/venv/Lib/site-packages/pandas/compat/__pycache__/pyarrow.cpython-312.pyc and b/venv/Lib/site-packages/pandas/compat/__pycache__/pyarrow.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/compat/numpy/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/compat/numpy/__pycache__/__init__.cpython-312.pyc
index 55b55dc4..00827252 100644
Binary files a/venv/Lib/site-packages/pandas/compat/numpy/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/compat/numpy/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/compat/numpy/__pycache__/function.cpython-312.pyc b/venv/Lib/site-packages/pandas/compat/numpy/__pycache__/function.cpython-312.pyc
index aa588651..d36bf4b9 100644
Binary files a/venv/Lib/site-packages/pandas/compat/numpy/__pycache__/function.cpython-312.pyc and b/venv/Lib/site-packages/pandas/compat/numpy/__pycache__/function.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/__pycache__/__init__.cpython-312.pyc
index 26cf276e..04f8f658 100644
Binary files a/venv/Lib/site-packages/pandas/core/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/__pycache__/accessor.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/__pycache__/accessor.cpython-312.pyc
index 9f9df5cb..86fcc555 100644
Binary files a/venv/Lib/site-packages/pandas/core/__pycache__/accessor.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/__pycache__/accessor.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/__pycache__/algorithms.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/__pycache__/algorithms.cpython-312.pyc
index 12a3cea3..2cafff65 100644
Binary files a/venv/Lib/site-packages/pandas/core/__pycache__/algorithms.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/__pycache__/algorithms.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/__pycache__/api.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/__pycache__/api.cpython-312.pyc
index f4c03879..87c1ec2f 100644
Binary files a/venv/Lib/site-packages/pandas/core/__pycache__/api.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/__pycache__/api.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/__pycache__/apply.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/__pycache__/apply.cpython-312.pyc
index b24dd9f6..2643e258 100644
Binary files a/venv/Lib/site-packages/pandas/core/__pycache__/apply.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/__pycache__/apply.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/__pycache__/arraylike.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/__pycache__/arraylike.cpython-312.pyc
index 1096c371..c286eb66 100644
Binary files a/venv/Lib/site-packages/pandas/core/__pycache__/arraylike.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/__pycache__/arraylike.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/__pycache__/base.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/__pycache__/base.cpython-312.pyc
index 4595d50b..aab7d69e 100644
Binary files a/venv/Lib/site-packages/pandas/core/__pycache__/base.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/__pycache__/base.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/__pycache__/common.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/__pycache__/common.cpython-312.pyc
index e3ed7d01..a901d3a1 100644
Binary files a/venv/Lib/site-packages/pandas/core/__pycache__/common.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/__pycache__/common.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/__pycache__/config_init.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/__pycache__/config_init.cpython-312.pyc
index c7172302..7fef0cbe 100644
Binary files a/venv/Lib/site-packages/pandas/core/__pycache__/config_init.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/__pycache__/config_init.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/__pycache__/construction.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/__pycache__/construction.cpython-312.pyc
index 6a4f2b36..4f0569f6 100644
Binary files a/venv/Lib/site-packages/pandas/core/__pycache__/construction.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/__pycache__/construction.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/__pycache__/flags.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/__pycache__/flags.cpython-312.pyc
index c000bcde..c0ace556 100644
Binary files a/venv/Lib/site-packages/pandas/core/__pycache__/flags.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/__pycache__/flags.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/__pycache__/frame.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/__pycache__/frame.cpython-312.pyc
index 18879c43..03e21424 100644
Binary files a/venv/Lib/site-packages/pandas/core/__pycache__/frame.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/__pycache__/frame.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/__pycache__/generic.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/__pycache__/generic.cpython-312.pyc
index 99fbadef..0af231ad 100644
Binary files a/venv/Lib/site-packages/pandas/core/__pycache__/generic.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/__pycache__/generic.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/__pycache__/indexing.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/__pycache__/indexing.cpython-312.pyc
index 445a4a8f..b6d60704 100644
Binary files a/venv/Lib/site-packages/pandas/core/__pycache__/indexing.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/__pycache__/indexing.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/__pycache__/missing.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/__pycache__/missing.cpython-312.pyc
index 1463cea2..a02ef3ea 100644
Binary files a/venv/Lib/site-packages/pandas/core/__pycache__/missing.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/__pycache__/missing.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/__pycache__/nanops.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/__pycache__/nanops.cpython-312.pyc
index 15645769..c316a9c6 100644
Binary files a/venv/Lib/site-packages/pandas/core/__pycache__/nanops.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/__pycache__/nanops.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/__pycache__/resample.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/__pycache__/resample.cpython-312.pyc
index 72ecaa49..6dfcd849 100644
Binary files a/venv/Lib/site-packages/pandas/core/__pycache__/resample.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/__pycache__/resample.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/__pycache__/roperator.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/__pycache__/roperator.cpython-312.pyc
index 6a0fbec0..0ddc5d20 100644
Binary files a/venv/Lib/site-packages/pandas/core/__pycache__/roperator.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/__pycache__/roperator.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/__pycache__/sample.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/__pycache__/sample.cpython-312.pyc
index 5ccf22ed..7ab17e71 100644
Binary files a/venv/Lib/site-packages/pandas/core/__pycache__/sample.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/__pycache__/sample.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/__pycache__/series.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/__pycache__/series.cpython-312.pyc
index ebeecffc..e47b9578 100644
Binary files a/venv/Lib/site-packages/pandas/core/__pycache__/series.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/__pycache__/series.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/__pycache__/shared_docs.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/__pycache__/shared_docs.cpython-312.pyc
index 3af54ea8..afeabfbc 100644
Binary files a/venv/Lib/site-packages/pandas/core/__pycache__/shared_docs.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/__pycache__/shared_docs.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/__pycache__/sorting.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/__pycache__/sorting.cpython-312.pyc
index 5e05649e..3b1d869e 100644
Binary files a/venv/Lib/site-packages/pandas/core/__pycache__/sorting.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/__pycache__/sorting.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/_numba/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/_numba/__pycache__/__init__.cpython-312.pyc
index b43a12c4..742e1d64 100644
Binary files a/venv/Lib/site-packages/pandas/core/_numba/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/_numba/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/_numba/__pycache__/executor.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/_numba/__pycache__/executor.cpython-312.pyc
index 1b7445a6..c9e68316 100644
Binary files a/venv/Lib/site-packages/pandas/core/_numba/__pycache__/executor.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/_numba/__pycache__/executor.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/array_algos/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/array_algos/__pycache__/__init__.cpython-312.pyc
index 6a444b8d..222d5193 100644
Binary files a/venv/Lib/site-packages/pandas/core/array_algos/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/array_algos/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/array_algos/__pycache__/datetimelike_accumulations.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/array_algos/__pycache__/datetimelike_accumulations.cpython-312.pyc
index 8186c8fc..5da533bf 100644
Binary files a/venv/Lib/site-packages/pandas/core/array_algos/__pycache__/datetimelike_accumulations.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/array_algos/__pycache__/datetimelike_accumulations.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/array_algos/__pycache__/masked_accumulations.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/array_algos/__pycache__/masked_accumulations.cpython-312.pyc
index 863f414c..4fda5f84 100644
Binary files a/venv/Lib/site-packages/pandas/core/array_algos/__pycache__/masked_accumulations.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/array_algos/__pycache__/masked_accumulations.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/array_algos/__pycache__/masked_reductions.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/array_algos/__pycache__/masked_reductions.cpython-312.pyc
index 03ad3326..6b4c102a 100644
Binary files a/venv/Lib/site-packages/pandas/core/array_algos/__pycache__/masked_reductions.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/array_algos/__pycache__/masked_reductions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/array_algos/__pycache__/putmask.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/array_algos/__pycache__/putmask.cpython-312.pyc
index dffb66b9..c9fb8b52 100644
Binary files a/venv/Lib/site-packages/pandas/core/array_algos/__pycache__/putmask.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/array_algos/__pycache__/putmask.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/array_algos/__pycache__/quantile.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/array_algos/__pycache__/quantile.cpython-312.pyc
index d98ea7fe..68ed0b5c 100644
Binary files a/venv/Lib/site-packages/pandas/core/array_algos/__pycache__/quantile.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/array_algos/__pycache__/quantile.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/array_algos/__pycache__/replace.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/array_algos/__pycache__/replace.cpython-312.pyc
index 1d463861..1dbcf519 100644
Binary files a/venv/Lib/site-packages/pandas/core/array_algos/__pycache__/replace.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/array_algos/__pycache__/replace.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/array_algos/__pycache__/take.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/array_algos/__pycache__/take.cpython-312.pyc
index 4043faec..cdf01332 100644
Binary files a/venv/Lib/site-packages/pandas/core/array_algos/__pycache__/take.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/array_algos/__pycache__/take.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/array_algos/__pycache__/transforms.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/array_algos/__pycache__/transforms.cpython-312.pyc
index 63136f8b..fedfce4a 100644
Binary files a/venv/Lib/site-packages/pandas/core/array_algos/__pycache__/transforms.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/array_algos/__pycache__/transforms.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/__init__.cpython-312.pyc
index e1533278..4261b003 100644
Binary files a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/_arrow_string_mixins.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/_arrow_string_mixins.cpython-312.pyc
index f0aee8b1..b10cf2ab 100644
Binary files a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/_arrow_string_mixins.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/_arrow_string_mixins.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/_mixins.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/_mixins.cpython-312.pyc
index 76658a97..cd6ee368 100644
Binary files a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/_mixins.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/_mixins.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/_ranges.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/_ranges.cpython-312.pyc
index 55717ccb..a296be70 100644
Binary files a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/_ranges.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/_ranges.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/_utils.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/_utils.cpython-312.pyc
index 0d1e587b..000c9272 100644
Binary files a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/_utils.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/_utils.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/base.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/base.cpython-312.pyc
index f965d4da..f72d8f03 100644
Binary files a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/base.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/base.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/boolean.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/boolean.cpython-312.pyc
index 2de505ac..900c92ed 100644
Binary files a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/boolean.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/boolean.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/categorical.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/categorical.cpython-312.pyc
index f2623095..aad96b16 100644
Binary files a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/categorical.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/categorical.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/datetimelike.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/datetimelike.cpython-312.pyc
index 02c4dc5f..b7267fd0 100644
Binary files a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/datetimelike.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/datetimelike.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/datetimes.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/datetimes.cpython-312.pyc
index c787903a..152d2905 100644
Binary files a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/datetimes.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/datetimes.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/floating.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/floating.cpython-312.pyc
index 13018344..cf739cb3 100644
Binary files a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/floating.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/floating.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/integer.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/integer.cpython-312.pyc
index b036baf5..8818e47e 100644
Binary files a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/integer.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/integer.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/interval.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/interval.cpython-312.pyc
index 1a7e441a..03a22461 100644
Binary files a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/interval.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/interval.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/masked.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/masked.cpython-312.pyc
index bd1d0c95..c2147dfa 100644
Binary files a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/masked.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/masked.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/numeric.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/numeric.cpython-312.pyc
index a05d2ee1..18f43752 100644
Binary files a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/numeric.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/numeric.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/numpy_.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/numpy_.cpython-312.pyc
index 78c47afa..51942f7a 100644
Binary files a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/numpy_.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/numpy_.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/period.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/period.cpython-312.pyc
index be70b90e..125ad79e 100644
Binary files a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/period.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/period.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/string_.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/string_.cpython-312.pyc
index 2bc7a599..c7d9e18f 100644
Binary files a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/string_.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/string_.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/string_arrow.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/string_arrow.cpython-312.pyc
index 7a53dcfa..587081b3 100644
Binary files a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/string_arrow.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/string_arrow.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/timedeltas.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/timedeltas.cpython-312.pyc
index 2dfcfb31..f816b13d 100644
Binary files a/venv/Lib/site-packages/pandas/core/arrays/__pycache__/timedeltas.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/arrays/__pycache__/timedeltas.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/arrays/arrow/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/arrays/arrow/__pycache__/__init__.cpython-312.pyc
index 2d0c9ceb..4116987d 100644
Binary files a/venv/Lib/site-packages/pandas/core/arrays/arrow/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/arrays/arrow/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/arrays/arrow/__pycache__/accessors.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/arrays/arrow/__pycache__/accessors.cpython-312.pyc
index 4c797fc1..299037f1 100644
Binary files a/venv/Lib/site-packages/pandas/core/arrays/arrow/__pycache__/accessors.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/arrays/arrow/__pycache__/accessors.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/arrays/arrow/__pycache__/array.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/arrays/arrow/__pycache__/array.cpython-312.pyc
index bd3e3e6c..c23128ac 100644
Binary files a/venv/Lib/site-packages/pandas/core/arrays/arrow/__pycache__/array.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/arrays/arrow/__pycache__/array.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/arrays/sparse/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/arrays/sparse/__pycache__/__init__.cpython-312.pyc
index e4a8d05b..e3eb65ba 100644
Binary files a/venv/Lib/site-packages/pandas/core/arrays/sparse/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/arrays/sparse/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/arrays/sparse/__pycache__/accessor.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/arrays/sparse/__pycache__/accessor.cpython-312.pyc
index bdab3663..2baf301d 100644
Binary files a/venv/Lib/site-packages/pandas/core/arrays/sparse/__pycache__/accessor.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/arrays/sparse/__pycache__/accessor.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/arrays/sparse/__pycache__/array.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/arrays/sparse/__pycache__/array.cpython-312.pyc
index 13f5cefe..99c42c06 100644
Binary files a/venv/Lib/site-packages/pandas/core/arrays/sparse/__pycache__/array.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/arrays/sparse/__pycache__/array.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/computation/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/computation/__pycache__/__init__.cpython-312.pyc
index 860b9c78..30332149 100644
Binary files a/venv/Lib/site-packages/pandas/core/computation/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/computation/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/computation/__pycache__/align.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/computation/__pycache__/align.cpython-312.pyc
index 41769061..b98608c8 100644
Binary files a/venv/Lib/site-packages/pandas/core/computation/__pycache__/align.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/computation/__pycache__/align.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/computation/__pycache__/api.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/computation/__pycache__/api.cpython-312.pyc
index 4f5f4638..ee0969b4 100644
Binary files a/venv/Lib/site-packages/pandas/core/computation/__pycache__/api.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/computation/__pycache__/api.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/computation/__pycache__/check.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/computation/__pycache__/check.cpython-312.pyc
index 50d786b8..83cb50a8 100644
Binary files a/venv/Lib/site-packages/pandas/core/computation/__pycache__/check.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/computation/__pycache__/check.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/computation/__pycache__/common.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/computation/__pycache__/common.cpython-312.pyc
index 1373ecdd..67a77075 100644
Binary files a/venv/Lib/site-packages/pandas/core/computation/__pycache__/common.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/computation/__pycache__/common.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/computation/__pycache__/engines.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/computation/__pycache__/engines.cpython-312.pyc
index 4a511744..d6e60e2c 100644
Binary files a/venv/Lib/site-packages/pandas/core/computation/__pycache__/engines.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/computation/__pycache__/engines.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/computation/__pycache__/eval.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/computation/__pycache__/eval.cpython-312.pyc
index c64fc542..41dbe0f0 100644
Binary files a/venv/Lib/site-packages/pandas/core/computation/__pycache__/eval.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/computation/__pycache__/eval.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/computation/__pycache__/expr.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/computation/__pycache__/expr.cpython-312.pyc
index fc4482cf..49183f6f 100644
Binary files a/venv/Lib/site-packages/pandas/core/computation/__pycache__/expr.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/computation/__pycache__/expr.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/computation/__pycache__/expressions.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/computation/__pycache__/expressions.cpython-312.pyc
index 594c28c1..be5bc206 100644
Binary files a/venv/Lib/site-packages/pandas/core/computation/__pycache__/expressions.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/computation/__pycache__/expressions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/computation/__pycache__/ops.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/computation/__pycache__/ops.cpython-312.pyc
index 303dae86..0658d78d 100644
Binary files a/venv/Lib/site-packages/pandas/core/computation/__pycache__/ops.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/computation/__pycache__/ops.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/computation/__pycache__/parsing.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/computation/__pycache__/parsing.cpython-312.pyc
index ff92db90..b2826db8 100644
Binary files a/venv/Lib/site-packages/pandas/core/computation/__pycache__/parsing.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/computation/__pycache__/parsing.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/computation/__pycache__/pytables.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/computation/__pycache__/pytables.cpython-312.pyc
index 683d84c5..1d68f6d1 100644
Binary files a/venv/Lib/site-packages/pandas/core/computation/__pycache__/pytables.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/computation/__pycache__/pytables.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/computation/__pycache__/scope.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/computation/__pycache__/scope.cpython-312.pyc
index ab217f79..47d76506 100644
Binary files a/venv/Lib/site-packages/pandas/core/computation/__pycache__/scope.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/computation/__pycache__/scope.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/__init__.cpython-312.pyc
index e278d9b2..caf258c6 100644
Binary files a/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/api.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/api.cpython-312.pyc
index 0856d5c9..e43f2aea 100644
Binary files a/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/api.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/api.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/astype.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/astype.cpython-312.pyc
index dbecd22d..6edd60e6 100644
Binary files a/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/astype.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/astype.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/base.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/base.cpython-312.pyc
index 3b2402d8..2c39c5fc 100644
Binary files a/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/base.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/base.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/cast.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/cast.cpython-312.pyc
index 1fa3a47a..5b258cdc 100644
Binary files a/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/cast.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/cast.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/common.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/common.cpython-312.pyc
index 2db8d8a4..98c854be 100644
Binary files a/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/common.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/common.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/concat.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/concat.cpython-312.pyc
index c2546cbd..93bcca9a 100644
Binary files a/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/concat.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/concat.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/dtypes.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/dtypes.cpython-312.pyc
index 58efefa0..f098bc48 100644
Binary files a/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/dtypes.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/dtypes.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/generic.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/generic.cpython-312.pyc
index 912fd2df..cab15dec 100644
Binary files a/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/generic.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/generic.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/inference.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/inference.cpython-312.pyc
index 6730c8eb..16fd8c20 100644
Binary files a/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/inference.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/inference.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/missing.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/missing.cpython-312.pyc
index 65f27917..d5a7ea22 100644
Binary files a/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/missing.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/dtypes/__pycache__/missing.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/groupby/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/groupby/__pycache__/__init__.cpython-312.pyc
index 358e2cad..5fd6c066 100644
Binary files a/venv/Lib/site-packages/pandas/core/groupby/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/groupby/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/groupby/__pycache__/base.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/groupby/__pycache__/base.cpython-312.pyc
index c5ad7ac2..6a4fe4d6 100644
Binary files a/venv/Lib/site-packages/pandas/core/groupby/__pycache__/base.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/groupby/__pycache__/base.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/groupby/__pycache__/categorical.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/groupby/__pycache__/categorical.cpython-312.pyc
index 1e1f5581..5e3fac8c 100644
Binary files a/venv/Lib/site-packages/pandas/core/groupby/__pycache__/categorical.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/groupby/__pycache__/categorical.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/groupby/__pycache__/generic.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/groupby/__pycache__/generic.cpython-312.pyc
index 1a29dd1c..1e7379d0 100644
Binary files a/venv/Lib/site-packages/pandas/core/groupby/__pycache__/generic.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/groupby/__pycache__/generic.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/groupby/__pycache__/groupby.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/groupby/__pycache__/groupby.cpython-312.pyc
index 58c8553e..963fa740 100644
Binary files a/venv/Lib/site-packages/pandas/core/groupby/__pycache__/groupby.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/groupby/__pycache__/groupby.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/groupby/__pycache__/grouper.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/groupby/__pycache__/grouper.cpython-312.pyc
index f7376c36..1e809922 100644
Binary files a/venv/Lib/site-packages/pandas/core/groupby/__pycache__/grouper.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/groupby/__pycache__/grouper.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/groupby/__pycache__/indexing.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/groupby/__pycache__/indexing.cpython-312.pyc
index 1f829801..fb7fed08 100644
Binary files a/venv/Lib/site-packages/pandas/core/groupby/__pycache__/indexing.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/groupby/__pycache__/indexing.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/groupby/__pycache__/numba_.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/groupby/__pycache__/numba_.cpython-312.pyc
index 50492c43..48166e13 100644
Binary files a/venv/Lib/site-packages/pandas/core/groupby/__pycache__/numba_.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/groupby/__pycache__/numba_.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/groupby/__pycache__/ops.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/groupby/__pycache__/ops.cpython-312.pyc
index 6bfbd689..0b88147c 100644
Binary files a/venv/Lib/site-packages/pandas/core/groupby/__pycache__/ops.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/groupby/__pycache__/ops.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/indexers/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/indexers/__pycache__/__init__.cpython-312.pyc
index a6fb9822..31a31cad 100644
Binary files a/venv/Lib/site-packages/pandas/core/indexers/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/indexers/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/indexers/__pycache__/objects.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/indexers/__pycache__/objects.cpython-312.pyc
index 90330122..1d9c61bf 100644
Binary files a/venv/Lib/site-packages/pandas/core/indexers/__pycache__/objects.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/indexers/__pycache__/objects.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/indexers/__pycache__/utils.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/indexers/__pycache__/utils.cpython-312.pyc
index b3eab9bd..87214b46 100644
Binary files a/venv/Lib/site-packages/pandas/core/indexers/__pycache__/utils.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/indexers/__pycache__/utils.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/indexes/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/indexes/__pycache__/__init__.cpython-312.pyc
index 9f52d382..82720d5e 100644
Binary files a/venv/Lib/site-packages/pandas/core/indexes/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/indexes/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/indexes/__pycache__/accessors.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/indexes/__pycache__/accessors.cpython-312.pyc
index 030afecc..23f79d4a 100644
Binary files a/venv/Lib/site-packages/pandas/core/indexes/__pycache__/accessors.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/indexes/__pycache__/accessors.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/indexes/__pycache__/api.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/indexes/__pycache__/api.cpython-312.pyc
index 4ed4cd62..bf342b0e 100644
Binary files a/venv/Lib/site-packages/pandas/core/indexes/__pycache__/api.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/indexes/__pycache__/api.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/indexes/__pycache__/base.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/indexes/__pycache__/base.cpython-312.pyc
index f7ab6746..16cca797 100644
Binary files a/venv/Lib/site-packages/pandas/core/indexes/__pycache__/base.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/indexes/__pycache__/base.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/indexes/__pycache__/category.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/indexes/__pycache__/category.cpython-312.pyc
index 87ff1904..216d7137 100644
Binary files a/venv/Lib/site-packages/pandas/core/indexes/__pycache__/category.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/indexes/__pycache__/category.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/indexes/__pycache__/datetimelike.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/indexes/__pycache__/datetimelike.cpython-312.pyc
index b8bd7c57..bfd94d9a 100644
Binary files a/venv/Lib/site-packages/pandas/core/indexes/__pycache__/datetimelike.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/indexes/__pycache__/datetimelike.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/indexes/__pycache__/datetimes.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/indexes/__pycache__/datetimes.cpython-312.pyc
index f35db196..42087762 100644
Binary files a/venv/Lib/site-packages/pandas/core/indexes/__pycache__/datetimes.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/indexes/__pycache__/datetimes.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/indexes/__pycache__/extension.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/indexes/__pycache__/extension.cpython-312.pyc
index 343ca883..e2938ea5 100644
Binary files a/venv/Lib/site-packages/pandas/core/indexes/__pycache__/extension.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/indexes/__pycache__/extension.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/indexes/__pycache__/frozen.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/indexes/__pycache__/frozen.cpython-312.pyc
index 2892b719..82034ed4 100644
Binary files a/venv/Lib/site-packages/pandas/core/indexes/__pycache__/frozen.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/indexes/__pycache__/frozen.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/indexes/__pycache__/interval.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/indexes/__pycache__/interval.cpython-312.pyc
index a093df15..da9ba8e0 100644
Binary files a/venv/Lib/site-packages/pandas/core/indexes/__pycache__/interval.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/indexes/__pycache__/interval.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/indexes/__pycache__/multi.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/indexes/__pycache__/multi.cpython-312.pyc
index 3d91243b..c3aeffca 100644
Binary files a/venv/Lib/site-packages/pandas/core/indexes/__pycache__/multi.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/indexes/__pycache__/multi.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/indexes/__pycache__/period.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/indexes/__pycache__/period.cpython-312.pyc
index 8bc02ab9..6d132d89 100644
Binary files a/venv/Lib/site-packages/pandas/core/indexes/__pycache__/period.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/indexes/__pycache__/period.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/indexes/__pycache__/range.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/indexes/__pycache__/range.cpython-312.pyc
index c18a6bd7..75d7058c 100644
Binary files a/venv/Lib/site-packages/pandas/core/indexes/__pycache__/range.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/indexes/__pycache__/range.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/indexes/__pycache__/timedeltas.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/indexes/__pycache__/timedeltas.cpython-312.pyc
index 4a709652..e04f527d 100644
Binary files a/venv/Lib/site-packages/pandas/core/indexes/__pycache__/timedeltas.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/indexes/__pycache__/timedeltas.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/interchange/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/interchange/__pycache__/__init__.cpython-312.pyc
index ac2fd652..bae90436 100644
Binary files a/venv/Lib/site-packages/pandas/core/interchange/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/interchange/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/interchange/__pycache__/dataframe_protocol.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/interchange/__pycache__/dataframe_protocol.cpython-312.pyc
index e766330a..38a4360a 100644
Binary files a/venv/Lib/site-packages/pandas/core/interchange/__pycache__/dataframe_protocol.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/interchange/__pycache__/dataframe_protocol.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/interchange/__pycache__/from_dataframe.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/interchange/__pycache__/from_dataframe.cpython-312.pyc
index 6b884afb..881e8287 100644
Binary files a/venv/Lib/site-packages/pandas/core/interchange/__pycache__/from_dataframe.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/interchange/__pycache__/from_dataframe.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/interchange/__pycache__/utils.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/interchange/__pycache__/utils.cpython-312.pyc
index 779f5f09..27200a27 100644
Binary files a/venv/Lib/site-packages/pandas/core/interchange/__pycache__/utils.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/interchange/__pycache__/utils.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/internals/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/internals/__pycache__/__init__.cpython-312.pyc
index 2243121f..93a675cd 100644
Binary files a/venv/Lib/site-packages/pandas/core/internals/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/internals/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/internals/__pycache__/api.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/internals/__pycache__/api.cpython-312.pyc
index 58bbff8b..29e07254 100644
Binary files a/venv/Lib/site-packages/pandas/core/internals/__pycache__/api.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/internals/__pycache__/api.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/internals/__pycache__/array_manager.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/internals/__pycache__/array_manager.cpython-312.pyc
index 2abaf2be..c1be93ff 100644
Binary files a/venv/Lib/site-packages/pandas/core/internals/__pycache__/array_manager.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/internals/__pycache__/array_manager.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/internals/__pycache__/base.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/internals/__pycache__/base.cpython-312.pyc
index ad9f19d9..ec9fd953 100644
Binary files a/venv/Lib/site-packages/pandas/core/internals/__pycache__/base.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/internals/__pycache__/base.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/internals/__pycache__/blocks.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/internals/__pycache__/blocks.cpython-312.pyc
index e3e36b56..c0896fd0 100644
Binary files a/venv/Lib/site-packages/pandas/core/internals/__pycache__/blocks.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/internals/__pycache__/blocks.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/internals/__pycache__/concat.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/internals/__pycache__/concat.cpython-312.pyc
index 6efefd29..df9fca0c 100644
Binary files a/venv/Lib/site-packages/pandas/core/internals/__pycache__/concat.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/internals/__pycache__/concat.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/internals/__pycache__/construction.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/internals/__pycache__/construction.cpython-312.pyc
index b04c7f0a..429acbcc 100644
Binary files a/venv/Lib/site-packages/pandas/core/internals/__pycache__/construction.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/internals/__pycache__/construction.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/internals/__pycache__/managers.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/internals/__pycache__/managers.cpython-312.pyc
index 23acb8f9..a5991fa0 100644
Binary files a/venv/Lib/site-packages/pandas/core/internals/__pycache__/managers.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/internals/__pycache__/managers.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/internals/__pycache__/ops.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/internals/__pycache__/ops.cpython-312.pyc
index c96397f5..80bdfaeb 100644
Binary files a/venv/Lib/site-packages/pandas/core/internals/__pycache__/ops.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/internals/__pycache__/ops.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/methods/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/methods/__pycache__/__init__.cpython-312.pyc
index 0fde03d1..ac68b041 100644
Binary files a/venv/Lib/site-packages/pandas/core/methods/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/methods/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/methods/__pycache__/describe.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/methods/__pycache__/describe.cpython-312.pyc
index b4e3b8dc..aa26245b 100644
Binary files a/venv/Lib/site-packages/pandas/core/methods/__pycache__/describe.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/methods/__pycache__/describe.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/methods/__pycache__/selectn.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/methods/__pycache__/selectn.cpython-312.pyc
index f3ddf5ab..0dc170d9 100644
Binary files a/venv/Lib/site-packages/pandas/core/methods/__pycache__/selectn.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/methods/__pycache__/selectn.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/ops/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/ops/__pycache__/__init__.cpython-312.pyc
index 86661c23..51f073bd 100644
Binary files a/venv/Lib/site-packages/pandas/core/ops/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/ops/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/ops/__pycache__/array_ops.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/ops/__pycache__/array_ops.cpython-312.pyc
index 7e969939..cfab908c 100644
Binary files a/venv/Lib/site-packages/pandas/core/ops/__pycache__/array_ops.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/ops/__pycache__/array_ops.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/ops/__pycache__/common.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/ops/__pycache__/common.cpython-312.pyc
index 773b2b9f..7fffc7f8 100644
Binary files a/venv/Lib/site-packages/pandas/core/ops/__pycache__/common.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/ops/__pycache__/common.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/ops/__pycache__/dispatch.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/ops/__pycache__/dispatch.cpython-312.pyc
index 4b910adc..053f1d80 100644
Binary files a/venv/Lib/site-packages/pandas/core/ops/__pycache__/dispatch.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/ops/__pycache__/dispatch.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/ops/__pycache__/docstrings.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/ops/__pycache__/docstrings.cpython-312.pyc
index 24f7586b..a4b31e0c 100644
Binary files a/venv/Lib/site-packages/pandas/core/ops/__pycache__/docstrings.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/ops/__pycache__/docstrings.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/ops/__pycache__/invalid.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/ops/__pycache__/invalid.cpython-312.pyc
index 36502667..7b06fb00 100644
Binary files a/venv/Lib/site-packages/pandas/core/ops/__pycache__/invalid.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/ops/__pycache__/invalid.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/ops/__pycache__/mask_ops.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/ops/__pycache__/mask_ops.cpython-312.pyc
index 8b8467ac..bb0a9eb0 100644
Binary files a/venv/Lib/site-packages/pandas/core/ops/__pycache__/mask_ops.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/ops/__pycache__/mask_ops.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/ops/__pycache__/missing.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/ops/__pycache__/missing.cpython-312.pyc
index 8e2f9f73..17fbc045 100644
Binary files a/venv/Lib/site-packages/pandas/core/ops/__pycache__/missing.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/ops/__pycache__/missing.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/reshape/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/reshape/__pycache__/__init__.cpython-312.pyc
index 9f6099a1..91481a5c 100644
Binary files a/venv/Lib/site-packages/pandas/core/reshape/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/reshape/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/reshape/__pycache__/api.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/reshape/__pycache__/api.cpython-312.pyc
index 20567de3..41cd07dd 100644
Binary files a/venv/Lib/site-packages/pandas/core/reshape/__pycache__/api.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/reshape/__pycache__/api.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/reshape/__pycache__/concat.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/reshape/__pycache__/concat.cpython-312.pyc
index 9ef1af23..467610ab 100644
Binary files a/venv/Lib/site-packages/pandas/core/reshape/__pycache__/concat.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/reshape/__pycache__/concat.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/reshape/__pycache__/encoding.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/reshape/__pycache__/encoding.cpython-312.pyc
index f5654d85..62d30740 100644
Binary files a/venv/Lib/site-packages/pandas/core/reshape/__pycache__/encoding.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/reshape/__pycache__/encoding.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/reshape/__pycache__/melt.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/reshape/__pycache__/melt.cpython-312.pyc
index 9e5f4328..814aafd4 100644
Binary files a/venv/Lib/site-packages/pandas/core/reshape/__pycache__/melt.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/reshape/__pycache__/melt.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/reshape/__pycache__/merge.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/reshape/__pycache__/merge.cpython-312.pyc
index a6989aad..1a85ba40 100644
Binary files a/venv/Lib/site-packages/pandas/core/reshape/__pycache__/merge.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/reshape/__pycache__/merge.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/reshape/__pycache__/pivot.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/reshape/__pycache__/pivot.cpython-312.pyc
index 68f72b52..bad8fc04 100644
Binary files a/venv/Lib/site-packages/pandas/core/reshape/__pycache__/pivot.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/reshape/__pycache__/pivot.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/reshape/__pycache__/tile.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/reshape/__pycache__/tile.cpython-312.pyc
index 669c8848..54742770 100644
Binary files a/venv/Lib/site-packages/pandas/core/reshape/__pycache__/tile.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/reshape/__pycache__/tile.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/reshape/__pycache__/util.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/reshape/__pycache__/util.cpython-312.pyc
index 4e306d6c..5609ae0e 100644
Binary files a/venv/Lib/site-packages/pandas/core/reshape/__pycache__/util.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/reshape/__pycache__/util.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/strings/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/strings/__pycache__/__init__.cpython-312.pyc
index 37b50a6e..e900aded 100644
Binary files a/venv/Lib/site-packages/pandas/core/strings/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/strings/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/strings/__pycache__/accessor.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/strings/__pycache__/accessor.cpython-312.pyc
index 55d480d8..a60a7b8b 100644
Binary files a/venv/Lib/site-packages/pandas/core/strings/__pycache__/accessor.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/strings/__pycache__/accessor.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/strings/__pycache__/base.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/strings/__pycache__/base.cpython-312.pyc
index 0eaf0bf7..4ba5d056 100644
Binary files a/venv/Lib/site-packages/pandas/core/strings/__pycache__/base.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/strings/__pycache__/base.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/strings/__pycache__/object_array.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/strings/__pycache__/object_array.cpython-312.pyc
index 9e7e79d1..2cf7f049 100644
Binary files a/venv/Lib/site-packages/pandas/core/strings/__pycache__/object_array.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/strings/__pycache__/object_array.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/tools/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/tools/__pycache__/__init__.cpython-312.pyc
index 9ee37f59..69802113 100644
Binary files a/venv/Lib/site-packages/pandas/core/tools/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/tools/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/tools/__pycache__/datetimes.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/tools/__pycache__/datetimes.cpython-312.pyc
index d74ff9cd..eaaf2db1 100644
Binary files a/venv/Lib/site-packages/pandas/core/tools/__pycache__/datetimes.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/tools/__pycache__/datetimes.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/tools/__pycache__/numeric.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/tools/__pycache__/numeric.cpython-312.pyc
index df323f6f..1c5308d3 100644
Binary files a/venv/Lib/site-packages/pandas/core/tools/__pycache__/numeric.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/tools/__pycache__/numeric.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/tools/__pycache__/timedeltas.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/tools/__pycache__/timedeltas.cpython-312.pyc
index b32166e1..0159c292 100644
Binary files a/venv/Lib/site-packages/pandas/core/tools/__pycache__/timedeltas.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/tools/__pycache__/timedeltas.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/tools/__pycache__/times.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/tools/__pycache__/times.cpython-312.pyc
index 043c9d1d..f1d39080 100644
Binary files a/venv/Lib/site-packages/pandas/core/tools/__pycache__/times.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/tools/__pycache__/times.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/util/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/util/__pycache__/__init__.cpython-312.pyc
index 42998350..6c93b3a1 100644
Binary files a/venv/Lib/site-packages/pandas/core/util/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/util/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/util/__pycache__/hashing.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/util/__pycache__/hashing.cpython-312.pyc
index fec3827f..248baf7a 100644
Binary files a/venv/Lib/site-packages/pandas/core/util/__pycache__/hashing.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/util/__pycache__/hashing.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/util/__pycache__/numba_.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/util/__pycache__/numba_.cpython-312.pyc
index 7cdb5454..abf1f82c 100644
Binary files a/venv/Lib/site-packages/pandas/core/util/__pycache__/numba_.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/util/__pycache__/numba_.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/window/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/window/__pycache__/__init__.cpython-312.pyc
index ed0c54fe..c17a882c 100644
Binary files a/venv/Lib/site-packages/pandas/core/window/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/window/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/window/__pycache__/common.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/window/__pycache__/common.cpython-312.pyc
index 4ef6327e..15d4623f 100644
Binary files a/venv/Lib/site-packages/pandas/core/window/__pycache__/common.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/window/__pycache__/common.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/window/__pycache__/doc.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/window/__pycache__/doc.cpython-312.pyc
index fc38b720..7b088ca9 100644
Binary files a/venv/Lib/site-packages/pandas/core/window/__pycache__/doc.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/window/__pycache__/doc.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/window/__pycache__/ewm.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/window/__pycache__/ewm.cpython-312.pyc
index 508cc8fb..1ea52add 100644
Binary files a/venv/Lib/site-packages/pandas/core/window/__pycache__/ewm.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/window/__pycache__/ewm.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/window/__pycache__/expanding.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/window/__pycache__/expanding.cpython-312.pyc
index f2c55a1a..58f99f5d 100644
Binary files a/venv/Lib/site-packages/pandas/core/window/__pycache__/expanding.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/window/__pycache__/expanding.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/window/__pycache__/numba_.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/window/__pycache__/numba_.cpython-312.pyc
index 692313f1..1d5b52f0 100644
Binary files a/venv/Lib/site-packages/pandas/core/window/__pycache__/numba_.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/window/__pycache__/numba_.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/window/__pycache__/online.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/window/__pycache__/online.cpython-312.pyc
index ee8eec5e..5e001fa7 100644
Binary files a/venv/Lib/site-packages/pandas/core/window/__pycache__/online.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/window/__pycache__/online.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/core/window/__pycache__/rolling.cpython-312.pyc b/venv/Lib/site-packages/pandas/core/window/__pycache__/rolling.cpython-312.pyc
index 487ee373..18c37a75 100644
Binary files a/venv/Lib/site-packages/pandas/core/window/__pycache__/rolling.cpython-312.pyc and b/venv/Lib/site-packages/pandas/core/window/__pycache__/rolling.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/errors/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/errors/__pycache__/__init__.cpython-312.pyc
index 638e9fbd..af8a30e8 100644
Binary files a/venv/Lib/site-packages/pandas/errors/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/errors/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/__pycache__/__init__.cpython-312.pyc
index dd650c36..755df84c 100644
Binary files a/venv/Lib/site-packages/pandas/io/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/__pycache__/_util.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/__pycache__/_util.cpython-312.pyc
index 0dd42a53..f14906c0 100644
Binary files a/venv/Lib/site-packages/pandas/io/__pycache__/_util.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/__pycache__/_util.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/__pycache__/api.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/__pycache__/api.cpython-312.pyc
index d239f589..afe72bc2 100644
Binary files a/venv/Lib/site-packages/pandas/io/__pycache__/api.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/__pycache__/api.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/__pycache__/clipboards.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/__pycache__/clipboards.cpython-312.pyc
index 59a191ed..760570ab 100644
Binary files a/venv/Lib/site-packages/pandas/io/__pycache__/clipboards.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/__pycache__/clipboards.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/__pycache__/common.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/__pycache__/common.cpython-312.pyc
index b477ef14..43152163 100644
Binary files a/venv/Lib/site-packages/pandas/io/__pycache__/common.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/__pycache__/common.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/__pycache__/feather_format.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/__pycache__/feather_format.cpython-312.pyc
index 6ec7044a..c9231490 100644
Binary files a/venv/Lib/site-packages/pandas/io/__pycache__/feather_format.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/__pycache__/feather_format.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/__pycache__/gbq.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/__pycache__/gbq.cpython-312.pyc
index 66dcfb3b..1c3f23d7 100644
Binary files a/venv/Lib/site-packages/pandas/io/__pycache__/gbq.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/__pycache__/gbq.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/__pycache__/html.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/__pycache__/html.cpython-312.pyc
index 5ed21849..2d67485f 100644
Binary files a/venv/Lib/site-packages/pandas/io/__pycache__/html.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/__pycache__/html.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/__pycache__/orc.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/__pycache__/orc.cpython-312.pyc
index ada3aa2c..b8f869dc 100644
Binary files a/venv/Lib/site-packages/pandas/io/__pycache__/orc.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/__pycache__/orc.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/__pycache__/parquet.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/__pycache__/parquet.cpython-312.pyc
index aad08346..1e9a33a8 100644
Binary files a/venv/Lib/site-packages/pandas/io/__pycache__/parquet.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/__pycache__/parquet.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/__pycache__/pickle.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/__pycache__/pickle.cpython-312.pyc
index 90f7d91d..d0efb488 100644
Binary files a/venv/Lib/site-packages/pandas/io/__pycache__/pickle.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/__pycache__/pickle.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/__pycache__/pytables.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/__pycache__/pytables.cpython-312.pyc
index c4b5151d..cec7fd4b 100644
Binary files a/venv/Lib/site-packages/pandas/io/__pycache__/pytables.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/__pycache__/pytables.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/__pycache__/spss.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/__pycache__/spss.cpython-312.pyc
index b7069001..6cc69756 100644
Binary files a/venv/Lib/site-packages/pandas/io/__pycache__/spss.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/__pycache__/spss.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/__pycache__/sql.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/__pycache__/sql.cpython-312.pyc
index c0e93c46..74dda29c 100644
Binary files a/venv/Lib/site-packages/pandas/io/__pycache__/sql.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/__pycache__/sql.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/__pycache__/stata.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/__pycache__/stata.cpython-312.pyc
index 516e237f..12417b90 100644
Binary files a/venv/Lib/site-packages/pandas/io/__pycache__/stata.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/__pycache__/stata.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/__pycache__/xml.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/__pycache__/xml.cpython-312.pyc
index 4c33c8be..594703cc 100644
Binary files a/venv/Lib/site-packages/pandas/io/__pycache__/xml.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/__pycache__/xml.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/excel/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/excel/__pycache__/__init__.cpython-312.pyc
index 738c37a7..5c4a016a 100644
Binary files a/venv/Lib/site-packages/pandas/io/excel/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/excel/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/excel/__pycache__/_base.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/excel/__pycache__/_base.cpython-312.pyc
index ecb70079..2ee0d3ec 100644
Binary files a/venv/Lib/site-packages/pandas/io/excel/__pycache__/_base.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/excel/__pycache__/_base.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/excel/__pycache__/_calamine.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/excel/__pycache__/_calamine.cpython-312.pyc
index bf07f69c..578ec6dd 100644
Binary files a/venv/Lib/site-packages/pandas/io/excel/__pycache__/_calamine.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/excel/__pycache__/_calamine.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/excel/__pycache__/_odfreader.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/excel/__pycache__/_odfreader.cpython-312.pyc
index fdc872cc..46b6736a 100644
Binary files a/venv/Lib/site-packages/pandas/io/excel/__pycache__/_odfreader.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/excel/__pycache__/_odfreader.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/excel/__pycache__/_odswriter.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/excel/__pycache__/_odswriter.cpython-312.pyc
index 4a30de80..dba2bb51 100644
Binary files a/venv/Lib/site-packages/pandas/io/excel/__pycache__/_odswriter.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/excel/__pycache__/_odswriter.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/excel/__pycache__/_openpyxl.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/excel/__pycache__/_openpyxl.cpython-312.pyc
index da9cb5ad..d973fb10 100644
Binary files a/venv/Lib/site-packages/pandas/io/excel/__pycache__/_openpyxl.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/excel/__pycache__/_openpyxl.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/excel/__pycache__/_pyxlsb.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/excel/__pycache__/_pyxlsb.cpython-312.pyc
index 8aeb3655..a981901b 100644
Binary files a/venv/Lib/site-packages/pandas/io/excel/__pycache__/_pyxlsb.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/excel/__pycache__/_pyxlsb.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/excel/__pycache__/_util.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/excel/__pycache__/_util.cpython-312.pyc
index 99d376e4..fbface06 100644
Binary files a/venv/Lib/site-packages/pandas/io/excel/__pycache__/_util.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/excel/__pycache__/_util.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/excel/__pycache__/_xlrd.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/excel/__pycache__/_xlrd.cpython-312.pyc
index fab443ad..0531334d 100644
Binary files a/venv/Lib/site-packages/pandas/io/excel/__pycache__/_xlrd.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/excel/__pycache__/_xlrd.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/excel/__pycache__/_xlsxwriter.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/excel/__pycache__/_xlsxwriter.cpython-312.pyc
index 80b5c571..f7eef104 100644
Binary files a/venv/Lib/site-packages/pandas/io/excel/__pycache__/_xlsxwriter.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/excel/__pycache__/_xlsxwriter.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/formats/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/formats/__pycache__/__init__.cpython-312.pyc
index d8a50d8d..e999c8fb 100644
Binary files a/venv/Lib/site-packages/pandas/io/formats/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/formats/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/formats/__pycache__/console.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/formats/__pycache__/console.cpython-312.pyc
index 8dfd8a8f..09bacd1f 100644
Binary files a/venv/Lib/site-packages/pandas/io/formats/__pycache__/console.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/formats/__pycache__/console.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/formats/__pycache__/csvs.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/formats/__pycache__/csvs.cpython-312.pyc
index d4749c35..b6cfd6f6 100644
Binary files a/venv/Lib/site-packages/pandas/io/formats/__pycache__/csvs.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/formats/__pycache__/csvs.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/formats/__pycache__/format.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/formats/__pycache__/format.cpython-312.pyc
index 889eaadc..03af0a76 100644
Binary files a/venv/Lib/site-packages/pandas/io/formats/__pycache__/format.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/formats/__pycache__/format.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/formats/__pycache__/info.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/formats/__pycache__/info.cpython-312.pyc
index 8015f342..ce5c1e5f 100644
Binary files a/venv/Lib/site-packages/pandas/io/formats/__pycache__/info.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/formats/__pycache__/info.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/formats/__pycache__/printing.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/formats/__pycache__/printing.cpython-312.pyc
index f92190bc..5526ef32 100644
Binary files a/venv/Lib/site-packages/pandas/io/formats/__pycache__/printing.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/formats/__pycache__/printing.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/json/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/json/__pycache__/__init__.cpython-312.pyc
index 759ac9ff..6b3f3711 100644
Binary files a/venv/Lib/site-packages/pandas/io/json/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/json/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/json/__pycache__/_json.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/json/__pycache__/_json.cpython-312.pyc
index ce32e60a..25021d34 100644
Binary files a/venv/Lib/site-packages/pandas/io/json/__pycache__/_json.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/json/__pycache__/_json.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/json/__pycache__/_normalize.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/json/__pycache__/_normalize.cpython-312.pyc
index 393fe07e..3967631e 100644
Binary files a/venv/Lib/site-packages/pandas/io/json/__pycache__/_normalize.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/json/__pycache__/_normalize.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/json/__pycache__/_table_schema.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/json/__pycache__/_table_schema.cpython-312.pyc
index b69dac40..b450c459 100644
Binary files a/venv/Lib/site-packages/pandas/io/json/__pycache__/_table_schema.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/json/__pycache__/_table_schema.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/parsers/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/parsers/__pycache__/__init__.cpython-312.pyc
index c04a3cb7..5aa20b03 100644
Binary files a/venv/Lib/site-packages/pandas/io/parsers/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/parsers/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/parsers/__pycache__/arrow_parser_wrapper.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/parsers/__pycache__/arrow_parser_wrapper.cpython-312.pyc
index bc73a46b..f36034a8 100644
Binary files a/venv/Lib/site-packages/pandas/io/parsers/__pycache__/arrow_parser_wrapper.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/parsers/__pycache__/arrow_parser_wrapper.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/parsers/__pycache__/base_parser.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/parsers/__pycache__/base_parser.cpython-312.pyc
index 2ce296b1..f4c4d1d6 100644
Binary files a/venv/Lib/site-packages/pandas/io/parsers/__pycache__/base_parser.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/parsers/__pycache__/base_parser.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/parsers/__pycache__/c_parser_wrapper.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/parsers/__pycache__/c_parser_wrapper.cpython-312.pyc
index 9328e5f2..8b4a153c 100644
Binary files a/venv/Lib/site-packages/pandas/io/parsers/__pycache__/c_parser_wrapper.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/parsers/__pycache__/c_parser_wrapper.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/parsers/__pycache__/python_parser.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/parsers/__pycache__/python_parser.cpython-312.pyc
index a7862d6c..dd24f632 100644
Binary files a/venv/Lib/site-packages/pandas/io/parsers/__pycache__/python_parser.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/parsers/__pycache__/python_parser.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/parsers/__pycache__/readers.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/parsers/__pycache__/readers.cpython-312.pyc
index d5162538..a246c764 100644
Binary files a/venv/Lib/site-packages/pandas/io/parsers/__pycache__/readers.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/parsers/__pycache__/readers.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/sas/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/sas/__pycache__/__init__.cpython-312.pyc
index e899a0cc..e562bb3a 100644
Binary files a/venv/Lib/site-packages/pandas/io/sas/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/sas/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/io/sas/__pycache__/sasreader.cpython-312.pyc b/venv/Lib/site-packages/pandas/io/sas/__pycache__/sasreader.cpython-312.pyc
index 975bc1a1..a957637b 100644
Binary files a/venv/Lib/site-packages/pandas/io/sas/__pycache__/sasreader.cpython-312.pyc and b/venv/Lib/site-packages/pandas/io/sas/__pycache__/sasreader.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/plotting/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/plotting/__pycache__/__init__.cpython-312.pyc
index 69254932..d4eea7e0 100644
Binary files a/venv/Lib/site-packages/pandas/plotting/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/plotting/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/plotting/__pycache__/_core.cpython-312.pyc b/venv/Lib/site-packages/pandas/plotting/__pycache__/_core.cpython-312.pyc
index e071cd94..b1be9191 100644
Binary files a/venv/Lib/site-packages/pandas/plotting/__pycache__/_core.cpython-312.pyc and b/venv/Lib/site-packages/pandas/plotting/__pycache__/_core.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/plotting/__pycache__/_misc.cpython-312.pyc b/venv/Lib/site-packages/pandas/plotting/__pycache__/_misc.cpython-312.pyc
index b152a16d..3f2e4f8f 100644
Binary files a/venv/Lib/site-packages/pandas/plotting/__pycache__/_misc.cpython-312.pyc and b/venv/Lib/site-packages/pandas/plotting/__pycache__/_misc.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/tseries/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/tseries/__pycache__/__init__.cpython-312.pyc
index 12f89ff2..bad0800c 100644
Binary files a/venv/Lib/site-packages/pandas/tseries/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/tseries/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/tseries/__pycache__/api.cpython-312.pyc b/venv/Lib/site-packages/pandas/tseries/__pycache__/api.cpython-312.pyc
index 6b617315..93984ef2 100644
Binary files a/venv/Lib/site-packages/pandas/tseries/__pycache__/api.cpython-312.pyc and b/venv/Lib/site-packages/pandas/tseries/__pycache__/api.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/tseries/__pycache__/frequencies.cpython-312.pyc b/venv/Lib/site-packages/pandas/tseries/__pycache__/frequencies.cpython-312.pyc
index de803f43..dcf149d3 100644
Binary files a/venv/Lib/site-packages/pandas/tseries/__pycache__/frequencies.cpython-312.pyc and b/venv/Lib/site-packages/pandas/tseries/__pycache__/frequencies.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/tseries/__pycache__/offsets.cpython-312.pyc b/venv/Lib/site-packages/pandas/tseries/__pycache__/offsets.cpython-312.pyc
index c6035486..aab43ac7 100644
Binary files a/venv/Lib/site-packages/pandas/tseries/__pycache__/offsets.cpython-312.pyc and b/venv/Lib/site-packages/pandas/tseries/__pycache__/offsets.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/util/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/util/__pycache__/__init__.cpython-312.pyc
index 4e168e49..ad504c00 100644
Binary files a/venv/Lib/site-packages/pandas/util/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/util/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/util/__pycache__/_decorators.cpython-312.pyc b/venv/Lib/site-packages/pandas/util/__pycache__/_decorators.cpython-312.pyc
index 404240d4..a2433122 100644
Binary files a/venv/Lib/site-packages/pandas/util/__pycache__/_decorators.cpython-312.pyc and b/venv/Lib/site-packages/pandas/util/__pycache__/_decorators.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/util/__pycache__/_exceptions.cpython-312.pyc b/venv/Lib/site-packages/pandas/util/__pycache__/_exceptions.cpython-312.pyc
index 6ca00f99..47e22be9 100644
Binary files a/venv/Lib/site-packages/pandas/util/__pycache__/_exceptions.cpython-312.pyc and b/venv/Lib/site-packages/pandas/util/__pycache__/_exceptions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/util/__pycache__/_print_versions.cpython-312.pyc b/venv/Lib/site-packages/pandas/util/__pycache__/_print_versions.cpython-312.pyc
index beb393e1..777b0cbb 100644
Binary files a/venv/Lib/site-packages/pandas/util/__pycache__/_print_versions.cpython-312.pyc and b/venv/Lib/site-packages/pandas/util/__pycache__/_print_versions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/util/__pycache__/_tester.cpython-312.pyc b/venv/Lib/site-packages/pandas/util/__pycache__/_tester.cpython-312.pyc
index 5cd4f72e..0281e66d 100644
Binary files a/venv/Lib/site-packages/pandas/util/__pycache__/_tester.cpython-312.pyc and b/venv/Lib/site-packages/pandas/util/__pycache__/_tester.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/util/__pycache__/_validators.cpython-312.pyc b/venv/Lib/site-packages/pandas/util/__pycache__/_validators.cpython-312.pyc
index 4cd998b2..4c316bb4 100644
Binary files a/venv/Lib/site-packages/pandas/util/__pycache__/_validators.cpython-312.pyc and b/venv/Lib/site-packages/pandas/util/__pycache__/_validators.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pandas/util/version/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pandas/util/version/__pycache__/__init__.cpython-312.pyc
index 66b99c2c..43bb7889 100644
Binary files a/venv/Lib/site-packages/pandas/util/version/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pandas/util/version/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/__pycache__/__init__.cpython-312.pyc
index c623f8d3..fe8fe004 100644
Binary files a/venv/Lib/site-packages/pip/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/__pycache__/__init__.cpython-312.pyc
index 251d8a03..819661c5 100644
Binary files a/venv/Lib/site-packages/pip/_internal/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/__pycache__/build_env.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/__pycache__/build_env.cpython-312.pyc
index d2e5bc6e..2618cf63 100644
Binary files a/venv/Lib/site-packages/pip/_internal/__pycache__/build_env.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/__pycache__/build_env.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/__pycache__/cache.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/__pycache__/cache.cpython-312.pyc
index ee375d3b..1a078920 100644
Binary files a/venv/Lib/site-packages/pip/_internal/__pycache__/cache.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/__pycache__/cache.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/__pycache__/configuration.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/__pycache__/configuration.cpython-312.pyc
index 7297d567..ae64dd3a 100644
Binary files a/venv/Lib/site-packages/pip/_internal/__pycache__/configuration.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/__pycache__/configuration.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/__pycache__/exceptions.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/__pycache__/exceptions.cpython-312.pyc
index de0bdba1..998a22ae 100644
Binary files a/venv/Lib/site-packages/pip/_internal/__pycache__/exceptions.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/__pycache__/exceptions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/__pycache__/pyproject.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/__pycache__/pyproject.cpython-312.pyc
index 988daa52..3848e33c 100644
Binary files a/venv/Lib/site-packages/pip/_internal/__pycache__/pyproject.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/__pycache__/pyproject.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/__pycache__/self_outdated_check.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/__pycache__/self_outdated_check.cpython-312.pyc
index 873b03fe..5e681f5a 100644
Binary files a/venv/Lib/site-packages/pip/_internal/__pycache__/self_outdated_check.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/__pycache__/self_outdated_check.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/__pycache__/wheel_builder.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/__pycache__/wheel_builder.cpython-312.pyc
index bdafee07..16054d15 100644
Binary files a/venv/Lib/site-packages/pip/_internal/__pycache__/wheel_builder.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/__pycache__/wheel_builder.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-312.pyc
index 4979f017..5ad7aa59 100644
Binary files a/venv/Lib/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/cli/__pycache__/autocompletion.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/cli/__pycache__/autocompletion.cpython-312.pyc
index 08bb3507..4ecc7fb2 100644
Binary files a/venv/Lib/site-packages/pip/_internal/cli/__pycache__/autocompletion.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/cli/__pycache__/autocompletion.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-312.pyc
index 1613ca04..bfaa01c8 100644
Binary files a/venv/Lib/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-312.pyc
index f11cac48..02ba0532 100644
Binary files a/venv/Lib/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/cli/__pycache__/command_context.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/cli/__pycache__/command_context.cpython-312.pyc
index 03d18899..c7c06ea1 100644
Binary files a/venv/Lib/site-packages/pip/_internal/cli/__pycache__/command_context.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/cli/__pycache__/command_context.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/cli/__pycache__/main.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/cli/__pycache__/main.cpython-312.pyc
index efe5c7c7..aa0854e8 100644
Binary files a/venv/Lib/site-packages/pip/_internal/cli/__pycache__/main.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/cli/__pycache__/main.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-312.pyc
index fce18ea7..409520db 100644
Binary files a/venv/Lib/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/cli/__pycache__/parser.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/cli/__pycache__/parser.cpython-312.pyc
index a8ff6488..06be0eb0 100644
Binary files a/venv/Lib/site-packages/pip/_internal/cli/__pycache__/parser.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/cli/__pycache__/parser.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/cli/__pycache__/progress_bars.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/cli/__pycache__/progress_bars.cpython-312.pyc
index 650966c0..356d0fff 100644
Binary files a/venv/Lib/site-packages/pip/_internal/cli/__pycache__/progress_bars.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/cli/__pycache__/progress_bars.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/cli/__pycache__/req_command.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/cli/__pycache__/req_command.cpython-312.pyc
index c6967013..4281f84c 100644
Binary files a/venv/Lib/site-packages/pip/_internal/cli/__pycache__/req_command.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/cli/__pycache__/req_command.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/cli/__pycache__/spinners.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/cli/__pycache__/spinners.cpython-312.pyc
index ba240a44..6a515f92 100644
Binary files a/venv/Lib/site-packages/pip/_internal/cli/__pycache__/spinners.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/cli/__pycache__/spinners.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-312.pyc
index 9b0205cb..fa0abf74 100644
Binary files a/venv/Lib/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-312.pyc
index 91d203d4..2f4f4b00 100644
Binary files a/venv/Lib/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/commands/__pycache__/install.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/commands/__pycache__/install.cpython-312.pyc
index d84f4ce6..78afbea6 100644
Binary files a/venv/Lib/site-packages/pip/_internal/commands/__pycache__/install.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/commands/__pycache__/install.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-312.pyc
index 987a5974..47d5ac96 100644
Binary files a/venv/Lib/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/distributions/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/distributions/__pycache__/__init__.cpython-312.pyc
index 32497d8d..c6976399 100644
Binary files a/venv/Lib/site-packages/pip/_internal/distributions/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/distributions/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/distributions/__pycache__/base.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/distributions/__pycache__/base.cpython-312.pyc
index 8e0f564a..ad6af117 100644
Binary files a/venv/Lib/site-packages/pip/_internal/distributions/__pycache__/base.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/distributions/__pycache__/base.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/distributions/__pycache__/installed.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/distributions/__pycache__/installed.cpython-312.pyc
index e4949acc..71ee4cd8 100644
Binary files a/venv/Lib/site-packages/pip/_internal/distributions/__pycache__/installed.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/distributions/__pycache__/installed.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/distributions/__pycache__/sdist.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/distributions/__pycache__/sdist.cpython-312.pyc
index 017dce8d..a6596232 100644
Binary files a/venv/Lib/site-packages/pip/_internal/distributions/__pycache__/sdist.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/distributions/__pycache__/sdist.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/distributions/__pycache__/wheel.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/distributions/__pycache__/wheel.cpython-312.pyc
index 0dcd876d..dcd568f5 100644
Binary files a/venv/Lib/site-packages/pip/_internal/distributions/__pycache__/wheel.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/distributions/__pycache__/wheel.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/index/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/index/__pycache__/__init__.cpython-312.pyc
index f6575a7e..63868825 100644
Binary files a/venv/Lib/site-packages/pip/_internal/index/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/index/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/index/__pycache__/collector.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/index/__pycache__/collector.cpython-312.pyc
index bb58f087..2d4b5c3b 100644
Binary files a/venv/Lib/site-packages/pip/_internal/index/__pycache__/collector.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/index/__pycache__/collector.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/index/__pycache__/package_finder.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/index/__pycache__/package_finder.cpython-312.pyc
index eac6e063..d7a866fe 100644
Binary files a/venv/Lib/site-packages/pip/_internal/index/__pycache__/package_finder.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/index/__pycache__/package_finder.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/index/__pycache__/sources.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/index/__pycache__/sources.cpython-312.pyc
index 7b678ee2..8412079d 100644
Binary files a/venv/Lib/site-packages/pip/_internal/index/__pycache__/sources.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/index/__pycache__/sources.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/locations/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/locations/__pycache__/__init__.cpython-312.pyc
index 2807f4ea..fa49a444 100644
Binary files a/venv/Lib/site-packages/pip/_internal/locations/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/locations/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/locations/__pycache__/_sysconfig.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/locations/__pycache__/_sysconfig.cpython-312.pyc
index 2b6d12bd..b40fb780 100644
Binary files a/venv/Lib/site-packages/pip/_internal/locations/__pycache__/_sysconfig.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/locations/__pycache__/_sysconfig.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/locations/__pycache__/base.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/locations/__pycache__/base.cpython-312.pyc
index efd9dbd3..84d3c6aa 100644
Binary files a/venv/Lib/site-packages/pip/_internal/locations/__pycache__/base.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/locations/__pycache__/base.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/metadata/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/metadata/__pycache__/__init__.cpython-312.pyc
index cbec41af..29fb874d 100644
Binary files a/venv/Lib/site-packages/pip/_internal/metadata/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/metadata/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/metadata/__pycache__/_json.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/metadata/__pycache__/_json.cpython-312.pyc
index 3af3de0f..d7aa5815 100644
Binary files a/venv/Lib/site-packages/pip/_internal/metadata/__pycache__/_json.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/metadata/__pycache__/_json.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/metadata/__pycache__/base.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/metadata/__pycache__/base.cpython-312.pyc
index 86950b7b..2fa19c45 100644
Binary files a/venv/Lib/site-packages/pip/_internal/metadata/__pycache__/base.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/metadata/__pycache__/base.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/metadata/__pycache__/pkg_resources.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/metadata/__pycache__/pkg_resources.cpython-312.pyc
index 852734f5..6ee9629c 100644
Binary files a/venv/Lib/site-packages/pip/_internal/metadata/__pycache__/pkg_resources.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/metadata/__pycache__/pkg_resources.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/metadata/importlib/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/metadata/importlib/__pycache__/__init__.cpython-312.pyc
index 393b9ce4..be47b42e 100644
Binary files a/venv/Lib/site-packages/pip/_internal/metadata/importlib/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/metadata/importlib/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/metadata/importlib/__pycache__/_compat.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/metadata/importlib/__pycache__/_compat.cpython-312.pyc
index 2b3f3156..b26c4372 100644
Binary files a/venv/Lib/site-packages/pip/_internal/metadata/importlib/__pycache__/_compat.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/metadata/importlib/__pycache__/_compat.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/metadata/importlib/__pycache__/_dists.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/metadata/importlib/__pycache__/_dists.cpython-312.pyc
index e7b3c543..385e0532 100644
Binary files a/venv/Lib/site-packages/pip/_internal/metadata/importlib/__pycache__/_dists.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/metadata/importlib/__pycache__/_dists.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/metadata/importlib/__pycache__/_envs.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/metadata/importlib/__pycache__/_envs.cpython-312.pyc
index 84afb51e..c8212515 100644
Binary files a/venv/Lib/site-packages/pip/_internal/metadata/importlib/__pycache__/_envs.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/metadata/importlib/__pycache__/_envs.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/models/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/models/__pycache__/__init__.cpython-312.pyc
index 8d196e48..1b02d8b3 100644
Binary files a/venv/Lib/site-packages/pip/_internal/models/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/models/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/models/__pycache__/candidate.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/models/__pycache__/candidate.cpython-312.pyc
index fadc0010..1d37ff17 100644
Binary files a/venv/Lib/site-packages/pip/_internal/models/__pycache__/candidate.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/models/__pycache__/candidate.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/models/__pycache__/direct_url.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/models/__pycache__/direct_url.cpython-312.pyc
index 98dc38b0..44f50623 100644
Binary files a/venv/Lib/site-packages/pip/_internal/models/__pycache__/direct_url.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/models/__pycache__/direct_url.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/models/__pycache__/format_control.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/models/__pycache__/format_control.cpython-312.pyc
index 7c96a2e9..99ed746c 100644
Binary files a/venv/Lib/site-packages/pip/_internal/models/__pycache__/format_control.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/models/__pycache__/format_control.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/models/__pycache__/index.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/models/__pycache__/index.cpython-312.pyc
index b483a1d9..0a06f4cb 100644
Binary files a/venv/Lib/site-packages/pip/_internal/models/__pycache__/index.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/models/__pycache__/index.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/models/__pycache__/installation_report.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/models/__pycache__/installation_report.cpython-312.pyc
index a7f682cb..754a1d06 100644
Binary files a/venv/Lib/site-packages/pip/_internal/models/__pycache__/installation_report.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/models/__pycache__/installation_report.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/models/__pycache__/link.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/models/__pycache__/link.cpython-312.pyc
index 803d8a77..42f32211 100644
Binary files a/venv/Lib/site-packages/pip/_internal/models/__pycache__/link.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/models/__pycache__/link.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/models/__pycache__/scheme.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/models/__pycache__/scheme.cpython-312.pyc
index 53ff205a..d13870fa 100644
Binary files a/venv/Lib/site-packages/pip/_internal/models/__pycache__/scheme.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/models/__pycache__/scheme.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-312.pyc
index 56f666e3..598440ee 100644
Binary files a/venv/Lib/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/models/__pycache__/selection_prefs.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/models/__pycache__/selection_prefs.cpython-312.pyc
index 66731265..71f75120 100644
Binary files a/venv/Lib/site-packages/pip/_internal/models/__pycache__/selection_prefs.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/models/__pycache__/selection_prefs.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/models/__pycache__/target_python.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/models/__pycache__/target_python.cpython-312.pyc
index f6ac4e7f..3cb635c5 100644
Binary files a/venv/Lib/site-packages/pip/_internal/models/__pycache__/target_python.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/models/__pycache__/target_python.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/models/__pycache__/wheel.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/models/__pycache__/wheel.cpython-312.pyc
index 3e486237..ec359919 100644
Binary files a/venv/Lib/site-packages/pip/_internal/models/__pycache__/wheel.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/models/__pycache__/wheel.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/network/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/network/__pycache__/__init__.cpython-312.pyc
index 02963e50..1386ae25 100644
Binary files a/venv/Lib/site-packages/pip/_internal/network/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/network/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/network/__pycache__/auth.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/network/__pycache__/auth.cpython-312.pyc
index c3661311..17bf668b 100644
Binary files a/venv/Lib/site-packages/pip/_internal/network/__pycache__/auth.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/network/__pycache__/auth.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/network/__pycache__/cache.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/network/__pycache__/cache.cpython-312.pyc
index 91cc5729..be4f38ba 100644
Binary files a/venv/Lib/site-packages/pip/_internal/network/__pycache__/cache.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/network/__pycache__/cache.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/network/__pycache__/download.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/network/__pycache__/download.cpython-312.pyc
index 0a47edf4..fa8e45fb 100644
Binary files a/venv/Lib/site-packages/pip/_internal/network/__pycache__/download.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/network/__pycache__/download.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/network/__pycache__/lazy_wheel.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/network/__pycache__/lazy_wheel.cpython-312.pyc
index e350bf67..49164d2f 100644
Binary files a/venv/Lib/site-packages/pip/_internal/network/__pycache__/lazy_wheel.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/network/__pycache__/lazy_wheel.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/network/__pycache__/session.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/network/__pycache__/session.cpython-312.pyc
index ee5ac4cc..ee9052f2 100644
Binary files a/venv/Lib/site-packages/pip/_internal/network/__pycache__/session.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/network/__pycache__/session.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/network/__pycache__/utils.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/network/__pycache__/utils.cpython-312.pyc
index a0f78baf..c672d8e9 100644
Binary files a/venv/Lib/site-packages/pip/_internal/network/__pycache__/utils.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/network/__pycache__/utils.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-312.pyc
index 0f81fc2d..57e758f4 100644
Binary files a/venv/Lib/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/operations/__pycache__/check.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/operations/__pycache__/check.cpython-312.pyc
index b68d8cc0..249d6ed2 100644
Binary files a/venv/Lib/site-packages/pip/_internal/operations/__pycache__/check.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/operations/__pycache__/check.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-312.pyc
index cc707f80..07efaba6 100644
Binary files a/venv/Lib/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/__init__.cpython-312.pyc
index 4c911b01..e2dddc63 100644
Binary files a/venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/build_tracker.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/build_tracker.cpython-312.pyc
index c1e9b2cb..ed4f98e1 100644
Binary files a/venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/build_tracker.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/build_tracker.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/metadata.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/metadata.cpython-312.pyc
index 1eb5ae37..871443d9 100644
Binary files a/venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/metadata.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/metadata.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/metadata_editable.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/metadata_editable.cpython-312.pyc
index 191ca44a..edc7896e 100644
Binary files a/venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/metadata_editable.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/metadata_editable.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-312.pyc
index 49449e86..acb3bead 100644
Binary files a/venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/wheel.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/wheel.cpython-312.pyc
index 7789bb3b..7baba89a 100644
Binary files a/venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/wheel.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/wheel.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/wheel_editable.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/wheel_editable.cpython-312.pyc
index 820a1871..fbffa562 100644
Binary files a/venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/wheel_editable.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/wheel_editable.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/wheel_legacy.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/wheel_legacy.cpython-312.pyc
index b030e3b9..cc1f31d6 100644
Binary files a/venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/wheel_legacy.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/wheel_legacy.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/operations/install/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/operations/install/__pycache__/__init__.cpython-312.pyc
index c71b282f..bfe68902 100644
Binary files a/venv/Lib/site-packages/pip/_internal/operations/install/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/operations/install/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/operations/install/__pycache__/editable_legacy.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/operations/install/__pycache__/editable_legacy.cpython-312.pyc
index 0ee9811c..ee82a7e5 100644
Binary files a/venv/Lib/site-packages/pip/_internal/operations/install/__pycache__/editable_legacy.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/operations/install/__pycache__/editable_legacy.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/operations/install/__pycache__/wheel.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/operations/install/__pycache__/wheel.cpython-312.pyc
index e641a125..f45f71be 100644
Binary files a/venv/Lib/site-packages/pip/_internal/operations/install/__pycache__/wheel.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/operations/install/__pycache__/wheel.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/req/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/req/__pycache__/__init__.cpython-312.pyc
index 5dee07df..3e26e539 100644
Binary files a/venv/Lib/site-packages/pip/_internal/req/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/req/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/req/__pycache__/constructors.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/req/__pycache__/constructors.cpython-312.pyc
index 90562fb4..7433b11f 100644
Binary files a/venv/Lib/site-packages/pip/_internal/req/__pycache__/constructors.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/req/__pycache__/constructors.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/req/__pycache__/req_file.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/req/__pycache__/req_file.cpython-312.pyc
index fd8cc038..5e6dfee7 100644
Binary files a/venv/Lib/site-packages/pip/_internal/req/__pycache__/req_file.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/req/__pycache__/req_file.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/req/__pycache__/req_install.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/req/__pycache__/req_install.cpython-312.pyc
index 0c637f22..33c50af0 100644
Binary files a/venv/Lib/site-packages/pip/_internal/req/__pycache__/req_install.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/req/__pycache__/req_install.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/req/__pycache__/req_set.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/req/__pycache__/req_set.cpython-312.pyc
index 60fa5d5b..8e023fbc 100644
Binary files a/venv/Lib/site-packages/pip/_internal/req/__pycache__/req_set.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/req/__pycache__/req_set.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-312.pyc
index bf06e8b2..863f7ea3 100644
Binary files a/venv/Lib/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/resolution/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/resolution/__pycache__/__init__.cpython-312.pyc
index 9340045c..d62708a9 100644
Binary files a/venv/Lib/site-packages/pip/_internal/resolution/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/resolution/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/resolution/__pycache__/base.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/resolution/__pycache__/base.cpython-312.pyc
index 509ec0f5..99c469e5 100644
Binary files a/venv/Lib/site-packages/pip/_internal/resolution/__pycache__/base.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/resolution/__pycache__/base.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-312.pyc
index 39785517..469d5f98 100644
Binary files a/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/base.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/base.cpython-312.pyc
index 921811fa..9af71ff2 100644
Binary files a/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/base.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/base.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-312.pyc
index 36bf898d..395c70cf 100644
Binary files a/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-312.pyc
index 11f3ad0a..7e4d1735 100644
Binary files a/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/found_candidates.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/found_candidates.cpython-312.pyc
index c06c45d4..d67ba561 100644
Binary files a/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/found_candidates.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/found_candidates.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-312.pyc
index f44b0621..f5106dcf 100644
Binary files a/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/reporter.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/reporter.cpython-312.pyc
index 88449bdb..8c14044c 100644
Binary files a/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/reporter.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/reporter.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/requirements.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/requirements.cpython-312.pyc
index 2a99cbc1..7eedc6ca 100644
Binary files a/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/requirements.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/requirements.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/resolver.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/resolver.cpython-312.pyc
index b5ff8973..b3dc8802 100644
Binary files a/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/resolver.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/resolver.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-312.pyc
index 16a8d73d..bb12f0f2 100644
Binary files a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/_jaraco_text.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/_jaraco_text.cpython-312.pyc
index cb188e11..865a4a4a 100644
Binary files a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/_jaraco_text.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/_jaraco_text.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/_log.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/_log.cpython-312.pyc
index 854e0457..d5179584 100644
Binary files a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/_log.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/_log.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-312.pyc
index bbddfb3d..28ecebbe 100644
Binary files a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/compat.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/compat.cpython-312.pyc
index 158d3bcb..9003310e 100644
Binary files a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/compat.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/compat.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/compatibility_tags.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/compatibility_tags.cpython-312.pyc
index 64b6bbd8..8862f4a2 100644
Binary files a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/compatibility_tags.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/compatibility_tags.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-312.pyc
index 72afd8a1..f56ee82f 100644
Binary files a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/direct_url_helpers.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/direct_url_helpers.cpython-312.pyc
index 72a93a35..be5f791c 100644
Binary files a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/direct_url_helpers.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/direct_url_helpers.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/egg_link.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/egg_link.cpython-312.pyc
index 355573d7..afda5be3 100644
Binary files a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/egg_link.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/egg_link.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-312.pyc
index 2304fbfd..1133df0f 100644
Binary files a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/entrypoints.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/entrypoints.cpython-312.pyc
index dd751fd1..f68ca162 100644
Binary files a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/entrypoints.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/entrypoints.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-312.pyc
index d406f35a..7ae6b469 100644
Binary files a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/filetypes.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/filetypes.cpython-312.pyc
index cc0a56a0..def56fbc 100644
Binary files a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/filetypes.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/filetypes.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-312.pyc
index cb2b4a83..48a89869 100644
Binary files a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-312.pyc
index 33d7e907..89c3a269 100644
Binary files a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/logging.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/logging.cpython-312.pyc
index 9817053d..5737a696 100644
Binary files a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/logging.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/logging.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/misc.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/misc.cpython-312.pyc
index 7d5fd2b3..a02072f8 100644
Binary files a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/misc.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/misc.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/models.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/models.cpython-312.pyc
index e656677f..bd61e903 100644
Binary files a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/models.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/models.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-312.pyc
index 5b88cc71..58c3ae13 100644
Binary files a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-312.pyc
index 738a1b7d..33bd9556 100644
Binary files a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/subprocess.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/subprocess.cpython-312.pyc
index daa00a5e..fd9e1857 100644
Binary files a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/subprocess.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/subprocess.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-312.pyc
index 8d40b61b..b01cd063 100644
Binary files a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/unpacking.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/unpacking.cpython-312.pyc
index 0020fae3..147eb2be 100644
Binary files a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/unpacking.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/unpacking.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/urls.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/urls.cpython-312.pyc
index c0613f7d..930b4e02 100644
Binary files a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/urls.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/urls.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/virtualenv.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/virtualenv.cpython-312.pyc
index ac20d867..dd455203 100644
Binary files a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/virtualenv.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/virtualenv.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/wheel.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/wheel.cpython-312.pyc
index c08fc4c7..7c6e432b 100644
Binary files a/venv/Lib/site-packages/pip/_internal/utils/__pycache__/wheel.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/utils/__pycache__/wheel.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-312.pyc
index 188cf467..b824b25b 100644
Binary files a/venv/Lib/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-312.pyc
index e31835f6..a47c30d6 100644
Binary files a/venv/Lib/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/vcs/__pycache__/git.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/vcs/__pycache__/git.cpython-312.pyc
index 2c361f2d..1e37227c 100644
Binary files a/venv/Lib/site-packages/pip/_internal/vcs/__pycache__/git.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/vcs/__pycache__/git.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-312.pyc
index a49fea32..d50a8e63 100644
Binary files a/venv/Lib/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-312.pyc
index 29692d36..0ab5a0af 100644
Binary files a/venv/Lib/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_internal/vcs/__pycache__/versioncontrol.cpython-312.pyc b/venv/Lib/site-packages/pip/_internal/vcs/__pycache__/versioncontrol.cpython-312.pyc
index 06304203..057378c1 100644
Binary files a/venv/Lib/site-packages/pip/_internal/vcs/__pycache__/versioncontrol.cpython-312.pyc and b/venv/Lib/site-packages/pip/_internal/vcs/__pycache__/versioncontrol.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/__pycache__/__init__.cpython-312.pyc
index b3cf8879..2331b57a 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-312.pyc
index d3542b06..021ef74d 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-312.pyc
index 03dbb4d8..266da169 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/cache.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/cache.cpython-312.pyc
index 2a6ab4ac..1f4b2b99 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/cache.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/cache.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/controller.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/controller.cpython-312.pyc
index aa86b016..aac5977d 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/controller.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/controller.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-312.pyc
index 0636572d..4ce4b18d 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/serialize.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/serialize.cpython-312.pyc
index eb351adb..79149042 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/serialize.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/serialize.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-312.pyc
index 45324f7e..7c699900 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-312.pyc
index 0c2a0a74..854c4d93 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-312.pyc
index 33f7c426..ef18370b 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-312.pyc
index 90abd28e..9a101792 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/certifi/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/certifi/__pycache__/__init__.cpython-312.pyc
index d5c72291..6c6ec82c 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/certifi/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/certifi/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/certifi/__pycache__/core.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/certifi/__pycache__/core.cpython-312.pyc
index e8d465ab..2f3b47f2 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/certifi/__pycache__/core.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/certifi/__pycache__/core.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/__init__.cpython-312.pyc
index 995265b0..2281cd2e 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/big5freq.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/big5freq.cpython-312.pyc
index 4da57e9f..b0903ab3 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/big5freq.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/big5freq.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/big5prober.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/big5prober.cpython-312.pyc
index 09a1088c..6f7bf522 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/big5prober.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/big5prober.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/chardistribution.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/chardistribution.cpython-312.pyc
index 07037225..09a20a7b 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/chardistribution.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/chardistribution.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-312.pyc
index b8d98e4c..8a582062 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/charsetprober.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/charsetprober.cpython-312.pyc
index 5b8bb873..947b1ec3 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/charsetprober.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/charsetprober.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-312.pyc
index 0ce5a118..591ea1b8 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachinedict.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachinedict.cpython-312.pyc
index 2dc13c4f..ddc518dd 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachinedict.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachinedict.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/cp949prober.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/cp949prober.cpython-312.pyc
index e24b811b..abcbec51 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/cp949prober.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/cp949prober.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/enums.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/enums.cpython-312.pyc
index a37e1478..fdabf5bd 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/enums.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/enums.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/escprober.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/escprober.cpython-312.pyc
index 75cf25a5..db679a61 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/escprober.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/escprober.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/escsm.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/escsm.cpython-312.pyc
index 92dc1d78..b52d010f 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/escsm.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/escsm.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/eucjpprober.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/eucjpprober.cpython-312.pyc
index c893cc11..e4942ee6 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/eucjpprober.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/eucjpprober.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/euckrfreq.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/euckrfreq.cpython-312.pyc
index fdc487a8..d2d1f80a 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/euckrfreq.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/euckrfreq.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/euckrprober.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/euckrprober.cpython-312.pyc
index d16e79b6..b39f0dc4 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/euckrprober.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/euckrprober.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/euctwfreq.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/euctwfreq.cpython-312.pyc
index 86704d87..3bbc18b7 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/euctwfreq.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/euctwfreq.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/euctwprober.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/euctwprober.cpython-312.pyc
index b53f6f72..879bf753 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/euctwprober.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/euctwprober.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/gb2312freq.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/gb2312freq.cpython-312.pyc
index 046524a7..cd08ea41 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/gb2312freq.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/gb2312freq.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/gb2312prober.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/gb2312prober.cpython-312.pyc
index 91cae7b5..5c9e3c79 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/gb2312prober.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/gb2312prober.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/hebrewprober.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/hebrewprober.cpython-312.pyc
index 2c758c3e..c4f78da2 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/hebrewprober.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/hebrewprober.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/jisfreq.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/jisfreq.cpython-312.pyc
index 17881b6d..e8616838 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/jisfreq.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/jisfreq.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/johabfreq.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/johabfreq.cpython-312.pyc
index ad7b6dea..796a8d73 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/johabfreq.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/johabfreq.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/johabprober.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/johabprober.cpython-312.pyc
index fec4e5e0..a42b208b 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/johabprober.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/johabprober.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/jpcntx.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/jpcntx.cpython-312.pyc
index 4a819880..2b85dd93 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/jpcntx.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/jpcntx.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-312.pyc
index 04b3d128..b364acb1 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-312.pyc
index 76e61b01..9148238c 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-312.pyc
index 2987ddb8..ffe520b6 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langrussianmodel.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langrussianmodel.cpython-312.pyc
index 7916ea11..753ecd1d 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langrussianmodel.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langrussianmodel.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langthaimodel.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langthaimodel.cpython-312.pyc
index 9da30a28..54c133ab 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langthaimodel.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langthaimodel.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-312.pyc
index fabb6282..e69620d0 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/latin1prober.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/latin1prober.cpython-312.pyc
index 3a733a83..7e540bd7 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/latin1prober.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/latin1prober.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/macromanprober.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/macromanprober.cpython-312.pyc
index 6ea0bd7a..18443ff7 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/macromanprober.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/macromanprober.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-312.pyc
index 66417240..49310c55 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-312.pyc
index 3c2dd662..62604084 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/mbcssm.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/mbcssm.cpython-312.pyc
index 78f98717..28d7c53c 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/mbcssm.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/mbcssm.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/resultdict.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/resultdict.cpython-312.pyc
index d5790a40..1650747b 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/resultdict.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/resultdict.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-312.pyc
index e8e7da13..c18dea9a 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-312.pyc
index 13fe3854..084cbe34 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/sjisprober.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/sjisprober.cpython-312.pyc
index c0517346..ef794c07 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/sjisprober.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/sjisprober.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/universaldetector.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/universaldetector.cpython-312.pyc
index d27e487e..a059c49e 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/universaldetector.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/universaldetector.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/utf1632prober.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/utf1632prober.cpython-312.pyc
index 3b375047..96e81d83 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/utf1632prober.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/utf1632prober.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/utf8prober.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/utf8prober.cpython-312.pyc
index 8f8c45ca..0d190b1d 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/utf8prober.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/utf8prober.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/version.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/version.cpython-312.pyc
index 57ee74b6..0eac4622 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/version.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/version.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/__init__.cpython-312.pyc
index 2bbc6440..0428877e 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/compat.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/compat.cpython-312.pyc
index 4942b8f9..db2557a1 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/compat.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/compat.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/resources.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/resources.cpython-312.pyc
index fb11a47f..b341d829 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/resources.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/resources.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/scripts.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/scripts.cpython-312.pyc
index f48d9298..12f86120 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/scripts.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/scripts.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/util.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/util.cpython-312.pyc
index cd3bf9df..8fbfbdc2 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/util.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/util.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/idna/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/idna/__pycache__/__init__.cpython-312.pyc
index fac1f9e7..ed35ca81 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/idna/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/idna/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/idna/__pycache__/core.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/idna/__pycache__/core.cpython-312.pyc
index 414c0435..6ed413fe 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/idna/__pycache__/core.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/idna/__pycache__/core.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/idna/__pycache__/idnadata.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/idna/__pycache__/idnadata.cpython-312.pyc
index 1f6b15c1..8679d8a0 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/idna/__pycache__/idnadata.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/idna/__pycache__/idnadata.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/idna/__pycache__/intranges.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/idna/__pycache__/intranges.cpython-312.pyc
index 52d1e179..90277b30 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/idna/__pycache__/intranges.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/idna/__pycache__/intranges.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/idna/__pycache__/package_data.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/idna/__pycache__/package_data.cpython-312.pyc
index 5983873e..a2383dad 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/idna/__pycache__/package_data.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/idna/__pycache__/package_data.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/msgpack/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/msgpack/__pycache__/__init__.cpython-312.pyc
index 7df01261..6c28f73b 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/msgpack/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/msgpack/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/msgpack/__pycache__/exceptions.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/msgpack/__pycache__/exceptions.cpython-312.pyc
index 7c663142..13ce9deb 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/msgpack/__pycache__/exceptions.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/msgpack/__pycache__/exceptions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/msgpack/__pycache__/ext.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/msgpack/__pycache__/ext.cpython-312.pyc
index 59e0c476..c06f8392 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/msgpack/__pycache__/ext.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/msgpack/__pycache__/ext.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/msgpack/__pycache__/fallback.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/msgpack/__pycache__/fallback.cpython-312.pyc
index 2aa95cdf..38480a8c 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/msgpack/__pycache__/fallback.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/msgpack/__pycache__/fallback.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/__about__.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/__about__.cpython-312.pyc
index f0fa7193..13ade599 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/__about__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/__about__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/__init__.cpython-312.pyc
index 21117c31..8e89cc24 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/_manylinux.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/_manylinux.cpython-312.pyc
index 4a28938a..a5a190e0 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/_manylinux.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/_manylinux.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/_musllinux.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/_musllinux.cpython-312.pyc
index 2b1754a1..6047529d 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/_musllinux.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/_musllinux.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/_structures.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/_structures.cpython-312.pyc
index f3524b24..a0825c1e 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/_structures.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/_structures.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/markers.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/markers.cpython-312.pyc
index 40efded5..cf553f95 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/markers.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/markers.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/requirements.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/requirements.cpython-312.pyc
index bf56f14d..c83e7680 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/requirements.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/requirements.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/specifiers.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/specifiers.cpython-312.pyc
index 953275bd..4d25f812 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/specifiers.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/specifiers.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/tags.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/tags.cpython-312.pyc
index 15082962..28e01c97 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/tags.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/tags.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/utils.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/utils.cpython-312.pyc
index e37283f5..5a231d5a 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/utils.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/utils.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/version.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/version.cpython-312.pyc
index 7457256e..ab567930 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/version.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/version.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/pkg_resources/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/pkg_resources/__pycache__/__init__.cpython-312.pyc
index 7a1f37b8..a20d570f 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/pkg_resources/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/pkg_resources/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/__init__.cpython-312.pyc
index 41385f53..346a13a0 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/api.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/api.cpython-312.pyc
index 82633b6d..8550f9a8 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/api.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/api.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/version.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/version.cpython-312.pyc
index df6939f9..9e8c9479 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/version.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/version.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/windows.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/windows.cpython-312.pyc
index a379486b..804810ed 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/windows.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/windows.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/__init__.cpython-312.pyc
index 8198fd78..c290dc17 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/filter.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/filter.cpython-312.pyc
index 5ed50f7f..0e86ae85 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/filter.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/filter.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/lexer.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/lexer.cpython-312.pyc
index 00a362f8..256a28e9 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/lexer.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/lexer.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/modeline.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/modeline.cpython-312.pyc
index 0053fdd1..3498b31b 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/modeline.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/modeline.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/plugin.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/plugin.cpython-312.pyc
index a6ed523f..70d7f3a5 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/plugin.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/plugin.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/regexopt.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/regexopt.cpython-312.pyc
index 98e4dd50..6586ae90 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/regexopt.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/regexopt.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/style.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/style.cpython-312.pyc
index 55fc9240..18e60564 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/style.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/style.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/token.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/token.cpython-312.pyc
index a5990aca..75cd51b3 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/token.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/token.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/util.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/util.cpython-312.pyc
index 067816c3..e2196b61 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/util.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/util.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/pygments/filters/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/pygments/filters/__pycache__/__init__.cpython-312.pyc
index 067f41fb..875acd78 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/pygments/filters/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/pygments/filters/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/pygments/lexers/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/pygments/lexers/__pycache__/__init__.cpython-312.pyc
index 90c22cea..da626db5 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/pygments/lexers/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/pygments/lexers/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/pygments/lexers/__pycache__/_mapping.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/pygments/lexers/__pycache__/_mapping.cpython-312.pyc
index b4dee3e3..3726a00a 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/pygments/lexers/__pycache__/_mapping.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/pygments/lexers/__pycache__/_mapping.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/pygments/styles/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/pygments/styles/__pycache__/__init__.cpython-312.pyc
index eac17df1..edf55396 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/pygments/styles/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/pygments/styles/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/__init__.cpython-312.pyc
index 63b40751..46d3996a 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/actions.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/actions.cpython-312.pyc
index 83289e8a..c449925b 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/actions.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/actions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/common.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/common.cpython-312.pyc
index 8eb64312..ded4108f 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/common.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/common.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/core.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/core.cpython-312.pyc
index 99cfb4cf..275dbc3b 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/core.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/core.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/exceptions.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/exceptions.cpython-312.pyc
index f77b49c2..9943f1f5 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/exceptions.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/exceptions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/helpers.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/helpers.cpython-312.pyc
index 2b0f1aba..f5c75845 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/helpers.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/helpers.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/results.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/results.cpython-312.pyc
index 4cfb4694..fc851c00 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/results.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/results.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/testing.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/testing.cpython-312.pyc
index ff64f9a8..d7b81f59 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/testing.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/testing.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/unicode.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/unicode.cpython-312.pyc
index 904b2ab1..e00d401f 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/unicode.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/unicode.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/util.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/util.cpython-312.pyc
index 5ac93d96..7590e796 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/util.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/util.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/pyproject_hooks/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/pyproject_hooks/__pycache__/__init__.cpython-312.pyc
index 4d3d95c6..f327d1b8 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/pyproject_hooks/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/pyproject_hooks/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/pyproject_hooks/__pycache__/_impl.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/pyproject_hooks/__pycache__/_impl.cpython-312.pyc
index 11576a1a..8474a4b3 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/pyproject_hooks/__pycache__/_impl.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/pyproject_hooks/__pycache__/_impl.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/pyproject_hooks/_in_process/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/pyproject_hooks/_in_process/__pycache__/__init__.cpython-312.pyc
index e0368b6a..c2c509ea 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/pyproject_hooks/_in_process/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/pyproject_hooks/_in_process/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/__init__.cpython-312.pyc
index 7bef8a5a..225dbe85 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/__version__.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/__version__.cpython-312.pyc
index e1765af6..7c339da7 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/__version__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/__version__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/_internal_utils.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/_internal_utils.cpython-312.pyc
index 447c72fd..18b82da7 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/_internal_utils.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/_internal_utils.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/adapters.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/adapters.cpython-312.pyc
index 764b1995..6f0c6773 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/adapters.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/adapters.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/api.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/api.cpython-312.pyc
index d605a378..b94e3225 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/api.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/api.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/auth.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/auth.cpython-312.pyc
index 90d231ec..7f342ae4 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/auth.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/auth.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/certs.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/certs.cpython-312.pyc
index 07436947..6a3ac934 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/certs.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/certs.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/compat.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/compat.cpython-312.pyc
index e3f145e6..9644e002 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/compat.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/compat.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/cookies.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/cookies.cpython-312.pyc
index 4625e775..e2f184b8 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/cookies.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/cookies.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/exceptions.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/exceptions.cpython-312.pyc
index 39b439c6..66c78bf1 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/exceptions.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/exceptions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/hooks.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/hooks.cpython-312.pyc
index 91009dd3..47ceb7a1 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/hooks.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/hooks.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/models.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/models.cpython-312.pyc
index 1fdf73a8..06d33d57 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/models.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/models.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/packages.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/packages.cpython-312.pyc
index 9a57304d..710fe043 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/packages.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/packages.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/sessions.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/sessions.cpython-312.pyc
index b19edf91..2dea436d 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/sessions.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/sessions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/status_codes.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/status_codes.cpython-312.pyc
index 47bfd2da..f282d47b 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/status_codes.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/status_codes.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/structures.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/structures.cpython-312.pyc
index 0d59b21b..0f6dfd3f 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/structures.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/structures.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/utils.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/utils.cpython-312.pyc
index 93ed0925..662319a3 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/utils.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/requests/__pycache__/utils.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/__init__.cpython-312.pyc
index 94809391..cbdd18cd 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/providers.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/providers.cpython-312.pyc
index 330b8c98..d004d8f3 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/providers.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/providers.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/reporters.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/reporters.cpython-312.pyc
index 1b81b1a9..116003eb 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/reporters.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/reporters.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/resolvers.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/resolvers.cpython-312.pyc
index 4da81279..1cdc0cda 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/resolvers.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/resolvers.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/structs.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/structs.cpython-312.pyc
index 39dbd446..d923fec2 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/structs.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/structs.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/resolvelib/compat/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/resolvelib/compat/__pycache__/__init__.cpython-312.pyc
index 1ce74bd5..ef6efb84 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/resolvelib/compat/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/resolvelib/compat/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/resolvelib/compat/__pycache__/collections_abc.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/resolvelib/compat/__pycache__/collections_abc.cpython-312.pyc
index 59f4fdb8..ea5e99f2 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/resolvelib/compat/__pycache__/collections_abc.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/resolvelib/compat/__pycache__/collections_abc.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/__init__.cpython-312.pyc
index e8cebc0b..9cdcabb8 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_cell_widths.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_cell_widths.cpython-312.pyc
index ea3a2813..7ddaebba 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_cell_widths.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_cell_widths.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_emoji_codes.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_emoji_codes.cpython-312.pyc
index f28a1266..a8a716ec 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_emoji_codes.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_emoji_codes.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_emoji_replace.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_emoji_replace.cpython-312.pyc
index 22a8f1a5..e7ddbce7 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_emoji_replace.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_emoji_replace.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_export_format.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_export_format.cpython-312.pyc
index d72463e2..26465e07 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_export_format.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_export_format.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_extension.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_extension.cpython-312.pyc
index 11d381a1..a8385e61 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_extension.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_extension.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_fileno.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_fileno.cpython-312.pyc
index b597d7d3..a4816278 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_fileno.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_fileno.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_log_render.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_log_render.cpython-312.pyc
index d7ed20cd..660ba9ab 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_log_render.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_log_render.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_loop.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_loop.cpython-312.pyc
index b65ed52b..3bfa08ec 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_loop.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_loop.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_null_file.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_null_file.cpython-312.pyc
index 0661c4c9..7170a103 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_null_file.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_null_file.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_palettes.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_palettes.cpython-312.pyc
index 2894abc1..f335e8be 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_palettes.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_palettes.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_pick.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_pick.cpython-312.pyc
index ccf0be6f..7749f0df 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_pick.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_pick.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_ratio.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_ratio.cpython-312.pyc
index 3b4ba937..6414958e 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_ratio.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_ratio.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_spinners.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_spinners.cpython-312.pyc
index db8971b9..e069a015 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_spinners.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_spinners.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_win32_console.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_win32_console.cpython-312.pyc
index 953dcbcf..fdb2ad75 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_win32_console.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_win32_console.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_windows.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_windows.cpython-312.pyc
index de7486ff..051488e3 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_windows.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_windows.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_wrap.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_wrap.cpython-312.pyc
index edc9e8f8..30542381 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_wrap.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_wrap.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/abc.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/abc.cpython-312.pyc
index 765a25e4..de963460 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/abc.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/abc.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/align.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/align.cpython-312.pyc
index cf8ddca2..862e352b 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/align.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/align.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/ansi.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/ansi.cpython-312.pyc
index 47daac77..29c7fd59 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/ansi.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/ansi.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/box.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/box.cpython-312.pyc
index 71a93ed4..27e8ba87 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/box.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/box.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/cells.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/cells.cpython-312.pyc
index 875a71a7..6ac56aae 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/cells.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/cells.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/color.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/color.cpython-312.pyc
index 8f5c63b5..9a911b15 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/color.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/color.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/color_triplet.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/color_triplet.cpython-312.pyc
index 9edbafc9..7a1e6b3c 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/color_triplet.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/color_triplet.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/columns.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/columns.cpython-312.pyc
index 2a3d6ece..4fe2eae2 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/columns.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/columns.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/console.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/console.cpython-312.pyc
index cf133d82..d7e7beab 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/console.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/console.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/constrain.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/constrain.cpython-312.pyc
index 228ff3d6..3435603b 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/constrain.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/constrain.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/containers.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/containers.cpython-312.pyc
index 42f84ea1..d896819b 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/containers.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/containers.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/control.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/control.cpython-312.pyc
index 4b4e30cd..91bcd917 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/control.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/control.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/default_styles.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/default_styles.cpython-312.pyc
index 06b25d8c..befc4a5c 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/default_styles.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/default_styles.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/emoji.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/emoji.cpython-312.pyc
index 1ee9b2dc..f03190d4 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/emoji.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/emoji.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/errors.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/errors.cpython-312.pyc
index f181643d..338a2d53 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/errors.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/errors.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/file_proxy.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/file_proxy.cpython-312.pyc
index c7e45f91..d68bd246 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/file_proxy.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/file_proxy.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/filesize.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/filesize.cpython-312.pyc
index d33b63bd..c8b1f53f 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/filesize.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/filesize.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/highlighter.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/highlighter.cpython-312.pyc
index 8a51f085..2d3912d9 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/highlighter.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/highlighter.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/jupyter.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/jupyter.cpython-312.pyc
index 9d7792d5..e3c2fedd 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/jupyter.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/jupyter.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/live.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/live.cpython-312.pyc
index 06de1008..3e471672 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/live.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/live.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/live_render.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/live_render.cpython-312.pyc
index 4685ec6d..3409a656 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/live_render.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/live_render.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/logging.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/logging.cpython-312.pyc
index 59fdfa2c..cc94450e 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/logging.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/logging.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/markup.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/markup.cpython-312.pyc
index e9c413bb..0cf6cc61 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/markup.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/markup.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/measure.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/measure.cpython-312.pyc
index 3d77a1b0..4502cc71 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/measure.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/measure.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/padding.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/padding.cpython-312.pyc
index 05e78636..96f2d060 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/padding.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/padding.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/pager.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/pager.cpython-312.pyc
index 57f4d730..c2ddd206 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/pager.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/pager.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/palette.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/palette.cpython-312.pyc
index 8a0d86b8..f103c895 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/palette.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/palette.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/panel.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/panel.cpython-312.pyc
index 829892e4..4302c0a9 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/panel.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/panel.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/pretty.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/pretty.cpython-312.pyc
index 0d4d75a6..fee83623 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/pretty.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/pretty.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/progress.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/progress.cpython-312.pyc
index c6048ac3..c5de1054 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/progress.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/progress.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/progress_bar.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/progress_bar.cpython-312.pyc
index 75df968c..93343326 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/progress_bar.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/progress_bar.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/protocol.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/protocol.cpython-312.pyc
index ad0d4f18..9ef168dd 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/protocol.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/protocol.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/region.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/region.cpython-312.pyc
index bc23d20c..b652ba2d 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/region.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/region.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/repr.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/repr.cpython-312.pyc
index d74f7d1a..6c4cfb68 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/repr.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/repr.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/scope.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/scope.cpython-312.pyc
index e0e2ed92..391b751a 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/scope.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/scope.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/screen.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/screen.cpython-312.pyc
index c1acdca7..a030386c 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/screen.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/screen.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/segment.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/segment.cpython-312.pyc
index 015ca5f1..77276716 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/segment.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/segment.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/spinner.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/spinner.cpython-312.pyc
index 51857cc9..a793d5e2 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/spinner.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/spinner.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/style.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/style.cpython-312.pyc
index 984ee64f..c6af8c36 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/style.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/style.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/styled.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/styled.cpython-312.pyc
index 52ebaed0..19e5b1af 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/styled.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/styled.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/syntax.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/syntax.cpython-312.pyc
index 3f26c47d..f60eb79f 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/syntax.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/syntax.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/table.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/table.cpython-312.pyc
index 8909955d..5920fc29 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/table.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/table.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/terminal_theme.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/terminal_theme.cpython-312.pyc
index cabfb9fa..0ab68ef4 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/terminal_theme.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/terminal_theme.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/text.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/text.cpython-312.pyc
index 24adf1a1..f41386a0 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/text.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/text.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/theme.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/theme.cpython-312.pyc
index a63465a3..2f096c61 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/theme.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/theme.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/themes.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/themes.cpython-312.pyc
index fec19f32..f0e8c184 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/themes.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/themes.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/traceback.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/traceback.cpython-312.pyc
index 8c9bb2c9..8981318c 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/traceback.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/rich/__pycache__/traceback.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/__init__.cpython-312.pyc
index a1d4b6a2..2df0bc4a 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/_asyncio.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/_asyncio.cpython-312.pyc
index 91617b10..6f1f4218 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/_asyncio.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/_asyncio.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/_utils.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/_utils.cpython-312.pyc
index 082833be..b96b75ed 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/_utils.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/_utils.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/after.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/after.cpython-312.pyc
index bec05142..61daca72 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/after.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/after.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/before.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/before.cpython-312.pyc
index e5e77fa8..93ba5eac 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/before.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/before.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/before_sleep.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/before_sleep.cpython-312.pyc
index 4fec6e9a..a2d41581 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/before_sleep.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/before_sleep.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/nap.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/nap.cpython-312.pyc
index d2c0264a..2d7aef24 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/nap.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/nap.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/retry.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/retry.cpython-312.pyc
index 4ce517ca..84d8b226 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/retry.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/retry.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/stop.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/stop.cpython-312.pyc
index 1ad48ecb..cbc2d44b 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/stop.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/stop.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/wait.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/wait.cpython-312.pyc
index af610544..d78f402d 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/wait.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/wait.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/tomli/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/tomli/__pycache__/__init__.cpython-312.pyc
index da10f9e9..6c9e4260 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/tomli/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/tomli/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/tomli/__pycache__/_parser.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/tomli/__pycache__/_parser.cpython-312.pyc
index 5bd14221..e8d7af4a 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/tomli/__pycache__/_parser.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/tomli/__pycache__/_parser.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/tomli/__pycache__/_re.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/tomli/__pycache__/_re.cpython-312.pyc
index 6fede51b..2545bdd9 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/tomli/__pycache__/_re.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/tomli/__pycache__/_re.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/tomli/__pycache__/_types.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/tomli/__pycache__/_types.cpython-312.pyc
index 30625709..9d28e419 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/tomli/__pycache__/_types.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/tomli/__pycache__/_types.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/__init__.cpython-312.pyc
index 93af891e..8f41d195 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/_collections.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/_collections.cpython-312.pyc
index bcdae9cd..3ec63465 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/_collections.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/_collections.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/_version.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/_version.cpython-312.pyc
index f3365a51..f685d279 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/_version.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/_version.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/connection.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/connection.cpython-312.pyc
index 2f395b35..2fe7cbb9 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/connection.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/connection.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/connectionpool.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/connectionpool.cpython-312.pyc
index ba963a35..afd86166 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/connectionpool.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/connectionpool.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/exceptions.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/exceptions.cpython-312.pyc
index e247d4a3..329138f5 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/exceptions.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/exceptions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/fields.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/fields.cpython-312.pyc
index a7cfce79..76c410bd 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/fields.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/fields.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/filepost.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/filepost.cpython-312.pyc
index 6d8ea601..70d20dbf 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/filepost.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/filepost.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/poolmanager.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/poolmanager.cpython-312.pyc
index acfccda4..aba900dd 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/poolmanager.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/poolmanager.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/request.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/request.cpython-312.pyc
index 5b6eb6ed..2e594410 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/request.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/request.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/response.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/response.cpython-312.pyc
index 9dda6be7..d14274e1 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/response.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-312.pyc
index 0bc67ff1..94262649 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/_appengine_environ.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/_appengine_environ.cpython-312.pyc
index 8fdc60f8..ab8db992 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/_appengine_environ.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/_appengine_environ.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-312.pyc
index eb525373..3892026e 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-312.pyc
index b7f2b5f7..3ac063cf 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/urllib3/packages/__pycache__/six.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/urllib3/packages/__pycache__/six.cpython-312.pyc
index b439a1fb..56fab104 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/urllib3/packages/__pycache__/six.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/urllib3/packages/__pycache__/six.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/__init__.cpython-312.pyc
index e9e25478..f4566259 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/connection.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/connection.cpython-312.pyc
index fd484857..7b51edbb 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/connection.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/connection.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/proxy.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/proxy.cpython-312.pyc
index d075c782..ec09782f 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/proxy.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/proxy.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/queue.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/queue.cpython-312.pyc
index b4aae558..a341b999 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/queue.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/queue.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/request.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/request.cpython-312.pyc
index 32eae843..64ce982e 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/request.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/request.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/response.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/response.cpython-312.pyc
index a165ebe4..c68462aa 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/response.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/retry.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/retry.cpython-312.pyc
index 6d4bc4bc..2ffc7d17 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/retry.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/retry.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-312.pyc
index b1f4b7ef..cc743104 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_match_hostname.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_match_hostname.cpython-312.pyc
index f4793e59..27d7fd28 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_match_hostname.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_match_hostname.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/ssltransport.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/ssltransport.cpython-312.pyc
index a3d5897c..55bd3a6c 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/ssltransport.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/ssltransport.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/timeout.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/timeout.cpython-312.pyc
index bd87c6a0..194ce71a 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/timeout.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/timeout.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/url.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/url.cpython-312.pyc
index 243804b4..38928a41 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/url.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/url.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/wait.cpython-312.pyc b/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/wait.cpython-312.pyc
index 0b8a5a0c..f6f0698d 100644
Binary files a/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/wait.cpython-312.pyc and b/venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/wait.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/propcache/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/propcache/__pycache__/__init__.cpython-312.pyc
index 0a3224e4..9a804495 100644
Binary files a/venv/Lib/site-packages/propcache/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/propcache/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/propcache/__pycache__/_helpers.cpython-312.pyc b/venv/Lib/site-packages/propcache/__pycache__/_helpers.cpython-312.pyc
index 7009d40e..adeab1ae 100644
Binary files a/venv/Lib/site-packages/propcache/__pycache__/_helpers.cpython-312.pyc and b/venv/Lib/site-packages/propcache/__pycache__/_helpers.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/propcache/__pycache__/api.cpython-312.pyc b/venv/Lib/site-packages/propcache/__pycache__/api.cpython-312.pyc
index 65aad137..cfbaaa9a 100644
Binary files a/venv/Lib/site-packages/propcache/__pycache__/api.cpython-312.pyc and b/venv/Lib/site-packages/propcache/__pycache__/api.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/psutil/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/psutil/__pycache__/__init__.cpython-312.pyc
index 7b3a8564..c4b49992 100644
Binary files a/venv/Lib/site-packages/psutil/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/psutil/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/psutil/__pycache__/_common.cpython-312.pyc b/venv/Lib/site-packages/psutil/__pycache__/_common.cpython-312.pyc
index d8b09eda..35a07e63 100644
Binary files a/venv/Lib/site-packages/psutil/__pycache__/_common.cpython-312.pyc and b/venv/Lib/site-packages/psutil/__pycache__/_common.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/psutil/__pycache__/_pswindows.cpython-312.pyc b/venv/Lib/site-packages/psutil/__pycache__/_pswindows.cpython-312.pyc
index 058555a2..4285edc0 100644
Binary files a/venv/Lib/site-packages/psutil/__pycache__/_pswindows.cpython-312.pyc and b/venv/Lib/site-packages/psutil/__pycache__/_pswindows.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pydantic/__pycache__/__init__.cpython-312.pyc
index 9ce57b55..a3b953ff 100644
Binary files a/venv/Lib/site-packages/pydantic/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/__pycache__/_migration.cpython-312.pyc b/venv/Lib/site-packages/pydantic/__pycache__/_migration.cpython-312.pyc
index 856fba43..e2cc4584 100644
Binary files a/venv/Lib/site-packages/pydantic/__pycache__/_migration.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/__pycache__/_migration.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/__pycache__/aliases.cpython-312.pyc b/venv/Lib/site-packages/pydantic/__pycache__/aliases.cpython-312.pyc
index 243c3135..9ffaf82a 100644
Binary files a/venv/Lib/site-packages/pydantic/__pycache__/aliases.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/__pycache__/aliases.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/__pycache__/annotated_handlers.cpython-312.pyc b/venv/Lib/site-packages/pydantic/__pycache__/annotated_handlers.cpython-312.pyc
index 41e77389..003e9051 100644
Binary files a/venv/Lib/site-packages/pydantic/__pycache__/annotated_handlers.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/__pycache__/annotated_handlers.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/__pycache__/color.cpython-312.pyc b/venv/Lib/site-packages/pydantic/__pycache__/color.cpython-312.pyc
index 218c346a..785e1119 100644
Binary files a/venv/Lib/site-packages/pydantic/__pycache__/color.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/__pycache__/color.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/__pycache__/config.cpython-312.pyc b/venv/Lib/site-packages/pydantic/__pycache__/config.cpython-312.pyc
index ae3ef31f..784c17f4 100644
Binary files a/venv/Lib/site-packages/pydantic/__pycache__/config.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/__pycache__/config.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/__pycache__/errors.cpython-312.pyc b/venv/Lib/site-packages/pydantic/__pycache__/errors.cpython-312.pyc
index 897ef888..53ecf96c 100644
Binary files a/venv/Lib/site-packages/pydantic/__pycache__/errors.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/__pycache__/errors.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/__pycache__/fields.cpython-312.pyc b/venv/Lib/site-packages/pydantic/__pycache__/fields.cpython-312.pyc
index e06466cf..fe6cce4f 100644
Binary files a/venv/Lib/site-packages/pydantic/__pycache__/fields.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/__pycache__/fields.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/__pycache__/functional_validators.cpython-312.pyc b/venv/Lib/site-packages/pydantic/__pycache__/functional_validators.cpython-312.pyc
index 271ead41..492c28ea 100644
Binary files a/venv/Lib/site-packages/pydantic/__pycache__/functional_validators.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/__pycache__/functional_validators.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/__pycache__/json_schema.cpython-312.pyc b/venv/Lib/site-packages/pydantic/__pycache__/json_schema.cpython-312.pyc
index 0d9dc2a0..b5c8ef9d 100644
Binary files a/venv/Lib/site-packages/pydantic/__pycache__/json_schema.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/__pycache__/json_schema.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/__pycache__/main.cpython-312.pyc b/venv/Lib/site-packages/pydantic/__pycache__/main.cpython-312.pyc
index 5f793465..df3b0bc5 100644
Binary files a/venv/Lib/site-packages/pydantic/__pycache__/main.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/__pycache__/main.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/__pycache__/networks.cpython-312.pyc b/venv/Lib/site-packages/pydantic/__pycache__/networks.cpython-312.pyc
index 301248de..76e8cd53 100644
Binary files a/venv/Lib/site-packages/pydantic/__pycache__/networks.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/__pycache__/networks.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/__pycache__/type_adapter.cpython-312.pyc b/venv/Lib/site-packages/pydantic/__pycache__/type_adapter.cpython-312.pyc
index 182f0a63..dffcdda2 100644
Binary files a/venv/Lib/site-packages/pydantic/__pycache__/type_adapter.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/__pycache__/type_adapter.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/__pycache__/types.cpython-312.pyc b/venv/Lib/site-packages/pydantic/__pycache__/types.cpython-312.pyc
index 19e09cdc..731e8d90 100644
Binary files a/venv/Lib/site-packages/pydantic/__pycache__/types.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/__pycache__/types.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/__pycache__/version.cpython-312.pyc b/venv/Lib/site-packages/pydantic/__pycache__/version.cpython-312.pyc
index 8b2a087e..04d50b48 100644
Binary files a/venv/Lib/site-packages/pydantic/__pycache__/version.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/__pycache__/version.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/__pycache__/warnings.cpython-312.pyc b/venv/Lib/site-packages/pydantic/__pycache__/warnings.cpython-312.pyc
index bf868df5..1621d240 100644
Binary files a/venv/Lib/site-packages/pydantic/__pycache__/warnings.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/__pycache__/warnings.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/_internal/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pydantic/_internal/__pycache__/__init__.cpython-312.pyc
index 5535d22f..768b308d 100644
Binary files a/venv/Lib/site-packages/pydantic/_internal/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/_internal/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_config.cpython-312.pyc b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_config.cpython-312.pyc
index 75146acd..edb03e2f 100644
Binary files a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_config.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_config.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_core_metadata.cpython-312.pyc b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_core_metadata.cpython-312.pyc
index 5b29545f..bfdd2ed1 100644
Binary files a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_core_metadata.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_core_metadata.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_core_utils.cpython-312.pyc b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_core_utils.cpython-312.pyc
index ecf45100..d05bf21e 100644
Binary files a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_core_utils.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_core_utils.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_decorators.cpython-312.pyc b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_decorators.cpython-312.pyc
index 9046da8a..13513e02 100644
Binary files a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_decorators.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_decorators.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_discriminated_union.cpython-312.pyc b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_discriminated_union.cpython-312.pyc
index dc6fd8af..4f285061 100644
Binary files a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_discriminated_union.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_discriminated_union.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_docs_extraction.cpython-312.pyc b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_docs_extraction.cpython-312.pyc
index bbd704a1..28d6af81 100644
Binary files a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_docs_extraction.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_docs_extraction.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_fields.cpython-312.pyc b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_fields.cpython-312.pyc
index 57dfeb3f..15e13e30 100644
Binary files a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_fields.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_fields.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_forward_ref.cpython-312.pyc b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_forward_ref.cpython-312.pyc
index a7615355..2d8d9017 100644
Binary files a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_forward_ref.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_forward_ref.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_generate_schema.cpython-312.pyc b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_generate_schema.cpython-312.pyc
index c44e8bdc..6eaf2904 100644
Binary files a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_generate_schema.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_generate_schema.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_generics.cpython-312.pyc b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_generics.cpython-312.pyc
index 1b80872b..5ad18f53 100644
Binary files a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_generics.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_generics.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_import_utils.cpython-312.pyc b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_import_utils.cpython-312.pyc
index 091482d9..d691d634 100644
Binary files a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_import_utils.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_import_utils.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_internal_dataclass.cpython-312.pyc b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_internal_dataclass.cpython-312.pyc
index 2f56fc20..8161e75e 100644
Binary files a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_internal_dataclass.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_internal_dataclass.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_known_annotated_metadata.cpython-312.pyc b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_known_annotated_metadata.cpython-312.pyc
index 192ade22..6819e94a 100644
Binary files a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_known_annotated_metadata.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_known_annotated_metadata.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_mock_val_ser.cpython-312.pyc b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_mock_val_ser.cpython-312.pyc
index df068429..678f825d 100644
Binary files a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_mock_val_ser.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_mock_val_ser.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_model_construction.cpython-312.pyc b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_model_construction.cpython-312.pyc
index 63152d85..a37475c0 100644
Binary files a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_model_construction.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_model_construction.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_namespace_utils.cpython-312.pyc b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_namespace_utils.cpython-312.pyc
index 68649c4d..c641be8c 100644
Binary files a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_namespace_utils.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_namespace_utils.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_repr.cpython-312.pyc b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_repr.cpython-312.pyc
index e15c5dac..52578662 100644
Binary files a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_repr.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_repr.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_schema_gather.cpython-312.pyc b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_schema_gather.cpython-312.pyc
index 441fb6f0..fa4128c9 100644
Binary files a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_schema_gather.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_schema_gather.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_schema_generation_shared.cpython-312.pyc b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_schema_generation_shared.cpython-312.pyc
index 9aad74a8..6124353b 100644
Binary files a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_schema_generation_shared.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_schema_generation_shared.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_serializers.cpython-312.pyc b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_serializers.cpython-312.pyc
index 9454fdd9..25b8ec1a 100644
Binary files a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_serializers.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_serializers.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_signature.cpython-312.pyc b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_signature.cpython-312.pyc
index 6bcbdd5c..41ca88ab 100644
Binary files a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_signature.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_signature.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_typing_extra.cpython-312.pyc b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_typing_extra.cpython-312.pyc
index 6073ecda..da7db70f 100644
Binary files a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_typing_extra.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_typing_extra.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_utils.cpython-312.pyc b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_utils.cpython-312.pyc
index d61cb418..b817891c 100644
Binary files a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_utils.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_utils.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_validators.cpython-312.pyc b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_validators.cpython-312.pyc
index c51fb6ca..ead553b8 100644
Binary files a/venv/Lib/site-packages/pydantic/_internal/__pycache__/_validators.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/_internal/__pycache__/_validators.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/plugin/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pydantic/plugin/__pycache__/__init__.cpython-312.pyc
index 9caff606..a177608f 100644
Binary files a/venv/Lib/site-packages/pydantic/plugin/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/plugin/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/plugin/__pycache__/_loader.cpython-312.pyc b/venv/Lib/site-packages/pydantic/plugin/__pycache__/_loader.cpython-312.pyc
index 26c4527c..7e5e9ea3 100644
Binary files a/venv/Lib/site-packages/pydantic/plugin/__pycache__/_loader.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/plugin/__pycache__/_loader.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/plugin/__pycache__/_schema_validator.cpython-312.pyc b/venv/Lib/site-packages/pydantic/plugin/__pycache__/_schema_validator.cpython-312.pyc
index c321f9ce..5480ef9a 100644
Binary files a/venv/Lib/site-packages/pydantic/plugin/__pycache__/_schema_validator.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/plugin/__pycache__/_schema_validator.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/v1/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pydantic/v1/__pycache__/__init__.cpython-312.pyc
index 1039d7f0..a23fd38e 100644
Binary files a/venv/Lib/site-packages/pydantic/v1/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/v1/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/v1/__pycache__/annotated_types.cpython-312.pyc b/venv/Lib/site-packages/pydantic/v1/__pycache__/annotated_types.cpython-312.pyc
index d2254939..539a077c 100644
Binary files a/venv/Lib/site-packages/pydantic/v1/__pycache__/annotated_types.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/v1/__pycache__/annotated_types.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/v1/__pycache__/class_validators.cpython-312.pyc b/venv/Lib/site-packages/pydantic/v1/__pycache__/class_validators.cpython-312.pyc
index 8dca342a..b57ef862 100644
Binary files a/venv/Lib/site-packages/pydantic/v1/__pycache__/class_validators.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/v1/__pycache__/class_validators.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/v1/__pycache__/color.cpython-312.pyc b/venv/Lib/site-packages/pydantic/v1/__pycache__/color.cpython-312.pyc
index 8afa2579..455290a2 100644
Binary files a/venv/Lib/site-packages/pydantic/v1/__pycache__/color.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/v1/__pycache__/color.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/v1/__pycache__/config.cpython-312.pyc b/venv/Lib/site-packages/pydantic/v1/__pycache__/config.cpython-312.pyc
index 58475973..3a0d0bac 100644
Binary files a/venv/Lib/site-packages/pydantic/v1/__pycache__/config.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/v1/__pycache__/config.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/v1/__pycache__/dataclasses.cpython-312.pyc b/venv/Lib/site-packages/pydantic/v1/__pycache__/dataclasses.cpython-312.pyc
index 0807aa96..bafdd998 100644
Binary files a/venv/Lib/site-packages/pydantic/v1/__pycache__/dataclasses.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/v1/__pycache__/dataclasses.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/v1/__pycache__/datetime_parse.cpython-312.pyc b/venv/Lib/site-packages/pydantic/v1/__pycache__/datetime_parse.cpython-312.pyc
index fbeb377d..118b15fb 100644
Binary files a/venv/Lib/site-packages/pydantic/v1/__pycache__/datetime_parse.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/v1/__pycache__/datetime_parse.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/v1/__pycache__/decorator.cpython-312.pyc b/venv/Lib/site-packages/pydantic/v1/__pycache__/decorator.cpython-312.pyc
index 965ee3e3..0c411edf 100644
Binary files a/venv/Lib/site-packages/pydantic/v1/__pycache__/decorator.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/v1/__pycache__/decorator.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/v1/__pycache__/env_settings.cpython-312.pyc b/venv/Lib/site-packages/pydantic/v1/__pycache__/env_settings.cpython-312.pyc
index 8a0b8044..2c909ca0 100644
Binary files a/venv/Lib/site-packages/pydantic/v1/__pycache__/env_settings.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/v1/__pycache__/env_settings.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/v1/__pycache__/error_wrappers.cpython-312.pyc b/venv/Lib/site-packages/pydantic/v1/__pycache__/error_wrappers.cpython-312.pyc
index c327c738..a0e129cf 100644
Binary files a/venv/Lib/site-packages/pydantic/v1/__pycache__/error_wrappers.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/v1/__pycache__/error_wrappers.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/v1/__pycache__/errors.cpython-312.pyc b/venv/Lib/site-packages/pydantic/v1/__pycache__/errors.cpython-312.pyc
index 480b857a..bb8f876f 100644
Binary files a/venv/Lib/site-packages/pydantic/v1/__pycache__/errors.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/v1/__pycache__/errors.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/v1/__pycache__/fields.cpython-312.pyc b/venv/Lib/site-packages/pydantic/v1/__pycache__/fields.cpython-312.pyc
index 74201142..f1b20ff0 100644
Binary files a/venv/Lib/site-packages/pydantic/v1/__pycache__/fields.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/v1/__pycache__/fields.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/v1/__pycache__/json.cpython-312.pyc b/venv/Lib/site-packages/pydantic/v1/__pycache__/json.cpython-312.pyc
index 65e0aa16..8013e273 100644
Binary files a/venv/Lib/site-packages/pydantic/v1/__pycache__/json.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/v1/__pycache__/json.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/v1/__pycache__/main.cpython-312.pyc b/venv/Lib/site-packages/pydantic/v1/__pycache__/main.cpython-312.pyc
index fe06031c..2c0f7891 100644
Binary files a/venv/Lib/site-packages/pydantic/v1/__pycache__/main.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/v1/__pycache__/main.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/v1/__pycache__/networks.cpython-312.pyc b/venv/Lib/site-packages/pydantic/v1/__pycache__/networks.cpython-312.pyc
index ad01acc3..9a07f105 100644
Binary files a/venv/Lib/site-packages/pydantic/v1/__pycache__/networks.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/v1/__pycache__/networks.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/v1/__pycache__/parse.cpython-312.pyc b/venv/Lib/site-packages/pydantic/v1/__pycache__/parse.cpython-312.pyc
index b4b1d494..f1852130 100644
Binary files a/venv/Lib/site-packages/pydantic/v1/__pycache__/parse.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/v1/__pycache__/parse.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/v1/__pycache__/schema.cpython-312.pyc b/venv/Lib/site-packages/pydantic/v1/__pycache__/schema.cpython-312.pyc
index cf0342fc..a3ba9987 100644
Binary files a/venv/Lib/site-packages/pydantic/v1/__pycache__/schema.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/v1/__pycache__/schema.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/v1/__pycache__/tools.cpython-312.pyc b/venv/Lib/site-packages/pydantic/v1/__pycache__/tools.cpython-312.pyc
index e072cba3..c5b86d4b 100644
Binary files a/venv/Lib/site-packages/pydantic/v1/__pycache__/tools.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/v1/__pycache__/tools.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/v1/__pycache__/types.cpython-312.pyc b/venv/Lib/site-packages/pydantic/v1/__pycache__/types.cpython-312.pyc
index 88b48a63..59314259 100644
Binary files a/venv/Lib/site-packages/pydantic/v1/__pycache__/types.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/v1/__pycache__/types.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/v1/__pycache__/typing.cpython-312.pyc b/venv/Lib/site-packages/pydantic/v1/__pycache__/typing.cpython-312.pyc
index 1ee77a5b..56713392 100644
Binary files a/venv/Lib/site-packages/pydantic/v1/__pycache__/typing.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/v1/__pycache__/typing.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/v1/__pycache__/utils.cpython-312.pyc b/venv/Lib/site-packages/pydantic/v1/__pycache__/utils.cpython-312.pyc
index 5f0ae56b..8b6ce9ef 100644
Binary files a/venv/Lib/site-packages/pydantic/v1/__pycache__/utils.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/v1/__pycache__/utils.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/v1/__pycache__/validators.cpython-312.pyc b/venv/Lib/site-packages/pydantic/v1/__pycache__/validators.cpython-312.pyc
index dcc37200..f3cf3cc9 100644
Binary files a/venv/Lib/site-packages/pydantic/v1/__pycache__/validators.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/v1/__pycache__/validators.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic/v1/__pycache__/version.cpython-312.pyc b/venv/Lib/site-packages/pydantic/v1/__pycache__/version.cpython-312.pyc
index 6baf351d..0fa53f04 100644
Binary files a/venv/Lib/site-packages/pydantic/v1/__pycache__/version.cpython-312.pyc and b/venv/Lib/site-packages/pydantic/v1/__pycache__/version.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic_core/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pydantic_core/__pycache__/__init__.cpython-312.pyc
index 86a12996..41916df6 100644
Binary files a/venv/Lib/site-packages/pydantic_core/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pydantic_core/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pydantic_core/__pycache__/core_schema.cpython-312.pyc b/venv/Lib/site-packages/pydantic_core/__pycache__/core_schema.cpython-312.pyc
index 0e6e520a..91b41308 100644
Binary files a/venv/Lib/site-packages/pydantic_core/__pycache__/core_schema.cpython-312.pyc and b/venv/Lib/site-packages/pydantic_core/__pycache__/core_schema.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/python_multipart-0.0.20.dist-info/INSTALLER b/venv/Lib/site-packages/python_multipart-0.0.20.dist-info/INSTALLER
new file mode 100644
index 00000000..a1b589e3
--- /dev/null
+++ b/venv/Lib/site-packages/python_multipart-0.0.20.dist-info/INSTALLER
@@ -0,0 +1 @@
+pip
diff --git a/venv/Lib/site-packages/python_multipart-0.0.20.dist-info/METADATA b/venv/Lib/site-packages/python_multipart-0.0.20.dist-info/METADATA
new file mode 100644
index 00000000..155ce8b6
--- /dev/null
+++ b/venv/Lib/site-packages/python_multipart-0.0.20.dist-info/METADATA
@@ -0,0 +1,40 @@
+Metadata-Version: 2.4
+Name: python-multipart
+Version: 0.0.20
+Summary: A streaming multipart parser for Python
+Project-URL: Homepage, https://github.com/Kludex/python-multipart
+Project-URL: Documentation, https://kludex.github.io/python-multipart/
+Project-URL: Changelog, https://github.com/Kludex/python-multipart/blob/master/CHANGELOG.md
+Project-URL: Source, https://github.com/Kludex/python-multipart
+Author-email: Andrew Dunham , Marcelo Trylesinski
+License-Expression: Apache-2.0
+License-File: LICENSE.txt
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Environment :: Web Environment
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: Apache Software License
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3 :: Only
+Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: 3.9
+Classifier: Programming Language :: Python :: 3.10
+Classifier: Programming Language :: Python :: 3.11
+Classifier: Programming Language :: Python :: 3.12
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Requires-Python: >=3.8
+Description-Content-Type: text/markdown
+
+# [Python-Multipart](https://kludex.github.io/python-multipart/)
+
+[](https://pypi.python.org/pypi/python-multipart)
+[](https://pypi.org/project/python-multipart)
+
+---
+
+`python-multipart` is an Apache2-licensed streaming multipart parser for Python.
+Test coverage is currently 100%.
+
+## Why?
+
+Because streaming uploads are awesome for large files.
diff --git a/venv/Lib/site-packages/python_multipart-0.0.20.dist-info/RECORD b/venv/Lib/site-packages/python_multipart-0.0.20.dist-info/RECORD
new file mode 100644
index 00000000..f80836d0
--- /dev/null
+++ b/venv/Lib/site-packages/python_multipart-0.0.20.dist-info/RECORD
@@ -0,0 +1,23 @@
+multipart/__init__.py,sha256=_ttxOAFnTN4jeac-_8NeXpaXYYo0PPEIp8Ogo4YFNHE,935
+multipart/__pycache__/__init__.cpython-312.pyc,,
+multipart/__pycache__/decoders.cpython-312.pyc,,
+multipart/__pycache__/exceptions.cpython-312.pyc,,
+multipart/__pycache__/multipart.cpython-312.pyc,,
+multipart/decoders.py,sha256=XvkAwTU9UFPiXkc0hkvovHf0W6H3vK-2ieWlhav02hQ,40
+multipart/exceptions.py,sha256=6D_X-seiOmMAlIeiGlPGUs8-vpcvIGJeQycFMDb1f7A,42
+multipart/multipart.py,sha256=8fDH14j_VMbrch_58wlzi63XNARGv80kOZAyN72aG7A,41
+python_multipart-0.0.20.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
+python_multipart-0.0.20.dist-info/METADATA,sha256=h2GtPOVShbVkpBUrjp5KE3t6eiJJhd0_WCaCXrb5TgU,1817
+python_multipart-0.0.20.dist-info/RECORD,,
+python_multipart-0.0.20.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
+python_multipart-0.0.20.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
+python_multipart-0.0.20.dist-info/licenses/LICENSE.txt,sha256=qOgzF2zWF9rwC51tOfoVyo7evG0WQwec0vSJPAwom-I,556
+python_multipart/__init__.py,sha256=Nlw6Yrc__qXnCZLo17OzbJR2w2mwiSFk69IG4Wl35EU,512
+python_multipart/__pycache__/__init__.cpython-312.pyc,,
+python_multipart/__pycache__/decoders.cpython-312.pyc,,
+python_multipart/__pycache__/exceptions.cpython-312.pyc,,
+python_multipart/__pycache__/multipart.cpython-312.pyc,,
+python_multipart/decoders.py,sha256=JM43FMNn_EKP0MI2ZkuZHhNa0MOASoIR0U5TvdG585k,6669
+python_multipart/exceptions.py,sha256=a9buSOv_eiHZoukEJhdWX9LJYSJ6t7XOK3ZEaWoQZlk,992
+python_multipart/multipart.py,sha256=pk3o3eB3KXbNxzOBxbEjCdz-1ESEZIMXVIfl12grG-o,76427
+python_multipart/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
diff --git a/venv/Lib/site-packages/python_multipart-0.0.20.dist-info/REQUESTED b/venv/Lib/site-packages/python_multipart-0.0.20.dist-info/REQUESTED
new file mode 100644
index 00000000..e69de29b
diff --git a/venv/Lib/site-packages/python_multipart-0.0.20.dist-info/WHEEL b/venv/Lib/site-packages/python_multipart-0.0.20.dist-info/WHEEL
new file mode 100644
index 00000000..12228d41
--- /dev/null
+++ b/venv/Lib/site-packages/python_multipart-0.0.20.dist-info/WHEEL
@@ -0,0 +1,4 @@
+Wheel-Version: 1.0
+Generator: hatchling 1.27.0
+Root-Is-Purelib: true
+Tag: py3-none-any
diff --git a/venv/Lib/site-packages/python_multipart-0.0.20.dist-info/licenses/LICENSE.txt b/venv/Lib/site-packages/python_multipart-0.0.20.dist-info/licenses/LICENSE.txt
new file mode 100644
index 00000000..303a1bf5
--- /dev/null
+++ b/venv/Lib/site-packages/python_multipart-0.0.20.dist-info/licenses/LICENSE.txt
@@ -0,0 +1,14 @@
+Copyright 2012, Andrew Dunham
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
diff --git a/venv/Lib/site-packages/python_multipart/__init__.py b/venv/Lib/site-packages/python_multipart/__init__.py
new file mode 100644
index 00000000..e4265264
--- /dev/null
+++ b/venv/Lib/site-packages/python_multipart/__init__.py
@@ -0,0 +1,25 @@
+# This is the canonical package information.
+__author__ = "Andrew Dunham"
+__license__ = "Apache"
+__copyright__ = "Copyright (c) 2012-2013, Andrew Dunham"
+__version__ = "0.0.20"
+
+from .multipart import (
+ BaseParser,
+ FormParser,
+ MultipartParser,
+ OctetStreamParser,
+ QuerystringParser,
+ create_form_parser,
+ parse_form,
+)
+
+__all__ = (
+ "BaseParser",
+ "FormParser",
+ "MultipartParser",
+ "OctetStreamParser",
+ "QuerystringParser",
+ "create_form_parser",
+ "parse_form",
+)
diff --git a/venv/Lib/site-packages/python_multipart/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/python_multipart/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 00000000..f4d55911
Binary files /dev/null and b/venv/Lib/site-packages/python_multipart/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/python_multipart/__pycache__/decoders.cpython-312.pyc b/venv/Lib/site-packages/python_multipart/__pycache__/decoders.cpython-312.pyc
new file mode 100644
index 00000000..fbfc62eb
Binary files /dev/null and b/venv/Lib/site-packages/python_multipart/__pycache__/decoders.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/python_multipart/__pycache__/exceptions.cpython-312.pyc b/venv/Lib/site-packages/python_multipart/__pycache__/exceptions.cpython-312.pyc
new file mode 100644
index 00000000..b6a4f75b
Binary files /dev/null and b/venv/Lib/site-packages/python_multipart/__pycache__/exceptions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/python_multipart/__pycache__/multipart.cpython-312.pyc b/venv/Lib/site-packages/python_multipart/__pycache__/multipart.cpython-312.pyc
new file mode 100644
index 00000000..d53857a5
Binary files /dev/null and b/venv/Lib/site-packages/python_multipart/__pycache__/multipart.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/python_multipart/decoders.py b/venv/Lib/site-packages/python_multipart/decoders.py
new file mode 100644
index 00000000..82b56a1e
--- /dev/null
+++ b/venv/Lib/site-packages/python_multipart/decoders.py
@@ -0,0 +1,185 @@
+import base64
+import binascii
+from typing import TYPE_CHECKING
+
+from .exceptions import DecodeError
+
+if TYPE_CHECKING: # pragma: no cover
+ from typing import Protocol, TypeVar
+
+ _T_contra = TypeVar("_T_contra", contravariant=True)
+
+ class SupportsWrite(Protocol[_T_contra]):
+ def write(self, __b: _T_contra) -> object: ...
+
+ # No way to specify optional methods. See
+ # https://github.com/python/typing/issues/601
+ # close() [Optional]
+ # finalize() [Optional]
+
+
+class Base64Decoder:
+ """This object provides an interface to decode a stream of Base64 data. It
+ is instantiated with an "underlying object", and whenever a write()
+ operation is performed, it will decode the incoming data as Base64, and
+ call write() on the underlying object. This is primarily used for decoding
+ form data encoded as Base64, but can be used for other purposes::
+
+ from python_multipart.decoders import Base64Decoder
+ fd = open("notb64.txt", "wb")
+ decoder = Base64Decoder(fd)
+ try:
+ decoder.write("Zm9vYmFy") # "foobar" in Base64
+ decoder.finalize()
+ finally:
+ decoder.close()
+
+ # The contents of "notb64.txt" should be "foobar".
+
+ This object will also pass all finalize() and close() calls to the
+ underlying object, if the underlying object supports them.
+
+ Note that this class maintains a cache of base64 chunks, so that a write of
+ arbitrary size can be performed. You must call :meth:`finalize` on this
+ object after all writes are completed to ensure that all data is flushed
+ to the underlying object.
+
+ :param underlying: the underlying object to pass writes to
+ """
+
+ def __init__(self, underlying: "SupportsWrite[bytes]") -> None:
+ self.cache = bytearray()
+ self.underlying = underlying
+
+ def write(self, data: bytes) -> int:
+ """Takes any input data provided, decodes it as base64, and passes it
+ on to the underlying object. If the data provided is invalid base64
+ data, then this method will raise
+ a :class:`python_multipart.exceptions.DecodeError`
+
+ :param data: base64 data to decode
+ """
+
+ # Prepend any cache info to our data.
+ if len(self.cache) > 0:
+ data = self.cache + data
+
+ # Slice off a string that's a multiple of 4.
+ decode_len = (len(data) // 4) * 4
+ val = data[:decode_len]
+
+ # Decode and write, if we have any.
+ if len(val) > 0:
+ try:
+ decoded = base64.b64decode(val)
+ except binascii.Error:
+ raise DecodeError("There was an error raised while decoding base64-encoded data.")
+
+ self.underlying.write(decoded)
+
+ # Get the remaining bytes and save in our cache.
+ remaining_len = len(data) % 4
+ if remaining_len > 0:
+ self.cache[:] = data[-remaining_len:]
+ else:
+ self.cache[:] = b""
+
+ # Return the length of the data to indicate no error.
+ return len(data)
+
+ def close(self) -> None:
+ """Close this decoder. If the underlying object has a `close()`
+ method, this function will call it.
+ """
+ if hasattr(self.underlying, "close"):
+ self.underlying.close()
+
+ def finalize(self) -> None:
+ """Finalize this object. This should be called when no more data
+ should be written to the stream. This function can raise a
+ :class:`python_multipart.exceptions.DecodeError` if there is some remaining
+ data in the cache.
+
+ If the underlying object has a `finalize()` method, this function will
+ call it.
+ """
+ if len(self.cache) > 0:
+ raise DecodeError(
+ "There are %d bytes remaining in the Base64Decoder cache when finalize() is called" % len(self.cache)
+ )
+
+ if hasattr(self.underlying, "finalize"):
+ self.underlying.finalize()
+
+ def __repr__(self) -> str:
+ return f"{self.__class__.__name__}(underlying={self.underlying!r})"
+
+
+class QuotedPrintableDecoder:
+ """This object provides an interface to decode a stream of quoted-printable
+ data. It is instantiated with an "underlying object", in the same manner
+ as the :class:`python_multipart.decoders.Base64Decoder` class. This class behaves
+ in exactly the same way, including maintaining a cache of quoted-printable
+ chunks.
+
+ :param underlying: the underlying object to pass writes to
+ """
+
+ def __init__(self, underlying: "SupportsWrite[bytes]") -> None:
+ self.cache = b""
+ self.underlying = underlying
+
+ def write(self, data: bytes) -> int:
+ """Takes any input data provided, decodes it as quoted-printable, and
+ passes it on to the underlying object.
+
+ :param data: quoted-printable data to decode
+ """
+ # Prepend any cache info to our data.
+ if len(self.cache) > 0:
+ data = self.cache + data
+
+ # If the last 2 characters have an '=' sign in it, then we won't be
+ # able to decode the encoded value and we'll need to save it for the
+ # next decoding step.
+ if data[-2:].find(b"=") != -1:
+ enc, rest = data[:-2], data[-2:]
+ else:
+ enc = data
+ rest = b""
+
+ # Encode and write, if we have data.
+ if len(enc) > 0:
+ self.underlying.write(binascii.a2b_qp(enc))
+
+ # Save remaining in cache.
+ self.cache = rest
+ return len(data)
+
+ def close(self) -> None:
+ """Close this decoder. If the underlying object has a `close()`
+ method, this function will call it.
+ """
+ if hasattr(self.underlying, "close"):
+ self.underlying.close()
+
+ def finalize(self) -> None:
+ """Finalize this object. This should be called when no more data
+ should be written to the stream. This function will not raise any
+ exceptions, but it may write more data to the underlying object if
+ there is data remaining in the cache.
+
+ If the underlying object has a `finalize()` method, this function will
+ call it.
+ """
+ # If we have a cache, write and then remove it.
+ if len(self.cache) > 0: # pragma: no cover
+ self.underlying.write(binascii.a2b_qp(self.cache))
+ self.cache = b""
+
+ # Finalize our underlying stream.
+ if hasattr(self.underlying, "finalize"):
+ self.underlying.finalize()
+
+ def __repr__(self) -> str:
+ return f"{self.__class__.__name__}(underlying={self.underlying!r})"
diff --git a/venv/Lib/site-packages/python_multipart/exceptions.py b/venv/Lib/site-packages/python_multipart/exceptions.py
new file mode 100644
index 00000000..cc3671f5
--- /dev/null
+++ b/venv/Lib/site-packages/python_multipart/exceptions.py
@@ -0,0 +1,34 @@
+class FormParserError(ValueError):
+ """Base error class for our form parser."""
+
+
+class ParseError(FormParserError):
+ """This exception (or a subclass) is raised when there is an error while
+ parsing something.
+ """
+
+ #: This is the offset in the input data chunk (*NOT* the overall stream) in
+ #: which the parse error occurred. It will be -1 if not specified.
+ offset = -1
+
+
+class MultipartParseError(ParseError):
+ """This is a specific error that is raised when the MultipartParser detects
+ an error while parsing.
+ """
+
+
+class QuerystringParseError(ParseError):
+ """This is a specific error that is raised when the QuerystringParser
+ detects an error while parsing.
+ """
+
+
+class DecodeError(ParseError):
+ """This exception is raised when there is a decoding error - for example
+ with the Base64Decoder or QuotedPrintableDecoder.
+ """
+
+
+class FileError(FormParserError, OSError):
+ """Exception class for problems with the File class."""
diff --git a/venv/Lib/site-packages/python_multipart/multipart.py b/venv/Lib/site-packages/python_multipart/multipart.py
new file mode 100644
index 00000000..f26a815a
--- /dev/null
+++ b/venv/Lib/site-packages/python_multipart/multipart.py
@@ -0,0 +1,1873 @@
+from __future__ import annotations
+
+import logging
+import os
+import shutil
+import sys
+import tempfile
+from email.message import Message
+from enum import IntEnum
+from io import BufferedRandom, BytesIO
+from numbers import Number
+from typing import TYPE_CHECKING, cast
+
+from .decoders import Base64Decoder, QuotedPrintableDecoder
+from .exceptions import FileError, FormParserError, MultipartParseError, QuerystringParseError
+
+if TYPE_CHECKING: # pragma: no cover
+ from typing import Any, Callable, Literal, Protocol, TypedDict
+
+ from typing_extensions import TypeAlias
+
+ class SupportsRead(Protocol):
+ def read(self, __n: int) -> bytes: ...
+
+ class QuerystringCallbacks(TypedDict, total=False):
+ on_field_start: Callable[[], None]
+ on_field_name: Callable[[bytes, int, int], None]
+ on_field_data: Callable[[bytes, int, int], None]
+ on_field_end: Callable[[], None]
+ on_end: Callable[[], None]
+
+ class OctetStreamCallbacks(TypedDict, total=False):
+ on_start: Callable[[], None]
+ on_data: Callable[[bytes, int, int], None]
+ on_end: Callable[[], None]
+
+ class MultipartCallbacks(TypedDict, total=False):
+ on_part_begin: Callable[[], None]
+ on_part_data: Callable[[bytes, int, int], None]
+ on_part_end: Callable[[], None]
+ on_header_begin: Callable[[], None]
+ on_header_field: Callable[[bytes, int, int], None]
+ on_header_value: Callable[[bytes, int, int], None]
+ on_header_end: Callable[[], None]
+ on_headers_finished: Callable[[], None]
+ on_end: Callable[[], None]
+
+ class FormParserConfig(TypedDict):
+ UPLOAD_DIR: str | None
+ UPLOAD_KEEP_FILENAME: bool
+ UPLOAD_KEEP_EXTENSIONS: bool
+ UPLOAD_ERROR_ON_BAD_CTE: bool
+ MAX_MEMORY_FILE_SIZE: int
+ MAX_BODY_SIZE: float
+
+ class FileConfig(TypedDict, total=False):
+ UPLOAD_DIR: str | bytes | None
+ UPLOAD_DELETE_TMP: bool
+ UPLOAD_KEEP_FILENAME: bool
+ UPLOAD_KEEP_EXTENSIONS: bool
+ MAX_MEMORY_FILE_SIZE: int
+
+ class _FormProtocol(Protocol):
+ def write(self, data: bytes) -> int: ...
+
+ def finalize(self) -> None: ...
+
+ def close(self) -> None: ...
+
+ class FieldProtocol(_FormProtocol, Protocol):
+ def __init__(self, name: bytes | None) -> None: ...
+
+ def set_none(self) -> None: ...
+
+ class FileProtocol(_FormProtocol, Protocol):
+ def __init__(self, file_name: bytes | None, field_name: bytes | None, config: FileConfig) -> None: ...
+
+ OnFieldCallback = Callable[[FieldProtocol], None]
+ OnFileCallback = Callable[[FileProtocol], None]
+
+ CallbackName: TypeAlias = Literal[
+ "start",
+ "data",
+ "end",
+ "field_start",
+ "field_name",
+ "field_data",
+ "field_end",
+ "part_begin",
+ "part_data",
+ "part_end",
+ "header_begin",
+ "header_field",
+ "header_value",
+ "header_end",
+ "headers_finished",
+ ]
+
+# Unique missing object.
+_missing = object()
+
+
+class QuerystringState(IntEnum):
+ """Querystring parser states.
+
+ These are used to keep track of the state of the parser, and are used to determine
+ what to do when new data is encountered.
+ """
+
+ BEFORE_FIELD = 0
+ FIELD_NAME = 1
+ FIELD_DATA = 2
+
+
+class MultipartState(IntEnum):
+ """Multipart parser states.
+
+ These are used to keep track of the state of the parser, and are used to determine
+ what to do when new data is encountered.
+ """
+
+ START = 0
+ START_BOUNDARY = 1
+ HEADER_FIELD_START = 2
+ HEADER_FIELD = 3
+ HEADER_VALUE_START = 4
+ HEADER_VALUE = 5
+ HEADER_VALUE_ALMOST_DONE = 6
+ HEADERS_ALMOST_DONE = 7
+ PART_DATA_START = 8
+ PART_DATA = 9
+ PART_DATA_END = 10
+ END_BOUNDARY = 11
+ END = 12
+
+
+# Flags for the multipart parser.
+FLAG_PART_BOUNDARY = 1
+FLAG_LAST_BOUNDARY = 2
+
+# Get constants. Since iterating over a str on Python 2 gives you a 1-length
+# string, but iterating over a bytes object on Python 3 gives you an integer,
+# we need to save these constants.
+CR = b"\r"[0]
+LF = b"\n"[0]
+COLON = b":"[0]
+SPACE = b" "[0]
+HYPHEN = b"-"[0]
+AMPERSAND = b"&"[0]
+SEMICOLON = b";"[0]
+LOWER_A = b"a"[0]
+LOWER_Z = b"z"[0]
+NULL = b"\x00"[0]
+
+# fmt: off
+# Mask for ASCII characters that can be http tokens.
+# Per RFC7230 - 3.2.6, this is all alpha-numeric characters
+# and these: !#$%&'*+-.^_`|~
+TOKEN_CHARS_SET = frozenset(
+ b"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ b"abcdefghijklmnopqrstuvwxyz"
+ b"0123456789"
+ b"!#$%&'*+-.^_`|~")
+# fmt: on
+
+
+def parse_options_header(value: str | bytes | None) -> tuple[bytes, dict[bytes, bytes]]:
+ """Parses a Content-Type header into a value in the following format: (content_type, {parameters})."""
+ # Uses email.message.Message to parse the header as described in PEP 594.
+ # Ref: https://peps.python.org/pep-0594/#cgi
+ if not value:
+ return (b"", {})
+
+ # If we are passed bytes, we assume that it conforms to WSGI, encoding in latin-1.
+ if isinstance(value, bytes): # pragma: no cover
+ value = value.decode("latin-1")
+
+ # For types
+ assert isinstance(value, str), "Value should be a string by now"
+
+ # If we have no options, return the string as-is.
+ if ";" not in value:
+ return (value.lower().strip().encode("latin-1"), {})
+
+ # Split at the first semicolon, to get our value and then options.
+ # ctype, rest = value.split(b';', 1)
+ message = Message()
+ message["content-type"] = value
+ params = message.get_params()
+ # If there were no parameters, this would have already returned above
+ assert params, "At least the content type value should be present"
+ ctype = params.pop(0)[0].encode("latin-1")
+ options: dict[bytes, bytes] = {}
+ for param in params:
+ key, value = param
+ # If the value returned from get_params() is a 3-tuple, the last
+ # element corresponds to the value.
+ # See: https://docs.python.org/3/library/email.compat32-message.html
+ if isinstance(value, tuple):
+ value = value[-1]
+ # If the value is a filename, we need to fix a bug on IE6 that sends
+ # the full file path instead of the filename.
+ if key == "filename":
+ if value[1:3] == ":\\" or value[:2] == "\\\\":
+ value = value.split("\\")[-1]
+ options[key.encode("latin-1")] = value.encode("latin-1")
+ return ctype, options
+
+
+class Field:
+ """A Field object represents a (parsed) form field. It represents a single
+ field with a corresponding name and value.
+
+ The name that a :class:`Field` will be instantiated with is the same name
+ that would be found in the following HTML::
+
+
+
+ This class defines two methods, :meth:`on_data` and :meth:`on_end`, that
+ will be called when data is written to the Field, and when the Field is
+ finalized, respectively.
+
+ Args:
+ name: The name of the form field.
+ """
+
+ def __init__(self, name: bytes | None) -> None:
+ self._name = name
+ self._value: list[bytes] = []
+
+ # We cache the joined version of _value for speed.
+ self._cache = _missing
+
+ @classmethod
+ def from_value(cls, name: bytes, value: bytes | None) -> Field:
+ """Create an instance of a :class:`Field`, and set the corresponding
+ value - either None or an actual value. This method will also
+ finalize the Field itself.
+
+ Args:
+ name: the name of the form field.
+ value: the value of the form field - either a bytestring or None.
+
+ Returns:
+ A new instance of a [`Field`][python_multipart.Field].
+ """
+
+ f = cls(name)
+ if value is None:
+ f.set_none()
+ else:
+ f.write(value)
+ f.finalize()
+ return f
+
+ def write(self, data: bytes) -> int:
+ """Write some data into the form field.
+
+ Args:
+ data: The data to write to the field.
+
+ Returns:
+ The number of bytes written.
+ """
+ return self.on_data(data)
+
+ def on_data(self, data: bytes) -> int:
+ """This method is a callback that will be called whenever data is
+ written to the Field.
+
+ Args:
+ data: The data to write to the field.
+
+ Returns:
+ The number of bytes written.
+ """
+ self._value.append(data)
+ self._cache = _missing
+ return len(data)
+
+ def on_end(self) -> None:
+ """This method is called whenever the Field is finalized."""
+ if self._cache is _missing:
+ self._cache = b"".join(self._value)
+
+ def finalize(self) -> None:
+ """Finalize the form field."""
+ self.on_end()
+
+ def close(self) -> None:
+ """Close the Field object. This will free any underlying cache."""
+ # Free our value array.
+ if self._cache is _missing:
+ self._cache = b"".join(self._value)
+
+ del self._value
+
+ def set_none(self) -> None:
+ """Some fields in a querystring can possibly have a value of None - for
+ example, the string "foo&bar=&baz=asdf" will have a field with the
+ name "foo" and value None, one with name "bar" and value "", and one
+ with name "baz" and value "asdf". Since the write() interface doesn't
+ support writing None, this function will set the field value to None.
+ """
+ self._cache = None
+
+ @property
+ def field_name(self) -> bytes | None:
+ """This property returns the name of the field."""
+ return self._name
+
+ @property
+ def value(self) -> bytes | None:
+ """This property returns the value of the form field."""
+ if self._cache is _missing:
+ self._cache = b"".join(self._value)
+
+ assert isinstance(self._cache, bytes) or self._cache is None
+ return self._cache
+
+ def __eq__(self, other: object) -> bool:
+ if isinstance(other, Field):
+ return self.field_name == other.field_name and self.value == other.value
+ else:
+ return NotImplemented
+
+ def __repr__(self) -> str:
+ if self.value is not None and len(self.value) > 97:
+ # We get the repr, and then insert three dots before the final
+ # quote.
+ v = repr(self.value[:97])[:-1] + "...'"
+ else:
+ v = repr(self.value)
+
+ return "{}(field_name={!r}, value={})".format(self.__class__.__name__, self.field_name, v)
+
+
+class File:
+ """This class represents an uploaded file. It handles writing file data to
+ either an in-memory file or a temporary file on-disk, if the optional
+ threshold is passed.
+
+ There are some options that can be passed to the File to change behavior
+ of the class. Valid options are as follows:
+
+ | Name | Type | Default | Description |
+ |-----------------------|-------|---------|-------------|
+ | UPLOAD_DIR | `str` | None | The directory to store uploaded files in. If this is None, a temporary file will be created in the system's standard location. |
+ | UPLOAD_DELETE_TMP | `bool`| True | Delete automatically created TMP file |
+ | UPLOAD_KEEP_FILENAME | `bool`| False | Whether or not to keep the filename of the uploaded file. If True, then the filename will be converted to a safe representation (e.g. by removing any invalid path segments), and then saved with the same name). Otherwise, a temporary name will be used. |
+ | UPLOAD_KEEP_EXTENSIONS| `bool`| False | Whether or not to keep the uploaded file's extension. If False, the file will be saved with the default temporary extension (usually ".tmp"). Otherwise, the file's extension will be maintained. Note that this will properly combine with the UPLOAD_KEEP_FILENAME setting. |
+ | MAX_MEMORY_FILE_SIZE | `int` | 1 MiB | The maximum number of bytes of a File to keep in memory. By default, the contents of a File are kept into memory until a certain limit is reached, after which the contents of the File are written to a temporary file. This behavior can be disabled by setting this value to an appropriately large value (or, for example, infinity, such as `float('inf')`. |
+
+ Args:
+ file_name: The name of the file that this [`File`][python_multipart.File] represents.
+ field_name: The name of the form field that this file was uploaded with. This can be None, if, for example,
+ the file was uploaded with Content-Type application/octet-stream.
+ config: The configuration for this File. See above for valid configuration keys and their corresponding values.
+ """ # noqa: E501
+
+ def __init__(self, file_name: bytes | None, field_name: bytes | None = None, config: FileConfig = {}) -> None:
+ # Save configuration, set other variables default.
+ self.logger = logging.getLogger(__name__)
+ self._config = config
+ self._in_memory = True
+ self._bytes_written = 0
+ self._fileobj: BytesIO | BufferedRandom = BytesIO()
+
+ # Save the provided field/file name.
+ self._field_name = field_name
+ self._file_name = file_name
+
+ # Our actual file name is None by default, since, depending on our
+ # config, we may not actually use the provided name.
+ self._actual_file_name: bytes | None = None
+
+ # Split the extension from the filename.
+ if file_name is not None:
+ base, ext = os.path.splitext(file_name)
+ self._file_base = base
+ self._ext = ext
+
+ @property
+ def field_name(self) -> bytes | None:
+ """The form field associated with this file. May be None if there isn't
+ one, for example when we have an application/octet-stream upload.
+ """
+ return self._field_name
+
+ @property
+ def file_name(self) -> bytes | None:
+ """The file name given in the upload request."""
+ return self._file_name
+
+ @property
+ def actual_file_name(self) -> bytes | None:
+ """The file name that this file is saved as. Will be None if it's not
+ currently saved on disk.
+ """
+ return self._actual_file_name
+
+ @property
+ def file_object(self) -> BytesIO | BufferedRandom:
+ """The file object that we're currently writing to. Note that this
+ will either be an instance of a :class:`io.BytesIO`, or a regular file
+ object.
+ """
+ return self._fileobj
+
+ @property
+ def size(self) -> int:
+ """The total size of this file, counted as the number of bytes that
+ currently have been written to the file.
+ """
+ return self._bytes_written
+
+ @property
+ def in_memory(self) -> bool:
+ """A boolean representing whether or not this file object is currently
+ stored in-memory or on-disk.
+ """
+ return self._in_memory
+
+ def flush_to_disk(self) -> None:
+ """If the file is already on-disk, do nothing. Otherwise, copy from
+ the in-memory buffer to a disk file, and then reassign our internal
+ file object to this new disk file.
+
+ Note that if you attempt to flush a file that is already on-disk, a
+ warning will be logged to this module's logger.
+ """
+ if not self._in_memory:
+ self.logger.warning("Trying to flush to disk when we're not in memory")
+ return
+
+ # Go back to the start of our file.
+ self._fileobj.seek(0)
+
+ # Open a new file.
+ new_file = self._get_disk_file()
+
+ # Copy the file objects.
+ shutil.copyfileobj(self._fileobj, new_file)
+
+ # Seek to the new position in our new file.
+ new_file.seek(self._bytes_written)
+
+ # Reassign the fileobject.
+ old_fileobj = self._fileobj
+ self._fileobj = new_file
+
+ # We're no longer in memory.
+ self._in_memory = False
+
+ # Close the old file object.
+ old_fileobj.close()
+
+ def _get_disk_file(self) -> BufferedRandom:
+ """This function is responsible for getting a file object on-disk for us."""
+ self.logger.info("Opening a file on disk")
+
+ file_dir = self._config.get("UPLOAD_DIR")
+ keep_filename = self._config.get("UPLOAD_KEEP_FILENAME", False)
+ keep_extensions = self._config.get("UPLOAD_KEEP_EXTENSIONS", False)
+ delete_tmp = self._config.get("UPLOAD_DELETE_TMP", True)
+ tmp_file: None | BufferedRandom = None
+
+ # If we have a directory and are to keep the filename...
+ if file_dir is not None and keep_filename:
+ self.logger.info("Saving with filename in: %r", file_dir)
+
+ # Build our filename.
+ # TODO: what happens if we don't have a filename?
+ fname = self._file_base + self._ext if keep_extensions else self._file_base
+
+ path = os.path.join(file_dir, fname) # type: ignore[arg-type]
+ try:
+ self.logger.info("Opening file: %r", path)
+ tmp_file = open(path, "w+b")
+ except OSError:
+ tmp_file = None
+
+ self.logger.exception("Error opening temporary file")
+ raise FileError("Error opening temporary file: %r" % path)
+ else:
+ # Build options array.
+ # Note that on Python 3, tempfile doesn't support byte names. We
+ # encode our paths using the default filesystem encoding.
+ suffix = self._ext.decode(sys.getfilesystemencoding()) if keep_extensions else None
+
+ if file_dir is None:
+ dir = None
+ elif isinstance(file_dir, bytes):
+ dir = file_dir.decode(sys.getfilesystemencoding())
+ else:
+ dir = file_dir # pragma: no cover
+
+ # Create a temporary (named) file with the appropriate settings.
+ self.logger.info(
+ "Creating a temporary file with options: %r", {"suffix": suffix, "delete": delete_tmp, "dir": dir}
+ )
+ try:
+ tmp_file = cast(BufferedRandom, tempfile.NamedTemporaryFile(suffix=suffix, delete=delete_tmp, dir=dir))
+ except OSError:
+ self.logger.exception("Error creating named temporary file")
+ raise FileError("Error creating named temporary file")
+
+ assert tmp_file is not None
+ # Encode filename as bytes.
+ if isinstance(tmp_file.name, str):
+ fname = tmp_file.name.encode(sys.getfilesystemencoding())
+ else:
+ fname = cast(bytes, tmp_file.name) # pragma: no cover
+
+ self._actual_file_name = fname
+ return tmp_file
+
+ def write(self, data: bytes) -> int:
+ """Write some data to the File.
+
+ :param data: a bytestring
+ """
+ return self.on_data(data)
+
+ def on_data(self, data: bytes) -> int:
+ """This method is a callback that will be called whenever data is
+ written to the File.
+
+ Args:
+ data: The data to write to the file.
+
+ Returns:
+ The number of bytes written.
+ """
+ bwritten = self._fileobj.write(data)
+
+ # If the bytes written isn't the same as the length, just return.
+ if bwritten != len(data):
+ self.logger.warning("bwritten != len(data) (%d != %d)", bwritten, len(data))
+ return bwritten
+
+ # Keep track of how many bytes we've written.
+ self._bytes_written += bwritten
+
+ # If we're in-memory and are over our limit, we create a file.
+ max_memory_file_size = self._config.get("MAX_MEMORY_FILE_SIZE")
+ if self._in_memory and max_memory_file_size is not None and (self._bytes_written > max_memory_file_size):
+ self.logger.info("Flushing to disk")
+ self.flush_to_disk()
+
+ # Return the number of bytes written.
+ return bwritten
+
+ def on_end(self) -> None:
+ """This method is called whenever the Field is finalized."""
+ # Flush the underlying file object
+ self._fileobj.flush()
+
+ def finalize(self) -> None:
+ """Finalize the form file. This will not close the underlying file,
+ but simply signal that we are finished writing to the File.
+ """
+ self.on_end()
+
+ def close(self) -> None:
+ """Close the File object. This will actually close the underlying
+ file object (whether it's a :class:`io.BytesIO` or an actual file
+ object).
+ """
+ self._fileobj.close()
+
+ def __repr__(self) -> str:
+ return "{}(file_name={!r}, field_name={!r})".format(self.__class__.__name__, self.file_name, self.field_name)
+
+
+class BaseParser:
+ """This class is the base class for all parsers. It contains the logic for
+ calling and adding callbacks.
+
+ A callback can be one of two different forms. "Notification callbacks" are
+ callbacks that are called when something happens - for example, when a new
+ part of a multipart message is encountered by the parser. "Data callbacks"
+ are called when we get some sort of data - for example, part of the body of
+ a multipart chunk. Notification callbacks are called with no parameters,
+ whereas data callbacks are called with three, as follows::
+
+ data_callback(data, start, end)
+
+ The "data" parameter is a bytestring (i.e. "foo" on Python 2, or b"foo" on
+ Python 3). "start" and "end" are integer indexes into the "data" string
+ that represent the data of interest. Thus, in a data callback, the slice
+ `data[start:end]` represents the data that the callback is "interested in".
+ The callback is not passed a copy of the data, since copying severely hurts
+ performance.
+ """
+
+ def __init__(self) -> None:
+ self.logger = logging.getLogger(__name__)
+ self.callbacks: QuerystringCallbacks | OctetStreamCallbacks | MultipartCallbacks = {}
+
+ def callback(
+ self, name: CallbackName, data: bytes | None = None, start: int | None = None, end: int | None = None
+ ) -> None:
+ """This function calls a provided callback with some data. If the
+ callback is not set, will do nothing.
+
+ Args:
+ name: The name of the callback to call (as a string).
+ data: Data to pass to the callback. If None, then it is assumed that the callback is a notification
+ callback, and no parameters are given.
+ end: An integer that is passed to the data callback.
+ start: An integer that is passed to the data callback.
+ """
+ on_name = "on_" + name
+ func = self.callbacks.get(on_name)
+ if func is None:
+ return
+ func = cast("Callable[..., Any]", func)
+ # Depending on whether we're given a buffer...
+ if data is not None:
+ # Don't do anything if we have start == end.
+ if start is not None and start == end:
+ return
+
+ self.logger.debug("Calling %s with data[%d:%d]", on_name, start, end)
+ func(data, start, end)
+ else:
+ self.logger.debug("Calling %s with no data", on_name)
+ func()
+
+ def set_callback(self, name: CallbackName, new_func: Callable[..., Any] | None) -> None:
+ """Update the function for a callback. Removes from the callbacks dict
+ if new_func is None.
+
+ :param name: The name of the callback to call (as a string).
+
+ :param new_func: The new function for the callback. If None, then the
+ callback will be removed (with no error if it does not
+ exist).
+ """
+ if new_func is None:
+ self.callbacks.pop("on_" + name, None) # type: ignore[misc]
+ else:
+ self.callbacks["on_" + name] = new_func # type: ignore[literal-required]
+
+ def close(self) -> None:
+ pass # pragma: no cover
+
+ def finalize(self) -> None:
+ pass # pragma: no cover
+
+ def __repr__(self) -> str:
+ return "%s()" % self.__class__.__name__
+
+
+class OctetStreamParser(BaseParser):
+ """This parser parses an octet-stream request body and calls callbacks when
+ incoming data is received. Callbacks are as follows:
+
+ | Callback Name | Parameters | Description |
+ |----------------|-----------------|-----------------------------------------------------|
+ | on_start | None | Called when the first data is parsed. |
+ | on_data | data, start, end| Called for each data chunk that is parsed. |
+ | on_end | None | Called when the parser is finished parsing all data.|
+
+ Args:
+ callbacks: A dictionary of callbacks. See the documentation for [`BaseParser`][python_multipart.BaseParser].
+ max_size: The maximum size of body to parse. Defaults to infinity - i.e. unbounded.
+ """
+
+ def __init__(self, callbacks: OctetStreamCallbacks = {}, max_size: float = float("inf")):
+ super().__init__()
+ self.callbacks = callbacks
+ self._started = False
+
+ if not isinstance(max_size, Number) or max_size < 1:
+ raise ValueError("max_size must be a positive number, not %r" % max_size)
+ self.max_size: int | float = max_size
+ self._current_size = 0
+
+ def write(self, data: bytes) -> int:
+ """Write some data to the parser, which will perform size verification,
+ and then pass the data to the underlying callback.
+
+ Args:
+ data: The data to write to the parser.
+
+ Returns:
+ The number of bytes written.
+ """
+ if not self._started:
+ self.callback("start")
+ self._started = True
+
+ # Truncate data length.
+ data_len = len(data)
+ if (self._current_size + data_len) > self.max_size:
+ # We truncate the length of data that we are to process.
+ new_size = int(self.max_size - self._current_size)
+ self.logger.warning(
+ "Current size is %d (max %d), so truncating data length from %d to %d",
+ self._current_size,
+ self.max_size,
+ data_len,
+ new_size,
+ )
+ data_len = new_size
+
+ # Increment size, then callback, in case there's an exception.
+ self._current_size += data_len
+ self.callback("data", data, 0, data_len)
+ return data_len
+
+ def finalize(self) -> None:
+ """Finalize this parser, which signals to that we are finished parsing,
+ and sends the on_end callback.
+ """
+ self.callback("end")
+
+ def __repr__(self) -> str:
+ return "%s()" % self.__class__.__name__
+
+
+class QuerystringParser(BaseParser):
+ """This is a streaming querystring parser. It will consume data, and call
+ the callbacks given when it has data.
+
+ | Callback Name | Parameters | Description |
+ |----------------|-----------------|-----------------------------------------------------|
+ | on_field_start | None | Called when a new field is encountered. |
+ | on_field_name | data, start, end| Called when a portion of a field's name is encountered. |
+ | on_field_data | data, start, end| Called when a portion of a field's data is encountered. |
+ | on_field_end | None | Called when the end of a field is encountered. |
+ | on_end | None | Called when the parser is finished parsing all data.|
+
+ Args:
+ callbacks: A dictionary of callbacks. See the documentation for [`BaseParser`][python_multipart.BaseParser].
+ strict_parsing: Whether or not to parse the body strictly. Defaults to False. If this is set to True, then the
+ behavior of the parser changes as the following: if a field has a value with an equal sign
+ (e.g. "foo=bar", or "foo="), it is always included. If a field has no equals sign (e.g. "...&name&..."),
+ it will be treated as an error if 'strict_parsing' is True, otherwise included. If an error is encountered,
+ then a [`QuerystringParseError`][python_multipart.exceptions.QuerystringParseError] will be raised.
+ max_size: The maximum size of body to parse. Defaults to infinity - i.e. unbounded.
+ """ # noqa: E501
+
+ state: QuerystringState
+
+ def __init__(
+ self, callbacks: QuerystringCallbacks = {}, strict_parsing: bool = False, max_size: float = float("inf")
+ ) -> None:
+ super().__init__()
+ self.state = QuerystringState.BEFORE_FIELD
+ self._found_sep = False
+
+ self.callbacks = callbacks
+
+ # Max-size stuff
+ if not isinstance(max_size, Number) or max_size < 1:
+ raise ValueError("max_size must be a positive number, not %r" % max_size)
+ self.max_size: int | float = max_size
+ self._current_size = 0
+
+ # Should parsing be strict?
+ self.strict_parsing = strict_parsing
+
+ def write(self, data: bytes) -> int:
+ """Write some data to the parser, which will perform size verification,
+ parse into either a field name or value, and then pass the
+ corresponding data to the underlying callback. If an error is
+ encountered while parsing, a QuerystringParseError will be raised. The
+ "offset" attribute of the raised exception will be set to the offset in
+ the input data chunk (NOT the overall stream) that caused the error.
+
+ Args:
+ data: The data to write to the parser.
+
+ Returns:
+ The number of bytes written.
+ """
+ # Handle sizing.
+ data_len = len(data)
+ if (self._current_size + data_len) > self.max_size:
+ # We truncate the length of data that we are to process.
+ new_size = int(self.max_size - self._current_size)
+ self.logger.warning(
+ "Current size is %d (max %d), so truncating data length from %d to %d",
+ self._current_size,
+ self.max_size,
+ data_len,
+ new_size,
+ )
+ data_len = new_size
+
+ l = 0
+ try:
+ l = self._internal_write(data, data_len)
+ finally:
+ self._current_size += l
+
+ return l
+
+ def _internal_write(self, data: bytes, length: int) -> int:
+ state = self.state
+ strict_parsing = self.strict_parsing
+ found_sep = self._found_sep
+
+ i = 0
+ while i < length:
+ ch = data[i]
+
+ # Depending on our state...
+ if state == QuerystringState.BEFORE_FIELD:
+ # If the 'found_sep' flag is set, we've already encountered
+ # and skipped a single separator. If so, we check our strict
+ # parsing flag and decide what to do. Otherwise, we haven't
+ # yet reached a separator, and thus, if we do, we need to skip
+ # it as it will be the boundary between fields that's supposed
+ # to be there.
+ if ch == AMPERSAND or ch == SEMICOLON:
+ if found_sep:
+ # If we're parsing strictly, we disallow blank chunks.
+ if strict_parsing:
+ e = QuerystringParseError("Skipping duplicate ampersand/semicolon at %d" % i)
+ e.offset = i
+ raise e
+ else:
+ self.logger.debug("Skipping duplicate ampersand/semicolon at %d", i)
+ else:
+ # This case is when we're skipping the (first)
+ # separator between fields, so we just set our flag
+ # and continue on.
+ found_sep = True
+ else:
+ # Emit a field-start event, and go to that state. Also,
+ # reset the "found_sep" flag, for the next time we get to
+ # this state.
+ self.callback("field_start")
+ i -= 1
+ state = QuerystringState.FIELD_NAME
+ found_sep = False
+
+ elif state == QuerystringState.FIELD_NAME:
+ # Try and find a separator - we ensure that, if we do, we only
+ # look for the equal sign before it.
+ sep_pos = data.find(b"&", i)
+ if sep_pos == -1:
+ sep_pos = data.find(b";", i)
+
+ # See if we can find an equals sign in the remaining data. If
+ # so, we can immediately emit the field name and jump to the
+ # data state.
+ if sep_pos != -1:
+ equals_pos = data.find(b"=", i, sep_pos)
+ else:
+ equals_pos = data.find(b"=", i)
+
+ if equals_pos != -1:
+ # Emit this name.
+ self.callback("field_name", data, i, equals_pos)
+
+ # Jump i to this position. Note that it will then have 1
+ # added to it below, which means the next iteration of this
+ # loop will inspect the character after the equals sign.
+ i = equals_pos
+ state = QuerystringState.FIELD_DATA
+ else:
+ # No equals sign found.
+ if not strict_parsing:
+ # See also comments in the QuerystringState.FIELD_DATA case below.
+ # If we found the separator, we emit the name and just
+ # end - there's no data callback at all (not even with
+ # a blank value).
+ if sep_pos != -1:
+ self.callback("field_name", data, i, sep_pos)
+ self.callback("field_end")
+
+ i = sep_pos - 1
+ state = QuerystringState.BEFORE_FIELD
+ else:
+ # Otherwise, no separator in this block, so the
+ # rest of this chunk must be a name.
+ self.callback("field_name", data, i, length)
+ i = length
+
+ else:
+ # We're parsing strictly. If we find a separator,
+ # this is an error - we require an equals sign.
+ if sep_pos != -1:
+ e = QuerystringParseError(
+ "When strict_parsing is True, we require an "
+ "equals sign in all field chunks. Did not "
+ "find one in the chunk that starts at %d" % (i,)
+ )
+ e.offset = i
+ raise e
+
+ # No separator in the rest of this chunk, so it's just
+ # a field name.
+ self.callback("field_name", data, i, length)
+ i = length
+
+ elif state == QuerystringState.FIELD_DATA:
+ # Try finding either an ampersand or a semicolon after this
+ # position.
+ sep_pos = data.find(b"&", i)
+ if sep_pos == -1:
+ sep_pos = data.find(b";", i)
+
+ # If we found it, callback this bit as data and then go back
+ # to expecting to find a field.
+ if sep_pos != -1:
+ self.callback("field_data", data, i, sep_pos)
+ self.callback("field_end")
+
+ # Note that we go to the separator, which brings us to the
+ # "before field" state. This allows us to properly emit
+ # "field_start" events only when we actually have data for
+ # a field of some sort.
+ i = sep_pos - 1
+ state = QuerystringState.BEFORE_FIELD
+
+ # Otherwise, emit the rest as data and finish.
+ else:
+ self.callback("field_data", data, i, length)
+ i = length
+
+ else: # pragma: no cover (error case)
+ msg = "Reached an unknown state %d at %d" % (state, i)
+ self.logger.warning(msg)
+ e = QuerystringParseError(msg)
+ e.offset = i
+ raise e
+
+ i += 1
+
+ self.state = state
+ self._found_sep = found_sep
+ return len(data)
+
+ def finalize(self) -> None:
+ """Finalize this parser, which signals to that we are finished parsing,
+ if we're still in the middle of a field, an on_field_end callback, and
+ then the on_end callback.
+ """
+ # If we're currently in the middle of a field, we finish it.
+ if self.state == QuerystringState.FIELD_DATA:
+ self.callback("field_end")
+ self.callback("end")
+
+ def __repr__(self) -> str:
+ return "{}(strict_parsing={!r}, max_size={!r})".format(
+ self.__class__.__name__, self.strict_parsing, self.max_size
+ )
+
+
+class MultipartParser(BaseParser):
+ """This class is a streaming multipart/form-data parser.
+
+ | Callback Name | Parameters | Description |
+ |--------------------|-----------------|-------------|
+ | on_part_begin | None | Called when a new part of the multipart message is encountered. |
+ | on_part_data | data, start, end| Called when a portion of a part's data is encountered. |
+ | on_part_end | None | Called when the end of a part is reached. |
+ | on_header_begin | None | Called when we've found a new header in a part of a multipart message |
+ | on_header_field | data, start, end| Called each time an additional portion of a header is read (i.e. the part of the header that is before the colon; the "Foo" in "Foo: Bar"). |
+ | on_header_value | data, start, end| Called when we get data for a header. |
+ | on_header_end | None | Called when the current header is finished - i.e. we've reached the newline at the end of the header. |
+ | on_headers_finished| None | Called when all headers are finished, and before the part data starts. |
+ | on_end | None | Called when the parser is finished parsing all data. |
+
+ Args:
+ boundary: The multipart boundary. This is required, and must match what is given in the HTTP request - usually in the Content-Type header.
+ callbacks: A dictionary of callbacks. See the documentation for [`BaseParser`][python_multipart.BaseParser].
+ max_size: The maximum size of body to parse. Defaults to infinity - i.e. unbounded.
+ """ # noqa: E501
+
+ def __init__(
+ self, boundary: bytes | str, callbacks: MultipartCallbacks = {}, max_size: float = float("inf")
+ ) -> None:
+ # Initialize parser state.
+ super().__init__()
+ self.state = MultipartState.START
+ self.index = self.flags = 0
+
+ self.callbacks = callbacks
+
+ if not isinstance(max_size, Number) or max_size < 1:
+ raise ValueError("max_size must be a positive number, not %r" % max_size)
+ self.max_size = max_size
+ self._current_size = 0
+
+ # Setup marks. These are used to track the state of data received.
+ self.marks: dict[str, int] = {}
+
+ # Save our boundary.
+ if isinstance(boundary, str): # pragma: no cover
+ boundary = boundary.encode("latin-1")
+ self.boundary = b"\r\n--" + boundary
+
+ def write(self, data: bytes) -> int:
+ """Write some data to the parser, which will perform size verification,
+ and then parse the data into the appropriate location (e.g. header,
+ data, etc.), and pass this on to the underlying callback. If an error
+ is encountered, a MultipartParseError will be raised. The "offset"
+ attribute on the raised exception will be set to the offset of the byte
+ in the input chunk that caused the error.
+
+ Args:
+ data: The data to write to the parser.
+
+ Returns:
+ The number of bytes written.
+ """
+ # Handle sizing.
+ data_len = len(data)
+ if (self._current_size + data_len) > self.max_size:
+ # We truncate the length of data that we are to process.
+ new_size = int(self.max_size - self._current_size)
+ self.logger.warning(
+ "Current size is %d (max %d), so truncating data length from %d to %d",
+ self._current_size,
+ self.max_size,
+ data_len,
+ new_size,
+ )
+ data_len = new_size
+
+ l = 0
+ try:
+ l = self._internal_write(data, data_len)
+ finally:
+ self._current_size += l
+
+ return l
+
+ def _internal_write(self, data: bytes, length: int) -> int:
+ # Get values from locals.
+ boundary = self.boundary
+
+ # Get our state, flags and index. These are persisted between calls to
+ # this function.
+ state = self.state
+ index = self.index
+ flags = self.flags
+
+ # Our index defaults to 0.
+ i = 0
+
+ # Set a mark.
+ def set_mark(name: str) -> None:
+ self.marks[name] = i
+
+ # Remove a mark.
+ def delete_mark(name: str, reset: bool = False) -> None:
+ self.marks.pop(name, None)
+
+ # Helper function that makes calling a callback with data easier. The
+ # 'remaining' parameter will callback from the marked value until the
+ # end of the buffer, and reset the mark, instead of deleting it. This
+ # is used at the end of the function to call our callbacks with any
+ # remaining data in this chunk.
+ def data_callback(name: CallbackName, end_i: int, remaining: bool = False) -> None:
+ marked_index = self.marks.get(name)
+ if marked_index is None:
+ return
+
+ # Otherwise, we call it from the mark to the current byte we're
+ # processing.
+ if end_i <= marked_index:
+ # There is no additional data to send.
+ pass
+ elif marked_index >= 0:
+ # We are emitting data from the local buffer.
+ self.callback(name, data, marked_index, end_i)
+ else:
+ # Some of the data comes from a partial boundary match.
+ # and requires look-behind.
+ # We need to use self.flags (and not flags) because we care about
+ # the state when we entered the loop.
+ lookbehind_len = -marked_index
+ if lookbehind_len <= len(boundary):
+ self.callback(name, boundary, 0, lookbehind_len)
+ elif self.flags & FLAG_PART_BOUNDARY:
+ lookback = boundary + b"\r\n"
+ self.callback(name, lookback, 0, lookbehind_len)
+ elif self.flags & FLAG_LAST_BOUNDARY:
+ lookback = boundary + b"--\r\n"
+ self.callback(name, lookback, 0, lookbehind_len)
+ else: # pragma: no cover (error case)
+ self.logger.warning("Look-back buffer error")
+
+ if end_i > 0:
+ self.callback(name, data, 0, end_i)
+ # If we're getting remaining data, we have got all the data we
+ # can be certain is not a boundary, leaving only a partial boundary match.
+ if remaining:
+ self.marks[name] = end_i - length
+ else:
+ self.marks.pop(name, None)
+
+ # For each byte...
+ while i < length:
+ c = data[i]
+
+ if state == MultipartState.START:
+ # Skip leading newlines
+ if c == CR or c == LF:
+ i += 1
+ continue
+
+ # index is used as in index into our boundary. Set to 0.
+ index = 0
+
+ # Move to the next state, but decrement i so that we re-process
+ # this character.
+ state = MultipartState.START_BOUNDARY
+ i -= 1
+
+ elif state == MultipartState.START_BOUNDARY:
+ # Check to ensure that the last 2 characters in our boundary
+ # are CRLF.
+ if index == len(boundary) - 2:
+ if c == HYPHEN:
+ # Potential empty message.
+ state = MultipartState.END_BOUNDARY
+ elif c != CR:
+ # Error!
+ msg = "Did not find CR at end of boundary (%d)" % (i,)
+ self.logger.warning(msg)
+ e = MultipartParseError(msg)
+ e.offset = i
+ raise e
+
+ index += 1
+
+ elif index == len(boundary) - 2 + 1:
+ if c != LF:
+ msg = "Did not find LF at end of boundary (%d)" % (i,)
+ self.logger.warning(msg)
+ e = MultipartParseError(msg)
+ e.offset = i
+ raise e
+
+ # The index is now used for indexing into our boundary.
+ index = 0
+
+ # Callback for the start of a part.
+ self.callback("part_begin")
+
+ # Move to the next character and state.
+ state = MultipartState.HEADER_FIELD_START
+
+ else:
+ # Check to ensure our boundary matches
+ if c != boundary[index + 2]:
+ msg = "Expected boundary character %r, got %r at index %d" % (boundary[index + 2], c, index + 2)
+ self.logger.warning(msg)
+ e = MultipartParseError(msg)
+ e.offset = i
+ raise e
+
+ # Increment index into boundary and continue.
+ index += 1
+
+ elif state == MultipartState.HEADER_FIELD_START:
+ # Mark the start of a header field here, reset the index, and
+ # continue parsing our header field.
+ index = 0
+
+ # Set a mark of our header field.
+ set_mark("header_field")
+
+ # Notify that we're starting a header if the next character is
+ # not a CR; a CR at the beginning of the header will cause us
+ # to stop parsing headers in the MultipartState.HEADER_FIELD state,
+ # below.
+ if c != CR:
+ self.callback("header_begin")
+
+ # Move to parsing header fields.
+ state = MultipartState.HEADER_FIELD
+ i -= 1
+
+ elif state == MultipartState.HEADER_FIELD:
+ # If we've reached a CR at the beginning of a header, it means
+ # that we've reached the second of 2 newlines, and so there are
+ # no more headers to parse.
+ if c == CR and index == 0:
+ delete_mark("header_field")
+ state = MultipartState.HEADERS_ALMOST_DONE
+ i += 1
+ continue
+
+ # Increment our index in the header.
+ index += 1
+
+ # If we've reached a colon, we're done with this header.
+ if c == COLON:
+ # A 0-length header is an error.
+ if index == 1:
+ msg = "Found 0-length header at %d" % (i,)
+ self.logger.warning(msg)
+ e = MultipartParseError(msg)
+ e.offset = i
+ raise e
+
+ # Call our callback with the header field.
+ data_callback("header_field", i)
+
+ # Move to parsing the header value.
+ state = MultipartState.HEADER_VALUE_START
+
+ elif c not in TOKEN_CHARS_SET:
+ msg = "Found invalid character %r in header at %d" % (c, i)
+ self.logger.warning(msg)
+ e = MultipartParseError(msg)
+ e.offset = i
+ raise e
+
+ elif state == MultipartState.HEADER_VALUE_START:
+ # Skip leading spaces.
+ if c == SPACE:
+ i += 1
+ continue
+
+ # Mark the start of the header value.
+ set_mark("header_value")
+
+ # Move to the header-value state, reprocessing this character.
+ state = MultipartState.HEADER_VALUE
+ i -= 1
+
+ elif state == MultipartState.HEADER_VALUE:
+ # If we've got a CR, we're nearly done our headers. Otherwise,
+ # we do nothing and just move past this character.
+ if c == CR:
+ data_callback("header_value", i)
+ self.callback("header_end")
+ state = MultipartState.HEADER_VALUE_ALMOST_DONE
+
+ elif state == MultipartState.HEADER_VALUE_ALMOST_DONE:
+ # The last character should be a LF. If not, it's an error.
+ if c != LF:
+ msg = "Did not find LF character at end of header " "(found %r)" % (c,)
+ self.logger.warning(msg)
+ e = MultipartParseError(msg)
+ e.offset = i
+ raise e
+
+ # Move back to the start of another header. Note that if that
+ # state detects ANOTHER newline, it'll trigger the end of our
+ # headers.
+ state = MultipartState.HEADER_FIELD_START
+
+ elif state == MultipartState.HEADERS_ALMOST_DONE:
+ # We're almost done our headers. This is reached when we parse
+ # a CR at the beginning of a header, so our next character
+ # should be a LF, or it's an error.
+ if c != LF:
+ msg = f"Did not find LF at end of headers (found {c!r})"
+ self.logger.warning(msg)
+ e = MultipartParseError(msg)
+ e.offset = i
+ raise e
+
+ self.callback("headers_finished")
+ state = MultipartState.PART_DATA_START
+
+ elif state == MultipartState.PART_DATA_START:
+ # Mark the start of our part data.
+ set_mark("part_data")
+
+ # Start processing part data, including this character.
+ state = MultipartState.PART_DATA
+ i -= 1
+
+ elif state == MultipartState.PART_DATA:
+ # We're processing our part data right now. During this, we
+ # need to efficiently search for our boundary, since any data
+ # on any number of lines can be a part of the current data.
+
+ # Save the current value of our index. We use this in case we
+ # find part of a boundary, but it doesn't match fully.
+ prev_index = index
+
+ # Set up variables.
+ boundary_length = len(boundary)
+ data_length = length
+
+ # If our index is 0, we're starting a new part, so start our
+ # search.
+ if index == 0:
+ # The most common case is likely to be that the whole
+ # boundary is present in the buffer.
+ # Calling `find` is much faster than iterating here.
+ i0 = data.find(boundary, i, data_length)
+ if i0 >= 0:
+ # We matched the whole boundary string.
+ index = boundary_length - 1
+ i = i0 + boundary_length - 1
+ else:
+ # No match found for whole string.
+ # There may be a partial boundary at the end of the
+ # data, which the find will not match.
+ # Since the length should to be searched is limited to
+ # the boundary length, just perform a naive search.
+ i = max(i, data_length - boundary_length)
+
+ # Search forward until we either hit the end of our buffer,
+ # or reach a potential start of the boundary.
+ while i < data_length - 1 and data[i] != boundary[0]:
+ i += 1
+
+ c = data[i]
+
+ # Now, we have a couple of cases here. If our index is before
+ # the end of the boundary...
+ if index < boundary_length:
+ # If the character matches...
+ if boundary[index] == c:
+ # The current character matches, so continue!
+ index += 1
+ else:
+ index = 0
+
+ # Our index is equal to the length of our boundary!
+ elif index == boundary_length:
+ # First we increment it.
+ index += 1
+
+ # Now, if we've reached a newline, we need to set this as
+ # the potential end of our boundary.
+ if c == CR:
+ flags |= FLAG_PART_BOUNDARY
+
+ # Otherwise, if this is a hyphen, we might be at the last
+ # of all boundaries.
+ elif c == HYPHEN:
+ flags |= FLAG_LAST_BOUNDARY
+
+ # Otherwise, we reset our index, since this isn't either a
+ # newline or a hyphen.
+ else:
+ index = 0
+
+ # Our index is right after the part boundary, which should be
+ # a LF.
+ elif index == boundary_length + 1:
+ # If we're at a part boundary (i.e. we've seen a CR
+ # character already)...
+ if flags & FLAG_PART_BOUNDARY:
+ # We need a LF character next.
+ if c == LF:
+ # Unset the part boundary flag.
+ flags &= ~FLAG_PART_BOUNDARY
+
+ # We have identified a boundary, callback for any data before it.
+ data_callback("part_data", i - index)
+ # Callback indicating that we've reached the end of
+ # a part, and are starting a new one.
+ self.callback("part_end")
+ self.callback("part_begin")
+
+ # Move to parsing new headers.
+ index = 0
+ state = MultipartState.HEADER_FIELD_START
+ i += 1
+ continue
+
+ # We didn't find an LF character, so no match. Reset
+ # our index and clear our flag.
+ index = 0
+ flags &= ~FLAG_PART_BOUNDARY
+
+ # Otherwise, if we're at the last boundary (i.e. we've
+ # seen a hyphen already)...
+ elif flags & FLAG_LAST_BOUNDARY:
+ # We need a second hyphen here.
+ if c == HYPHEN:
+ # We have identified a boundary, callback for any data before it.
+ data_callback("part_data", i - index)
+ # Callback to end the current part, and then the
+ # message.
+ self.callback("part_end")
+ self.callback("end")
+ state = MultipartState.END
+ else:
+ # No match, so reset index.
+ index = 0
+
+ # Otherwise, our index is 0. If the previous index is not, it
+ # means we reset something, and we need to take the data we
+ # thought was part of our boundary and send it along as actual
+ # data.
+ if index == 0 and prev_index > 0:
+ # Overwrite our previous index.
+ prev_index = 0
+
+ # Re-consider the current character, since this could be
+ # the start of the boundary itself.
+ i -= 1
+
+ elif state == MultipartState.END_BOUNDARY:
+ if index == len(boundary) - 2 + 1:
+ if c != HYPHEN:
+ msg = "Did not find - at end of boundary (%d)" % (i,)
+ self.logger.warning(msg)
+ e = MultipartParseError(msg)
+ e.offset = i
+ raise e
+ index += 1
+ self.callback("end")
+ state = MultipartState.END
+
+ elif state == MultipartState.END:
+ # Don't do anything if chunk ends with CRLF.
+ if c == CR and i + 1 < length and data[i + 1] == LF:
+ i += 2
+ continue
+ # Skip data after the last boundary.
+ self.logger.warning("Skipping data after last boundary")
+ i = length
+ break
+
+ else: # pragma: no cover (error case)
+ # We got into a strange state somehow! Just stop processing.
+ msg = "Reached an unknown state %d at %d" % (state, i)
+ self.logger.warning(msg)
+ e = MultipartParseError(msg)
+ e.offset = i
+ raise e
+
+ # Move to the next byte.
+ i += 1
+
+ # We call our callbacks with any remaining data. Note that we pass
+ # the 'remaining' flag, which sets the mark back to 0 instead of
+ # deleting it, if it's found. This is because, if the mark is found
+ # at this point, we assume that there's data for one of these things
+ # that has been parsed, but not yet emitted. And, as such, it implies
+ # that we haven't yet reached the end of this 'thing'. So, by setting
+ # the mark to 0, we cause any data callbacks that take place in future
+ # calls to this function to start from the beginning of that buffer.
+ data_callback("header_field", length, True)
+ data_callback("header_value", length, True)
+ data_callback("part_data", length - index, True)
+
+ # Save values to locals.
+ self.state = state
+ self.index = index
+ self.flags = flags
+
+ # Return our data length to indicate no errors, and that we processed
+ # all of it.
+ return length
+
+ def finalize(self) -> None:
+ """Finalize this parser, which signals to that we are finished parsing.
+
+ Note: It does not currently, but in the future, it will verify that we
+ are in the final state of the parser (i.e. the end of the multipart
+ message is well-formed), and, if not, throw an error.
+ """
+ # TODO: verify that we're in the state MultipartState.END, otherwise throw an
+ # error or otherwise state that we're not finished parsing.
+ pass
+
+ def __repr__(self) -> str:
+ return f"{self.__class__.__name__}(boundary={self.boundary!r})"
+
+
+class FormParser:
+ """This class is the all-in-one form parser. Given all the information
+ necessary to parse a form, it will instantiate the correct parser, create
+ the proper :class:`Field` and :class:`File` classes to store the data that
+ is parsed, and call the two given callbacks with each field and file as
+ they become available.
+
+ Args:
+ content_type: The Content-Type of the incoming request. This is used to select the appropriate parser.
+ on_field: The callback to call when a field has been parsed and is ready for usage. See above for parameters.
+ on_file: The callback to call when a file has been parsed and is ready for usage. See above for parameters.
+ on_end: An optional callback to call when all fields and files in a request has been parsed. Can be None.
+ boundary: If the request is a multipart/form-data request, this should be the boundary of the request, as given
+ in the Content-Type header, as a bytestring.
+ file_name: If the request is of type application/octet-stream, then the body of the request will not contain any
+ information about the uploaded file. In such cases, you can provide the file name of the uploaded file
+ manually.
+ FileClass: The class to use for uploaded files. Defaults to :class:`File`, but you can provide your own class
+ if you wish to customize behaviour. The class will be instantiated as FileClass(file_name, field_name), and
+ it must provide the following functions::
+ - file_instance.write(data)
+ - file_instance.finalize()
+ - file_instance.close()
+ FieldClass: The class to use for uploaded fields. Defaults to :class:`Field`, but you can provide your own
+ class if you wish to customize behaviour. The class will be instantiated as FieldClass(field_name), and it
+ must provide the following functions::
+ - field_instance.write(data)
+ - field_instance.finalize()
+ - field_instance.close()
+ - field_instance.set_none()
+ config: Configuration to use for this FormParser. The default values are taken from the DEFAULT_CONFIG value,
+ and then any keys present in this dictionary will overwrite the default values.
+ """
+
+ #: This is the default configuration for our form parser.
+ #: Note: all file sizes should be in bytes.
+ DEFAULT_CONFIG: FormParserConfig = {
+ "MAX_BODY_SIZE": float("inf"),
+ "MAX_MEMORY_FILE_SIZE": 1 * 1024 * 1024,
+ "UPLOAD_DIR": None,
+ "UPLOAD_KEEP_FILENAME": False,
+ "UPLOAD_KEEP_EXTENSIONS": False,
+ # Error on invalid Content-Transfer-Encoding?
+ "UPLOAD_ERROR_ON_BAD_CTE": False,
+ }
+
+ def __init__(
+ self,
+ content_type: str,
+ on_field: OnFieldCallback | None,
+ on_file: OnFileCallback | None,
+ on_end: Callable[[], None] | None = None,
+ boundary: bytes | str | None = None,
+ file_name: bytes | None = None,
+ FileClass: type[FileProtocol] = File,
+ FieldClass: type[FieldProtocol] = Field,
+ config: dict[Any, Any] = {},
+ ) -> None:
+ self.logger = logging.getLogger(__name__)
+
+ # Save variables.
+ self.content_type = content_type
+ self.boundary = boundary
+ self.bytes_received = 0
+ self.parser = None
+
+ # Save callbacks.
+ self.on_field = on_field
+ self.on_file = on_file
+ self.on_end = on_end
+
+ # Save classes.
+ self.FileClass = File
+ self.FieldClass = Field
+
+ # Set configuration options.
+ self.config: FormParserConfig = self.DEFAULT_CONFIG.copy()
+ self.config.update(config) # type: ignore[typeddict-item]
+
+ parser: OctetStreamParser | MultipartParser | QuerystringParser | None = None
+
+ # Depending on the Content-Type, we instantiate the correct parser.
+ if content_type == "application/octet-stream":
+ file: FileProtocol = None # type: ignore
+
+ def on_start() -> None:
+ nonlocal file
+ file = FileClass(file_name, None, config=cast("FileConfig", self.config))
+
+ def on_data(data: bytes, start: int, end: int) -> None:
+ nonlocal file
+ file.write(data[start:end])
+
+ def _on_end() -> None:
+ nonlocal file
+ # Finalize the file itself.
+ file.finalize()
+
+ # Call our callback.
+ if on_file:
+ on_file(file)
+
+ # Call the on-end callback.
+ if self.on_end is not None:
+ self.on_end()
+
+ # Instantiate an octet-stream parser
+ parser = OctetStreamParser(
+ callbacks={"on_start": on_start, "on_data": on_data, "on_end": _on_end},
+ max_size=self.config["MAX_BODY_SIZE"],
+ )
+
+ elif content_type == "application/x-www-form-urlencoded" or content_type == "application/x-url-encoded":
+ name_buffer: list[bytes] = []
+
+ f: FieldProtocol | None = None
+
+ def on_field_start() -> None:
+ pass
+
+ def on_field_name(data: bytes, start: int, end: int) -> None:
+ name_buffer.append(data[start:end])
+
+ def on_field_data(data: bytes, start: int, end: int) -> None:
+ nonlocal f
+ if f is None:
+ f = FieldClass(b"".join(name_buffer))
+ del name_buffer[:]
+ f.write(data[start:end])
+
+ def on_field_end() -> None:
+ nonlocal f
+ # Finalize and call callback.
+ if f is None:
+ # If we get here, it's because there was no field data.
+ # We create a field, set it to None, and then continue.
+ f = FieldClass(b"".join(name_buffer))
+ del name_buffer[:]
+ f.set_none()
+
+ f.finalize()
+ if on_field:
+ on_field(f)
+ f = None
+
+ def _on_end() -> None:
+ if self.on_end is not None:
+ self.on_end()
+
+ # Instantiate parser.
+ parser = QuerystringParser(
+ callbacks={
+ "on_field_start": on_field_start,
+ "on_field_name": on_field_name,
+ "on_field_data": on_field_data,
+ "on_field_end": on_field_end,
+ "on_end": _on_end,
+ },
+ max_size=self.config["MAX_BODY_SIZE"],
+ )
+
+ elif content_type == "multipart/form-data":
+ if boundary is None:
+ self.logger.error("No boundary given")
+ raise FormParserError("No boundary given")
+
+ header_name: list[bytes] = []
+ header_value: list[bytes] = []
+ headers: dict[bytes, bytes] = {}
+
+ f_multi: FileProtocol | FieldProtocol | None = None
+ writer = None
+ is_file = False
+
+ def on_part_begin() -> None:
+ # Reset headers in case this isn't the first part.
+ nonlocal headers
+ headers = {}
+
+ def on_part_data(data: bytes, start: int, end: int) -> None:
+ nonlocal writer
+ assert writer is not None
+ writer.write(data[start:end])
+ # TODO: check for error here.
+
+ def on_part_end() -> None:
+ nonlocal f_multi, is_file
+ assert f_multi is not None
+ f_multi.finalize()
+ if is_file:
+ if on_file:
+ on_file(f_multi)
+ else:
+ if on_field:
+ on_field(cast("FieldProtocol", f_multi))
+
+ def on_header_field(data: bytes, start: int, end: int) -> None:
+ header_name.append(data[start:end])
+
+ def on_header_value(data: bytes, start: int, end: int) -> None:
+ header_value.append(data[start:end])
+
+ def on_header_end() -> None:
+ headers[b"".join(header_name)] = b"".join(header_value)
+ del header_name[:]
+ del header_value[:]
+
+ def on_headers_finished() -> None:
+ nonlocal is_file, f_multi, writer
+ # Reset the 'is file' flag.
+ is_file = False
+
+ # Parse the content-disposition header.
+ # TODO: handle mixed case
+ content_disp = headers.get(b"Content-Disposition")
+ disp, options = parse_options_header(content_disp)
+
+ # Get the field and filename.
+ field_name = options.get(b"name")
+ file_name = options.get(b"filename")
+ # TODO: check for errors
+
+ # Create the proper class.
+ if file_name is None:
+ f_multi = FieldClass(field_name)
+ else:
+ f_multi = FileClass(file_name, field_name, config=cast("FileConfig", self.config))
+ is_file = True
+
+ # Parse the given Content-Transfer-Encoding to determine what
+ # we need to do with the incoming data.
+ # TODO: check that we properly handle 8bit / 7bit encoding.
+ transfer_encoding = headers.get(b"Content-Transfer-Encoding", b"7bit")
+
+ if transfer_encoding in (b"binary", b"8bit", b"7bit"):
+ writer = f_multi
+
+ elif transfer_encoding == b"base64":
+ writer = Base64Decoder(f_multi)
+
+ elif transfer_encoding == b"quoted-printable":
+ writer = QuotedPrintableDecoder(f_multi)
+
+ else:
+ self.logger.warning("Unknown Content-Transfer-Encoding: %r", transfer_encoding)
+ if self.config["UPLOAD_ERROR_ON_BAD_CTE"]:
+ raise FormParserError('Unknown Content-Transfer-Encoding "{!r}"'.format(transfer_encoding))
+ else:
+ # If we aren't erroring, then we just treat this as an
+ # unencoded Content-Transfer-Encoding.
+ writer = f_multi
+
+ def _on_end() -> None:
+ nonlocal writer
+ if writer is not None:
+ writer.finalize()
+ if self.on_end is not None:
+ self.on_end()
+
+ # Instantiate a multipart parser.
+ parser = MultipartParser(
+ boundary,
+ callbacks={
+ "on_part_begin": on_part_begin,
+ "on_part_data": on_part_data,
+ "on_part_end": on_part_end,
+ "on_header_field": on_header_field,
+ "on_header_value": on_header_value,
+ "on_header_end": on_header_end,
+ "on_headers_finished": on_headers_finished,
+ "on_end": _on_end,
+ },
+ max_size=self.config["MAX_BODY_SIZE"],
+ )
+
+ else:
+ self.logger.warning("Unknown Content-Type: %r", content_type)
+ raise FormParserError("Unknown Content-Type: {}".format(content_type))
+
+ self.parser = parser
+
+ def write(self, data: bytes) -> int:
+ """Write some data. The parser will forward this to the appropriate
+ underlying parser.
+
+ Args:
+ data: The data to write.
+
+ Returns:
+ The number of bytes processed.
+ """
+ self.bytes_received += len(data)
+ # TODO: check the parser's return value for errors?
+ assert self.parser is not None
+ return self.parser.write(data)
+
+ def finalize(self) -> None:
+ """Finalize the parser."""
+ if self.parser is not None and hasattr(self.parser, "finalize"):
+ self.parser.finalize()
+
+ def close(self) -> None:
+ """Close the parser."""
+ if self.parser is not None and hasattr(self.parser, "close"):
+ self.parser.close()
+
+ def __repr__(self) -> str:
+ return "{}(content_type={!r}, parser={!r})".format(self.__class__.__name__, self.content_type, self.parser)
+
+
+def create_form_parser(
+ headers: dict[str, bytes],
+ on_field: OnFieldCallback | None,
+ on_file: OnFileCallback | None,
+ trust_x_headers: bool = False,
+ config: dict[Any, Any] = {},
+) -> FormParser:
+ """This function is a helper function to aid in creating a FormParser
+ instances. Given a dictionary-like headers object, it will determine
+ the correct information needed, instantiate a FormParser with the
+ appropriate values and given callbacks, and then return the corresponding
+ parser.
+
+ Args:
+ headers: A dictionary-like object of HTTP headers. The only required header is Content-Type.
+ on_field: Callback to call with each parsed field.
+ on_file: Callback to call with each parsed file.
+ trust_x_headers: Whether or not to trust information received from certain X-Headers - for example, the file
+ name from X-File-Name.
+ config: Configuration variables to pass to the FormParser.
+ """
+ content_type: str | bytes | None = headers.get("Content-Type")
+ if content_type is None:
+ logging.getLogger(__name__).warning("No Content-Type header given")
+ raise ValueError("No Content-Type header given!")
+
+ # Boundaries are optional (the FormParser will raise if one is needed
+ # but not given).
+ content_type, params = parse_options_header(content_type)
+ boundary = params.get(b"boundary")
+
+ # We need content_type to be a string, not a bytes object.
+ content_type = content_type.decode("latin-1")
+
+ # File names are optional.
+ file_name = headers.get("X-File-Name")
+
+ # Instantiate a form parser.
+ form_parser = FormParser(content_type, on_field, on_file, boundary=boundary, file_name=file_name, config=config)
+
+ # Return our parser.
+ return form_parser
+
+
+def parse_form(
+ headers: dict[str, bytes],
+ input_stream: SupportsRead,
+ on_field: OnFieldCallback | None,
+ on_file: OnFileCallback | None,
+ chunk_size: int = 1048576,
+) -> None:
+ """This function is useful if you just want to parse a request body,
+ without too much work. Pass it a dictionary-like object of the request's
+ headers, and a file-like object for the input stream, along with two
+ callbacks that will get called whenever a field or file is parsed.
+
+ Args:
+ headers: A dictionary-like object of HTTP headers. The only required header is Content-Type.
+ input_stream: A file-like object that represents the request body. The read() method must return bytestrings.
+ on_field: Callback to call with each parsed field.
+ on_file: Callback to call with each parsed file.
+ chunk_size: The maximum size to read from the input stream and write to the parser at one time.
+ Defaults to 1 MiB.
+ """
+ # Create our form parser.
+ parser = create_form_parser(headers, on_field, on_file)
+
+ # Read chunks of 1MiB and write to the parser, but never read more than
+ # the given Content-Length, if any.
+ content_length: int | float | bytes | None = headers.get("Content-Length")
+ if content_length is not None:
+ content_length = int(content_length)
+ else:
+ content_length = float("inf")
+ bytes_read = 0
+
+ while True:
+ # Read only up to the Content-Length given.
+ max_readable = int(min(content_length - bytes_read, chunk_size))
+ buff = input_stream.read(max_readable)
+
+ # Write to the parser and update our length.
+ parser.write(buff)
+ bytes_read += len(buff)
+
+ # If we get a buffer that's smaller than the size requested, or if we
+ # have read up to our content length, we're done.
+ if len(buff) != max_readable or bytes_read == content_length:
+ break
+
+ # Tell our parser that we're done writing data.
+ parser.finalize()
diff --git a/venv/Lib/site-packages/python_multipart/py.typed b/venv/Lib/site-packages/python_multipart/py.typed
new file mode 100644
index 00000000..e69de29b
diff --git a/venv/Lib/site-packages/pytz/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/pytz/__pycache__/__init__.cpython-312.pyc
index 9719bb9b..1b14e32a 100644
Binary files a/venv/Lib/site-packages/pytz/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/pytz/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pytz/__pycache__/exceptions.cpython-312.pyc b/venv/Lib/site-packages/pytz/__pycache__/exceptions.cpython-312.pyc
index 8d294773..e1463e86 100644
Binary files a/venv/Lib/site-packages/pytz/__pycache__/exceptions.cpython-312.pyc and b/venv/Lib/site-packages/pytz/__pycache__/exceptions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pytz/__pycache__/lazy.cpython-312.pyc b/venv/Lib/site-packages/pytz/__pycache__/lazy.cpython-312.pyc
index 89efa8fb..330f5aeb 100644
Binary files a/venv/Lib/site-packages/pytz/__pycache__/lazy.cpython-312.pyc and b/venv/Lib/site-packages/pytz/__pycache__/lazy.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pytz/__pycache__/tzfile.cpython-312.pyc b/venv/Lib/site-packages/pytz/__pycache__/tzfile.cpython-312.pyc
index cce75675..21693205 100644
Binary files a/venv/Lib/site-packages/pytz/__pycache__/tzfile.cpython-312.pyc and b/venv/Lib/site-packages/pytz/__pycache__/tzfile.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/pytz/__pycache__/tzinfo.cpython-312.pyc b/venv/Lib/site-packages/pytz/__pycache__/tzinfo.cpython-312.pyc
index bc5d9920..62abe62a 100644
Binary files a/venv/Lib/site-packages/pytz/__pycache__/tzinfo.cpython-312.pyc and b/venv/Lib/site-packages/pytz/__pycache__/tzinfo.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/requests-2.32.4.dist-info/INSTALLER b/venv/Lib/site-packages/requests-2.32.4.dist-info/INSTALLER
new file mode 100644
index 00000000..a1b589e3
--- /dev/null
+++ b/venv/Lib/site-packages/requests-2.32.4.dist-info/INSTALLER
@@ -0,0 +1 @@
+pip
diff --git a/venv/Lib/site-packages/requests-2.32.4.dist-info/METADATA b/venv/Lib/site-packages/requests-2.32.4.dist-info/METADATA
new file mode 100644
index 00000000..837ff4da
--- /dev/null
+++ b/venv/Lib/site-packages/requests-2.32.4.dist-info/METADATA
@@ -0,0 +1,133 @@
+Metadata-Version: 2.4
+Name: requests
+Version: 2.32.4
+Summary: Python HTTP for Humans.
+Home-page: https://requests.readthedocs.io
+Author: Kenneth Reitz
+Author-email: me@kennethreitz.org
+License: Apache-2.0
+Project-URL: Documentation, https://requests.readthedocs.io
+Project-URL: Source, https://github.com/psf/requests
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Environment :: Web Environment
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: Apache Software License
+Classifier: Natural Language :: English
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: 3.9
+Classifier: Programming Language :: Python :: 3.10
+Classifier: Programming Language :: Python :: 3.11
+Classifier: Programming Language :: Python :: 3.12
+Classifier: Programming Language :: Python :: 3.13
+Classifier: Programming Language :: Python :: 3 :: Only
+Classifier: Programming Language :: Python :: Implementation :: CPython
+Classifier: Programming Language :: Python :: Implementation :: PyPy
+Classifier: Topic :: Internet :: WWW/HTTP
+Classifier: Topic :: Software Development :: Libraries
+Requires-Python: >=3.8
+Description-Content-Type: text/markdown
+License-File: LICENSE
+Requires-Dist: charset_normalizer<4,>=2
+Requires-Dist: idna<4,>=2.5
+Requires-Dist: urllib3<3,>=1.21.1
+Requires-Dist: certifi>=2017.4.17
+Provides-Extra: security
+Provides-Extra: socks
+Requires-Dist: PySocks!=1.5.7,>=1.5.6; extra == "socks"
+Provides-Extra: use-chardet-on-py3
+Requires-Dist: chardet<6,>=3.0.2; extra == "use-chardet-on-py3"
+Dynamic: author
+Dynamic: author-email
+Dynamic: classifier
+Dynamic: description
+Dynamic: description-content-type
+Dynamic: home-page
+Dynamic: license
+Dynamic: license-file
+Dynamic: project-url
+Dynamic: provides-extra
+Dynamic: requires-dist
+Dynamic: requires-python
+Dynamic: summary
+
+# Requests
+
+**Requests** is a simple, yet elegant, HTTP library.
+
+```python
+>>> import requests
+>>> r = requests.get('https://httpbin.org/basic-auth/user/pass', auth=('user', 'pass'))
+>>> r.status_code
+200
+>>> r.headers['content-type']
+'application/json; charset=utf8'
+>>> r.encoding
+'utf-8'
+>>> r.text
+'{"authenticated": true, ...'
+>>> r.json()
+{'authenticated': True, ...}
+```
+
+Requests allows you to send HTTP/1.1 requests extremely easily. There’s no need to manually add query strings to your URLs, or to form-encode your `PUT` & `POST` data — but nowadays, just use the `json` method!
+
+Requests is one of the most downloaded Python packages today, pulling in around `30M downloads / week`— according to GitHub, Requests is currently [depended upon](https://github.com/psf/requests/network/dependents?package_id=UGFja2FnZS01NzA4OTExNg%3D%3D) by `1,000,000+` repositories. You may certainly put your trust in this code.
+
+[](https://pepy.tech/project/requests)
+[](https://pypi.org/project/requests)
+[](https://github.com/psf/requests/graphs/contributors)
+
+## Installing Requests and Supported Versions
+
+Requests is available on PyPI:
+
+```console
+$ python -m pip install requests
+```
+
+Requests officially supports Python 3.8+.
+
+## Supported Features & Best–Practices
+
+Requests is ready for the demands of building robust and reliable HTTP–speaking applications, for the needs of today.
+
+- Keep-Alive & Connection Pooling
+- International Domains and URLs
+- Sessions with Cookie Persistence
+- Browser-style TLS/SSL Verification
+- Basic & Digest Authentication
+- Familiar `dict`–like Cookies
+- Automatic Content Decompression and Decoding
+- Multi-part File Uploads
+- SOCKS Proxy Support
+- Connection Timeouts
+- Streaming Downloads
+- Automatic honoring of `.netrc`
+- Chunked HTTP Requests
+
+## API Reference and User Guide available on [Read the Docs](https://requests.readthedocs.io)
+
+[](https://requests.readthedocs.io)
+
+## Cloning the repository
+
+When cloning the Requests repository, you may need to add the `-c
+fetch.fsck.badTimezone=ignore` flag to avoid an error about a bad commit (see
+[this issue](https://github.com/psf/requests/issues/2690) for more background):
+
+```shell
+git clone -c fetch.fsck.badTimezone=ignore https://github.com/psf/requests.git
+```
+
+You can also apply this setting to your global Git config:
+
+```shell
+git config --global fetch.fsck.badTimezone ignore
+```
+
+---
+
+[](https://kennethreitz.org) [](https://www.python.org/psf)
diff --git a/venv/Lib/site-packages/requests-2.32.4.dist-info/RECORD b/venv/Lib/site-packages/requests-2.32.4.dist-info/RECORD
new file mode 100644
index 00000000..fdad7f40
--- /dev/null
+++ b/venv/Lib/site-packages/requests-2.32.4.dist-info/RECORD
@@ -0,0 +1,42 @@
+requests-2.32.4.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
+requests-2.32.4.dist-info/METADATA,sha256=3S42LvNNoL2EP2IjC1VCXoElnGrTTVWwPgImVB4FYF4,4934
+requests-2.32.4.dist-info/RECORD,,
+requests-2.32.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
+requests-2.32.4.dist-info/licenses/LICENSE,sha256=CeipvOyAZxBGUsFoaFqwkx54aPnIKEtm9a5u2uXxEws,10142
+requests-2.32.4.dist-info/top_level.txt,sha256=fMSVmHfb5rbGOo6xv-O_tUX6j-WyixssE-SnwcDRxNQ,9
+requests/__init__.py,sha256=4xaAERmPDIBPsa2PsjpU9r06yooK-2mZKHTZAhWRWts,5072
+requests/__pycache__/__init__.cpython-312.pyc,,
+requests/__pycache__/__version__.cpython-312.pyc,,
+requests/__pycache__/_internal_utils.cpython-312.pyc,,
+requests/__pycache__/adapters.cpython-312.pyc,,
+requests/__pycache__/api.cpython-312.pyc,,
+requests/__pycache__/auth.cpython-312.pyc,,
+requests/__pycache__/certs.cpython-312.pyc,,
+requests/__pycache__/compat.cpython-312.pyc,,
+requests/__pycache__/cookies.cpython-312.pyc,,
+requests/__pycache__/exceptions.cpython-312.pyc,,
+requests/__pycache__/help.cpython-312.pyc,,
+requests/__pycache__/hooks.cpython-312.pyc,,
+requests/__pycache__/models.cpython-312.pyc,,
+requests/__pycache__/packages.cpython-312.pyc,,
+requests/__pycache__/sessions.cpython-312.pyc,,
+requests/__pycache__/status_codes.cpython-312.pyc,,
+requests/__pycache__/structures.cpython-312.pyc,,
+requests/__pycache__/utils.cpython-312.pyc,,
+requests/__version__.py,sha256=FDq681Y3EvBjdDp5UqplMZ28uTTYlM_Jib0sAV-NpXc,435
+requests/_internal_utils.py,sha256=nMQymr4hs32TqVo5AbCrmcJEhvPUh7xXlluyqwslLiQ,1495
+requests/adapters.py,sha256=KIcecscqam6reOCXRl4DwP4jX8Jcl8sd57ft17KR2cQ,27451
+requests/api.py,sha256=_Zb9Oa7tzVIizTKwFrPjDEY9ejtm_OnSRERnADxGsQs,6449
+requests/auth.py,sha256=kF75tqnLctZ9Mf_hm9TZIj4cQWnN5uxRz8oWsx5wmR0,10186
+requests/certs.py,sha256=Z9Sb410Anv6jUFTyss0jFFhU6xst8ctELqfy8Ev23gw,429
+requests/compat.py,sha256=J7sIjR6XoDGp5JTVzOxkK5fSoUVUa_Pjc7iRZhAWGmI,2142
+requests/cookies.py,sha256=bNi-iqEj4NPZ00-ob-rHvzkvObzN3lEpgw3g6paS3Xw,18590
+requests/exceptions.py,sha256=jJPS1UWATs86ShVUaLorTiJb1SaGuoNEWgICJep-VkY,4260
+requests/help.py,sha256=gPX5d_H7Xd88aDABejhqGgl9B1VFRTt5BmiYvL3PzIQ,3875
+requests/hooks.py,sha256=CiuysiHA39V5UfcCBXFIx83IrDpuwfN9RcTUgv28ftQ,733
+requests/models.py,sha256=MjZdZ4k7tnw-1nz5PKShjmPmqyk0L6DciwnFngb_Vk4,35510
+requests/packages.py,sha256=_g0gZ681UyAlKHRjH6kanbaoxx2eAb6qzcXiODyTIoc,904
+requests/sessions.py,sha256=ykTI8UWGSltOfH07HKollH7kTBGw4WhiBVaQGmckTw4,30495
+requests/status_codes.py,sha256=iJUAeA25baTdw-6PfD0eF4qhpINDJRJI-yaMqxs4LEI,4322
+requests/structures.py,sha256=-IbmhVz06S-5aPSZuUthZ6-6D9XOjRuTXHOabY041XM,2912
+requests/utils.py,sha256=WqU86rZ3wvhC-tQjWcjtH_HEKZwWB3iWCZV6SW5DEdQ,33213
diff --git a/venv/Lib/site-packages/deepgram_sdk-4.2.0.dist-info/WHEEL b/venv/Lib/site-packages/requests-2.32.4.dist-info/WHEEL
similarity index 100%
rename from venv/Lib/site-packages/deepgram_sdk-4.2.0.dist-info/WHEEL
rename to venv/Lib/site-packages/requests-2.32.4.dist-info/WHEEL
diff --git a/venv/Lib/site-packages/requests-2.32.4.dist-info/licenses/LICENSE b/venv/Lib/site-packages/requests-2.32.4.dist-info/licenses/LICENSE
new file mode 100644
index 00000000..67db8588
--- /dev/null
+++ b/venv/Lib/site-packages/requests-2.32.4.dist-info/licenses/LICENSE
@@ -0,0 +1,175 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
diff --git a/venv/Lib/site-packages/requests-2.32.4.dist-info/top_level.txt b/venv/Lib/site-packages/requests-2.32.4.dist-info/top_level.txt
new file mode 100644
index 00000000..f2293605
--- /dev/null
+++ b/venv/Lib/site-packages/requests-2.32.4.dist-info/top_level.txt
@@ -0,0 +1 @@
+requests
diff --git a/venv/Lib/site-packages/requests/__init__.py b/venv/Lib/site-packages/requests/__init__.py
new file mode 100644
index 00000000..051cda13
--- /dev/null
+++ b/venv/Lib/site-packages/requests/__init__.py
@@ -0,0 +1,184 @@
+# __
+# /__) _ _ _ _ _/ _
+# / ( (- (/ (/ (- _) / _)
+# /
+
+"""
+Requests HTTP Library
+~~~~~~~~~~~~~~~~~~~~~
+
+Requests is an HTTP library, written in Python, for human beings.
+Basic GET usage:
+
+ >>> import requests
+ >>> r = requests.get('https://www.python.org')
+ >>> r.status_code
+ 200
+ >>> b'Python is a programming language' in r.content
+ True
+
+... or POST:
+
+ >>> payload = dict(key1='value1', key2='value2')
+ >>> r = requests.post('https://httpbin.org/post', data=payload)
+ >>> print(r.text)
+ {
+ ...
+ "form": {
+ "key1": "value1",
+ "key2": "value2"
+ },
+ ...
+ }
+
+The other HTTP methods are supported - see `requests.api`. Full documentation
+is at .
+
+:copyright: (c) 2017 by Kenneth Reitz.
+:license: Apache 2.0, see LICENSE for more details.
+"""
+
+import warnings
+
+import urllib3
+
+from .exceptions import RequestsDependencyWarning
+
+try:
+ from charset_normalizer import __version__ as charset_normalizer_version
+except ImportError:
+ charset_normalizer_version = None
+
+try:
+ from chardet import __version__ as chardet_version
+except ImportError:
+ chardet_version = None
+
+
+def check_compatibility(urllib3_version, chardet_version, charset_normalizer_version):
+ urllib3_version = urllib3_version.split(".")
+ assert urllib3_version != ["dev"] # Verify urllib3 isn't installed from git.
+
+ # Sometimes, urllib3 only reports its version as 16.1.
+ if len(urllib3_version) == 2:
+ urllib3_version.append("0")
+
+ # Check urllib3 for compatibility.
+ major, minor, patch = urllib3_version # noqa: F811
+ major, minor, patch = int(major), int(minor), int(patch)
+ # urllib3 >= 1.21.1
+ assert major >= 1
+ if major == 1:
+ assert minor >= 21
+
+ # Check charset_normalizer for compatibility.
+ if chardet_version:
+ major, minor, patch = chardet_version.split(".")[:3]
+ major, minor, patch = int(major), int(minor), int(patch)
+ # chardet_version >= 3.0.2, < 6.0.0
+ assert (3, 0, 2) <= (major, minor, patch) < (6, 0, 0)
+ elif charset_normalizer_version:
+ major, minor, patch = charset_normalizer_version.split(".")[:3]
+ major, minor, patch = int(major), int(minor), int(patch)
+ # charset_normalizer >= 2.0.0 < 4.0.0
+ assert (2, 0, 0) <= (major, minor, patch) < (4, 0, 0)
+ else:
+ warnings.warn(
+ "Unable to find acceptable character detection dependency "
+ "(chardet or charset_normalizer).",
+ RequestsDependencyWarning,
+ )
+
+
+def _check_cryptography(cryptography_version):
+ # cryptography < 1.3.4
+ try:
+ cryptography_version = list(map(int, cryptography_version.split(".")))
+ except ValueError:
+ return
+
+ if cryptography_version < [1, 3, 4]:
+ warning = "Old version of cryptography ({}) may cause slowdown.".format(
+ cryptography_version
+ )
+ warnings.warn(warning, RequestsDependencyWarning)
+
+
+# Check imported dependencies for compatibility.
+try:
+ check_compatibility(
+ urllib3.__version__, chardet_version, charset_normalizer_version
+ )
+except (AssertionError, ValueError):
+ warnings.warn(
+ "urllib3 ({}) or chardet ({})/charset_normalizer ({}) doesn't match a supported "
+ "version!".format(
+ urllib3.__version__, chardet_version, charset_normalizer_version
+ ),
+ RequestsDependencyWarning,
+ )
+
+# Attempt to enable urllib3's fallback for SNI support
+# if the standard library doesn't support SNI or the
+# 'ssl' library isn't available.
+try:
+ try:
+ import ssl
+ except ImportError:
+ ssl = None
+
+ if not getattr(ssl, "HAS_SNI", False):
+ from urllib3.contrib import pyopenssl
+
+ pyopenssl.inject_into_urllib3()
+
+ # Check cryptography version
+ from cryptography import __version__ as cryptography_version
+
+ _check_cryptography(cryptography_version)
+except ImportError:
+ pass
+
+# urllib3's DependencyWarnings should be silenced.
+from urllib3.exceptions import DependencyWarning
+
+warnings.simplefilter("ignore", DependencyWarning)
+
+# Set default logging handler to avoid "No handler found" warnings.
+import logging
+from logging import NullHandler
+
+from . import packages, utils
+from .__version__ import (
+ __author__,
+ __author_email__,
+ __build__,
+ __cake__,
+ __copyright__,
+ __description__,
+ __license__,
+ __title__,
+ __url__,
+ __version__,
+)
+from .api import delete, get, head, options, patch, post, put, request
+from .exceptions import (
+ ConnectionError,
+ ConnectTimeout,
+ FileModeWarning,
+ HTTPError,
+ JSONDecodeError,
+ ReadTimeout,
+ RequestException,
+ Timeout,
+ TooManyRedirects,
+ URLRequired,
+)
+from .models import PreparedRequest, Request, Response
+from .sessions import Session, session
+from .status_codes import codes
+
+logging.getLogger(__name__).addHandler(NullHandler())
+
+# FileModeWarnings go off per the default.
+warnings.simplefilter("default", FileModeWarning, append=True)
diff --git a/venv/Lib/site-packages/requests/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/requests/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 00000000..8cb4ab36
Binary files /dev/null and b/venv/Lib/site-packages/requests/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/requests/__pycache__/__version__.cpython-312.pyc b/venv/Lib/site-packages/requests/__pycache__/__version__.cpython-312.pyc
new file mode 100644
index 00000000..585128cb
Binary files /dev/null and b/venv/Lib/site-packages/requests/__pycache__/__version__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/requests/__pycache__/_internal_utils.cpython-312.pyc b/venv/Lib/site-packages/requests/__pycache__/_internal_utils.cpython-312.pyc
new file mode 100644
index 00000000..20ceec26
Binary files /dev/null and b/venv/Lib/site-packages/requests/__pycache__/_internal_utils.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/requests/__pycache__/adapters.cpython-312.pyc b/venv/Lib/site-packages/requests/__pycache__/adapters.cpython-312.pyc
new file mode 100644
index 00000000..0064b68b
Binary files /dev/null and b/venv/Lib/site-packages/requests/__pycache__/adapters.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/requests/__pycache__/api.cpython-312.pyc b/venv/Lib/site-packages/requests/__pycache__/api.cpython-312.pyc
new file mode 100644
index 00000000..197220d7
Binary files /dev/null and b/venv/Lib/site-packages/requests/__pycache__/api.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/requests/__pycache__/auth.cpython-312.pyc b/venv/Lib/site-packages/requests/__pycache__/auth.cpython-312.pyc
new file mode 100644
index 00000000..30b3af4f
Binary files /dev/null and b/venv/Lib/site-packages/requests/__pycache__/auth.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/requests/__pycache__/certs.cpython-312.pyc b/venv/Lib/site-packages/requests/__pycache__/certs.cpython-312.pyc
new file mode 100644
index 00000000..4cc6f6ee
Binary files /dev/null and b/venv/Lib/site-packages/requests/__pycache__/certs.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/requests/__pycache__/compat.cpython-312.pyc b/venv/Lib/site-packages/requests/__pycache__/compat.cpython-312.pyc
new file mode 100644
index 00000000..32f99174
Binary files /dev/null and b/venv/Lib/site-packages/requests/__pycache__/compat.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/requests/__pycache__/cookies.cpython-312.pyc b/venv/Lib/site-packages/requests/__pycache__/cookies.cpython-312.pyc
new file mode 100644
index 00000000..bb60dc0e
Binary files /dev/null and b/venv/Lib/site-packages/requests/__pycache__/cookies.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/requests/__pycache__/exceptions.cpython-312.pyc b/venv/Lib/site-packages/requests/__pycache__/exceptions.cpython-312.pyc
new file mode 100644
index 00000000..7a6dddfb
Binary files /dev/null and b/venv/Lib/site-packages/requests/__pycache__/exceptions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/requests/__pycache__/help.cpython-312.pyc b/venv/Lib/site-packages/requests/__pycache__/help.cpython-312.pyc
new file mode 100644
index 00000000..9b9c3a05
Binary files /dev/null and b/venv/Lib/site-packages/requests/__pycache__/help.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/requests/__pycache__/hooks.cpython-312.pyc b/venv/Lib/site-packages/requests/__pycache__/hooks.cpython-312.pyc
new file mode 100644
index 00000000..406cc7b9
Binary files /dev/null and b/venv/Lib/site-packages/requests/__pycache__/hooks.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/requests/__pycache__/models.cpython-312.pyc b/venv/Lib/site-packages/requests/__pycache__/models.cpython-312.pyc
new file mode 100644
index 00000000..9fbfcc75
Binary files /dev/null and b/venv/Lib/site-packages/requests/__pycache__/models.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/requests/__pycache__/packages.cpython-312.pyc b/venv/Lib/site-packages/requests/__pycache__/packages.cpython-312.pyc
new file mode 100644
index 00000000..fe908128
Binary files /dev/null and b/venv/Lib/site-packages/requests/__pycache__/packages.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/requests/__pycache__/sessions.cpython-312.pyc b/venv/Lib/site-packages/requests/__pycache__/sessions.cpython-312.pyc
new file mode 100644
index 00000000..d718b171
Binary files /dev/null and b/venv/Lib/site-packages/requests/__pycache__/sessions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/requests/__pycache__/status_codes.cpython-312.pyc b/venv/Lib/site-packages/requests/__pycache__/status_codes.cpython-312.pyc
new file mode 100644
index 00000000..6c1d7995
Binary files /dev/null and b/venv/Lib/site-packages/requests/__pycache__/status_codes.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/requests/__pycache__/structures.cpython-312.pyc b/venv/Lib/site-packages/requests/__pycache__/structures.cpython-312.pyc
new file mode 100644
index 00000000..e79495e3
Binary files /dev/null and b/venv/Lib/site-packages/requests/__pycache__/structures.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/requests/__pycache__/utils.cpython-312.pyc b/venv/Lib/site-packages/requests/__pycache__/utils.cpython-312.pyc
new file mode 100644
index 00000000..0fba5b61
Binary files /dev/null and b/venv/Lib/site-packages/requests/__pycache__/utils.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/requests/__version__.py b/venv/Lib/site-packages/requests/__version__.py
new file mode 100644
index 00000000..3128a464
--- /dev/null
+++ b/venv/Lib/site-packages/requests/__version__.py
@@ -0,0 +1,14 @@
+# .-. .-. .-. . . .-. .-. .-. .-.
+# |( |- |.| | | |- `-. | `-.
+# ' ' `-' `-`.`-' `-' `-' ' `-'
+
+__title__ = "requests"
+__description__ = "Python HTTP for Humans."
+__url__ = "https://requests.readthedocs.io"
+__version__ = "2.32.4"
+__build__ = 0x023204
+__author__ = "Kenneth Reitz"
+__author_email__ = "me@kennethreitz.org"
+__license__ = "Apache-2.0"
+__copyright__ = "Copyright Kenneth Reitz"
+__cake__ = "\u2728 \U0001f370 \u2728"
diff --git a/venv/Lib/site-packages/requests/_internal_utils.py b/venv/Lib/site-packages/requests/_internal_utils.py
new file mode 100644
index 00000000..f2cf635e
--- /dev/null
+++ b/venv/Lib/site-packages/requests/_internal_utils.py
@@ -0,0 +1,50 @@
+"""
+requests._internal_utils
+~~~~~~~~~~~~~~
+
+Provides utility functions that are consumed internally by Requests
+which depend on extremely few external helpers (such as compat)
+"""
+import re
+
+from .compat import builtin_str
+
+_VALID_HEADER_NAME_RE_BYTE = re.compile(rb"^[^:\s][^:\r\n]*$")
+_VALID_HEADER_NAME_RE_STR = re.compile(r"^[^:\s][^:\r\n]*$")
+_VALID_HEADER_VALUE_RE_BYTE = re.compile(rb"^\S[^\r\n]*$|^$")
+_VALID_HEADER_VALUE_RE_STR = re.compile(r"^\S[^\r\n]*$|^$")
+
+_HEADER_VALIDATORS_STR = (_VALID_HEADER_NAME_RE_STR, _VALID_HEADER_VALUE_RE_STR)
+_HEADER_VALIDATORS_BYTE = (_VALID_HEADER_NAME_RE_BYTE, _VALID_HEADER_VALUE_RE_BYTE)
+HEADER_VALIDATORS = {
+ bytes: _HEADER_VALIDATORS_BYTE,
+ str: _HEADER_VALIDATORS_STR,
+}
+
+
+def to_native_string(string, encoding="ascii"):
+ """Given a string object, regardless of type, returns a representation of
+ that string in the native string type, encoding and decoding where
+ necessary. This assumes ASCII unless told otherwise.
+ """
+ if isinstance(string, builtin_str):
+ out = string
+ else:
+ out = string.decode(encoding)
+
+ return out
+
+
+def unicode_is_ascii(u_string):
+ """Determine if unicode string only contains ASCII characters.
+
+ :param str u_string: unicode string to check. Must be unicode
+ and not Python 2 `str`.
+ :rtype: bool
+ """
+ assert isinstance(u_string, str)
+ try:
+ u_string.encode("ascii")
+ return True
+ except UnicodeEncodeError:
+ return False
diff --git a/venv/Lib/site-packages/requests/adapters.py b/venv/Lib/site-packages/requests/adapters.py
new file mode 100644
index 00000000..9a58b160
--- /dev/null
+++ b/venv/Lib/site-packages/requests/adapters.py
@@ -0,0 +1,719 @@
+"""
+requests.adapters
+~~~~~~~~~~~~~~~~~
+
+This module contains the transport adapters that Requests uses to define
+and maintain connections.
+"""
+
+import os.path
+import socket # noqa: F401
+import typing
+import warnings
+
+from urllib3.exceptions import ClosedPoolError, ConnectTimeoutError
+from urllib3.exceptions import HTTPError as _HTTPError
+from urllib3.exceptions import InvalidHeader as _InvalidHeader
+from urllib3.exceptions import (
+ LocationValueError,
+ MaxRetryError,
+ NewConnectionError,
+ ProtocolError,
+)
+from urllib3.exceptions import ProxyError as _ProxyError
+from urllib3.exceptions import ReadTimeoutError, ResponseError
+from urllib3.exceptions import SSLError as _SSLError
+from urllib3.poolmanager import PoolManager, proxy_from_url
+from urllib3.util import Timeout as TimeoutSauce
+from urllib3.util import parse_url
+from urllib3.util.retry import Retry
+from urllib3.util.ssl_ import create_urllib3_context
+
+from .auth import _basic_auth_str
+from .compat import basestring, urlparse
+from .cookies import extract_cookies_to_jar
+from .exceptions import (
+ ConnectionError,
+ ConnectTimeout,
+ InvalidHeader,
+ InvalidProxyURL,
+ InvalidSchema,
+ InvalidURL,
+ ProxyError,
+ ReadTimeout,
+ RetryError,
+ SSLError,
+)
+from .models import Response
+from .structures import CaseInsensitiveDict
+from .utils import (
+ DEFAULT_CA_BUNDLE_PATH,
+ extract_zipped_paths,
+ get_auth_from_url,
+ get_encoding_from_headers,
+ prepend_scheme_if_needed,
+ select_proxy,
+ urldefragauth,
+)
+
+try:
+ from urllib3.contrib.socks import SOCKSProxyManager
+except ImportError:
+
+ def SOCKSProxyManager(*args, **kwargs):
+ raise InvalidSchema("Missing dependencies for SOCKS support.")
+
+
+if typing.TYPE_CHECKING:
+ from .models import PreparedRequest
+
+
+DEFAULT_POOLBLOCK = False
+DEFAULT_POOLSIZE = 10
+DEFAULT_RETRIES = 0
+DEFAULT_POOL_TIMEOUT = None
+
+
+try:
+ import ssl # noqa: F401
+
+ _preloaded_ssl_context = create_urllib3_context()
+ _preloaded_ssl_context.load_verify_locations(
+ extract_zipped_paths(DEFAULT_CA_BUNDLE_PATH)
+ )
+except ImportError:
+ # Bypass default SSLContext creation when Python
+ # interpreter isn't built with the ssl module.
+ _preloaded_ssl_context = None
+
+
+def _urllib3_request_context(
+ request: "PreparedRequest",
+ verify: "bool | str | None",
+ client_cert: "typing.Tuple[str, str] | str | None",
+ poolmanager: "PoolManager",
+) -> "(typing.Dict[str, typing.Any], typing.Dict[str, typing.Any])":
+ host_params = {}
+ pool_kwargs = {}
+ parsed_request_url = urlparse(request.url)
+ scheme = parsed_request_url.scheme.lower()
+ port = parsed_request_url.port
+
+ # Determine if we have and should use our default SSLContext
+ # to optimize performance on standard requests.
+ poolmanager_kwargs = getattr(poolmanager, "connection_pool_kw", {})
+ has_poolmanager_ssl_context = poolmanager_kwargs.get("ssl_context")
+ should_use_default_ssl_context = (
+ _preloaded_ssl_context is not None and not has_poolmanager_ssl_context
+ )
+
+ cert_reqs = "CERT_REQUIRED"
+ if verify is False:
+ cert_reqs = "CERT_NONE"
+ elif verify is True and should_use_default_ssl_context:
+ pool_kwargs["ssl_context"] = _preloaded_ssl_context
+ elif isinstance(verify, str):
+ if not os.path.isdir(verify):
+ pool_kwargs["ca_certs"] = verify
+ else:
+ pool_kwargs["ca_cert_dir"] = verify
+ pool_kwargs["cert_reqs"] = cert_reqs
+ if client_cert is not None:
+ if isinstance(client_cert, tuple) and len(client_cert) == 2:
+ pool_kwargs["cert_file"] = client_cert[0]
+ pool_kwargs["key_file"] = client_cert[1]
+ else:
+ # According to our docs, we allow users to specify just the client
+ # cert path
+ pool_kwargs["cert_file"] = client_cert
+ host_params = {
+ "scheme": scheme,
+ "host": parsed_request_url.hostname,
+ "port": port,
+ }
+ return host_params, pool_kwargs
+
+
+class BaseAdapter:
+ """The Base Transport Adapter"""
+
+ def __init__(self):
+ super().__init__()
+
+ def send(
+ self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None
+ ):
+ """Sends PreparedRequest object. Returns Response object.
+
+ :param request: The :class:`PreparedRequest ` being sent.
+ :param stream: (optional) Whether to stream the request content.
+ :param timeout: (optional) How long to wait for the server to send
+ data before giving up, as a float, or a :ref:`(connect timeout,
+ read timeout) ` tuple.
+ :type timeout: float or tuple
+ :param verify: (optional) Either a boolean, in which case it controls whether we verify
+ the server's TLS certificate, or a string, in which case it must be a path
+ to a CA bundle to use
+ :param cert: (optional) Any user-provided SSL certificate to be trusted.
+ :param proxies: (optional) The proxies dictionary to apply to the request.
+ """
+ raise NotImplementedError
+
+ def close(self):
+ """Cleans up adapter specific items."""
+ raise NotImplementedError
+
+
+class HTTPAdapter(BaseAdapter):
+ """The built-in HTTP Adapter for urllib3.
+
+ Provides a general-case interface for Requests sessions to contact HTTP and
+ HTTPS urls by implementing the Transport Adapter interface. This class will
+ usually be created by the :class:`Session ` class under the
+ covers.
+
+ :param pool_connections: The number of urllib3 connection pools to cache.
+ :param pool_maxsize: The maximum number of connections to save in the pool.
+ :param max_retries: The maximum number of retries each connection
+ should attempt. Note, this applies only to failed DNS lookups, socket
+ connections and connection timeouts, never to requests where data has
+ made it to the server. By default, Requests does not retry failed
+ connections. If you need granular control over the conditions under
+ which we retry a request, import urllib3's ``Retry`` class and pass
+ that instead.
+ :param pool_block: Whether the connection pool should block for connections.
+
+ Usage::
+
+ >>> import requests
+ >>> s = requests.Session()
+ >>> a = requests.adapters.HTTPAdapter(max_retries=3)
+ >>> s.mount('http://', a)
+ """
+
+ __attrs__ = [
+ "max_retries",
+ "config",
+ "_pool_connections",
+ "_pool_maxsize",
+ "_pool_block",
+ ]
+
+ def __init__(
+ self,
+ pool_connections=DEFAULT_POOLSIZE,
+ pool_maxsize=DEFAULT_POOLSIZE,
+ max_retries=DEFAULT_RETRIES,
+ pool_block=DEFAULT_POOLBLOCK,
+ ):
+ if max_retries == DEFAULT_RETRIES:
+ self.max_retries = Retry(0, read=False)
+ else:
+ self.max_retries = Retry.from_int(max_retries)
+ self.config = {}
+ self.proxy_manager = {}
+
+ super().__init__()
+
+ self._pool_connections = pool_connections
+ self._pool_maxsize = pool_maxsize
+ self._pool_block = pool_block
+
+ self.init_poolmanager(pool_connections, pool_maxsize, block=pool_block)
+
+ def __getstate__(self):
+ return {attr: getattr(self, attr, None) for attr in self.__attrs__}
+
+ def __setstate__(self, state):
+ # Can't handle by adding 'proxy_manager' to self.__attrs__ because
+ # self.poolmanager uses a lambda function, which isn't pickleable.
+ self.proxy_manager = {}
+ self.config = {}
+
+ for attr, value in state.items():
+ setattr(self, attr, value)
+
+ self.init_poolmanager(
+ self._pool_connections, self._pool_maxsize, block=self._pool_block
+ )
+
+ def init_poolmanager(
+ self, connections, maxsize, block=DEFAULT_POOLBLOCK, **pool_kwargs
+ ):
+ """Initializes a urllib3 PoolManager.
+
+ This method should not be called from user code, and is only
+ exposed for use when subclassing the
+ :class:`HTTPAdapter `.
+
+ :param connections: The number of urllib3 connection pools to cache.
+ :param maxsize: The maximum number of connections to save in the pool.
+ :param block: Block when no free connections are available.
+ :param pool_kwargs: Extra keyword arguments used to initialize the Pool Manager.
+ """
+ # save these values for pickling
+ self._pool_connections = connections
+ self._pool_maxsize = maxsize
+ self._pool_block = block
+
+ self.poolmanager = PoolManager(
+ num_pools=connections,
+ maxsize=maxsize,
+ block=block,
+ **pool_kwargs,
+ )
+
+ def proxy_manager_for(self, proxy, **proxy_kwargs):
+ """Return urllib3 ProxyManager for the given proxy.
+
+ This method should not be called from user code, and is only
+ exposed for use when subclassing the
+ :class:`HTTPAdapter `.
+
+ :param proxy: The proxy to return a urllib3 ProxyManager for.
+ :param proxy_kwargs: Extra keyword arguments used to configure the Proxy Manager.
+ :returns: ProxyManager
+ :rtype: urllib3.ProxyManager
+ """
+ if proxy in self.proxy_manager:
+ manager = self.proxy_manager[proxy]
+ elif proxy.lower().startswith("socks"):
+ username, password = get_auth_from_url(proxy)
+ manager = self.proxy_manager[proxy] = SOCKSProxyManager(
+ proxy,
+ username=username,
+ password=password,
+ num_pools=self._pool_connections,
+ maxsize=self._pool_maxsize,
+ block=self._pool_block,
+ **proxy_kwargs,
+ )
+ else:
+ proxy_headers = self.proxy_headers(proxy)
+ manager = self.proxy_manager[proxy] = proxy_from_url(
+ proxy,
+ proxy_headers=proxy_headers,
+ num_pools=self._pool_connections,
+ maxsize=self._pool_maxsize,
+ block=self._pool_block,
+ **proxy_kwargs,
+ )
+
+ return manager
+
+ def cert_verify(self, conn, url, verify, cert):
+ """Verify a SSL certificate. This method should not be called from user
+ code, and is only exposed for use when subclassing the
+ :class:`HTTPAdapter `.
+
+ :param conn: The urllib3 connection object associated with the cert.
+ :param url: The requested URL.
+ :param verify: Either a boolean, in which case it controls whether we verify
+ the server's TLS certificate, or a string, in which case it must be a path
+ to a CA bundle to use
+ :param cert: The SSL certificate to verify.
+ """
+ if url.lower().startswith("https") and verify:
+ conn.cert_reqs = "CERT_REQUIRED"
+
+ # Only load the CA certificates if 'verify' is a string indicating the CA bundle to use.
+ # Otherwise, if verify is a boolean, we don't load anything since
+ # the connection will be using a context with the default certificates already loaded,
+ # and this avoids a call to the slow load_verify_locations()
+ if verify is not True:
+ # `verify` must be a str with a path then
+ cert_loc = verify
+
+ if not os.path.exists(cert_loc):
+ raise OSError(
+ f"Could not find a suitable TLS CA certificate bundle, "
+ f"invalid path: {cert_loc}"
+ )
+
+ if not os.path.isdir(cert_loc):
+ conn.ca_certs = cert_loc
+ else:
+ conn.ca_cert_dir = cert_loc
+ else:
+ conn.cert_reqs = "CERT_NONE"
+ conn.ca_certs = None
+ conn.ca_cert_dir = None
+
+ if cert:
+ if not isinstance(cert, basestring):
+ conn.cert_file = cert[0]
+ conn.key_file = cert[1]
+ else:
+ conn.cert_file = cert
+ conn.key_file = None
+ if conn.cert_file and not os.path.exists(conn.cert_file):
+ raise OSError(
+ f"Could not find the TLS certificate file, "
+ f"invalid path: {conn.cert_file}"
+ )
+ if conn.key_file and not os.path.exists(conn.key_file):
+ raise OSError(
+ f"Could not find the TLS key file, invalid path: {conn.key_file}"
+ )
+
+ def build_response(self, req, resp):
+ """Builds a :class:`Response ` object from a urllib3
+ response. This should not be called from user code, and is only exposed
+ for use when subclassing the
+ :class:`HTTPAdapter `
+
+ :param req: The :class:`PreparedRequest ` used to generate the response.
+ :param resp: The urllib3 response object.
+ :rtype: requests.Response
+ """
+ response = Response()
+
+ # Fallback to None if there's no status_code, for whatever reason.
+ response.status_code = getattr(resp, "status", None)
+
+ # Make headers case-insensitive.
+ response.headers = CaseInsensitiveDict(getattr(resp, "headers", {}))
+
+ # Set encoding.
+ response.encoding = get_encoding_from_headers(response.headers)
+ response.raw = resp
+ response.reason = response.raw.reason
+
+ if isinstance(req.url, bytes):
+ response.url = req.url.decode("utf-8")
+ else:
+ response.url = req.url
+
+ # Add new cookies from the server.
+ extract_cookies_to_jar(response.cookies, req, resp)
+
+ # Give the Response some context.
+ response.request = req
+ response.connection = self
+
+ return response
+
+ def build_connection_pool_key_attributes(self, request, verify, cert=None):
+ """Build the PoolKey attributes used by urllib3 to return a connection.
+
+ This looks at the PreparedRequest, the user-specified verify value,
+ and the value of the cert parameter to determine what PoolKey values
+ to use to select a connection from a given urllib3 Connection Pool.
+
+ The SSL related pool key arguments are not consistently set. As of
+ this writing, use the following to determine what keys may be in that
+ dictionary:
+
+ * If ``verify`` is ``True``, ``"ssl_context"`` will be set and will be the
+ default Requests SSL Context
+ * If ``verify`` is ``False``, ``"ssl_context"`` will not be set but
+ ``"cert_reqs"`` will be set
+ * If ``verify`` is a string, (i.e., it is a user-specified trust bundle)
+ ``"ca_certs"`` will be set if the string is not a directory recognized
+ by :py:func:`os.path.isdir`, otherwise ``"ca_certs_dir"`` will be
+ set.
+ * If ``"cert"`` is specified, ``"cert_file"`` will always be set. If
+ ``"cert"`` is a tuple with a second item, ``"key_file"`` will also
+ be present
+
+ To override these settings, one may subclass this class, call this
+ method and use the above logic to change parameters as desired. For
+ example, if one wishes to use a custom :py:class:`ssl.SSLContext` one
+ must both set ``"ssl_context"`` and based on what else they require,
+ alter the other keys to ensure the desired behaviour.
+
+ :param request:
+ The PreparedReqest being sent over the connection.
+ :type request:
+ :class:`~requests.models.PreparedRequest`
+ :param verify:
+ Either a boolean, in which case it controls whether
+ we verify the server's TLS certificate, or a string, in which case it
+ must be a path to a CA bundle to use.
+ :param cert:
+ (optional) Any user-provided SSL certificate for client
+ authentication (a.k.a., mTLS). This may be a string (i.e., just
+ the path to a file which holds both certificate and key) or a
+ tuple of length 2 with the certificate file path and key file
+ path.
+ :returns:
+ A tuple of two dictionaries. The first is the "host parameters"
+ portion of the Pool Key including scheme, hostname, and port. The
+ second is a dictionary of SSLContext related parameters.
+ """
+ return _urllib3_request_context(request, verify, cert, self.poolmanager)
+
+ def get_connection_with_tls_context(self, request, verify, proxies=None, cert=None):
+ """Returns a urllib3 connection for the given request and TLS settings.
+ This should not be called from user code, and is only exposed for use
+ when subclassing the :class:`HTTPAdapter `.
+
+ :param request:
+ The :class:`PreparedRequest ` object to be sent
+ over the connection.
+ :param verify:
+ Either a boolean, in which case it controls whether we verify the
+ server's TLS certificate, or a string, in which case it must be a
+ path to a CA bundle to use.
+ :param proxies:
+ (optional) The proxies dictionary to apply to the request.
+ :param cert:
+ (optional) Any user-provided SSL certificate to be used for client
+ authentication (a.k.a., mTLS).
+ :rtype:
+ urllib3.ConnectionPool
+ """
+ proxy = select_proxy(request.url, proxies)
+ try:
+ host_params, pool_kwargs = self.build_connection_pool_key_attributes(
+ request,
+ verify,
+ cert,
+ )
+ except ValueError as e:
+ raise InvalidURL(e, request=request)
+ if proxy:
+ proxy = prepend_scheme_if_needed(proxy, "http")
+ proxy_url = parse_url(proxy)
+ if not proxy_url.host:
+ raise InvalidProxyURL(
+ "Please check proxy URL. It is malformed "
+ "and could be missing the host."
+ )
+ proxy_manager = self.proxy_manager_for(proxy)
+ conn = proxy_manager.connection_from_host(
+ **host_params, pool_kwargs=pool_kwargs
+ )
+ else:
+ # Only scheme should be lower case
+ conn = self.poolmanager.connection_from_host(
+ **host_params, pool_kwargs=pool_kwargs
+ )
+
+ return conn
+
+ def get_connection(self, url, proxies=None):
+ """DEPRECATED: Users should move to `get_connection_with_tls_context`
+ for all subclasses of HTTPAdapter using Requests>=2.32.2.
+
+ Returns a urllib3 connection for the given URL. This should not be
+ called from user code, and is only exposed for use when subclassing the
+ :class:`HTTPAdapter `.
+
+ :param url: The URL to connect to.
+ :param proxies: (optional) A Requests-style dictionary of proxies used on this request.
+ :rtype: urllib3.ConnectionPool
+ """
+ warnings.warn(
+ (
+ "`get_connection` has been deprecated in favor of "
+ "`get_connection_with_tls_context`. Custom HTTPAdapter subclasses "
+ "will need to migrate for Requests>=2.32.2. Please see "
+ "https://github.com/psf/requests/pull/6710 for more details."
+ ),
+ DeprecationWarning,
+ )
+ proxy = select_proxy(url, proxies)
+
+ if proxy:
+ proxy = prepend_scheme_if_needed(proxy, "http")
+ proxy_url = parse_url(proxy)
+ if not proxy_url.host:
+ raise InvalidProxyURL(
+ "Please check proxy URL. It is malformed "
+ "and could be missing the host."
+ )
+ proxy_manager = self.proxy_manager_for(proxy)
+ conn = proxy_manager.connection_from_url(url)
+ else:
+ # Only scheme should be lower case
+ parsed = urlparse(url)
+ url = parsed.geturl()
+ conn = self.poolmanager.connection_from_url(url)
+
+ return conn
+
+ def close(self):
+ """Disposes of any internal state.
+
+ Currently, this closes the PoolManager and any active ProxyManager,
+ which closes any pooled connections.
+ """
+ self.poolmanager.clear()
+ for proxy in self.proxy_manager.values():
+ proxy.clear()
+
+ def request_url(self, request, proxies):
+ """Obtain the url to use when making the final request.
+
+ If the message is being sent through a HTTP proxy, the full URL has to
+ be used. Otherwise, we should only use the path portion of the URL.
+
+ This should not be called from user code, and is only exposed for use
+ when subclassing the
+ :class:`HTTPAdapter `.
+
+ :param request: The :class:`PreparedRequest ` being sent.
+ :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs.
+ :rtype: str
+ """
+ proxy = select_proxy(request.url, proxies)
+ scheme = urlparse(request.url).scheme
+
+ is_proxied_http_request = proxy and scheme != "https"
+ using_socks_proxy = False
+ if proxy:
+ proxy_scheme = urlparse(proxy).scheme.lower()
+ using_socks_proxy = proxy_scheme.startswith("socks")
+
+ url = request.path_url
+ if url.startswith("//"): # Don't confuse urllib3
+ url = f"/{url.lstrip('/')}"
+
+ if is_proxied_http_request and not using_socks_proxy:
+ url = urldefragauth(request.url)
+
+ return url
+
+ def add_headers(self, request, **kwargs):
+ """Add any headers needed by the connection. As of v2.0 this does
+ nothing by default, but is left for overriding by users that subclass
+ the :class:`HTTPAdapter `.
+
+ This should not be called from user code, and is only exposed for use
+ when subclassing the
+ :class:`HTTPAdapter `.
+
+ :param request: The :class:`PreparedRequest ` to add headers to.
+ :param kwargs: The keyword arguments from the call to send().
+ """
+ pass
+
+ def proxy_headers(self, proxy):
+ """Returns a dictionary of the headers to add to any request sent
+ through a proxy. This works with urllib3 magic to ensure that they are
+ correctly sent to the proxy, rather than in a tunnelled request if
+ CONNECT is being used.
+
+ This should not be called from user code, and is only exposed for use
+ when subclassing the
+ :class:`HTTPAdapter `.
+
+ :param proxy: The url of the proxy being used for this request.
+ :rtype: dict
+ """
+ headers = {}
+ username, password = get_auth_from_url(proxy)
+
+ if username:
+ headers["Proxy-Authorization"] = _basic_auth_str(username, password)
+
+ return headers
+
+ def send(
+ self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None
+ ):
+ """Sends PreparedRequest object. Returns Response object.
+
+ :param request: The :class:`PreparedRequest ` being sent.
+ :param stream: (optional) Whether to stream the request content.
+ :param timeout: (optional) How long to wait for the server to send
+ data before giving up, as a float, or a :ref:`(connect timeout,
+ read timeout) ` tuple.
+ :type timeout: float or tuple or urllib3 Timeout object
+ :param verify: (optional) Either a boolean, in which case it controls whether
+ we verify the server's TLS certificate, or a string, in which case it
+ must be a path to a CA bundle to use
+ :param cert: (optional) Any user-provided SSL certificate to be trusted.
+ :param proxies: (optional) The proxies dictionary to apply to the request.
+ :rtype: requests.Response
+ """
+
+ try:
+ conn = self.get_connection_with_tls_context(
+ request, verify, proxies=proxies, cert=cert
+ )
+ except LocationValueError as e:
+ raise InvalidURL(e, request=request)
+
+ self.cert_verify(conn, request.url, verify, cert)
+ url = self.request_url(request, proxies)
+ self.add_headers(
+ request,
+ stream=stream,
+ timeout=timeout,
+ verify=verify,
+ cert=cert,
+ proxies=proxies,
+ )
+
+ chunked = not (request.body is None or "Content-Length" in request.headers)
+
+ if isinstance(timeout, tuple):
+ try:
+ connect, read = timeout
+ timeout = TimeoutSauce(connect=connect, read=read)
+ except ValueError:
+ raise ValueError(
+ f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, "
+ f"or a single float to set both timeouts to the same value."
+ )
+ elif isinstance(timeout, TimeoutSauce):
+ pass
+ else:
+ timeout = TimeoutSauce(connect=timeout, read=timeout)
+
+ try:
+ resp = conn.urlopen(
+ method=request.method,
+ url=url,
+ body=request.body,
+ headers=request.headers,
+ redirect=False,
+ assert_same_host=False,
+ preload_content=False,
+ decode_content=False,
+ retries=self.max_retries,
+ timeout=timeout,
+ chunked=chunked,
+ )
+
+ except (ProtocolError, OSError) as err:
+ raise ConnectionError(err, request=request)
+
+ except MaxRetryError as e:
+ if isinstance(e.reason, ConnectTimeoutError):
+ # TODO: Remove this in 3.0.0: see #2811
+ if not isinstance(e.reason, NewConnectionError):
+ raise ConnectTimeout(e, request=request)
+
+ if isinstance(e.reason, ResponseError):
+ raise RetryError(e, request=request)
+
+ if isinstance(e.reason, _ProxyError):
+ raise ProxyError(e, request=request)
+
+ if isinstance(e.reason, _SSLError):
+ # This branch is for urllib3 v1.22 and later.
+ raise SSLError(e, request=request)
+
+ raise ConnectionError(e, request=request)
+
+ except ClosedPoolError as e:
+ raise ConnectionError(e, request=request)
+
+ except _ProxyError as e:
+ raise ProxyError(e)
+
+ except (_SSLError, _HTTPError) as e:
+ if isinstance(e, _SSLError):
+ # This branch is for urllib3 versions earlier than v1.22
+ raise SSLError(e, request=request)
+ elif isinstance(e, ReadTimeoutError):
+ raise ReadTimeout(e, request=request)
+ elif isinstance(e, _InvalidHeader):
+ raise InvalidHeader(e, request=request)
+ else:
+ raise
+
+ return self.build_response(request, resp)
diff --git a/venv/Lib/site-packages/requests/api.py b/venv/Lib/site-packages/requests/api.py
new file mode 100644
index 00000000..59607445
--- /dev/null
+++ b/venv/Lib/site-packages/requests/api.py
@@ -0,0 +1,157 @@
+"""
+requests.api
+~~~~~~~~~~~~
+
+This module implements the Requests API.
+
+:copyright: (c) 2012 by Kenneth Reitz.
+:license: Apache2, see LICENSE for more details.
+"""
+
+from . import sessions
+
+
+def request(method, url, **kwargs):
+ """Constructs and sends a :class:`Request `.
+
+ :param method: method for the new :class:`Request` object: ``GET``, ``OPTIONS``, ``HEAD``, ``POST``, ``PUT``, ``PATCH``, or ``DELETE``.
+ :param url: URL for the new :class:`Request` object.
+ :param params: (optional) Dictionary, list of tuples or bytes to send
+ in the query string for the :class:`Request`.
+ :param data: (optional) Dictionary, list of tuples, bytes, or file-like
+ object to send in the body of the :class:`Request`.
+ :param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`.
+ :param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`.
+ :param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`.
+ :param files: (optional) Dictionary of ``'name': file-like-objects`` (or ``{'name': file-tuple}``) for multipart encoding upload.
+ ``file-tuple`` can be a 2-tuple ``('filename', fileobj)``, 3-tuple ``('filename', fileobj, 'content_type')``
+ or a 4-tuple ``('filename', fileobj, 'content_type', custom_headers)``, where ``'content_type'`` is a string
+ defining the content type of the given file and ``custom_headers`` a dict-like object containing additional headers
+ to add for the file.
+ :param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth.
+ :param timeout: (optional) How many seconds to wait for the server to send data
+ before giving up, as a float, or a :ref:`(connect timeout, read
+ timeout) ` tuple.
+ :type timeout: float or tuple
+ :param allow_redirects: (optional) Boolean. Enable/disable GET/OPTIONS/POST/PUT/PATCH/DELETE/HEAD redirection. Defaults to ``True``.
+ :type allow_redirects: bool
+ :param proxies: (optional) Dictionary mapping protocol to the URL of the proxy.
+ :param verify: (optional) Either a boolean, in which case it controls whether we verify
+ the server's TLS certificate, or a string, in which case it must be a path
+ to a CA bundle to use. Defaults to ``True``.
+ :param stream: (optional) if ``False``, the response content will be immediately downloaded.
+ :param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair.
+ :return: :class:`Response ` object
+ :rtype: requests.Response
+
+ Usage::
+
+ >>> import requests
+ >>> req = requests.request('GET', 'https://httpbin.org/get')
+ >>> req
+
+ """
+
+ # By using the 'with' statement we are sure the session is closed, thus we
+ # avoid leaving sockets open which can trigger a ResourceWarning in some
+ # cases, and look like a memory leak in others.
+ with sessions.Session() as session:
+ return session.request(method=method, url=url, **kwargs)
+
+
+def get(url, params=None, **kwargs):
+ r"""Sends a GET request.
+
+ :param url: URL for the new :class:`Request` object.
+ :param params: (optional) Dictionary, list of tuples or bytes to send
+ in the query string for the :class:`Request`.
+ :param \*\*kwargs: Optional arguments that ``request`` takes.
+ :return: :class:`Response ` object
+ :rtype: requests.Response
+ """
+
+ return request("get", url, params=params, **kwargs)
+
+
+def options(url, **kwargs):
+ r"""Sends an OPTIONS request.
+
+ :param url: URL for the new :class:`Request` object.
+ :param \*\*kwargs: Optional arguments that ``request`` takes.
+ :return: :class:`Response ` object
+ :rtype: requests.Response
+ """
+
+ return request("options", url, **kwargs)
+
+
+def head(url, **kwargs):
+ r"""Sends a HEAD request.
+
+ :param url: URL for the new :class:`Request` object.
+ :param \*\*kwargs: Optional arguments that ``request`` takes. If
+ `allow_redirects` is not provided, it will be set to `False` (as
+ opposed to the default :meth:`request` behavior).
+ :return: :class:`Response ` object
+ :rtype: requests.Response
+ """
+
+ kwargs.setdefault("allow_redirects", False)
+ return request("head", url, **kwargs)
+
+
+def post(url, data=None, json=None, **kwargs):
+ r"""Sends a POST request.
+
+ :param url: URL for the new :class:`Request` object.
+ :param data: (optional) Dictionary, list of tuples, bytes, or file-like
+ object to send in the body of the :class:`Request`.
+ :param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`.
+ :param \*\*kwargs: Optional arguments that ``request`` takes.
+ :return: :class:`Response ` object
+ :rtype: requests.Response
+ """
+
+ return request("post", url, data=data, json=json, **kwargs)
+
+
+def put(url, data=None, **kwargs):
+ r"""Sends a PUT request.
+
+ :param url: URL for the new :class:`Request` object.
+ :param data: (optional) Dictionary, list of tuples, bytes, or file-like
+ object to send in the body of the :class:`Request`.
+ :param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`.
+ :param \*\*kwargs: Optional arguments that ``request`` takes.
+ :return: :class:`Response ` object
+ :rtype: requests.Response
+ """
+
+ return request("put", url, data=data, **kwargs)
+
+
+def patch(url, data=None, **kwargs):
+ r"""Sends a PATCH request.
+
+ :param url: URL for the new :class:`Request` object.
+ :param data: (optional) Dictionary, list of tuples, bytes, or file-like
+ object to send in the body of the :class:`Request`.
+ :param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`.
+ :param \*\*kwargs: Optional arguments that ``request`` takes.
+ :return: :class:`Response ` object
+ :rtype: requests.Response
+ """
+
+ return request("patch", url, data=data, **kwargs)
+
+
+def delete(url, **kwargs):
+ r"""Sends a DELETE request.
+
+ :param url: URL for the new :class:`Request` object.
+ :param \*\*kwargs: Optional arguments that ``request`` takes.
+ :return: :class:`Response ` object
+ :rtype: requests.Response
+ """
+
+ return request("delete", url, **kwargs)
diff --git a/venv/Lib/site-packages/requests/auth.py b/venv/Lib/site-packages/requests/auth.py
new file mode 100644
index 00000000..4a7ce6dc
--- /dev/null
+++ b/venv/Lib/site-packages/requests/auth.py
@@ -0,0 +1,314 @@
+"""
+requests.auth
+~~~~~~~~~~~~~
+
+This module contains the authentication handlers for Requests.
+"""
+
+import hashlib
+import os
+import re
+import threading
+import time
+import warnings
+from base64 import b64encode
+
+from ._internal_utils import to_native_string
+from .compat import basestring, str, urlparse
+from .cookies import extract_cookies_to_jar
+from .utils import parse_dict_header
+
+CONTENT_TYPE_FORM_URLENCODED = "application/x-www-form-urlencoded"
+CONTENT_TYPE_MULTI_PART = "multipart/form-data"
+
+
+def _basic_auth_str(username, password):
+ """Returns a Basic Auth string."""
+
+ # "I want us to put a big-ol' comment on top of it that
+ # says that this behaviour is dumb but we need to preserve
+ # it because people are relying on it."
+ # - Lukasa
+ #
+ # These are here solely to maintain backwards compatibility
+ # for things like ints. This will be removed in 3.0.0.
+ if not isinstance(username, basestring):
+ warnings.warn(
+ "Non-string usernames will no longer be supported in Requests "
+ "3.0.0. Please convert the object you've passed in ({!r}) to "
+ "a string or bytes object in the near future to avoid "
+ "problems.".format(username),
+ category=DeprecationWarning,
+ )
+ username = str(username)
+
+ if not isinstance(password, basestring):
+ warnings.warn(
+ "Non-string passwords will no longer be supported in Requests "
+ "3.0.0. Please convert the object you've passed in ({!r}) to "
+ "a string or bytes object in the near future to avoid "
+ "problems.".format(type(password)),
+ category=DeprecationWarning,
+ )
+ password = str(password)
+ # -- End Removal --
+
+ if isinstance(username, str):
+ username = username.encode("latin1")
+
+ if isinstance(password, str):
+ password = password.encode("latin1")
+
+ authstr = "Basic " + to_native_string(
+ b64encode(b":".join((username, password))).strip()
+ )
+
+ return authstr
+
+
+class AuthBase:
+ """Base class that all auth implementations derive from"""
+
+ def __call__(self, r):
+ raise NotImplementedError("Auth hooks must be callable.")
+
+
+class HTTPBasicAuth(AuthBase):
+ """Attaches HTTP Basic Authentication to the given Request object."""
+
+ def __init__(self, username, password):
+ self.username = username
+ self.password = password
+
+ def __eq__(self, other):
+ return all(
+ [
+ self.username == getattr(other, "username", None),
+ self.password == getattr(other, "password", None),
+ ]
+ )
+
+ def __ne__(self, other):
+ return not self == other
+
+ def __call__(self, r):
+ r.headers["Authorization"] = _basic_auth_str(self.username, self.password)
+ return r
+
+
+class HTTPProxyAuth(HTTPBasicAuth):
+ """Attaches HTTP Proxy Authentication to a given Request object."""
+
+ def __call__(self, r):
+ r.headers["Proxy-Authorization"] = _basic_auth_str(self.username, self.password)
+ return r
+
+
+class HTTPDigestAuth(AuthBase):
+ """Attaches HTTP Digest Authentication to the given Request object."""
+
+ def __init__(self, username, password):
+ self.username = username
+ self.password = password
+ # Keep state in per-thread local storage
+ self._thread_local = threading.local()
+
+ def init_per_thread_state(self):
+ # Ensure state is initialized just once per-thread
+ if not hasattr(self._thread_local, "init"):
+ self._thread_local.init = True
+ self._thread_local.last_nonce = ""
+ self._thread_local.nonce_count = 0
+ self._thread_local.chal = {}
+ self._thread_local.pos = None
+ self._thread_local.num_401_calls = None
+
+ def build_digest_header(self, method, url):
+ """
+ :rtype: str
+ """
+
+ realm = self._thread_local.chal["realm"]
+ nonce = self._thread_local.chal["nonce"]
+ qop = self._thread_local.chal.get("qop")
+ algorithm = self._thread_local.chal.get("algorithm")
+ opaque = self._thread_local.chal.get("opaque")
+ hash_utf8 = None
+
+ if algorithm is None:
+ _algorithm = "MD5"
+ else:
+ _algorithm = algorithm.upper()
+ # lambdas assume digest modules are imported at the top level
+ if _algorithm == "MD5" or _algorithm == "MD5-SESS":
+
+ def md5_utf8(x):
+ if isinstance(x, str):
+ x = x.encode("utf-8")
+ return hashlib.md5(x).hexdigest()
+
+ hash_utf8 = md5_utf8
+ elif _algorithm == "SHA":
+
+ def sha_utf8(x):
+ if isinstance(x, str):
+ x = x.encode("utf-8")
+ return hashlib.sha1(x).hexdigest()
+
+ hash_utf8 = sha_utf8
+ elif _algorithm == "SHA-256":
+
+ def sha256_utf8(x):
+ if isinstance(x, str):
+ x = x.encode("utf-8")
+ return hashlib.sha256(x).hexdigest()
+
+ hash_utf8 = sha256_utf8
+ elif _algorithm == "SHA-512":
+
+ def sha512_utf8(x):
+ if isinstance(x, str):
+ x = x.encode("utf-8")
+ return hashlib.sha512(x).hexdigest()
+
+ hash_utf8 = sha512_utf8
+
+ KD = lambda s, d: hash_utf8(f"{s}:{d}") # noqa:E731
+
+ if hash_utf8 is None:
+ return None
+
+ # XXX not implemented yet
+ entdig = None
+ p_parsed = urlparse(url)
+ #: path is request-uri defined in RFC 2616 which should not be empty
+ path = p_parsed.path or "/"
+ if p_parsed.query:
+ path += f"?{p_parsed.query}"
+
+ A1 = f"{self.username}:{realm}:{self.password}"
+ A2 = f"{method}:{path}"
+
+ HA1 = hash_utf8(A1)
+ HA2 = hash_utf8(A2)
+
+ if nonce == self._thread_local.last_nonce:
+ self._thread_local.nonce_count += 1
+ else:
+ self._thread_local.nonce_count = 1
+ ncvalue = f"{self._thread_local.nonce_count:08x}"
+ s = str(self._thread_local.nonce_count).encode("utf-8")
+ s += nonce.encode("utf-8")
+ s += time.ctime().encode("utf-8")
+ s += os.urandom(8)
+
+ cnonce = hashlib.sha1(s).hexdigest()[:16]
+ if _algorithm == "MD5-SESS":
+ HA1 = hash_utf8(f"{HA1}:{nonce}:{cnonce}")
+
+ if not qop:
+ respdig = KD(HA1, f"{nonce}:{HA2}")
+ elif qop == "auth" or "auth" in qop.split(","):
+ noncebit = f"{nonce}:{ncvalue}:{cnonce}:auth:{HA2}"
+ respdig = KD(HA1, noncebit)
+ else:
+ # XXX handle auth-int.
+ return None
+
+ self._thread_local.last_nonce = nonce
+
+ # XXX should the partial digests be encoded too?
+ base = (
+ f'username="{self.username}", realm="{realm}", nonce="{nonce}", '
+ f'uri="{path}", response="{respdig}"'
+ )
+ if opaque:
+ base += f', opaque="{opaque}"'
+ if algorithm:
+ base += f', algorithm="{algorithm}"'
+ if entdig:
+ base += f', digest="{entdig}"'
+ if qop:
+ base += f', qop="auth", nc={ncvalue}, cnonce="{cnonce}"'
+
+ return f"Digest {base}"
+
+ def handle_redirect(self, r, **kwargs):
+ """Reset num_401_calls counter on redirects."""
+ if r.is_redirect:
+ self._thread_local.num_401_calls = 1
+
+ def handle_401(self, r, **kwargs):
+ """
+ Takes the given response and tries digest-auth, if needed.
+
+ :rtype: requests.Response
+ """
+
+ # If response is not 4xx, do not auth
+ # See https://github.com/psf/requests/issues/3772
+ if not 400 <= r.status_code < 500:
+ self._thread_local.num_401_calls = 1
+ return r
+
+ if self._thread_local.pos is not None:
+ # Rewind the file position indicator of the body to where
+ # it was to resend the request.
+ r.request.body.seek(self._thread_local.pos)
+ s_auth = r.headers.get("www-authenticate", "")
+
+ if "digest" in s_auth.lower() and self._thread_local.num_401_calls < 2:
+ self._thread_local.num_401_calls += 1
+ pat = re.compile(r"digest ", flags=re.IGNORECASE)
+ self._thread_local.chal = parse_dict_header(pat.sub("", s_auth, count=1))
+
+ # Consume content and release the original connection
+ # to allow our new request to reuse the same one.
+ r.content
+ r.close()
+ prep = r.request.copy()
+ extract_cookies_to_jar(prep._cookies, r.request, r.raw)
+ prep.prepare_cookies(prep._cookies)
+
+ prep.headers["Authorization"] = self.build_digest_header(
+ prep.method, prep.url
+ )
+ _r = r.connection.send(prep, **kwargs)
+ _r.history.append(r)
+ _r.request = prep
+
+ return _r
+
+ self._thread_local.num_401_calls = 1
+ return r
+
+ def __call__(self, r):
+ # Initialize per-thread state, if needed
+ self.init_per_thread_state()
+ # If we have a saved nonce, skip the 401
+ if self._thread_local.last_nonce:
+ r.headers["Authorization"] = self.build_digest_header(r.method, r.url)
+ try:
+ self._thread_local.pos = r.body.tell()
+ except AttributeError:
+ # In the case of HTTPDigestAuth being reused and the body of
+ # the previous request was a file-like object, pos has the
+ # file position of the previous body. Ensure it's set to
+ # None.
+ self._thread_local.pos = None
+ r.register_hook("response", self.handle_401)
+ r.register_hook("response", self.handle_redirect)
+ self._thread_local.num_401_calls = 1
+
+ return r
+
+ def __eq__(self, other):
+ return all(
+ [
+ self.username == getattr(other, "username", None),
+ self.password == getattr(other, "password", None),
+ ]
+ )
+
+ def __ne__(self, other):
+ return not self == other
diff --git a/venv/Lib/site-packages/requests/certs.py b/venv/Lib/site-packages/requests/certs.py
new file mode 100644
index 00000000..be422c3e
--- /dev/null
+++ b/venv/Lib/site-packages/requests/certs.py
@@ -0,0 +1,17 @@
+#!/usr/bin/env python
+
+"""
+requests.certs
+~~~~~~~~~~~~~~
+
+This module returns the preferred default CA certificate bundle. There is
+only one — the one from the certifi package.
+
+If you are packaging Requests, e.g., for a Linux distribution or a managed
+environment, you can change the definition of where() to return a separately
+packaged CA bundle.
+"""
+from certifi import where
+
+if __name__ == "__main__":
+ print(where())
diff --git a/venv/Lib/site-packages/requests/compat.py b/venv/Lib/site-packages/requests/compat.py
new file mode 100644
index 00000000..7f9d7543
--- /dev/null
+++ b/venv/Lib/site-packages/requests/compat.py
@@ -0,0 +1,106 @@
+"""
+requests.compat
+~~~~~~~~~~~~~~~
+
+This module previously handled import compatibility issues
+between Python 2 and Python 3. It remains for backwards
+compatibility until the next major version.
+"""
+
+import importlib
+import sys
+
+# -------
+# urllib3
+# -------
+from urllib3 import __version__ as urllib3_version
+
+# Detect which major version of urllib3 is being used.
+try:
+ is_urllib3_1 = int(urllib3_version.split(".")[0]) == 1
+except (TypeError, AttributeError):
+ # If we can't discern a version, prefer old functionality.
+ is_urllib3_1 = True
+
+# -------------------
+# Character Detection
+# -------------------
+
+
+def _resolve_char_detection():
+ """Find supported character detection libraries."""
+ chardet = None
+ for lib in ("chardet", "charset_normalizer"):
+ if chardet is None:
+ try:
+ chardet = importlib.import_module(lib)
+ except ImportError:
+ pass
+ return chardet
+
+
+chardet = _resolve_char_detection()
+
+# -------
+# Pythons
+# -------
+
+# Syntax sugar.
+_ver = sys.version_info
+
+#: Python 2.x?
+is_py2 = _ver[0] == 2
+
+#: Python 3.x?
+is_py3 = _ver[0] == 3
+
+# json/simplejson module import resolution
+has_simplejson = False
+try:
+ import simplejson as json
+
+ has_simplejson = True
+except ImportError:
+ import json
+
+if has_simplejson:
+ from simplejson import JSONDecodeError
+else:
+ from json import JSONDecodeError
+
+# Keep OrderedDict for backwards compatibility.
+from collections import OrderedDict
+from collections.abc import Callable, Mapping, MutableMapping
+from http import cookiejar as cookielib
+from http.cookies import Morsel
+from io import StringIO
+
+# --------------
+# Legacy Imports
+# --------------
+from urllib.parse import (
+ quote,
+ quote_plus,
+ unquote,
+ unquote_plus,
+ urldefrag,
+ urlencode,
+ urljoin,
+ urlparse,
+ urlsplit,
+ urlunparse,
+)
+from urllib.request import (
+ getproxies,
+ getproxies_environment,
+ parse_http_list,
+ proxy_bypass,
+ proxy_bypass_environment,
+)
+
+builtin_str = str
+str = str
+bytes = bytes
+basestring = (str, bytes)
+numeric_types = (int, float)
+integer_types = (int,)
diff --git a/venv/Lib/site-packages/requests/cookies.py b/venv/Lib/site-packages/requests/cookies.py
new file mode 100644
index 00000000..f69d0cda
--- /dev/null
+++ b/venv/Lib/site-packages/requests/cookies.py
@@ -0,0 +1,561 @@
+"""
+requests.cookies
+~~~~~~~~~~~~~~~~
+
+Compatibility code to be able to use `http.cookiejar.CookieJar` with requests.
+
+requests.utils imports from here, so be careful with imports.
+"""
+
+import calendar
+import copy
+import time
+
+from ._internal_utils import to_native_string
+from .compat import Morsel, MutableMapping, cookielib, urlparse, urlunparse
+
+try:
+ import threading
+except ImportError:
+ import dummy_threading as threading
+
+
+class MockRequest:
+ """Wraps a `requests.Request` to mimic a `urllib2.Request`.
+
+ The code in `http.cookiejar.CookieJar` expects this interface in order to correctly
+ manage cookie policies, i.e., determine whether a cookie can be set, given the
+ domains of the request and the cookie.
+
+ The original request object is read-only. The client is responsible for collecting
+ the new headers via `get_new_headers()` and interpreting them appropriately. You
+ probably want `get_cookie_header`, defined below.
+ """
+
+ def __init__(self, request):
+ self._r = request
+ self._new_headers = {}
+ self.type = urlparse(self._r.url).scheme
+
+ def get_type(self):
+ return self.type
+
+ def get_host(self):
+ return urlparse(self._r.url).netloc
+
+ def get_origin_req_host(self):
+ return self.get_host()
+
+ def get_full_url(self):
+ # Only return the response's URL if the user hadn't set the Host
+ # header
+ if not self._r.headers.get("Host"):
+ return self._r.url
+ # If they did set it, retrieve it and reconstruct the expected domain
+ host = to_native_string(self._r.headers["Host"], encoding="utf-8")
+ parsed = urlparse(self._r.url)
+ # Reconstruct the URL as we expect it
+ return urlunparse(
+ [
+ parsed.scheme,
+ host,
+ parsed.path,
+ parsed.params,
+ parsed.query,
+ parsed.fragment,
+ ]
+ )
+
+ def is_unverifiable(self):
+ return True
+
+ def has_header(self, name):
+ return name in self._r.headers or name in self._new_headers
+
+ def get_header(self, name, default=None):
+ return self._r.headers.get(name, self._new_headers.get(name, default))
+
+ def add_header(self, key, val):
+ """cookiejar has no legitimate use for this method; add it back if you find one."""
+ raise NotImplementedError(
+ "Cookie headers should be added with add_unredirected_header()"
+ )
+
+ def add_unredirected_header(self, name, value):
+ self._new_headers[name] = value
+
+ def get_new_headers(self):
+ return self._new_headers
+
+ @property
+ def unverifiable(self):
+ return self.is_unverifiable()
+
+ @property
+ def origin_req_host(self):
+ return self.get_origin_req_host()
+
+ @property
+ def host(self):
+ return self.get_host()
+
+
+class MockResponse:
+ """Wraps a `httplib.HTTPMessage` to mimic a `urllib.addinfourl`.
+
+ ...what? Basically, expose the parsed HTTP headers from the server response
+ the way `http.cookiejar` expects to see them.
+ """
+
+ def __init__(self, headers):
+ """Make a MockResponse for `cookiejar` to read.
+
+ :param headers: a httplib.HTTPMessage or analogous carrying the headers
+ """
+ self._headers = headers
+
+ def info(self):
+ return self._headers
+
+ def getheaders(self, name):
+ self._headers.getheaders(name)
+
+
+def extract_cookies_to_jar(jar, request, response):
+ """Extract the cookies from the response into a CookieJar.
+
+ :param jar: http.cookiejar.CookieJar (not necessarily a RequestsCookieJar)
+ :param request: our own requests.Request object
+ :param response: urllib3.HTTPResponse object
+ """
+ if not (hasattr(response, "_original_response") and response._original_response):
+ return
+ # the _original_response field is the wrapped httplib.HTTPResponse object,
+ req = MockRequest(request)
+ # pull out the HTTPMessage with the headers and put it in the mock:
+ res = MockResponse(response._original_response.msg)
+ jar.extract_cookies(res, req)
+
+
+def get_cookie_header(jar, request):
+ """
+ Produce an appropriate Cookie header string to be sent with `request`, or None.
+
+ :rtype: str
+ """
+ r = MockRequest(request)
+ jar.add_cookie_header(r)
+ return r.get_new_headers().get("Cookie")
+
+
+def remove_cookie_by_name(cookiejar, name, domain=None, path=None):
+ """Unsets a cookie by name, by default over all domains and paths.
+
+ Wraps CookieJar.clear(), is O(n).
+ """
+ clearables = []
+ for cookie in cookiejar:
+ if cookie.name != name:
+ continue
+ if domain is not None and domain != cookie.domain:
+ continue
+ if path is not None and path != cookie.path:
+ continue
+ clearables.append((cookie.domain, cookie.path, cookie.name))
+
+ for domain, path, name in clearables:
+ cookiejar.clear(domain, path, name)
+
+
+class CookieConflictError(RuntimeError):
+ """There are two cookies that meet the criteria specified in the cookie jar.
+ Use .get and .set and include domain and path args in order to be more specific.
+ """
+
+
+class RequestsCookieJar(cookielib.CookieJar, MutableMapping):
+ """Compatibility class; is a http.cookiejar.CookieJar, but exposes a dict
+ interface.
+
+ This is the CookieJar we create by default for requests and sessions that
+ don't specify one, since some clients may expect response.cookies and
+ session.cookies to support dict operations.
+
+ Requests does not use the dict interface internally; it's just for
+ compatibility with external client code. All requests code should work
+ out of the box with externally provided instances of ``CookieJar``, e.g.
+ ``LWPCookieJar`` and ``FileCookieJar``.
+
+ Unlike a regular CookieJar, this class is pickleable.
+
+ .. warning:: dictionary operations that are normally O(1) may be O(n).
+ """
+
+ def get(self, name, default=None, domain=None, path=None):
+ """Dict-like get() that also supports optional domain and path args in
+ order to resolve naming collisions from using one cookie jar over
+ multiple domains.
+
+ .. warning:: operation is O(n), not O(1).
+ """
+ try:
+ return self._find_no_duplicates(name, domain, path)
+ except KeyError:
+ return default
+
+ def set(self, name, value, **kwargs):
+ """Dict-like set() that also supports optional domain and path args in
+ order to resolve naming collisions from using one cookie jar over
+ multiple domains.
+ """
+ # support client code that unsets cookies by assignment of a None value:
+ if value is None:
+ remove_cookie_by_name(
+ self, name, domain=kwargs.get("domain"), path=kwargs.get("path")
+ )
+ return
+
+ if isinstance(value, Morsel):
+ c = morsel_to_cookie(value)
+ else:
+ c = create_cookie(name, value, **kwargs)
+ self.set_cookie(c)
+ return c
+
+ def iterkeys(self):
+ """Dict-like iterkeys() that returns an iterator of names of cookies
+ from the jar.
+
+ .. seealso:: itervalues() and iteritems().
+ """
+ for cookie in iter(self):
+ yield cookie.name
+
+ def keys(self):
+ """Dict-like keys() that returns a list of names of cookies from the
+ jar.
+
+ .. seealso:: values() and items().
+ """
+ return list(self.iterkeys())
+
+ def itervalues(self):
+ """Dict-like itervalues() that returns an iterator of values of cookies
+ from the jar.
+
+ .. seealso:: iterkeys() and iteritems().
+ """
+ for cookie in iter(self):
+ yield cookie.value
+
+ def values(self):
+ """Dict-like values() that returns a list of values of cookies from the
+ jar.
+
+ .. seealso:: keys() and items().
+ """
+ return list(self.itervalues())
+
+ def iteritems(self):
+ """Dict-like iteritems() that returns an iterator of name-value tuples
+ from the jar.
+
+ .. seealso:: iterkeys() and itervalues().
+ """
+ for cookie in iter(self):
+ yield cookie.name, cookie.value
+
+ def items(self):
+ """Dict-like items() that returns a list of name-value tuples from the
+ jar. Allows client-code to call ``dict(RequestsCookieJar)`` and get a
+ vanilla python dict of key value pairs.
+
+ .. seealso:: keys() and values().
+ """
+ return list(self.iteritems())
+
+ def list_domains(self):
+ """Utility method to list all the domains in the jar."""
+ domains = []
+ for cookie in iter(self):
+ if cookie.domain not in domains:
+ domains.append(cookie.domain)
+ return domains
+
+ def list_paths(self):
+ """Utility method to list all the paths in the jar."""
+ paths = []
+ for cookie in iter(self):
+ if cookie.path not in paths:
+ paths.append(cookie.path)
+ return paths
+
+ def multiple_domains(self):
+ """Returns True if there are multiple domains in the jar.
+ Returns False otherwise.
+
+ :rtype: bool
+ """
+ domains = []
+ for cookie in iter(self):
+ if cookie.domain is not None and cookie.domain in domains:
+ return True
+ domains.append(cookie.domain)
+ return False # there is only one domain in jar
+
+ def get_dict(self, domain=None, path=None):
+ """Takes as an argument an optional domain and path and returns a plain
+ old Python dict of name-value pairs of cookies that meet the
+ requirements.
+
+ :rtype: dict
+ """
+ dictionary = {}
+ for cookie in iter(self):
+ if (domain is None or cookie.domain == domain) and (
+ path is None or cookie.path == path
+ ):
+ dictionary[cookie.name] = cookie.value
+ return dictionary
+
+ def __contains__(self, name):
+ try:
+ return super().__contains__(name)
+ except CookieConflictError:
+ return True
+
+ def __getitem__(self, name):
+ """Dict-like __getitem__() for compatibility with client code. Throws
+ exception if there are more than one cookie with name. In that case,
+ use the more explicit get() method instead.
+
+ .. warning:: operation is O(n), not O(1).
+ """
+ return self._find_no_duplicates(name)
+
+ def __setitem__(self, name, value):
+ """Dict-like __setitem__ for compatibility with client code. Throws
+ exception if there is already a cookie of that name in the jar. In that
+ case, use the more explicit set() method instead.
+ """
+ self.set(name, value)
+
+ def __delitem__(self, name):
+ """Deletes a cookie given a name. Wraps ``http.cookiejar.CookieJar``'s
+ ``remove_cookie_by_name()``.
+ """
+ remove_cookie_by_name(self, name)
+
+ def set_cookie(self, cookie, *args, **kwargs):
+ if (
+ hasattr(cookie.value, "startswith")
+ and cookie.value.startswith('"')
+ and cookie.value.endswith('"')
+ ):
+ cookie.value = cookie.value.replace('\\"', "")
+ return super().set_cookie(cookie, *args, **kwargs)
+
+ def update(self, other):
+ """Updates this jar with cookies from another CookieJar or dict-like"""
+ if isinstance(other, cookielib.CookieJar):
+ for cookie in other:
+ self.set_cookie(copy.copy(cookie))
+ else:
+ super().update(other)
+
+ def _find(self, name, domain=None, path=None):
+ """Requests uses this method internally to get cookie values.
+
+ If there are conflicting cookies, _find arbitrarily chooses one.
+ See _find_no_duplicates if you want an exception thrown if there are
+ conflicting cookies.
+
+ :param name: a string containing name of cookie
+ :param domain: (optional) string containing domain of cookie
+ :param path: (optional) string containing path of cookie
+ :return: cookie.value
+ """
+ for cookie in iter(self):
+ if cookie.name == name:
+ if domain is None or cookie.domain == domain:
+ if path is None or cookie.path == path:
+ return cookie.value
+
+ raise KeyError(f"name={name!r}, domain={domain!r}, path={path!r}")
+
+ def _find_no_duplicates(self, name, domain=None, path=None):
+ """Both ``__get_item__`` and ``get`` call this function: it's never
+ used elsewhere in Requests.
+
+ :param name: a string containing name of cookie
+ :param domain: (optional) string containing domain of cookie
+ :param path: (optional) string containing path of cookie
+ :raises KeyError: if cookie is not found
+ :raises CookieConflictError: if there are multiple cookies
+ that match name and optionally domain and path
+ :return: cookie.value
+ """
+ toReturn = None
+ for cookie in iter(self):
+ if cookie.name == name:
+ if domain is None or cookie.domain == domain:
+ if path is None or cookie.path == path:
+ if toReturn is not None:
+ # if there are multiple cookies that meet passed in criteria
+ raise CookieConflictError(
+ f"There are multiple cookies with name, {name!r}"
+ )
+ # we will eventually return this as long as no cookie conflict
+ toReturn = cookie.value
+
+ if toReturn:
+ return toReturn
+ raise KeyError(f"name={name!r}, domain={domain!r}, path={path!r}")
+
+ def __getstate__(self):
+ """Unlike a normal CookieJar, this class is pickleable."""
+ state = self.__dict__.copy()
+ # remove the unpickleable RLock object
+ state.pop("_cookies_lock")
+ return state
+
+ def __setstate__(self, state):
+ """Unlike a normal CookieJar, this class is pickleable."""
+ self.__dict__.update(state)
+ if "_cookies_lock" not in self.__dict__:
+ self._cookies_lock = threading.RLock()
+
+ def copy(self):
+ """Return a copy of this RequestsCookieJar."""
+ new_cj = RequestsCookieJar()
+ new_cj.set_policy(self.get_policy())
+ new_cj.update(self)
+ return new_cj
+
+ def get_policy(self):
+ """Return the CookiePolicy instance used."""
+ return self._policy
+
+
+def _copy_cookie_jar(jar):
+ if jar is None:
+ return None
+
+ if hasattr(jar, "copy"):
+ # We're dealing with an instance of RequestsCookieJar
+ return jar.copy()
+ # We're dealing with a generic CookieJar instance
+ new_jar = copy.copy(jar)
+ new_jar.clear()
+ for cookie in jar:
+ new_jar.set_cookie(copy.copy(cookie))
+ return new_jar
+
+
+def create_cookie(name, value, **kwargs):
+ """Make a cookie from underspecified parameters.
+
+ By default, the pair of `name` and `value` will be set for the domain ''
+ and sent on every request (this is sometimes called a "supercookie").
+ """
+ result = {
+ "version": 0,
+ "name": name,
+ "value": value,
+ "port": None,
+ "domain": "",
+ "path": "/",
+ "secure": False,
+ "expires": None,
+ "discard": True,
+ "comment": None,
+ "comment_url": None,
+ "rest": {"HttpOnly": None},
+ "rfc2109": False,
+ }
+
+ badargs = set(kwargs) - set(result)
+ if badargs:
+ raise TypeError(
+ f"create_cookie() got unexpected keyword arguments: {list(badargs)}"
+ )
+
+ result.update(kwargs)
+ result["port_specified"] = bool(result["port"])
+ result["domain_specified"] = bool(result["domain"])
+ result["domain_initial_dot"] = result["domain"].startswith(".")
+ result["path_specified"] = bool(result["path"])
+
+ return cookielib.Cookie(**result)
+
+
+def morsel_to_cookie(morsel):
+ """Convert a Morsel object into a Cookie containing the one k/v pair."""
+
+ expires = None
+ if morsel["max-age"]:
+ try:
+ expires = int(time.time() + int(morsel["max-age"]))
+ except ValueError:
+ raise TypeError(f"max-age: {morsel['max-age']} must be integer")
+ elif morsel["expires"]:
+ time_template = "%a, %d-%b-%Y %H:%M:%S GMT"
+ expires = calendar.timegm(time.strptime(morsel["expires"], time_template))
+ return create_cookie(
+ comment=morsel["comment"],
+ comment_url=bool(morsel["comment"]),
+ discard=False,
+ domain=morsel["domain"],
+ expires=expires,
+ name=morsel.key,
+ path=morsel["path"],
+ port=None,
+ rest={"HttpOnly": morsel["httponly"]},
+ rfc2109=False,
+ secure=bool(morsel["secure"]),
+ value=morsel.value,
+ version=morsel["version"] or 0,
+ )
+
+
+def cookiejar_from_dict(cookie_dict, cookiejar=None, overwrite=True):
+ """Returns a CookieJar from a key/value dictionary.
+
+ :param cookie_dict: Dict of key/values to insert into CookieJar.
+ :param cookiejar: (optional) A cookiejar to add the cookies to.
+ :param overwrite: (optional) If False, will not replace cookies
+ already in the jar with new ones.
+ :rtype: CookieJar
+ """
+ if cookiejar is None:
+ cookiejar = RequestsCookieJar()
+
+ if cookie_dict is not None:
+ names_from_jar = [cookie.name for cookie in cookiejar]
+ for name in cookie_dict:
+ if overwrite or (name not in names_from_jar):
+ cookiejar.set_cookie(create_cookie(name, cookie_dict[name]))
+
+ return cookiejar
+
+
+def merge_cookies(cookiejar, cookies):
+ """Add cookies to cookiejar and returns a merged CookieJar.
+
+ :param cookiejar: CookieJar object to add the cookies to.
+ :param cookies: Dictionary or CookieJar object to be added.
+ :rtype: CookieJar
+ """
+ if not isinstance(cookiejar, cookielib.CookieJar):
+ raise ValueError("You can only merge into CookieJar")
+
+ if isinstance(cookies, dict):
+ cookiejar = cookiejar_from_dict(cookies, cookiejar=cookiejar, overwrite=False)
+ elif isinstance(cookies, cookielib.CookieJar):
+ try:
+ cookiejar.update(cookies)
+ except AttributeError:
+ for cookie_in_jar in cookies:
+ cookiejar.set_cookie(cookie_in_jar)
+
+ return cookiejar
diff --git a/venv/Lib/site-packages/requests/exceptions.py b/venv/Lib/site-packages/requests/exceptions.py
new file mode 100644
index 00000000..83986b48
--- /dev/null
+++ b/venv/Lib/site-packages/requests/exceptions.py
@@ -0,0 +1,151 @@
+"""
+requests.exceptions
+~~~~~~~~~~~~~~~~~~~
+
+This module contains the set of Requests' exceptions.
+"""
+from urllib3.exceptions import HTTPError as BaseHTTPError
+
+from .compat import JSONDecodeError as CompatJSONDecodeError
+
+
+class RequestException(IOError):
+ """There was an ambiguous exception that occurred while handling your
+ request.
+ """
+
+ def __init__(self, *args, **kwargs):
+ """Initialize RequestException with `request` and `response` objects."""
+ response = kwargs.pop("response", None)
+ self.response = response
+ self.request = kwargs.pop("request", None)
+ if response is not None and not self.request and hasattr(response, "request"):
+ self.request = self.response.request
+ super().__init__(*args, **kwargs)
+
+
+class InvalidJSONError(RequestException):
+ """A JSON error occurred."""
+
+
+class JSONDecodeError(InvalidJSONError, CompatJSONDecodeError):
+ """Couldn't decode the text into json"""
+
+ def __init__(self, *args, **kwargs):
+ """
+ Construct the JSONDecodeError instance first with all
+ args. Then use it's args to construct the IOError so that
+ the json specific args aren't used as IOError specific args
+ and the error message from JSONDecodeError is preserved.
+ """
+ CompatJSONDecodeError.__init__(self, *args)
+ InvalidJSONError.__init__(self, *self.args, **kwargs)
+
+ def __reduce__(self):
+ """
+ The __reduce__ method called when pickling the object must
+ be the one from the JSONDecodeError (be it json/simplejson)
+ as it expects all the arguments for instantiation, not just
+ one like the IOError, and the MRO would by default call the
+ __reduce__ method from the IOError due to the inheritance order.
+ """
+ return CompatJSONDecodeError.__reduce__(self)
+
+
+class HTTPError(RequestException):
+ """An HTTP error occurred."""
+
+
+class ConnectionError(RequestException):
+ """A Connection error occurred."""
+
+
+class ProxyError(ConnectionError):
+ """A proxy error occurred."""
+
+
+class SSLError(ConnectionError):
+ """An SSL error occurred."""
+
+
+class Timeout(RequestException):
+ """The request timed out.
+
+ Catching this error will catch both
+ :exc:`~requests.exceptions.ConnectTimeout` and
+ :exc:`~requests.exceptions.ReadTimeout` errors.
+ """
+
+
+class ConnectTimeout(ConnectionError, Timeout):
+ """The request timed out while trying to connect to the remote server.
+
+ Requests that produced this error are safe to retry.
+ """
+
+
+class ReadTimeout(Timeout):
+ """The server did not send any data in the allotted amount of time."""
+
+
+class URLRequired(RequestException):
+ """A valid URL is required to make a request."""
+
+
+class TooManyRedirects(RequestException):
+ """Too many redirects."""
+
+
+class MissingSchema(RequestException, ValueError):
+ """The URL scheme (e.g. http or https) is missing."""
+
+
+class InvalidSchema(RequestException, ValueError):
+ """The URL scheme provided is either invalid or unsupported."""
+
+
+class InvalidURL(RequestException, ValueError):
+ """The URL provided was somehow invalid."""
+
+
+class InvalidHeader(RequestException, ValueError):
+ """The header value provided was somehow invalid."""
+
+
+class InvalidProxyURL(InvalidURL):
+ """The proxy URL provided is invalid."""
+
+
+class ChunkedEncodingError(RequestException):
+ """The server declared chunked encoding but sent an invalid chunk."""
+
+
+class ContentDecodingError(RequestException, BaseHTTPError):
+ """Failed to decode response content."""
+
+
+class StreamConsumedError(RequestException, TypeError):
+ """The content for this response was already consumed."""
+
+
+class RetryError(RequestException):
+ """Custom retries logic failed"""
+
+
+class UnrewindableBodyError(RequestException):
+ """Requests encountered an error when trying to rewind a body."""
+
+
+# Warnings
+
+
+class RequestsWarning(Warning):
+ """Base warning for Requests."""
+
+
+class FileModeWarning(RequestsWarning, DeprecationWarning):
+ """A file was opened in text mode, but Requests determined its binary length."""
+
+
+class RequestsDependencyWarning(RequestsWarning):
+ """An imported dependency doesn't match the expected version range."""
diff --git a/venv/Lib/site-packages/requests/help.py b/venv/Lib/site-packages/requests/help.py
new file mode 100644
index 00000000..8fbcd656
--- /dev/null
+++ b/venv/Lib/site-packages/requests/help.py
@@ -0,0 +1,134 @@
+"""Module containing bug report helper(s)."""
+
+import json
+import platform
+import ssl
+import sys
+
+import idna
+import urllib3
+
+from . import __version__ as requests_version
+
+try:
+ import charset_normalizer
+except ImportError:
+ charset_normalizer = None
+
+try:
+ import chardet
+except ImportError:
+ chardet = None
+
+try:
+ from urllib3.contrib import pyopenssl
+except ImportError:
+ pyopenssl = None
+ OpenSSL = None
+ cryptography = None
+else:
+ import cryptography
+ import OpenSSL
+
+
+def _implementation():
+ """Return a dict with the Python implementation and version.
+
+ Provide both the name and the version of the Python implementation
+ currently running. For example, on CPython 3.10.3 it will return
+ {'name': 'CPython', 'version': '3.10.3'}.
+
+ This function works best on CPython and PyPy: in particular, it probably
+ doesn't work for Jython or IronPython. Future investigation should be done
+ to work out the correct shape of the code for those platforms.
+ """
+ implementation = platform.python_implementation()
+
+ if implementation == "CPython":
+ implementation_version = platform.python_version()
+ elif implementation == "PyPy":
+ implementation_version = "{}.{}.{}".format(
+ sys.pypy_version_info.major,
+ sys.pypy_version_info.minor,
+ sys.pypy_version_info.micro,
+ )
+ if sys.pypy_version_info.releaselevel != "final":
+ implementation_version = "".join(
+ [implementation_version, sys.pypy_version_info.releaselevel]
+ )
+ elif implementation == "Jython":
+ implementation_version = platform.python_version() # Complete Guess
+ elif implementation == "IronPython":
+ implementation_version = platform.python_version() # Complete Guess
+ else:
+ implementation_version = "Unknown"
+
+ return {"name": implementation, "version": implementation_version}
+
+
+def info():
+ """Generate information for a bug report."""
+ try:
+ platform_info = {
+ "system": platform.system(),
+ "release": platform.release(),
+ }
+ except OSError:
+ platform_info = {
+ "system": "Unknown",
+ "release": "Unknown",
+ }
+
+ implementation_info = _implementation()
+ urllib3_info = {"version": urllib3.__version__}
+ charset_normalizer_info = {"version": None}
+ chardet_info = {"version": None}
+ if charset_normalizer:
+ charset_normalizer_info = {"version": charset_normalizer.__version__}
+ if chardet:
+ chardet_info = {"version": chardet.__version__}
+
+ pyopenssl_info = {
+ "version": None,
+ "openssl_version": "",
+ }
+ if OpenSSL:
+ pyopenssl_info = {
+ "version": OpenSSL.__version__,
+ "openssl_version": f"{OpenSSL.SSL.OPENSSL_VERSION_NUMBER:x}",
+ }
+ cryptography_info = {
+ "version": getattr(cryptography, "__version__", ""),
+ }
+ idna_info = {
+ "version": getattr(idna, "__version__", ""),
+ }
+
+ system_ssl = ssl.OPENSSL_VERSION_NUMBER
+ system_ssl_info = {"version": f"{system_ssl:x}" if system_ssl is not None else ""}
+
+ return {
+ "platform": platform_info,
+ "implementation": implementation_info,
+ "system_ssl": system_ssl_info,
+ "using_pyopenssl": pyopenssl is not None,
+ "using_charset_normalizer": chardet is None,
+ "pyOpenSSL": pyopenssl_info,
+ "urllib3": urllib3_info,
+ "chardet": chardet_info,
+ "charset_normalizer": charset_normalizer_info,
+ "cryptography": cryptography_info,
+ "idna": idna_info,
+ "requests": {
+ "version": requests_version,
+ },
+ }
+
+
+def main():
+ """Pretty-print the bug information as JSON."""
+ print(json.dumps(info(), sort_keys=True, indent=2))
+
+
+if __name__ == "__main__":
+ main()
diff --git a/venv/Lib/site-packages/requests/hooks.py b/venv/Lib/site-packages/requests/hooks.py
new file mode 100644
index 00000000..d181ba2e
--- /dev/null
+++ b/venv/Lib/site-packages/requests/hooks.py
@@ -0,0 +1,33 @@
+"""
+requests.hooks
+~~~~~~~~~~~~~~
+
+This module provides the capabilities for the Requests hooks system.
+
+Available hooks:
+
+``response``:
+ The response generated from a Request.
+"""
+HOOKS = ["response"]
+
+
+def default_hooks():
+ return {event: [] for event in HOOKS}
+
+
+# TODO: response is the only one
+
+
+def dispatch_hook(key, hooks, hook_data, **kwargs):
+ """Dispatches a hook dictionary on a given piece of data."""
+ hooks = hooks or {}
+ hooks = hooks.get(key)
+ if hooks:
+ if hasattr(hooks, "__call__"):
+ hooks = [hooks]
+ for hook in hooks:
+ _hook_data = hook(hook_data, **kwargs)
+ if _hook_data is not None:
+ hook_data = _hook_data
+ return hook_data
diff --git a/venv/Lib/site-packages/requests/models.py b/venv/Lib/site-packages/requests/models.py
new file mode 100644
index 00000000..c4b25fa0
--- /dev/null
+++ b/venv/Lib/site-packages/requests/models.py
@@ -0,0 +1,1039 @@
+"""
+requests.models
+~~~~~~~~~~~~~~~
+
+This module contains the primary objects that power Requests.
+"""
+
+import datetime
+
+# Import encoding now, to avoid implicit import later.
+# Implicit import within threads may cause LookupError when standard library is in a ZIP,
+# such as in Embedded Python. See https://github.com/psf/requests/issues/3578.
+import encodings.idna # noqa: F401
+from io import UnsupportedOperation
+
+from urllib3.exceptions import (
+ DecodeError,
+ LocationParseError,
+ ProtocolError,
+ ReadTimeoutError,
+ SSLError,
+)
+from urllib3.fields import RequestField
+from urllib3.filepost import encode_multipart_formdata
+from urllib3.util import parse_url
+
+from ._internal_utils import to_native_string, unicode_is_ascii
+from .auth import HTTPBasicAuth
+from .compat import (
+ Callable,
+ JSONDecodeError,
+ Mapping,
+ basestring,
+ builtin_str,
+ chardet,
+ cookielib,
+)
+from .compat import json as complexjson
+from .compat import urlencode, urlsplit, urlunparse
+from .cookies import _copy_cookie_jar, cookiejar_from_dict, get_cookie_header
+from .exceptions import (
+ ChunkedEncodingError,
+ ConnectionError,
+ ContentDecodingError,
+ HTTPError,
+ InvalidJSONError,
+ InvalidURL,
+)
+from .exceptions import JSONDecodeError as RequestsJSONDecodeError
+from .exceptions import MissingSchema
+from .exceptions import SSLError as RequestsSSLError
+from .exceptions import StreamConsumedError
+from .hooks import default_hooks
+from .status_codes import codes
+from .structures import CaseInsensitiveDict
+from .utils import (
+ check_header_validity,
+ get_auth_from_url,
+ guess_filename,
+ guess_json_utf,
+ iter_slices,
+ parse_header_links,
+ requote_uri,
+ stream_decode_response_unicode,
+ super_len,
+ to_key_val_list,
+)
+
+#: The set of HTTP status codes that indicate an automatically
+#: processable redirect.
+REDIRECT_STATI = (
+ codes.moved, # 301
+ codes.found, # 302
+ codes.other, # 303
+ codes.temporary_redirect, # 307
+ codes.permanent_redirect, # 308
+)
+
+DEFAULT_REDIRECT_LIMIT = 30
+CONTENT_CHUNK_SIZE = 10 * 1024
+ITER_CHUNK_SIZE = 512
+
+
+class RequestEncodingMixin:
+ @property
+ def path_url(self):
+ """Build the path URL to use."""
+
+ url = []
+
+ p = urlsplit(self.url)
+
+ path = p.path
+ if not path:
+ path = "/"
+
+ url.append(path)
+
+ query = p.query
+ if query:
+ url.append("?")
+ url.append(query)
+
+ return "".join(url)
+
+ @staticmethod
+ def _encode_params(data):
+ """Encode parameters in a piece of data.
+
+ Will successfully encode parameters when passed as a dict or a list of
+ 2-tuples. Order is retained if data is a list of 2-tuples but arbitrary
+ if parameters are supplied as a dict.
+ """
+
+ if isinstance(data, (str, bytes)):
+ return data
+ elif hasattr(data, "read"):
+ return data
+ elif hasattr(data, "__iter__"):
+ result = []
+ for k, vs in to_key_val_list(data):
+ if isinstance(vs, basestring) or not hasattr(vs, "__iter__"):
+ vs = [vs]
+ for v in vs:
+ if v is not None:
+ result.append(
+ (
+ k.encode("utf-8") if isinstance(k, str) else k,
+ v.encode("utf-8") if isinstance(v, str) else v,
+ )
+ )
+ return urlencode(result, doseq=True)
+ else:
+ return data
+
+ @staticmethod
+ def _encode_files(files, data):
+ """Build the body for a multipart/form-data request.
+
+ Will successfully encode files when passed as a dict or a list of
+ tuples. Order is retained if data is a list of tuples but arbitrary
+ if parameters are supplied as a dict.
+ The tuples may be 2-tuples (filename, fileobj), 3-tuples (filename, fileobj, contentype)
+ or 4-tuples (filename, fileobj, contentype, custom_headers).
+ """
+ if not files:
+ raise ValueError("Files must be provided.")
+ elif isinstance(data, basestring):
+ raise ValueError("Data must not be a string.")
+
+ new_fields = []
+ fields = to_key_val_list(data or {})
+ files = to_key_val_list(files or {})
+
+ for field, val in fields:
+ if isinstance(val, basestring) or not hasattr(val, "__iter__"):
+ val = [val]
+ for v in val:
+ if v is not None:
+ # Don't call str() on bytestrings: in Py3 it all goes wrong.
+ if not isinstance(v, bytes):
+ v = str(v)
+
+ new_fields.append(
+ (
+ field.decode("utf-8")
+ if isinstance(field, bytes)
+ else field,
+ v.encode("utf-8") if isinstance(v, str) else v,
+ )
+ )
+
+ for k, v in files:
+ # support for explicit filename
+ ft = None
+ fh = None
+ if isinstance(v, (tuple, list)):
+ if len(v) == 2:
+ fn, fp = v
+ elif len(v) == 3:
+ fn, fp, ft = v
+ else:
+ fn, fp, ft, fh = v
+ else:
+ fn = guess_filename(v) or k
+ fp = v
+
+ if isinstance(fp, (str, bytes, bytearray)):
+ fdata = fp
+ elif hasattr(fp, "read"):
+ fdata = fp.read()
+ elif fp is None:
+ continue
+ else:
+ fdata = fp
+
+ rf = RequestField(name=k, data=fdata, filename=fn, headers=fh)
+ rf.make_multipart(content_type=ft)
+ new_fields.append(rf)
+
+ body, content_type = encode_multipart_formdata(new_fields)
+
+ return body, content_type
+
+
+class RequestHooksMixin:
+ def register_hook(self, event, hook):
+ """Properly register a hook."""
+
+ if event not in self.hooks:
+ raise ValueError(f'Unsupported event specified, with event name "{event}"')
+
+ if isinstance(hook, Callable):
+ self.hooks[event].append(hook)
+ elif hasattr(hook, "__iter__"):
+ self.hooks[event].extend(h for h in hook if isinstance(h, Callable))
+
+ def deregister_hook(self, event, hook):
+ """Deregister a previously registered hook.
+ Returns True if the hook existed, False if not.
+ """
+
+ try:
+ self.hooks[event].remove(hook)
+ return True
+ except ValueError:
+ return False
+
+
+class Request(RequestHooksMixin):
+ """A user-created :class:`Request ` object.
+
+ Used to prepare a :class:`PreparedRequest `, which is sent to the server.
+
+ :param method: HTTP method to use.
+ :param url: URL to send.
+ :param headers: dictionary of headers to send.
+ :param files: dictionary of {filename: fileobject} files to multipart upload.
+ :param data: the body to attach to the request. If a dictionary or
+ list of tuples ``[(key, value)]`` is provided, form-encoding will
+ take place.
+ :param json: json for the body to attach to the request (if files or data is not specified).
+ :param params: URL parameters to append to the URL. If a dictionary or
+ list of tuples ``[(key, value)]`` is provided, form-encoding will
+ take place.
+ :param auth: Auth handler or (user, pass) tuple.
+ :param cookies: dictionary or CookieJar of cookies to attach to this request.
+ :param hooks: dictionary of callback hooks, for internal usage.
+
+ Usage::
+
+ >>> import requests
+ >>> req = requests.Request('GET', 'https://httpbin.org/get')
+ >>> req.prepare()
+
+ """
+
+ def __init__(
+ self,
+ method=None,
+ url=None,
+ headers=None,
+ files=None,
+ data=None,
+ params=None,
+ auth=None,
+ cookies=None,
+ hooks=None,
+ json=None,
+ ):
+ # Default empty dicts for dict params.
+ data = [] if data is None else data
+ files = [] if files is None else files
+ headers = {} if headers is None else headers
+ params = {} if params is None else params
+ hooks = {} if hooks is None else hooks
+
+ self.hooks = default_hooks()
+ for k, v in list(hooks.items()):
+ self.register_hook(event=k, hook=v)
+
+ self.method = method
+ self.url = url
+ self.headers = headers
+ self.files = files
+ self.data = data
+ self.json = json
+ self.params = params
+ self.auth = auth
+ self.cookies = cookies
+
+ def __repr__(self):
+ return f""
+
+ def prepare(self):
+ """Constructs a :class:`PreparedRequest ` for transmission and returns it."""
+ p = PreparedRequest()
+ p.prepare(
+ method=self.method,
+ url=self.url,
+ headers=self.headers,
+ files=self.files,
+ data=self.data,
+ json=self.json,
+ params=self.params,
+ auth=self.auth,
+ cookies=self.cookies,
+ hooks=self.hooks,
+ )
+ return p
+
+
+class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
+ """The fully mutable :class:`PreparedRequest ` object,
+ containing the exact bytes that will be sent to the server.
+
+ Instances are generated from a :class:`Request ` object, and
+ should not be instantiated manually; doing so may produce undesirable
+ effects.
+
+ Usage::
+
+ >>> import requests
+ >>> req = requests.Request('GET', 'https://httpbin.org/get')
+ >>> r = req.prepare()
+ >>> r
+
+
+ >>> s = requests.Session()
+ >>> s.send(r)
+
+ """
+
+ def __init__(self):
+ #: HTTP verb to send to the server.
+ self.method = None
+ #: HTTP URL to send the request to.
+ self.url = None
+ #: dictionary of HTTP headers.
+ self.headers = None
+ # The `CookieJar` used to create the Cookie header will be stored here
+ # after prepare_cookies is called
+ self._cookies = None
+ #: request body to send to the server.
+ self.body = None
+ #: dictionary of callback hooks, for internal usage.
+ self.hooks = default_hooks()
+ #: integer denoting starting position of a readable file-like body.
+ self._body_position = None
+
+ def prepare(
+ self,
+ method=None,
+ url=None,
+ headers=None,
+ files=None,
+ data=None,
+ params=None,
+ auth=None,
+ cookies=None,
+ hooks=None,
+ json=None,
+ ):
+ """Prepares the entire request with the given parameters."""
+
+ self.prepare_method(method)
+ self.prepare_url(url, params)
+ self.prepare_headers(headers)
+ self.prepare_cookies(cookies)
+ self.prepare_body(data, files, json)
+ self.prepare_auth(auth, url)
+
+ # Note that prepare_auth must be last to enable authentication schemes
+ # such as OAuth to work on a fully prepared request.
+
+ # This MUST go after prepare_auth. Authenticators could add a hook
+ self.prepare_hooks(hooks)
+
+ def __repr__(self):
+ return f""
+
+ def copy(self):
+ p = PreparedRequest()
+ p.method = self.method
+ p.url = self.url
+ p.headers = self.headers.copy() if self.headers is not None else None
+ p._cookies = _copy_cookie_jar(self._cookies)
+ p.body = self.body
+ p.hooks = self.hooks
+ p._body_position = self._body_position
+ return p
+
+ def prepare_method(self, method):
+ """Prepares the given HTTP method."""
+ self.method = method
+ if self.method is not None:
+ self.method = to_native_string(self.method.upper())
+
+ @staticmethod
+ def _get_idna_encoded_host(host):
+ import idna
+
+ try:
+ host = idna.encode(host, uts46=True).decode("utf-8")
+ except idna.IDNAError:
+ raise UnicodeError
+ return host
+
+ def prepare_url(self, url, params):
+ """Prepares the given HTTP URL."""
+ #: Accept objects that have string representations.
+ #: We're unable to blindly call unicode/str functions
+ #: as this will include the bytestring indicator (b'')
+ #: on python 3.x.
+ #: https://github.com/psf/requests/pull/2238
+ if isinstance(url, bytes):
+ url = url.decode("utf8")
+ else:
+ url = str(url)
+
+ # Remove leading whitespaces from url
+ url = url.lstrip()
+
+ # Don't do any URL preparation for non-HTTP schemes like `mailto`,
+ # `data` etc to work around exceptions from `url_parse`, which
+ # handles RFC 3986 only.
+ if ":" in url and not url.lower().startswith("http"):
+ self.url = url
+ return
+
+ # Support for unicode domain names and paths.
+ try:
+ scheme, auth, host, port, path, query, fragment = parse_url(url)
+ except LocationParseError as e:
+ raise InvalidURL(*e.args)
+
+ if not scheme:
+ raise MissingSchema(
+ f"Invalid URL {url!r}: No scheme supplied. "
+ f"Perhaps you meant https://{url}?"
+ )
+
+ if not host:
+ raise InvalidURL(f"Invalid URL {url!r}: No host supplied")
+
+ # In general, we want to try IDNA encoding the hostname if the string contains
+ # non-ASCII characters. This allows users to automatically get the correct IDNA
+ # behaviour. For strings containing only ASCII characters, we need to also verify
+ # it doesn't start with a wildcard (*), before allowing the unencoded hostname.
+ if not unicode_is_ascii(host):
+ try:
+ host = self._get_idna_encoded_host(host)
+ except UnicodeError:
+ raise InvalidURL("URL has an invalid label.")
+ elif host.startswith(("*", ".")):
+ raise InvalidURL("URL has an invalid label.")
+
+ # Carefully reconstruct the network location
+ netloc = auth or ""
+ if netloc:
+ netloc += "@"
+ netloc += host
+ if port:
+ netloc += f":{port}"
+
+ # Bare domains aren't valid URLs.
+ if not path:
+ path = "/"
+
+ if isinstance(params, (str, bytes)):
+ params = to_native_string(params)
+
+ enc_params = self._encode_params(params)
+ if enc_params:
+ if query:
+ query = f"{query}&{enc_params}"
+ else:
+ query = enc_params
+
+ url = requote_uri(urlunparse([scheme, netloc, path, None, query, fragment]))
+ self.url = url
+
+ def prepare_headers(self, headers):
+ """Prepares the given HTTP headers."""
+
+ self.headers = CaseInsensitiveDict()
+ if headers:
+ for header in headers.items():
+ # Raise exception on invalid header value.
+ check_header_validity(header)
+ name, value = header
+ self.headers[to_native_string(name)] = value
+
+ def prepare_body(self, data, files, json=None):
+ """Prepares the given HTTP body data."""
+
+ # Check if file, fo, generator, iterator.
+ # If not, run through normal process.
+
+ # Nottin' on you.
+ body = None
+ content_type = None
+
+ if not data and json is not None:
+ # urllib3 requires a bytes-like body. Python 2's json.dumps
+ # provides this natively, but Python 3 gives a Unicode string.
+ content_type = "application/json"
+
+ try:
+ body = complexjson.dumps(json, allow_nan=False)
+ except ValueError as ve:
+ raise InvalidJSONError(ve, request=self)
+
+ if not isinstance(body, bytes):
+ body = body.encode("utf-8")
+
+ is_stream = all(
+ [
+ hasattr(data, "__iter__"),
+ not isinstance(data, (basestring, list, tuple, Mapping)),
+ ]
+ )
+
+ if is_stream:
+ try:
+ length = super_len(data)
+ except (TypeError, AttributeError, UnsupportedOperation):
+ length = None
+
+ body = data
+
+ if getattr(body, "tell", None) is not None:
+ # Record the current file position before reading.
+ # This will allow us to rewind a file in the event
+ # of a redirect.
+ try:
+ self._body_position = body.tell()
+ except OSError:
+ # This differentiates from None, allowing us to catch
+ # a failed `tell()` later when trying to rewind the body
+ self._body_position = object()
+
+ if files:
+ raise NotImplementedError(
+ "Streamed bodies and files are mutually exclusive."
+ )
+
+ if length:
+ self.headers["Content-Length"] = builtin_str(length)
+ else:
+ self.headers["Transfer-Encoding"] = "chunked"
+ else:
+ # Multi-part file uploads.
+ if files:
+ (body, content_type) = self._encode_files(files, data)
+ else:
+ if data:
+ body = self._encode_params(data)
+ if isinstance(data, basestring) or hasattr(data, "read"):
+ content_type = None
+ else:
+ content_type = "application/x-www-form-urlencoded"
+
+ self.prepare_content_length(body)
+
+ # Add content-type if it wasn't explicitly provided.
+ if content_type and ("content-type" not in self.headers):
+ self.headers["Content-Type"] = content_type
+
+ self.body = body
+
+ def prepare_content_length(self, body):
+ """Prepare Content-Length header based on request method and body"""
+ if body is not None:
+ length = super_len(body)
+ if length:
+ # If length exists, set it. Otherwise, we fallback
+ # to Transfer-Encoding: chunked.
+ self.headers["Content-Length"] = builtin_str(length)
+ elif (
+ self.method not in ("GET", "HEAD")
+ and self.headers.get("Content-Length") is None
+ ):
+ # Set Content-Length to 0 for methods that can have a body
+ # but don't provide one. (i.e. not GET or HEAD)
+ self.headers["Content-Length"] = "0"
+
+ def prepare_auth(self, auth, url=""):
+ """Prepares the given HTTP auth data."""
+
+ # If no Auth is explicitly provided, extract it from the URL first.
+ if auth is None:
+ url_auth = get_auth_from_url(self.url)
+ auth = url_auth if any(url_auth) else None
+
+ if auth:
+ if isinstance(auth, tuple) and len(auth) == 2:
+ # special-case basic HTTP auth
+ auth = HTTPBasicAuth(*auth)
+
+ # Allow auth to make its changes.
+ r = auth(self)
+
+ # Update self to reflect the auth changes.
+ self.__dict__.update(r.__dict__)
+
+ # Recompute Content-Length
+ self.prepare_content_length(self.body)
+
+ def prepare_cookies(self, cookies):
+ """Prepares the given HTTP cookie data.
+
+ This function eventually generates a ``Cookie`` header from the
+ given cookies using cookielib. Due to cookielib's design, the header
+ will not be regenerated if it already exists, meaning this function
+ can only be called once for the life of the
+ :class:`PreparedRequest ` object. Any subsequent calls
+ to ``prepare_cookies`` will have no actual effect, unless the "Cookie"
+ header is removed beforehand.
+ """
+ if isinstance(cookies, cookielib.CookieJar):
+ self._cookies = cookies
+ else:
+ self._cookies = cookiejar_from_dict(cookies)
+
+ cookie_header = get_cookie_header(self._cookies, self)
+ if cookie_header is not None:
+ self.headers["Cookie"] = cookie_header
+
+ def prepare_hooks(self, hooks):
+ """Prepares the given hooks."""
+ # hooks can be passed as None to the prepare method and to this
+ # method. To prevent iterating over None, simply use an empty list
+ # if hooks is False-y
+ hooks = hooks or []
+ for event in hooks:
+ self.register_hook(event, hooks[event])
+
+
+class Response:
+ """The :class:`Response ` object, which contains a
+ server's response to an HTTP request.
+ """
+
+ __attrs__ = [
+ "_content",
+ "status_code",
+ "headers",
+ "url",
+ "history",
+ "encoding",
+ "reason",
+ "cookies",
+ "elapsed",
+ "request",
+ ]
+
+ def __init__(self):
+ self._content = False
+ self._content_consumed = False
+ self._next = None
+
+ #: Integer Code of responded HTTP Status, e.g. 404 or 200.
+ self.status_code = None
+
+ #: Case-insensitive Dictionary of Response Headers.
+ #: For example, ``headers['content-encoding']`` will return the
+ #: value of a ``'Content-Encoding'`` response header.
+ self.headers = CaseInsensitiveDict()
+
+ #: File-like object representation of response (for advanced usage).
+ #: Use of ``raw`` requires that ``stream=True`` be set on the request.
+ #: This requirement does not apply for use internally to Requests.
+ self.raw = None
+
+ #: Final URL location of Response.
+ self.url = None
+
+ #: Encoding to decode with when accessing r.text.
+ self.encoding = None
+
+ #: A list of :class:`Response ` objects from
+ #: the history of the Request. Any redirect responses will end
+ #: up here. The list is sorted from the oldest to the most recent request.
+ self.history = []
+
+ #: Textual reason of responded HTTP Status, e.g. "Not Found" or "OK".
+ self.reason = None
+
+ #: A CookieJar of Cookies the server sent back.
+ self.cookies = cookiejar_from_dict({})
+
+ #: The amount of time elapsed between sending the request
+ #: and the arrival of the response (as a timedelta).
+ #: This property specifically measures the time taken between sending
+ #: the first byte of the request and finishing parsing the headers. It
+ #: is therefore unaffected by consuming the response content or the
+ #: value of the ``stream`` keyword argument.
+ self.elapsed = datetime.timedelta(0)
+
+ #: The :class:`PreparedRequest ` object to which this
+ #: is a response.
+ self.request = None
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, *args):
+ self.close()
+
+ def __getstate__(self):
+ # Consume everything; accessing the content attribute makes
+ # sure the content has been fully read.
+ if not self._content_consumed:
+ self.content
+
+ return {attr: getattr(self, attr, None) for attr in self.__attrs__}
+
+ def __setstate__(self, state):
+ for name, value in state.items():
+ setattr(self, name, value)
+
+ # pickled objects do not have .raw
+ setattr(self, "_content_consumed", True)
+ setattr(self, "raw", None)
+
+ def __repr__(self):
+ return f""
+
+ def __bool__(self):
+ """Returns True if :attr:`status_code` is less than 400.
+
+ This attribute checks if the status code of the response is between
+ 400 and 600 to see if there was a client error or a server error. If
+ the status code, is between 200 and 400, this will return True. This
+ is **not** a check to see if the response code is ``200 OK``.
+ """
+ return self.ok
+
+ def __nonzero__(self):
+ """Returns True if :attr:`status_code` is less than 400.
+
+ This attribute checks if the status code of the response is between
+ 400 and 600 to see if there was a client error or a server error. If
+ the status code, is between 200 and 400, this will return True. This
+ is **not** a check to see if the response code is ``200 OK``.
+ """
+ return self.ok
+
+ def __iter__(self):
+ """Allows you to use a response as an iterator."""
+ return self.iter_content(128)
+
+ @property
+ def ok(self):
+ """Returns True if :attr:`status_code` is less than 400, False if not.
+
+ This attribute checks if the status code of the response is between
+ 400 and 600 to see if there was a client error or a server error. If
+ the status code is between 200 and 400, this will return True. This
+ is **not** a check to see if the response code is ``200 OK``.
+ """
+ try:
+ self.raise_for_status()
+ except HTTPError:
+ return False
+ return True
+
+ @property
+ def is_redirect(self):
+ """True if this Response is a well-formed HTTP redirect that could have
+ been processed automatically (by :meth:`Session.resolve_redirects`).
+ """
+ return "location" in self.headers and self.status_code in REDIRECT_STATI
+
+ @property
+ def is_permanent_redirect(self):
+ """True if this Response one of the permanent versions of redirect."""
+ return "location" in self.headers and self.status_code in (
+ codes.moved_permanently,
+ codes.permanent_redirect,
+ )
+
+ @property
+ def next(self):
+ """Returns a PreparedRequest for the next request in a redirect chain, if there is one."""
+ return self._next
+
+ @property
+ def apparent_encoding(self):
+ """The apparent encoding, provided by the charset_normalizer or chardet libraries."""
+ if chardet is not None:
+ return chardet.detect(self.content)["encoding"]
+ else:
+ # If no character detection library is available, we'll fall back
+ # to a standard Python utf-8 str.
+ return "utf-8"
+
+ def iter_content(self, chunk_size=1, decode_unicode=False):
+ """Iterates over the response data. When stream=True is set on the
+ request, this avoids reading the content at once into memory for
+ large responses. The chunk size is the number of bytes it should
+ read into memory. This is not necessarily the length of each item
+ returned as decoding can take place.
+
+ chunk_size must be of type int or None. A value of None will
+ function differently depending on the value of `stream`.
+ stream=True will read data as it arrives in whatever size the
+ chunks are received. If stream=False, data is returned as
+ a single chunk.
+
+ If decode_unicode is True, content will be decoded using the best
+ available encoding based on the response.
+ """
+
+ def generate():
+ # Special case for urllib3.
+ if hasattr(self.raw, "stream"):
+ try:
+ yield from self.raw.stream(chunk_size, decode_content=True)
+ except ProtocolError as e:
+ raise ChunkedEncodingError(e)
+ except DecodeError as e:
+ raise ContentDecodingError(e)
+ except ReadTimeoutError as e:
+ raise ConnectionError(e)
+ except SSLError as e:
+ raise RequestsSSLError(e)
+ else:
+ # Standard file-like object.
+ while True:
+ chunk = self.raw.read(chunk_size)
+ if not chunk:
+ break
+ yield chunk
+
+ self._content_consumed = True
+
+ if self._content_consumed and isinstance(self._content, bool):
+ raise StreamConsumedError()
+ elif chunk_size is not None and not isinstance(chunk_size, int):
+ raise TypeError(
+ f"chunk_size must be an int, it is instead a {type(chunk_size)}."
+ )
+ # simulate reading small chunks of the content
+ reused_chunks = iter_slices(self._content, chunk_size)
+
+ stream_chunks = generate()
+
+ chunks = reused_chunks if self._content_consumed else stream_chunks
+
+ if decode_unicode:
+ chunks = stream_decode_response_unicode(chunks, self)
+
+ return chunks
+
+ def iter_lines(
+ self, chunk_size=ITER_CHUNK_SIZE, decode_unicode=False, delimiter=None
+ ):
+ """Iterates over the response data, one line at a time. When
+ stream=True is set on the request, this avoids reading the
+ content at once into memory for large responses.
+
+ .. note:: This method is not reentrant safe.
+ """
+
+ pending = None
+
+ for chunk in self.iter_content(
+ chunk_size=chunk_size, decode_unicode=decode_unicode
+ ):
+ if pending is not None:
+ chunk = pending + chunk
+
+ if delimiter:
+ lines = chunk.split(delimiter)
+ else:
+ lines = chunk.splitlines()
+
+ if lines and lines[-1] and chunk and lines[-1][-1] == chunk[-1]:
+ pending = lines.pop()
+ else:
+ pending = None
+
+ yield from lines
+
+ if pending is not None:
+ yield pending
+
+ @property
+ def content(self):
+ """Content of the response, in bytes."""
+
+ if self._content is False:
+ # Read the contents.
+ if self._content_consumed:
+ raise RuntimeError("The content for this response was already consumed")
+
+ if self.status_code == 0 or self.raw is None:
+ self._content = None
+ else:
+ self._content = b"".join(self.iter_content(CONTENT_CHUNK_SIZE)) or b""
+
+ self._content_consumed = True
+ # don't need to release the connection; that's been handled by urllib3
+ # since we exhausted the data.
+ return self._content
+
+ @property
+ def text(self):
+ """Content of the response, in unicode.
+
+ If Response.encoding is None, encoding will be guessed using
+ ``charset_normalizer`` or ``chardet``.
+
+ The encoding of the response content is determined based solely on HTTP
+ headers, following RFC 2616 to the letter. If you can take advantage of
+ non-HTTP knowledge to make a better guess at the encoding, you should
+ set ``r.encoding`` appropriately before accessing this property.
+ """
+
+ # Try charset from content-type
+ content = None
+ encoding = self.encoding
+
+ if not self.content:
+ return ""
+
+ # Fallback to auto-detected encoding.
+ if self.encoding is None:
+ encoding = self.apparent_encoding
+
+ # Decode unicode from given encoding.
+ try:
+ content = str(self.content, encoding, errors="replace")
+ except (LookupError, TypeError):
+ # A LookupError is raised if the encoding was not found which could
+ # indicate a misspelling or similar mistake.
+ #
+ # A TypeError can be raised if encoding is None
+ #
+ # So we try blindly encoding.
+ content = str(self.content, errors="replace")
+
+ return content
+
+ def json(self, **kwargs):
+ r"""Decodes the JSON response body (if any) as a Python object.
+
+ This may return a dictionary, list, etc. depending on what is in the response.
+
+ :param \*\*kwargs: Optional arguments that ``json.loads`` takes.
+ :raises requests.exceptions.JSONDecodeError: If the response body does not
+ contain valid json.
+ """
+
+ if not self.encoding and self.content and len(self.content) > 3:
+ # No encoding set. JSON RFC 4627 section 3 states we should expect
+ # UTF-8, -16 or -32. Detect which one to use; If the detection or
+ # decoding fails, fall back to `self.text` (using charset_normalizer to make
+ # a best guess).
+ encoding = guess_json_utf(self.content)
+ if encoding is not None:
+ try:
+ return complexjson.loads(self.content.decode(encoding), **kwargs)
+ except UnicodeDecodeError:
+ # Wrong UTF codec detected; usually because it's not UTF-8
+ # but some other 8-bit codec. This is an RFC violation,
+ # and the server didn't bother to tell us what codec *was*
+ # used.
+ pass
+ except JSONDecodeError as e:
+ raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)
+
+ try:
+ return complexjson.loads(self.text, **kwargs)
+ except JSONDecodeError as e:
+ # Catch JSON-related errors and raise as requests.JSONDecodeError
+ # This aliases json.JSONDecodeError and simplejson.JSONDecodeError
+ raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)
+
+ @property
+ def links(self):
+ """Returns the parsed header links of the response, if any."""
+
+ header = self.headers.get("link")
+
+ resolved_links = {}
+
+ if header:
+ links = parse_header_links(header)
+
+ for link in links:
+ key = link.get("rel") or link.get("url")
+ resolved_links[key] = link
+
+ return resolved_links
+
+ def raise_for_status(self):
+ """Raises :class:`HTTPError`, if one occurred."""
+
+ http_error_msg = ""
+ if isinstance(self.reason, bytes):
+ # We attempt to decode utf-8 first because some servers
+ # choose to localize their reason strings. If the string
+ # isn't utf-8, we fall back to iso-8859-1 for all other
+ # encodings. (See PR #3538)
+ try:
+ reason = self.reason.decode("utf-8")
+ except UnicodeDecodeError:
+ reason = self.reason.decode("iso-8859-1")
+ else:
+ reason = self.reason
+
+ if 400 <= self.status_code < 500:
+ http_error_msg = (
+ f"{self.status_code} Client Error: {reason} for url: {self.url}"
+ )
+
+ elif 500 <= self.status_code < 600:
+ http_error_msg = (
+ f"{self.status_code} Server Error: {reason} for url: {self.url}"
+ )
+
+ if http_error_msg:
+ raise HTTPError(http_error_msg, response=self)
+
+ def close(self):
+ """Releases the connection back to the pool. Once this method has been
+ called the underlying ``raw`` object must not be accessed again.
+
+ *Note: Should not normally need to be called explicitly.*
+ """
+ if not self._content_consumed:
+ self.raw.close()
+
+ release_conn = getattr(self.raw, "release_conn", None)
+ if release_conn is not None:
+ release_conn()
diff --git a/venv/Lib/site-packages/requests/packages.py b/venv/Lib/site-packages/requests/packages.py
new file mode 100644
index 00000000..5ab3d8e2
--- /dev/null
+++ b/venv/Lib/site-packages/requests/packages.py
@@ -0,0 +1,23 @@
+import sys
+
+from .compat import chardet
+
+# This code exists for backwards compatibility reasons.
+# I don't like it either. Just look the other way. :)
+
+for package in ("urllib3", "idna"):
+ locals()[package] = __import__(package)
+ # This traversal is apparently necessary such that the identities are
+ # preserved (requests.packages.urllib3.* is urllib3.*)
+ for mod in list(sys.modules):
+ if mod == package or mod.startswith(f"{package}."):
+ sys.modules[f"requests.packages.{mod}"] = sys.modules[mod]
+
+if chardet is not None:
+ target = chardet.__name__
+ for mod in list(sys.modules):
+ if mod == target or mod.startswith(f"{target}."):
+ imported_mod = sys.modules[mod]
+ sys.modules[f"requests.packages.{mod}"] = imported_mod
+ mod = mod.replace(target, "chardet")
+ sys.modules[f"requests.packages.{mod}"] = imported_mod
diff --git a/venv/Lib/site-packages/requests/sessions.py b/venv/Lib/site-packages/requests/sessions.py
new file mode 100644
index 00000000..b387bc36
--- /dev/null
+++ b/venv/Lib/site-packages/requests/sessions.py
@@ -0,0 +1,831 @@
+"""
+requests.sessions
+~~~~~~~~~~~~~~~~~
+
+This module provides a Session object to manage and persist settings across
+requests (cookies, auth, proxies).
+"""
+import os
+import sys
+import time
+from collections import OrderedDict
+from datetime import timedelta
+
+from ._internal_utils import to_native_string
+from .adapters import HTTPAdapter
+from .auth import _basic_auth_str
+from .compat import Mapping, cookielib, urljoin, urlparse
+from .cookies import (
+ RequestsCookieJar,
+ cookiejar_from_dict,
+ extract_cookies_to_jar,
+ merge_cookies,
+)
+from .exceptions import (
+ ChunkedEncodingError,
+ ContentDecodingError,
+ InvalidSchema,
+ TooManyRedirects,
+)
+from .hooks import default_hooks, dispatch_hook
+
+# formerly defined here, reexposed here for backward compatibility
+from .models import ( # noqa: F401
+ DEFAULT_REDIRECT_LIMIT,
+ REDIRECT_STATI,
+ PreparedRequest,
+ Request,
+)
+from .status_codes import codes
+from .structures import CaseInsensitiveDict
+from .utils import ( # noqa: F401
+ DEFAULT_PORTS,
+ default_headers,
+ get_auth_from_url,
+ get_environ_proxies,
+ get_netrc_auth,
+ requote_uri,
+ resolve_proxies,
+ rewind_body,
+ should_bypass_proxies,
+ to_key_val_list,
+)
+
+# Preferred clock, based on which one is more accurate on a given system.
+if sys.platform == "win32":
+ preferred_clock = time.perf_counter
+else:
+ preferred_clock = time.time
+
+
+def merge_setting(request_setting, session_setting, dict_class=OrderedDict):
+ """Determines appropriate setting for a given request, taking into account
+ the explicit setting on that request, and the setting in the session. If a
+ setting is a dictionary, they will be merged together using `dict_class`
+ """
+
+ if session_setting is None:
+ return request_setting
+
+ if request_setting is None:
+ return session_setting
+
+ # Bypass if not a dictionary (e.g. verify)
+ if not (
+ isinstance(session_setting, Mapping) and isinstance(request_setting, Mapping)
+ ):
+ return request_setting
+
+ merged_setting = dict_class(to_key_val_list(session_setting))
+ merged_setting.update(to_key_val_list(request_setting))
+
+ # Remove keys that are set to None. Extract keys first to avoid altering
+ # the dictionary during iteration.
+ none_keys = [k for (k, v) in merged_setting.items() if v is None]
+ for key in none_keys:
+ del merged_setting[key]
+
+ return merged_setting
+
+
+def merge_hooks(request_hooks, session_hooks, dict_class=OrderedDict):
+ """Properly merges both requests and session hooks.
+
+ This is necessary because when request_hooks == {'response': []}, the
+ merge breaks Session hooks entirely.
+ """
+ if session_hooks is None or session_hooks.get("response") == []:
+ return request_hooks
+
+ if request_hooks is None or request_hooks.get("response") == []:
+ return session_hooks
+
+ return merge_setting(request_hooks, session_hooks, dict_class)
+
+
+class SessionRedirectMixin:
+ def get_redirect_target(self, resp):
+ """Receives a Response. Returns a redirect URI or ``None``"""
+ # Due to the nature of how requests processes redirects this method will
+ # be called at least once upon the original response and at least twice
+ # on each subsequent redirect response (if any).
+ # If a custom mixin is used to handle this logic, it may be advantageous
+ # to cache the redirect location onto the response object as a private
+ # attribute.
+ if resp.is_redirect:
+ location = resp.headers["location"]
+ # Currently the underlying http module on py3 decode headers
+ # in latin1, but empirical evidence suggests that latin1 is very
+ # rarely used with non-ASCII characters in HTTP headers.
+ # It is more likely to get UTF8 header rather than latin1.
+ # This causes incorrect handling of UTF8 encoded location headers.
+ # To solve this, we re-encode the location in latin1.
+ location = location.encode("latin1")
+ return to_native_string(location, "utf8")
+ return None
+
+ def should_strip_auth(self, old_url, new_url):
+ """Decide whether Authorization header should be removed when redirecting"""
+ old_parsed = urlparse(old_url)
+ new_parsed = urlparse(new_url)
+ if old_parsed.hostname != new_parsed.hostname:
+ return True
+ # Special case: allow http -> https redirect when using the standard
+ # ports. This isn't specified by RFC 7235, but is kept to avoid
+ # breaking backwards compatibility with older versions of requests
+ # that allowed any redirects on the same host.
+ if (
+ old_parsed.scheme == "http"
+ and old_parsed.port in (80, None)
+ and new_parsed.scheme == "https"
+ and new_parsed.port in (443, None)
+ ):
+ return False
+
+ # Handle default port usage corresponding to scheme.
+ changed_port = old_parsed.port != new_parsed.port
+ changed_scheme = old_parsed.scheme != new_parsed.scheme
+ default_port = (DEFAULT_PORTS.get(old_parsed.scheme, None), None)
+ if (
+ not changed_scheme
+ and old_parsed.port in default_port
+ and new_parsed.port in default_port
+ ):
+ return False
+
+ # Standard case: root URI must match
+ return changed_port or changed_scheme
+
+ def resolve_redirects(
+ self,
+ resp,
+ req,
+ stream=False,
+ timeout=None,
+ verify=True,
+ cert=None,
+ proxies=None,
+ yield_requests=False,
+ **adapter_kwargs,
+ ):
+ """Receives a Response. Returns a generator of Responses or Requests."""
+
+ hist = [] # keep track of history
+
+ url = self.get_redirect_target(resp)
+ previous_fragment = urlparse(req.url).fragment
+ while url:
+ prepared_request = req.copy()
+
+ # Update history and keep track of redirects.
+ # resp.history must ignore the original request in this loop
+ hist.append(resp)
+ resp.history = hist[1:]
+
+ try:
+ resp.content # Consume socket so it can be released
+ except (ChunkedEncodingError, ContentDecodingError, RuntimeError):
+ resp.raw.read(decode_content=False)
+
+ if len(resp.history) >= self.max_redirects:
+ raise TooManyRedirects(
+ f"Exceeded {self.max_redirects} redirects.", response=resp
+ )
+
+ # Release the connection back into the pool.
+ resp.close()
+
+ # Handle redirection without scheme (see: RFC 1808 Section 4)
+ if url.startswith("//"):
+ parsed_rurl = urlparse(resp.url)
+ url = ":".join([to_native_string(parsed_rurl.scheme), url])
+
+ # Normalize url case and attach previous fragment if needed (RFC 7231 7.1.2)
+ parsed = urlparse(url)
+ if parsed.fragment == "" and previous_fragment:
+ parsed = parsed._replace(fragment=previous_fragment)
+ elif parsed.fragment:
+ previous_fragment = parsed.fragment
+ url = parsed.geturl()
+
+ # Facilitate relative 'location' headers, as allowed by RFC 7231.
+ # (e.g. '/path/to/resource' instead of 'http://domain.tld/path/to/resource')
+ # Compliant with RFC3986, we percent encode the url.
+ if not parsed.netloc:
+ url = urljoin(resp.url, requote_uri(url))
+ else:
+ url = requote_uri(url)
+
+ prepared_request.url = to_native_string(url)
+
+ self.rebuild_method(prepared_request, resp)
+
+ # https://github.com/psf/requests/issues/1084
+ if resp.status_code not in (
+ codes.temporary_redirect,
+ codes.permanent_redirect,
+ ):
+ # https://github.com/psf/requests/issues/3490
+ purged_headers = ("Content-Length", "Content-Type", "Transfer-Encoding")
+ for header in purged_headers:
+ prepared_request.headers.pop(header, None)
+ prepared_request.body = None
+
+ headers = prepared_request.headers
+ headers.pop("Cookie", None)
+
+ # Extract any cookies sent on the response to the cookiejar
+ # in the new request. Because we've mutated our copied prepared
+ # request, use the old one that we haven't yet touched.
+ extract_cookies_to_jar(prepared_request._cookies, req, resp.raw)
+ merge_cookies(prepared_request._cookies, self.cookies)
+ prepared_request.prepare_cookies(prepared_request._cookies)
+
+ # Rebuild auth and proxy information.
+ proxies = self.rebuild_proxies(prepared_request, proxies)
+ self.rebuild_auth(prepared_request, resp)
+
+ # A failed tell() sets `_body_position` to `object()`. This non-None
+ # value ensures `rewindable` will be True, allowing us to raise an
+ # UnrewindableBodyError, instead of hanging the connection.
+ rewindable = prepared_request._body_position is not None and (
+ "Content-Length" in headers or "Transfer-Encoding" in headers
+ )
+
+ # Attempt to rewind consumed file-like object.
+ if rewindable:
+ rewind_body(prepared_request)
+
+ # Override the original request.
+ req = prepared_request
+
+ if yield_requests:
+ yield req
+ else:
+ resp = self.send(
+ req,
+ stream=stream,
+ timeout=timeout,
+ verify=verify,
+ cert=cert,
+ proxies=proxies,
+ allow_redirects=False,
+ **adapter_kwargs,
+ )
+
+ extract_cookies_to_jar(self.cookies, prepared_request, resp.raw)
+
+ # extract redirect url, if any, for the next loop
+ url = self.get_redirect_target(resp)
+ yield resp
+
+ def rebuild_auth(self, prepared_request, response):
+ """When being redirected we may want to strip authentication from the
+ request to avoid leaking credentials. This method intelligently removes
+ and reapplies authentication where possible to avoid credential loss.
+ """
+ headers = prepared_request.headers
+ url = prepared_request.url
+
+ if "Authorization" in headers and self.should_strip_auth(
+ response.request.url, url
+ ):
+ # If we get redirected to a new host, we should strip out any
+ # authentication headers.
+ del headers["Authorization"]
+
+ # .netrc might have more auth for us on our new host.
+ new_auth = get_netrc_auth(url) if self.trust_env else None
+ if new_auth is not None:
+ prepared_request.prepare_auth(new_auth)
+
+ def rebuild_proxies(self, prepared_request, proxies):
+ """This method re-evaluates the proxy configuration by considering the
+ environment variables. If we are redirected to a URL covered by
+ NO_PROXY, we strip the proxy configuration. Otherwise, we set missing
+ proxy keys for this URL (in case they were stripped by a previous
+ redirect).
+
+ This method also replaces the Proxy-Authorization header where
+ necessary.
+
+ :rtype: dict
+ """
+ headers = prepared_request.headers
+ scheme = urlparse(prepared_request.url).scheme
+ new_proxies = resolve_proxies(prepared_request, proxies, self.trust_env)
+
+ if "Proxy-Authorization" in headers:
+ del headers["Proxy-Authorization"]
+
+ try:
+ username, password = get_auth_from_url(new_proxies[scheme])
+ except KeyError:
+ username, password = None, None
+
+ # urllib3 handles proxy authorization for us in the standard adapter.
+ # Avoid appending this to TLS tunneled requests where it may be leaked.
+ if not scheme.startswith("https") and username and password:
+ headers["Proxy-Authorization"] = _basic_auth_str(username, password)
+
+ return new_proxies
+
+ def rebuild_method(self, prepared_request, response):
+ """When being redirected we may want to change the method of the request
+ based on certain specs or browser behavior.
+ """
+ method = prepared_request.method
+
+ # https://tools.ietf.org/html/rfc7231#section-6.4.4
+ if response.status_code == codes.see_other and method != "HEAD":
+ method = "GET"
+
+ # Do what the browsers do, despite standards...
+ # First, turn 302s into GETs.
+ if response.status_code == codes.found and method != "HEAD":
+ method = "GET"
+
+ # Second, if a POST is responded to with a 301, turn it into a GET.
+ # This bizarre behaviour is explained in Issue 1704.
+ if response.status_code == codes.moved and method == "POST":
+ method = "GET"
+
+ prepared_request.method = method
+
+
+class Session(SessionRedirectMixin):
+ """A Requests session.
+
+ Provides cookie persistence, connection-pooling, and configuration.
+
+ Basic Usage::
+
+ >>> import requests
+ >>> s = requests.Session()
+ >>> s.get('https://httpbin.org/get')
+
+
+ Or as a context manager::
+
+ >>> with requests.Session() as s:
+ ... s.get('https://httpbin.org/get')
+
+ """
+
+ __attrs__ = [
+ "headers",
+ "cookies",
+ "auth",
+ "proxies",
+ "hooks",
+ "params",
+ "verify",
+ "cert",
+ "adapters",
+ "stream",
+ "trust_env",
+ "max_redirects",
+ ]
+
+ def __init__(self):
+ #: A case-insensitive dictionary of headers to be sent on each
+ #: :class:`Request ` sent from this
+ #: :class:`Session `.
+ self.headers = default_headers()
+
+ #: Default Authentication tuple or object to attach to
+ #: :class:`Request `.
+ self.auth = None
+
+ #: Dictionary mapping protocol or protocol and host to the URL of the proxy
+ #: (e.g. {'http': 'foo.bar:3128', 'http://host.name': 'foo.bar:4012'}) to
+ #: be used on each :class:`Request `.
+ self.proxies = {}
+
+ #: Event-handling hooks.
+ self.hooks = default_hooks()
+
+ #: Dictionary of querystring data to attach to each
+ #: :class:`Request `. The dictionary values may be lists for
+ #: representing multivalued query parameters.
+ self.params = {}
+
+ #: Stream response content default.
+ self.stream = False
+
+ #: SSL Verification default.
+ #: Defaults to `True`, requiring requests to verify the TLS certificate at the
+ #: remote end.
+ #: If verify is set to `False`, requests will accept any TLS certificate
+ #: presented by the server, and will ignore hostname mismatches and/or
+ #: expired certificates, which will make your application vulnerable to
+ #: man-in-the-middle (MitM) attacks.
+ #: Only set this to `False` for testing.
+ self.verify = True
+
+ #: SSL client certificate default, if String, path to ssl client
+ #: cert file (.pem). If Tuple, ('cert', 'key') pair.
+ self.cert = None
+
+ #: Maximum number of redirects allowed. If the request exceeds this
+ #: limit, a :class:`TooManyRedirects` exception is raised.
+ #: This defaults to requests.models.DEFAULT_REDIRECT_LIMIT, which is
+ #: 30.
+ self.max_redirects = DEFAULT_REDIRECT_LIMIT
+
+ #: Trust environment settings for proxy configuration, default
+ #: authentication and similar.
+ self.trust_env = True
+
+ #: A CookieJar containing all currently outstanding cookies set on this
+ #: session. By default it is a
+ #: :class:`RequestsCookieJar `, but
+ #: may be any other ``cookielib.CookieJar`` compatible object.
+ self.cookies = cookiejar_from_dict({})
+
+ # Default connection adapters.
+ self.adapters = OrderedDict()
+ self.mount("https://", HTTPAdapter())
+ self.mount("http://", HTTPAdapter())
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, *args):
+ self.close()
+
+ def prepare_request(self, request):
+ """Constructs a :class:`PreparedRequest ` for
+ transmission and returns it. The :class:`PreparedRequest` has settings
+ merged from the :class:`Request ` instance and those of the
+ :class:`Session`.
+
+ :param request: :class:`Request` instance to prepare with this
+ session's settings.
+ :rtype: requests.PreparedRequest
+ """
+ cookies = request.cookies or {}
+
+ # Bootstrap CookieJar.
+ if not isinstance(cookies, cookielib.CookieJar):
+ cookies = cookiejar_from_dict(cookies)
+
+ # Merge with session cookies
+ merged_cookies = merge_cookies(
+ merge_cookies(RequestsCookieJar(), self.cookies), cookies
+ )
+
+ # Set environment's basic authentication if not explicitly set.
+ auth = request.auth
+ if self.trust_env and not auth and not self.auth:
+ auth = get_netrc_auth(request.url)
+
+ p = PreparedRequest()
+ p.prepare(
+ method=request.method.upper(),
+ url=request.url,
+ files=request.files,
+ data=request.data,
+ json=request.json,
+ headers=merge_setting(
+ request.headers, self.headers, dict_class=CaseInsensitiveDict
+ ),
+ params=merge_setting(request.params, self.params),
+ auth=merge_setting(auth, self.auth),
+ cookies=merged_cookies,
+ hooks=merge_hooks(request.hooks, self.hooks),
+ )
+ return p
+
+ def request(
+ self,
+ method,
+ url,
+ params=None,
+ data=None,
+ headers=None,
+ cookies=None,
+ files=None,
+ auth=None,
+ timeout=None,
+ allow_redirects=True,
+ proxies=None,
+ hooks=None,
+ stream=None,
+ verify=None,
+ cert=None,
+ json=None,
+ ):
+ """Constructs a :class:`Request `, prepares it and sends it.
+ Returns :class:`Response ` object.
+
+ :param method: method for the new :class:`Request` object.
+ :param url: URL for the new :class:`Request` object.
+ :param params: (optional) Dictionary or bytes to be sent in the query
+ string for the :class:`Request`.
+ :param data: (optional) Dictionary, list of tuples, bytes, or file-like
+ object to send in the body of the :class:`Request`.
+ :param json: (optional) json to send in the body of the
+ :class:`Request`.
+ :param headers: (optional) Dictionary of HTTP Headers to send with the
+ :class:`Request`.
+ :param cookies: (optional) Dict or CookieJar object to send with the
+ :class:`Request`.
+ :param files: (optional) Dictionary of ``'filename': file-like-objects``
+ for multipart encoding upload.
+ :param auth: (optional) Auth tuple or callable to enable
+ Basic/Digest/Custom HTTP Auth.
+ :param timeout: (optional) How long to wait for the server to send
+ data before giving up, as a float, or a :ref:`(connect timeout,
+ read timeout) ` tuple.
+ :type timeout: float or tuple
+ :param allow_redirects: (optional) Set to True by default.
+ :type allow_redirects: bool
+ :param proxies: (optional) Dictionary mapping protocol or protocol and
+ hostname to the URL of the proxy.
+ :param hooks: (optional) Dictionary mapping hook name to one event or
+ list of events, event must be callable.
+ :param stream: (optional) whether to immediately download the response
+ content. Defaults to ``False``.
+ :param verify: (optional) Either a boolean, in which case it controls whether we verify
+ the server's TLS certificate, or a string, in which case it must be a path
+ to a CA bundle to use. Defaults to ``True``. When set to
+ ``False``, requests will accept any TLS certificate presented by
+ the server, and will ignore hostname mismatches and/or expired
+ certificates, which will make your application vulnerable to
+ man-in-the-middle (MitM) attacks. Setting verify to ``False``
+ may be useful during local development or testing.
+ :param cert: (optional) if String, path to ssl client cert file (.pem).
+ If Tuple, ('cert', 'key') pair.
+ :rtype: requests.Response
+ """
+ # Create the Request.
+ req = Request(
+ method=method.upper(),
+ url=url,
+ headers=headers,
+ files=files,
+ data=data or {},
+ json=json,
+ params=params or {},
+ auth=auth,
+ cookies=cookies,
+ hooks=hooks,
+ )
+ prep = self.prepare_request(req)
+
+ proxies = proxies or {}
+
+ settings = self.merge_environment_settings(
+ prep.url, proxies, stream, verify, cert
+ )
+
+ # Send the request.
+ send_kwargs = {
+ "timeout": timeout,
+ "allow_redirects": allow_redirects,
+ }
+ send_kwargs.update(settings)
+ resp = self.send(prep, **send_kwargs)
+
+ return resp
+
+ def get(self, url, **kwargs):
+ r"""Sends a GET request. Returns :class:`Response` object.
+
+ :param url: URL for the new :class:`Request` object.
+ :param \*\*kwargs: Optional arguments that ``request`` takes.
+ :rtype: requests.Response
+ """
+
+ kwargs.setdefault("allow_redirects", True)
+ return self.request("GET", url, **kwargs)
+
+ def options(self, url, **kwargs):
+ r"""Sends a OPTIONS request. Returns :class:`Response` object.
+
+ :param url: URL for the new :class:`Request` object.
+ :param \*\*kwargs: Optional arguments that ``request`` takes.
+ :rtype: requests.Response
+ """
+
+ kwargs.setdefault("allow_redirects", True)
+ return self.request("OPTIONS", url, **kwargs)
+
+ def head(self, url, **kwargs):
+ r"""Sends a HEAD request. Returns :class:`Response` object.
+
+ :param url: URL for the new :class:`Request` object.
+ :param \*\*kwargs: Optional arguments that ``request`` takes.
+ :rtype: requests.Response
+ """
+
+ kwargs.setdefault("allow_redirects", False)
+ return self.request("HEAD", url, **kwargs)
+
+ def post(self, url, data=None, json=None, **kwargs):
+ r"""Sends a POST request. Returns :class:`Response` object.
+
+ :param url: URL for the new :class:`Request` object.
+ :param data: (optional) Dictionary, list of tuples, bytes, or file-like
+ object to send in the body of the :class:`Request`.
+ :param json: (optional) json to send in the body of the :class:`Request`.
+ :param \*\*kwargs: Optional arguments that ``request`` takes.
+ :rtype: requests.Response
+ """
+
+ return self.request("POST", url, data=data, json=json, **kwargs)
+
+ def put(self, url, data=None, **kwargs):
+ r"""Sends a PUT request. Returns :class:`Response` object.
+
+ :param url: URL for the new :class:`Request` object.
+ :param data: (optional) Dictionary, list of tuples, bytes, or file-like
+ object to send in the body of the :class:`Request`.
+ :param \*\*kwargs: Optional arguments that ``request`` takes.
+ :rtype: requests.Response
+ """
+
+ return self.request("PUT", url, data=data, **kwargs)
+
+ def patch(self, url, data=None, **kwargs):
+ r"""Sends a PATCH request. Returns :class:`Response` object.
+
+ :param url: URL for the new :class:`Request` object.
+ :param data: (optional) Dictionary, list of tuples, bytes, or file-like
+ object to send in the body of the :class:`Request`.
+ :param \*\*kwargs: Optional arguments that ``request`` takes.
+ :rtype: requests.Response
+ """
+
+ return self.request("PATCH", url, data=data, **kwargs)
+
+ def delete(self, url, **kwargs):
+ r"""Sends a DELETE request. Returns :class:`Response` object.
+
+ :param url: URL for the new :class:`Request` object.
+ :param \*\*kwargs: Optional arguments that ``request`` takes.
+ :rtype: requests.Response
+ """
+
+ return self.request("DELETE", url, **kwargs)
+
+ def send(self, request, **kwargs):
+ """Send a given PreparedRequest.
+
+ :rtype: requests.Response
+ """
+ # Set defaults that the hooks can utilize to ensure they always have
+ # the correct parameters to reproduce the previous request.
+ kwargs.setdefault("stream", self.stream)
+ kwargs.setdefault("verify", self.verify)
+ kwargs.setdefault("cert", self.cert)
+ if "proxies" not in kwargs:
+ kwargs["proxies"] = resolve_proxies(request, self.proxies, self.trust_env)
+
+ # It's possible that users might accidentally send a Request object.
+ # Guard against that specific failure case.
+ if isinstance(request, Request):
+ raise ValueError("You can only send PreparedRequests.")
+
+ # Set up variables needed for resolve_redirects and dispatching of hooks
+ allow_redirects = kwargs.pop("allow_redirects", True)
+ stream = kwargs.get("stream")
+ hooks = request.hooks
+
+ # Get the appropriate adapter to use
+ adapter = self.get_adapter(url=request.url)
+
+ # Start time (approximately) of the request
+ start = preferred_clock()
+
+ # Send the request
+ r = adapter.send(request, **kwargs)
+
+ # Total elapsed time of the request (approximately)
+ elapsed = preferred_clock() - start
+ r.elapsed = timedelta(seconds=elapsed)
+
+ # Response manipulation hooks
+ r = dispatch_hook("response", hooks, r, **kwargs)
+
+ # Persist cookies
+ if r.history:
+ # If the hooks create history then we want those cookies too
+ for resp in r.history:
+ extract_cookies_to_jar(self.cookies, resp.request, resp.raw)
+
+ extract_cookies_to_jar(self.cookies, request, r.raw)
+
+ # Resolve redirects if allowed.
+ if allow_redirects:
+ # Redirect resolving generator.
+ gen = self.resolve_redirects(r, request, **kwargs)
+ history = [resp for resp in gen]
+ else:
+ history = []
+
+ # Shuffle things around if there's history.
+ if history:
+ # Insert the first (original) request at the start
+ history.insert(0, r)
+ # Get the last request made
+ r = history.pop()
+ r.history = history
+
+ # If redirects aren't being followed, store the response on the Request for Response.next().
+ if not allow_redirects:
+ try:
+ r._next = next(
+ self.resolve_redirects(r, request, yield_requests=True, **kwargs)
+ )
+ except StopIteration:
+ pass
+
+ if not stream:
+ r.content
+
+ return r
+
+ def merge_environment_settings(self, url, proxies, stream, verify, cert):
+ """
+ Check the environment and merge it with some settings.
+
+ :rtype: dict
+ """
+ # Gather clues from the surrounding environment.
+ if self.trust_env:
+ # Set environment's proxies.
+ no_proxy = proxies.get("no_proxy") if proxies is not None else None
+ env_proxies = get_environ_proxies(url, no_proxy=no_proxy)
+ for k, v in env_proxies.items():
+ proxies.setdefault(k, v)
+
+ # Look for requests environment configuration
+ # and be compatible with cURL.
+ if verify is True or verify is None:
+ verify = (
+ os.environ.get("REQUESTS_CA_BUNDLE")
+ or os.environ.get("CURL_CA_BUNDLE")
+ or verify
+ )
+
+ # Merge all the kwargs.
+ proxies = merge_setting(proxies, self.proxies)
+ stream = merge_setting(stream, self.stream)
+ verify = merge_setting(verify, self.verify)
+ cert = merge_setting(cert, self.cert)
+
+ return {"proxies": proxies, "stream": stream, "verify": verify, "cert": cert}
+
+ def get_adapter(self, url):
+ """
+ Returns the appropriate connection adapter for the given URL.
+
+ :rtype: requests.adapters.BaseAdapter
+ """
+ for prefix, adapter in self.adapters.items():
+ if url.lower().startswith(prefix.lower()):
+ return adapter
+
+ # Nothing matches :-/
+ raise InvalidSchema(f"No connection adapters were found for {url!r}")
+
+ def close(self):
+ """Closes all adapters and as such the session"""
+ for v in self.adapters.values():
+ v.close()
+
+ def mount(self, prefix, adapter):
+ """Registers a connection adapter to a prefix.
+
+ Adapters are sorted in descending order by prefix length.
+ """
+ self.adapters[prefix] = adapter
+ keys_to_move = [k for k in self.adapters if len(k) < len(prefix)]
+
+ for key in keys_to_move:
+ self.adapters[key] = self.adapters.pop(key)
+
+ def __getstate__(self):
+ state = {attr: getattr(self, attr, None) for attr in self.__attrs__}
+ return state
+
+ def __setstate__(self, state):
+ for attr, value in state.items():
+ setattr(self, attr, value)
+
+
+def session():
+ """
+ Returns a :class:`Session` for context-management.
+
+ .. deprecated:: 1.0.0
+
+ This method has been deprecated since version 1.0.0 and is only kept for
+ backwards compatibility. New code should use :class:`~requests.sessions.Session`
+ to create a session. This may be removed at a future date.
+
+ :rtype: Session
+ """
+ return Session()
diff --git a/venv/Lib/site-packages/requests/status_codes.py b/venv/Lib/site-packages/requests/status_codes.py
new file mode 100644
index 00000000..c7945a2f
--- /dev/null
+++ b/venv/Lib/site-packages/requests/status_codes.py
@@ -0,0 +1,128 @@
+r"""
+The ``codes`` object defines a mapping from common names for HTTP statuses
+to their numerical codes, accessible either as attributes or as dictionary
+items.
+
+Example::
+
+ >>> import requests
+ >>> requests.codes['temporary_redirect']
+ 307
+ >>> requests.codes.teapot
+ 418
+ >>> requests.codes['\o/']
+ 200
+
+Some codes have multiple names, and both upper- and lower-case versions of
+the names are allowed. For example, ``codes.ok``, ``codes.OK``, and
+``codes.okay`` all correspond to the HTTP status code 200.
+"""
+
+from .structures import LookupDict
+
+_codes = {
+ # Informational.
+ 100: ("continue",),
+ 101: ("switching_protocols",),
+ 102: ("processing", "early-hints"),
+ 103: ("checkpoint",),
+ 122: ("uri_too_long", "request_uri_too_long"),
+ 200: ("ok", "okay", "all_ok", "all_okay", "all_good", "\\o/", "✓"),
+ 201: ("created",),
+ 202: ("accepted",),
+ 203: ("non_authoritative_info", "non_authoritative_information"),
+ 204: ("no_content",),
+ 205: ("reset_content", "reset"),
+ 206: ("partial_content", "partial"),
+ 207: ("multi_status", "multiple_status", "multi_stati", "multiple_stati"),
+ 208: ("already_reported",),
+ 226: ("im_used",),
+ # Redirection.
+ 300: ("multiple_choices",),
+ 301: ("moved_permanently", "moved", "\\o-"),
+ 302: ("found",),
+ 303: ("see_other", "other"),
+ 304: ("not_modified",),
+ 305: ("use_proxy",),
+ 306: ("switch_proxy",),
+ 307: ("temporary_redirect", "temporary_moved", "temporary"),
+ 308: (
+ "permanent_redirect",
+ "resume_incomplete",
+ "resume",
+ ), # "resume" and "resume_incomplete" to be removed in 3.0
+ # Client Error.
+ 400: ("bad_request", "bad"),
+ 401: ("unauthorized",),
+ 402: ("payment_required", "payment"),
+ 403: ("forbidden",),
+ 404: ("not_found", "-o-"),
+ 405: ("method_not_allowed", "not_allowed"),
+ 406: ("not_acceptable",),
+ 407: ("proxy_authentication_required", "proxy_auth", "proxy_authentication"),
+ 408: ("request_timeout", "timeout"),
+ 409: ("conflict",),
+ 410: ("gone",),
+ 411: ("length_required",),
+ 412: ("precondition_failed", "precondition"),
+ 413: ("request_entity_too_large", "content_too_large"),
+ 414: ("request_uri_too_large", "uri_too_long"),
+ 415: ("unsupported_media_type", "unsupported_media", "media_type"),
+ 416: (
+ "requested_range_not_satisfiable",
+ "requested_range",
+ "range_not_satisfiable",
+ ),
+ 417: ("expectation_failed",),
+ 418: ("im_a_teapot", "teapot", "i_am_a_teapot"),
+ 421: ("misdirected_request",),
+ 422: ("unprocessable_entity", "unprocessable", "unprocessable_content"),
+ 423: ("locked",),
+ 424: ("failed_dependency", "dependency"),
+ 425: ("unordered_collection", "unordered", "too_early"),
+ 426: ("upgrade_required", "upgrade"),
+ 428: ("precondition_required", "precondition"),
+ 429: ("too_many_requests", "too_many"),
+ 431: ("header_fields_too_large", "fields_too_large"),
+ 444: ("no_response", "none"),
+ 449: ("retry_with", "retry"),
+ 450: ("blocked_by_windows_parental_controls", "parental_controls"),
+ 451: ("unavailable_for_legal_reasons", "legal_reasons"),
+ 499: ("client_closed_request",),
+ # Server Error.
+ 500: ("internal_server_error", "server_error", "/o\\", "✗"),
+ 501: ("not_implemented",),
+ 502: ("bad_gateway",),
+ 503: ("service_unavailable", "unavailable"),
+ 504: ("gateway_timeout",),
+ 505: ("http_version_not_supported", "http_version"),
+ 506: ("variant_also_negotiates",),
+ 507: ("insufficient_storage",),
+ 509: ("bandwidth_limit_exceeded", "bandwidth"),
+ 510: ("not_extended",),
+ 511: ("network_authentication_required", "network_auth", "network_authentication"),
+}
+
+codes = LookupDict(name="status_codes")
+
+
+def _init():
+ for code, titles in _codes.items():
+ for title in titles:
+ setattr(codes, title, code)
+ if not title.startswith(("\\", "/")):
+ setattr(codes, title.upper(), code)
+
+ def doc(code):
+ names = ", ".join(f"``{n}``" for n in _codes[code])
+ return "* %d: %s" % (code, names)
+
+ global __doc__
+ __doc__ = (
+ __doc__ + "\n" + "\n".join(doc(code) for code in sorted(_codes))
+ if __doc__ is not None
+ else None
+ )
+
+
+_init()
diff --git a/venv/Lib/site-packages/requests/structures.py b/venv/Lib/site-packages/requests/structures.py
new file mode 100644
index 00000000..188e13e4
--- /dev/null
+++ b/venv/Lib/site-packages/requests/structures.py
@@ -0,0 +1,99 @@
+"""
+requests.structures
+~~~~~~~~~~~~~~~~~~~
+
+Data structures that power Requests.
+"""
+
+from collections import OrderedDict
+
+from .compat import Mapping, MutableMapping
+
+
+class CaseInsensitiveDict(MutableMapping):
+ """A case-insensitive ``dict``-like object.
+
+ Implements all methods and operations of
+ ``MutableMapping`` as well as dict's ``copy``. Also
+ provides ``lower_items``.
+
+ All keys are expected to be strings. The structure remembers the
+ case of the last key to be set, and ``iter(instance)``,
+ ``keys()``, ``items()``, ``iterkeys()``, and ``iteritems()``
+ will contain case-sensitive keys. However, querying and contains
+ testing is case insensitive::
+
+ cid = CaseInsensitiveDict()
+ cid['Accept'] = 'application/json'
+ cid['aCCEPT'] == 'application/json' # True
+ list(cid) == ['Accept'] # True
+
+ For example, ``headers['content-encoding']`` will return the
+ value of a ``'Content-Encoding'`` response header, regardless
+ of how the header name was originally stored.
+
+ If the constructor, ``.update``, or equality comparison
+ operations are given keys that have equal ``.lower()``s, the
+ behavior is undefined.
+ """
+
+ def __init__(self, data=None, **kwargs):
+ self._store = OrderedDict()
+ if data is None:
+ data = {}
+ self.update(data, **kwargs)
+
+ def __setitem__(self, key, value):
+ # Use the lowercased key for lookups, but store the actual
+ # key alongside the value.
+ self._store[key.lower()] = (key, value)
+
+ def __getitem__(self, key):
+ return self._store[key.lower()][1]
+
+ def __delitem__(self, key):
+ del self._store[key.lower()]
+
+ def __iter__(self):
+ return (casedkey for casedkey, mappedvalue in self._store.values())
+
+ def __len__(self):
+ return len(self._store)
+
+ def lower_items(self):
+ """Like iteritems(), but with all lowercase keys."""
+ return ((lowerkey, keyval[1]) for (lowerkey, keyval) in self._store.items())
+
+ def __eq__(self, other):
+ if isinstance(other, Mapping):
+ other = CaseInsensitiveDict(other)
+ else:
+ return NotImplemented
+ # Compare insensitively
+ return dict(self.lower_items()) == dict(other.lower_items())
+
+ # Copy is required
+ def copy(self):
+ return CaseInsensitiveDict(self._store.values())
+
+ def __repr__(self):
+ return str(dict(self.items()))
+
+
+class LookupDict(dict):
+ """Dictionary lookup object."""
+
+ def __init__(self, name=None):
+ self.name = name
+ super().__init__()
+
+ def __repr__(self):
+ return f""
+
+ def __getitem__(self, key):
+ # We allow fall-through here, so values default to None
+
+ return self.__dict__.get(key, None)
+
+ def get(self, key, default=None):
+ return self.__dict__.get(key, default)
diff --git a/venv/Lib/site-packages/requests/utils.py b/venv/Lib/site-packages/requests/utils.py
new file mode 100644
index 00000000..8ab55852
--- /dev/null
+++ b/venv/Lib/site-packages/requests/utils.py
@@ -0,0 +1,1086 @@
+"""
+requests.utils
+~~~~~~~~~~~~~~
+
+This module provides utility functions that are used within Requests
+that are also useful for external consumption.
+"""
+
+import codecs
+import contextlib
+import io
+import os
+import re
+import socket
+import struct
+import sys
+import tempfile
+import warnings
+import zipfile
+from collections import OrderedDict
+
+from urllib3.util import make_headers, parse_url
+
+from . import certs
+from .__version__ import __version__
+
+# to_native_string is unused here, but imported here for backwards compatibility
+from ._internal_utils import ( # noqa: F401
+ _HEADER_VALIDATORS_BYTE,
+ _HEADER_VALIDATORS_STR,
+ HEADER_VALIDATORS,
+ to_native_string,
+)
+from .compat import (
+ Mapping,
+ basestring,
+ bytes,
+ getproxies,
+ getproxies_environment,
+ integer_types,
+ is_urllib3_1,
+)
+from .compat import parse_http_list as _parse_list_header
+from .compat import (
+ proxy_bypass,
+ proxy_bypass_environment,
+ quote,
+ str,
+ unquote,
+ urlparse,
+ urlunparse,
+)
+from .cookies import cookiejar_from_dict
+from .exceptions import (
+ FileModeWarning,
+ InvalidHeader,
+ InvalidURL,
+ UnrewindableBodyError,
+)
+from .structures import CaseInsensitiveDict
+
+NETRC_FILES = (".netrc", "_netrc")
+
+DEFAULT_CA_BUNDLE_PATH = certs.where()
+
+DEFAULT_PORTS = {"http": 80, "https": 443}
+
+# Ensure that ', ' is used to preserve previous delimiter behavior.
+DEFAULT_ACCEPT_ENCODING = ", ".join(
+ re.split(r",\s*", make_headers(accept_encoding=True)["accept-encoding"])
+)
+
+
+if sys.platform == "win32":
+ # provide a proxy_bypass version on Windows without DNS lookups
+
+ def proxy_bypass_registry(host):
+ try:
+ import winreg
+ except ImportError:
+ return False
+
+ try:
+ internetSettings = winreg.OpenKey(
+ winreg.HKEY_CURRENT_USER,
+ r"Software\Microsoft\Windows\CurrentVersion\Internet Settings",
+ )
+ # ProxyEnable could be REG_SZ or REG_DWORD, normalizing it
+ proxyEnable = int(winreg.QueryValueEx(internetSettings, "ProxyEnable")[0])
+ # ProxyOverride is almost always a string
+ proxyOverride = winreg.QueryValueEx(internetSettings, "ProxyOverride")[0]
+ except (OSError, ValueError):
+ return False
+ if not proxyEnable or not proxyOverride:
+ return False
+
+ # make a check value list from the registry entry: replace the
+ # '' string by the localhost entry and the corresponding
+ # canonical entry.
+ proxyOverride = proxyOverride.split(";")
+ # filter out empty strings to avoid re.match return true in the following code.
+ proxyOverride = filter(None, proxyOverride)
+ # now check if we match one of the registry values.
+ for test in proxyOverride:
+ if test == "":
+ if "." not in host:
+ return True
+ test = test.replace(".", r"\.") # mask dots
+ test = test.replace("*", r".*") # change glob sequence
+ test = test.replace("?", r".") # change glob char
+ if re.match(test, host, re.I):
+ return True
+ return False
+
+ def proxy_bypass(host): # noqa
+ """Return True, if the host should be bypassed.
+
+ Checks proxy settings gathered from the environment, if specified,
+ or the registry.
+ """
+ if getproxies_environment():
+ return proxy_bypass_environment(host)
+ else:
+ return proxy_bypass_registry(host)
+
+
+def dict_to_sequence(d):
+ """Returns an internal sequence dictionary update."""
+
+ if hasattr(d, "items"):
+ d = d.items()
+
+ return d
+
+
+def super_len(o):
+ total_length = None
+ current_position = 0
+
+ if not is_urllib3_1 and isinstance(o, str):
+ # urllib3 2.x+ treats all strings as utf-8 instead
+ # of latin-1 (iso-8859-1) like http.client.
+ o = o.encode("utf-8")
+
+ if hasattr(o, "__len__"):
+ total_length = len(o)
+
+ elif hasattr(o, "len"):
+ total_length = o.len
+
+ elif hasattr(o, "fileno"):
+ try:
+ fileno = o.fileno()
+ except (io.UnsupportedOperation, AttributeError):
+ # AttributeError is a surprising exception, seeing as how we've just checked
+ # that `hasattr(o, 'fileno')`. It happens for objects obtained via
+ # `Tarfile.extractfile()`, per issue 5229.
+ pass
+ else:
+ total_length = os.fstat(fileno).st_size
+
+ # Having used fstat to determine the file length, we need to
+ # confirm that this file was opened up in binary mode.
+ if "b" not in o.mode:
+ warnings.warn(
+ (
+ "Requests has determined the content-length for this "
+ "request using the binary size of the file: however, the "
+ "file has been opened in text mode (i.e. without the 'b' "
+ "flag in the mode). This may lead to an incorrect "
+ "content-length. In Requests 3.0, support will be removed "
+ "for files in text mode."
+ ),
+ FileModeWarning,
+ )
+
+ if hasattr(o, "tell"):
+ try:
+ current_position = o.tell()
+ except OSError:
+ # This can happen in some weird situations, such as when the file
+ # is actually a special file descriptor like stdin. In this
+ # instance, we don't know what the length is, so set it to zero and
+ # let requests chunk it instead.
+ if total_length is not None:
+ current_position = total_length
+ else:
+ if hasattr(o, "seek") and total_length is None:
+ # StringIO and BytesIO have seek but no usable fileno
+ try:
+ # seek to end of file
+ o.seek(0, 2)
+ total_length = o.tell()
+
+ # seek back to current position to support
+ # partially read file-like objects
+ o.seek(current_position or 0)
+ except OSError:
+ total_length = 0
+
+ if total_length is None:
+ total_length = 0
+
+ return max(0, total_length - current_position)
+
+
+def get_netrc_auth(url, raise_errors=False):
+ """Returns the Requests tuple auth for a given url from netrc."""
+
+ netrc_file = os.environ.get("NETRC")
+ if netrc_file is not None:
+ netrc_locations = (netrc_file,)
+ else:
+ netrc_locations = (f"~/{f}" for f in NETRC_FILES)
+
+ try:
+ from netrc import NetrcParseError, netrc
+
+ netrc_path = None
+
+ for f in netrc_locations:
+ loc = os.path.expanduser(f)
+ if os.path.exists(loc):
+ netrc_path = loc
+ break
+
+ # Abort early if there isn't one.
+ if netrc_path is None:
+ return
+
+ ri = urlparse(url)
+ host = ri.hostname
+
+ try:
+ _netrc = netrc(netrc_path).authenticators(host)
+ if _netrc:
+ # Return with login / password
+ login_i = 0 if _netrc[0] else 1
+ return (_netrc[login_i], _netrc[2])
+ except (NetrcParseError, OSError):
+ # If there was a parsing error or a permissions issue reading the file,
+ # we'll just skip netrc auth unless explicitly asked to raise errors.
+ if raise_errors:
+ raise
+
+ # App Engine hackiness.
+ except (ImportError, AttributeError):
+ pass
+
+
+def guess_filename(obj):
+ """Tries to guess the filename of the given object."""
+ name = getattr(obj, "name", None)
+ if name and isinstance(name, basestring) and name[0] != "<" and name[-1] != ">":
+ return os.path.basename(name)
+
+
+def extract_zipped_paths(path):
+ """Replace nonexistent paths that look like they refer to a member of a zip
+ archive with the location of an extracted copy of the target, or else
+ just return the provided path unchanged.
+ """
+ if os.path.exists(path):
+ # this is already a valid path, no need to do anything further
+ return path
+
+ # find the first valid part of the provided path and treat that as a zip archive
+ # assume the rest of the path is the name of a member in the archive
+ archive, member = os.path.split(path)
+ while archive and not os.path.exists(archive):
+ archive, prefix = os.path.split(archive)
+ if not prefix:
+ # If we don't check for an empty prefix after the split (in other words, archive remains unchanged after the split),
+ # we _can_ end up in an infinite loop on a rare corner case affecting a small number of users
+ break
+ member = "/".join([prefix, member])
+
+ if not zipfile.is_zipfile(archive):
+ return path
+
+ zip_file = zipfile.ZipFile(archive)
+ if member not in zip_file.namelist():
+ return path
+
+ # we have a valid zip archive and a valid member of that archive
+ tmp = tempfile.gettempdir()
+ extracted_path = os.path.join(tmp, member.split("/")[-1])
+ if not os.path.exists(extracted_path):
+ # use read + write to avoid the creating nested folders, we only want the file, avoids mkdir racing condition
+ with atomic_open(extracted_path) as file_handler:
+ file_handler.write(zip_file.read(member))
+ return extracted_path
+
+
+@contextlib.contextmanager
+def atomic_open(filename):
+ """Write a file to the disk in an atomic fashion"""
+ tmp_descriptor, tmp_name = tempfile.mkstemp(dir=os.path.dirname(filename))
+ try:
+ with os.fdopen(tmp_descriptor, "wb") as tmp_handler:
+ yield tmp_handler
+ os.replace(tmp_name, filename)
+ except BaseException:
+ os.remove(tmp_name)
+ raise
+
+
+def from_key_val_list(value):
+ """Take an object and test to see if it can be represented as a
+ dictionary. Unless it can not be represented as such, return an
+ OrderedDict, e.g.,
+
+ ::
+
+ >>> from_key_val_list([('key', 'val')])
+ OrderedDict([('key', 'val')])
+ >>> from_key_val_list('string')
+ Traceback (most recent call last):
+ ...
+ ValueError: cannot encode objects that are not 2-tuples
+ >>> from_key_val_list({'key': 'val'})
+ OrderedDict([('key', 'val')])
+
+ :rtype: OrderedDict
+ """
+ if value is None:
+ return None
+
+ if isinstance(value, (str, bytes, bool, int)):
+ raise ValueError("cannot encode objects that are not 2-tuples")
+
+ return OrderedDict(value)
+
+
+def to_key_val_list(value):
+ """Take an object and test to see if it can be represented as a
+ dictionary. If it can be, return a list of tuples, e.g.,
+
+ ::
+
+ >>> to_key_val_list([('key', 'val')])
+ [('key', 'val')]
+ >>> to_key_val_list({'key': 'val'})
+ [('key', 'val')]
+ >>> to_key_val_list('string')
+ Traceback (most recent call last):
+ ...
+ ValueError: cannot encode objects that are not 2-tuples
+
+ :rtype: list
+ """
+ if value is None:
+ return None
+
+ if isinstance(value, (str, bytes, bool, int)):
+ raise ValueError("cannot encode objects that are not 2-tuples")
+
+ if isinstance(value, Mapping):
+ value = value.items()
+
+ return list(value)
+
+
+# From mitsuhiko/werkzeug (used with permission).
+def parse_list_header(value):
+ """Parse lists as described by RFC 2068 Section 2.
+
+ In particular, parse comma-separated lists where the elements of
+ the list may include quoted-strings. A quoted-string could
+ contain a comma. A non-quoted string could have quotes in the
+ middle. Quotes are removed automatically after parsing.
+
+ It basically works like :func:`parse_set_header` just that items
+ may appear multiple times and case sensitivity is preserved.
+
+ The return value is a standard :class:`list`:
+
+ >>> parse_list_header('token, "quoted value"')
+ ['token', 'quoted value']
+
+ To create a header from the :class:`list` again, use the
+ :func:`dump_header` function.
+
+ :param value: a string with a list header.
+ :return: :class:`list`
+ :rtype: list
+ """
+ result = []
+ for item in _parse_list_header(value):
+ if item[:1] == item[-1:] == '"':
+ item = unquote_header_value(item[1:-1])
+ result.append(item)
+ return result
+
+
+# From mitsuhiko/werkzeug (used with permission).
+def parse_dict_header(value):
+ """Parse lists of key, value pairs as described by RFC 2068 Section 2 and
+ convert them into a python dict:
+
+ >>> d = parse_dict_header('foo="is a fish", bar="as well"')
+ >>> type(d) is dict
+ True
+ >>> sorted(d.items())
+ [('bar', 'as well'), ('foo', 'is a fish')]
+
+ If there is no value for a key it will be `None`:
+
+ >>> parse_dict_header('key_without_value')
+ {'key_without_value': None}
+
+ To create a header from the :class:`dict` again, use the
+ :func:`dump_header` function.
+
+ :param value: a string with a dict header.
+ :return: :class:`dict`
+ :rtype: dict
+ """
+ result = {}
+ for item in _parse_list_header(value):
+ if "=" not in item:
+ result[item] = None
+ continue
+ name, value = item.split("=", 1)
+ if value[:1] == value[-1:] == '"':
+ value = unquote_header_value(value[1:-1])
+ result[name] = value
+ return result
+
+
+# From mitsuhiko/werkzeug (used with permission).
+def unquote_header_value(value, is_filename=False):
+ r"""Unquotes a header value. (Reversal of :func:`quote_header_value`).
+ This does not use the real unquoting but what browsers are actually
+ using for quoting.
+
+ :param value: the header value to unquote.
+ :rtype: str
+ """
+ if value and value[0] == value[-1] == '"':
+ # this is not the real unquoting, but fixing this so that the
+ # RFC is met will result in bugs with internet explorer and
+ # probably some other browsers as well. IE for example is
+ # uploading files with "C:\foo\bar.txt" as filename
+ value = value[1:-1]
+
+ # if this is a filename and the starting characters look like
+ # a UNC path, then just return the value without quotes. Using the
+ # replace sequence below on a UNC path has the effect of turning
+ # the leading double slash into a single slash and then
+ # _fix_ie_filename() doesn't work correctly. See #458.
+ if not is_filename or value[:2] != "\\\\":
+ return value.replace("\\\\", "\\").replace('\\"', '"')
+ return value
+
+
+def dict_from_cookiejar(cj):
+ """Returns a key/value dictionary from a CookieJar.
+
+ :param cj: CookieJar object to extract cookies from.
+ :rtype: dict
+ """
+
+ cookie_dict = {cookie.name: cookie.value for cookie in cj}
+ return cookie_dict
+
+
+def add_dict_to_cookiejar(cj, cookie_dict):
+ """Returns a CookieJar from a key/value dictionary.
+
+ :param cj: CookieJar to insert cookies into.
+ :param cookie_dict: Dict of key/values to insert into CookieJar.
+ :rtype: CookieJar
+ """
+
+ return cookiejar_from_dict(cookie_dict, cj)
+
+
+def get_encodings_from_content(content):
+ """Returns encodings from given content string.
+
+ :param content: bytestring to extract encodings from.
+ """
+ warnings.warn(
+ (
+ "In requests 3.0, get_encodings_from_content will be removed. For "
+ "more information, please see the discussion on issue #2266. (This"
+ " warning should only appear once.)"
+ ),
+ DeprecationWarning,
+ )
+
+ charset_re = re.compile(r']', flags=re.I)
+ pragma_re = re.compile(r']', flags=re.I)
+ xml_re = re.compile(r'^<\?xml.*?encoding=["\']*(.+?)["\'>]')
+
+ return (
+ charset_re.findall(content)
+ + pragma_re.findall(content)
+ + xml_re.findall(content)
+ )
+
+
+def _parse_content_type_header(header):
+ """Returns content type and parameters from given header
+
+ :param header: string
+ :return: tuple containing content type and dictionary of
+ parameters
+ """
+
+ tokens = header.split(";")
+ content_type, params = tokens[0].strip(), tokens[1:]
+ params_dict = {}
+ items_to_strip = "\"' "
+
+ for param in params:
+ param = param.strip()
+ if param:
+ key, value = param, True
+ index_of_equals = param.find("=")
+ if index_of_equals != -1:
+ key = param[:index_of_equals].strip(items_to_strip)
+ value = param[index_of_equals + 1 :].strip(items_to_strip)
+ params_dict[key.lower()] = value
+ return content_type, params_dict
+
+
+def get_encoding_from_headers(headers):
+ """Returns encodings from given HTTP Header Dict.
+
+ :param headers: dictionary to extract encoding from.
+ :rtype: str
+ """
+
+ content_type = headers.get("content-type")
+
+ if not content_type:
+ return None
+
+ content_type, params = _parse_content_type_header(content_type)
+
+ if "charset" in params:
+ return params["charset"].strip("'\"")
+
+ if "text" in content_type:
+ return "ISO-8859-1"
+
+ if "application/json" in content_type:
+ # Assume UTF-8 based on RFC 4627: https://www.ietf.org/rfc/rfc4627.txt since the charset was unset
+ return "utf-8"
+
+
+def stream_decode_response_unicode(iterator, r):
+ """Stream decodes an iterator."""
+
+ if r.encoding is None:
+ yield from iterator
+ return
+
+ decoder = codecs.getincrementaldecoder(r.encoding)(errors="replace")
+ for chunk in iterator:
+ rv = decoder.decode(chunk)
+ if rv:
+ yield rv
+ rv = decoder.decode(b"", final=True)
+ if rv:
+ yield rv
+
+
+def iter_slices(string, slice_length):
+ """Iterate over slices of a string."""
+ pos = 0
+ if slice_length is None or slice_length <= 0:
+ slice_length = len(string)
+ while pos < len(string):
+ yield string[pos : pos + slice_length]
+ pos += slice_length
+
+
+def get_unicode_from_response(r):
+ """Returns the requested content back in unicode.
+
+ :param r: Response object to get unicode content from.
+
+ Tried:
+
+ 1. charset from content-type
+ 2. fall back and replace all unicode characters
+
+ :rtype: str
+ """
+ warnings.warn(
+ (
+ "In requests 3.0, get_unicode_from_response will be removed. For "
+ "more information, please see the discussion on issue #2266. (This"
+ " warning should only appear once.)"
+ ),
+ DeprecationWarning,
+ )
+
+ tried_encodings = []
+
+ # Try charset from content-type
+ encoding = get_encoding_from_headers(r.headers)
+
+ if encoding:
+ try:
+ return str(r.content, encoding)
+ except UnicodeError:
+ tried_encodings.append(encoding)
+
+ # Fall back:
+ try:
+ return str(r.content, encoding, errors="replace")
+ except TypeError:
+ return r.content
+
+
+# The unreserved URI characters (RFC 3986)
+UNRESERVED_SET = frozenset(
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + "0123456789-._~"
+)
+
+
+def unquote_unreserved(uri):
+ """Un-escape any percent-escape sequences in a URI that are unreserved
+ characters. This leaves all reserved, illegal and non-ASCII bytes encoded.
+
+ :rtype: str
+ """
+ parts = uri.split("%")
+ for i in range(1, len(parts)):
+ h = parts[i][0:2]
+ if len(h) == 2 and h.isalnum():
+ try:
+ c = chr(int(h, 16))
+ except ValueError:
+ raise InvalidURL(f"Invalid percent-escape sequence: '{h}'")
+
+ if c in UNRESERVED_SET:
+ parts[i] = c + parts[i][2:]
+ else:
+ parts[i] = f"%{parts[i]}"
+ else:
+ parts[i] = f"%{parts[i]}"
+ return "".join(parts)
+
+
+def requote_uri(uri):
+ """Re-quote the given URI.
+
+ This function passes the given URI through an unquote/quote cycle to
+ ensure that it is fully and consistently quoted.
+
+ :rtype: str
+ """
+ safe_with_percent = "!#$%&'()*+,/:;=?@[]~"
+ safe_without_percent = "!#$&'()*+,/:;=?@[]~"
+ try:
+ # Unquote only the unreserved characters
+ # Then quote only illegal characters (do not quote reserved,
+ # unreserved, or '%')
+ return quote(unquote_unreserved(uri), safe=safe_with_percent)
+ except InvalidURL:
+ # We couldn't unquote the given URI, so let's try quoting it, but
+ # there may be unquoted '%'s in the URI. We need to make sure they're
+ # properly quoted so they do not cause issues elsewhere.
+ return quote(uri, safe=safe_without_percent)
+
+
+def address_in_network(ip, net):
+ """This function allows you to check if an IP belongs to a network subnet
+
+ Example: returns True if ip = 192.168.1.1 and net = 192.168.1.0/24
+ returns False if ip = 192.168.1.1 and net = 192.168.100.0/24
+
+ :rtype: bool
+ """
+ ipaddr = struct.unpack("=L", socket.inet_aton(ip))[0]
+ netaddr, bits = net.split("/")
+ netmask = struct.unpack("=L", socket.inet_aton(dotted_netmask(int(bits))))[0]
+ network = struct.unpack("=L", socket.inet_aton(netaddr))[0] & netmask
+ return (ipaddr & netmask) == (network & netmask)
+
+
+def dotted_netmask(mask):
+ """Converts mask from /xx format to xxx.xxx.xxx.xxx
+
+ Example: if mask is 24 function returns 255.255.255.0
+
+ :rtype: str
+ """
+ bits = 0xFFFFFFFF ^ (1 << 32 - mask) - 1
+ return socket.inet_ntoa(struct.pack(">I", bits))
+
+
+def is_ipv4_address(string_ip):
+ """
+ :rtype: bool
+ """
+ try:
+ socket.inet_aton(string_ip)
+ except OSError:
+ return False
+ return True
+
+
+def is_valid_cidr(string_network):
+ """
+ Very simple check of the cidr format in no_proxy variable.
+
+ :rtype: bool
+ """
+ if string_network.count("/") == 1:
+ try:
+ mask = int(string_network.split("/")[1])
+ except ValueError:
+ return False
+
+ if mask < 1 or mask > 32:
+ return False
+
+ try:
+ socket.inet_aton(string_network.split("/")[0])
+ except OSError:
+ return False
+ else:
+ return False
+ return True
+
+
+@contextlib.contextmanager
+def set_environ(env_name, value):
+ """Set the environment variable 'env_name' to 'value'
+
+ Save previous value, yield, and then restore the previous value stored in
+ the environment variable 'env_name'.
+
+ If 'value' is None, do nothing"""
+ value_changed = value is not None
+ if value_changed:
+ old_value = os.environ.get(env_name)
+ os.environ[env_name] = value
+ try:
+ yield
+ finally:
+ if value_changed:
+ if old_value is None:
+ del os.environ[env_name]
+ else:
+ os.environ[env_name] = old_value
+
+
+def should_bypass_proxies(url, no_proxy):
+ """
+ Returns whether we should bypass proxies or not.
+
+ :rtype: bool
+ """
+
+ # Prioritize lowercase environment variables over uppercase
+ # to keep a consistent behaviour with other http projects (curl, wget).
+ def get_proxy(key):
+ return os.environ.get(key) or os.environ.get(key.upper())
+
+ # First check whether no_proxy is defined. If it is, check that the URL
+ # we're getting isn't in the no_proxy list.
+ no_proxy_arg = no_proxy
+ if no_proxy is None:
+ no_proxy = get_proxy("no_proxy")
+ parsed = urlparse(url)
+
+ if parsed.hostname is None:
+ # URLs don't always have hostnames, e.g. file:/// urls.
+ return True
+
+ if no_proxy:
+ # We need to check whether we match here. We need to see if we match
+ # the end of the hostname, both with and without the port.
+ no_proxy = (host for host in no_proxy.replace(" ", "").split(",") if host)
+
+ if is_ipv4_address(parsed.hostname):
+ for proxy_ip in no_proxy:
+ if is_valid_cidr(proxy_ip):
+ if address_in_network(parsed.hostname, proxy_ip):
+ return True
+ elif parsed.hostname == proxy_ip:
+ # If no_proxy ip was defined in plain IP notation instead of cidr notation &
+ # matches the IP of the index
+ return True
+ else:
+ host_with_port = parsed.hostname
+ if parsed.port:
+ host_with_port += f":{parsed.port}"
+
+ for host in no_proxy:
+ if parsed.hostname.endswith(host) or host_with_port.endswith(host):
+ # The URL does match something in no_proxy, so we don't want
+ # to apply the proxies on this URL.
+ return True
+
+ with set_environ("no_proxy", no_proxy_arg):
+ # parsed.hostname can be `None` in cases such as a file URI.
+ try:
+ bypass = proxy_bypass(parsed.hostname)
+ except (TypeError, socket.gaierror):
+ bypass = False
+
+ if bypass:
+ return True
+
+ return False
+
+
+def get_environ_proxies(url, no_proxy=None):
+ """
+ Return a dict of environment proxies.
+
+ :rtype: dict
+ """
+ if should_bypass_proxies(url, no_proxy=no_proxy):
+ return {}
+ else:
+ return getproxies()
+
+
+def select_proxy(url, proxies):
+ """Select a proxy for the url, if applicable.
+
+ :param url: The url being for the request
+ :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs
+ """
+ proxies = proxies or {}
+ urlparts = urlparse(url)
+ if urlparts.hostname is None:
+ return proxies.get(urlparts.scheme, proxies.get("all"))
+
+ proxy_keys = [
+ urlparts.scheme + "://" + urlparts.hostname,
+ urlparts.scheme,
+ "all://" + urlparts.hostname,
+ "all",
+ ]
+ proxy = None
+ for proxy_key in proxy_keys:
+ if proxy_key in proxies:
+ proxy = proxies[proxy_key]
+ break
+
+ return proxy
+
+
+def resolve_proxies(request, proxies, trust_env=True):
+ """This method takes proxy information from a request and configuration
+ input to resolve a mapping of target proxies. This will consider settings
+ such as NO_PROXY to strip proxy configurations.
+
+ :param request: Request or PreparedRequest
+ :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs
+ :param trust_env: Boolean declaring whether to trust environment configs
+
+ :rtype: dict
+ """
+ proxies = proxies if proxies is not None else {}
+ url = request.url
+ scheme = urlparse(url).scheme
+ no_proxy = proxies.get("no_proxy")
+ new_proxies = proxies.copy()
+
+ if trust_env and not should_bypass_proxies(url, no_proxy=no_proxy):
+ environ_proxies = get_environ_proxies(url, no_proxy=no_proxy)
+
+ proxy = environ_proxies.get(scheme, environ_proxies.get("all"))
+
+ if proxy:
+ new_proxies.setdefault(scheme, proxy)
+ return new_proxies
+
+
+def default_user_agent(name="python-requests"):
+ """
+ Return a string representing the default user agent.
+
+ :rtype: str
+ """
+ return f"{name}/{__version__}"
+
+
+def default_headers():
+ """
+ :rtype: requests.structures.CaseInsensitiveDict
+ """
+ return CaseInsensitiveDict(
+ {
+ "User-Agent": default_user_agent(),
+ "Accept-Encoding": DEFAULT_ACCEPT_ENCODING,
+ "Accept": "*/*",
+ "Connection": "keep-alive",
+ }
+ )
+
+
+def parse_header_links(value):
+ """Return a list of parsed link headers proxies.
+
+ i.e. Link: ; rel=front; type="image/jpeg",; rel=back;type="image/jpeg"
+
+ :rtype: list
+ """
+
+ links = []
+
+ replace_chars = " '\""
+
+ value = value.strip(replace_chars)
+ if not value:
+ return links
+
+ for val in re.split(", *<", value):
+ try:
+ url, params = val.split(";", 1)
+ except ValueError:
+ url, params = val, ""
+
+ link = {"url": url.strip("<> '\"")}
+
+ for param in params.split(";"):
+ try:
+ key, value = param.split("=")
+ except ValueError:
+ break
+
+ link[key.strip(replace_chars)] = value.strip(replace_chars)
+
+ links.append(link)
+
+ return links
+
+
+# Null bytes; no need to recreate these on each call to guess_json_utf
+_null = "\x00".encode("ascii") # encoding to ASCII for Python 3
+_null2 = _null * 2
+_null3 = _null * 3
+
+
+def guess_json_utf(data):
+ """
+ :rtype: str
+ """
+ # JSON always starts with two ASCII characters, so detection is as
+ # easy as counting the nulls and from their location and count
+ # determine the encoding. Also detect a BOM, if present.
+ sample = data[:4]
+ if sample in (codecs.BOM_UTF32_LE, codecs.BOM_UTF32_BE):
+ return "utf-32" # BOM included
+ if sample[:3] == codecs.BOM_UTF8:
+ return "utf-8-sig" # BOM included, MS style (discouraged)
+ if sample[:2] in (codecs.BOM_UTF16_LE, codecs.BOM_UTF16_BE):
+ return "utf-16" # BOM included
+ nullcount = sample.count(_null)
+ if nullcount == 0:
+ return "utf-8"
+ if nullcount == 2:
+ if sample[::2] == _null2: # 1st and 3rd are null
+ return "utf-16-be"
+ if sample[1::2] == _null2: # 2nd and 4th are null
+ return "utf-16-le"
+ # Did not detect 2 valid UTF-16 ascii-range characters
+ if nullcount == 3:
+ if sample[:3] == _null3:
+ return "utf-32-be"
+ if sample[1:] == _null3:
+ return "utf-32-le"
+ # Did not detect a valid UTF-32 ascii-range character
+ return None
+
+
+def prepend_scheme_if_needed(url, new_scheme):
+ """Given a URL that may or may not have a scheme, prepend the given scheme.
+ Does not replace a present scheme with the one provided as an argument.
+
+ :rtype: str
+ """
+ parsed = parse_url(url)
+ scheme, auth, host, port, path, query, fragment = parsed
+
+ # A defect in urlparse determines that there isn't a netloc present in some
+ # urls. We previously assumed parsing was overly cautious, and swapped the
+ # netloc and path. Due to a lack of tests on the original defect, this is
+ # maintained with parse_url for backwards compatibility.
+ netloc = parsed.netloc
+ if not netloc:
+ netloc, path = path, netloc
+
+ if auth:
+ # parse_url doesn't provide the netloc with auth
+ # so we'll add it ourselves.
+ netloc = "@".join([auth, netloc])
+ if scheme is None:
+ scheme = new_scheme
+ if path is None:
+ path = ""
+
+ return urlunparse((scheme, netloc, path, "", query, fragment))
+
+
+def get_auth_from_url(url):
+ """Given a url with authentication components, extract them into a tuple of
+ username,password.
+
+ :rtype: (str,str)
+ """
+ parsed = urlparse(url)
+
+ try:
+ auth = (unquote(parsed.username), unquote(parsed.password))
+ except (AttributeError, TypeError):
+ auth = ("", "")
+
+ return auth
+
+
+def check_header_validity(header):
+ """Verifies that header parts don't contain leading whitespace
+ reserved characters, or return characters.
+
+ :param header: tuple, in the format (name, value).
+ """
+ name, value = header
+ _validate_header_part(header, name, 0)
+ _validate_header_part(header, value, 1)
+
+
+def _validate_header_part(header, header_part, header_validator_index):
+ if isinstance(header_part, str):
+ validator = _HEADER_VALIDATORS_STR[header_validator_index]
+ elif isinstance(header_part, bytes):
+ validator = _HEADER_VALIDATORS_BYTE[header_validator_index]
+ else:
+ raise InvalidHeader(
+ f"Header part ({header_part!r}) from {header} "
+ f"must be of type str or bytes, not {type(header_part)}"
+ )
+
+ if not validator.match(header_part):
+ header_kind = "name" if header_validator_index == 0 else "value"
+ raise InvalidHeader(
+ f"Invalid leading whitespace, reserved character(s), or return "
+ f"character(s) in header {header_kind}: {header_part!r}"
+ )
+
+
+def urldefragauth(url):
+ """
+ Given a url remove the fragment and the authentication part.
+
+ :rtype: str
+ """
+ scheme, netloc, path, params, query, fragment = urlparse(url)
+
+ # see func:`prepend_scheme_if_needed`
+ if not netloc:
+ netloc, path = path, netloc
+
+ netloc = netloc.rsplit("@", 1)[-1]
+
+ return urlunparse((scheme, netloc, path, params, query, ""))
+
+
+def rewind_body(prepared_request):
+ """Move file pointer back to its recorded starting position
+ so it can be read again on redirect.
+ """
+ body_seek = getattr(prepared_request.body, "seek", None)
+ if body_seek is not None and isinstance(
+ prepared_request._body_position, integer_types
+ ):
+ try:
+ body_seek(prepared_request._body_position)
+ except OSError:
+ raise UnrewindableBodyError(
+ "An error occurred when rewinding request body for redirect."
+ )
+ else:
+ raise UnrewindableBodyError("Unable to rewind request body for redirect.")
diff --git a/venv/Lib/site-packages/sniffio/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/sniffio/__pycache__/__init__.cpython-312.pyc
index 5dd648f6..a430e2ab 100644
Binary files a/venv/Lib/site-packages/sniffio/__pycache__/__init__.cpython-312.pyc and b/venv/Lib/site-packages/sniffio/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/sniffio/__pycache__/_impl.cpython-312.pyc b/venv/Lib/site-packages/sniffio/__pycache__/_impl.cpython-312.pyc
index d9333ce8..eddebc3d 100644
Binary files a/venv/Lib/site-packages/sniffio/__pycache__/_impl.cpython-312.pyc and b/venv/Lib/site-packages/sniffio/__pycache__/_impl.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/sniffio/__pycache__/_version.cpython-312.pyc b/venv/Lib/site-packages/sniffio/__pycache__/_version.cpython-312.pyc
index 8bbe5e70..e4535d80 100644
Binary files a/venv/Lib/site-packages/sniffio/__pycache__/_version.cpython-312.pyc and b/venv/Lib/site-packages/sniffio/__pycache__/_version.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/starlette-0.46.2.dist-info/INSTALLER b/venv/Lib/site-packages/starlette-0.46.2.dist-info/INSTALLER
new file mode 100644
index 00000000..a1b589e3
--- /dev/null
+++ b/venv/Lib/site-packages/starlette-0.46.2.dist-info/INSTALLER
@@ -0,0 +1 @@
+pip
diff --git a/venv/Lib/site-packages/starlette-0.46.2.dist-info/METADATA b/venv/Lib/site-packages/starlette-0.46.2.dist-info/METADATA
new file mode 100644
index 00000000..bb1935a2
--- /dev/null
+++ b/venv/Lib/site-packages/starlette-0.46.2.dist-info/METADATA
@@ -0,0 +1,176 @@
+Metadata-Version: 2.4
+Name: starlette
+Version: 0.46.2
+Summary: The little ASGI library that shines.
+Project-URL: Homepage, https://github.com/encode/starlette
+Project-URL: Documentation, https://www.starlette.io/
+Project-URL: Changelog, https://www.starlette.io/release-notes/
+Project-URL: Funding, https://github.com/sponsors/encode
+Project-URL: Source, https://github.com/encode/starlette
+Author-email: Tom Christie
+License-Expression: BSD-3-Clause
+License-File: LICENSE.md
+Classifier: Development Status :: 3 - Alpha
+Classifier: Environment :: Web Environment
+Classifier: Framework :: AnyIO
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: BSD License
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.9
+Classifier: Programming Language :: Python :: 3.10
+Classifier: Programming Language :: Python :: 3.11
+Classifier: Programming Language :: Python :: 3.12
+Classifier: Programming Language :: Python :: 3.13
+Classifier: Topic :: Internet :: WWW/HTTP
+Requires-Python: >=3.9
+Requires-Dist: anyio<5,>=3.6.2
+Requires-Dist: typing-extensions>=3.10.0; python_version < '3.10'
+Provides-Extra: full
+Requires-Dist: httpx<0.29.0,>=0.27.0; extra == 'full'
+Requires-Dist: itsdangerous; extra == 'full'
+Requires-Dist: jinja2; extra == 'full'
+Requires-Dist: python-multipart>=0.0.18; extra == 'full'
+Requires-Dist: pyyaml; extra == 'full'
+Description-Content-Type: text/markdown
+
+
+
+
+
+
+
+
+
+
+ ✨ The little ASGI framework that shines. ✨
+
+
+---
+
+[](https://github.com/encode/starlette/actions)
+[](https://pypi.python.org/pypi/starlette)
+[](https://pypi.org/project/starlette)
+
+---
+
+**Documentation**: https://www.starlette.io
+
+**Source Code**: https://github.com/encode/starlette
+
+---
+
+# Starlette
+
+Starlette is a lightweight [ASGI][asgi] framework/toolkit,
+which is ideal for building async web services in Python.
+
+It is production-ready, and gives you the following:
+
+* A lightweight, low-complexity HTTP web framework.
+* WebSocket support.
+* In-process background tasks.
+* Startup and shutdown events.
+* Test client built on `httpx`.
+* CORS, GZip, Static Files, Streaming responses.
+* Session and Cookie support.
+* 100% test coverage.
+* 100% type annotated codebase.
+* Few hard dependencies.
+* Compatible with `asyncio` and `trio` backends.
+* Great overall performance [against independent benchmarks][techempower].
+
+## Installation
+
+```shell
+$ pip install starlette
+```
+
+You'll also want to install an ASGI server, such as [uvicorn](https://www.uvicorn.org/), [daphne](https://github.com/django/daphne/), or [hypercorn](https://hypercorn.readthedocs.io/en/latest/).
+
+```shell
+$ pip install uvicorn
+```
+
+## Example
+
+```python title="main.py"
+from starlette.applications import Starlette
+from starlette.responses import JSONResponse
+from starlette.routing import Route
+
+
+async def homepage(request):
+ return JSONResponse({'hello': 'world'})
+
+routes = [
+ Route("/", endpoint=homepage)
+]
+
+app = Starlette(debug=True, routes=routes)
+```
+
+Then run the application using Uvicorn:
+
+```shell
+$ uvicorn main:app
+```
+
+## Dependencies
+
+Starlette only requires `anyio`, and the following are optional:
+
+* [`httpx`][httpx] - Required if you want to use the `TestClient`.
+* [`jinja2`][jinja2] - Required if you want to use `Jinja2Templates`.
+* [`python-multipart`][python-multipart] - Required if you want to support form parsing, with `request.form()`.
+* [`itsdangerous`][itsdangerous] - Required for `SessionMiddleware` support.
+* [`pyyaml`][pyyaml] - Required for `SchemaGenerator` support.
+
+You can install all of these with `pip install starlette[full]`.
+
+## Framework or Toolkit
+
+Starlette is designed to be used either as a complete framework, or as
+an ASGI toolkit. You can use any of its components independently.
+
+```python
+from starlette.responses import PlainTextResponse
+
+
+async def app(scope, receive, send):
+ assert scope['type'] == 'http'
+ response = PlainTextResponse('Hello, world!')
+ await response(scope, receive, send)
+```
+
+Run the `app` application in `example.py`:
+
+```shell
+$ uvicorn example:app
+INFO: Started server process [11509]
+INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+Run uvicorn with `--reload` to enable auto-reloading on code changes.
+
+## Modularity
+
+The modularity that Starlette is designed on promotes building re-usable
+components that can be shared between any ASGI framework. This should enable
+an ecosystem of shared middleware and mountable applications.
+
+The clean API separation also means it's easier to understand each component
+in isolation.
+
+---
+
+
Starlette is BSD licensed code. Designed & crafted with care.— ⭐️ —
File {frame_filename},
+ line {frame_lineno},
+ in {frame_name}
+ {collapse_button}
+
+
{code_context}
+
+""" # noqa: E501
+
+LINE = """
+
+{lineno}. {line}
+"""
+
+CENTER_LINE = """
+
+{lineno}. {line}
+"""
+
+
+class ServerErrorMiddleware:
+ """
+ Handles returning 500 responses when a server error occurs.
+
+ If 'debug' is set, then traceback responses will be returned,
+ otherwise the designated 'handler' will be called.
+
+ This middleware class should generally be used to wrap *everything*
+ else up, so that unhandled exceptions anywhere in the stack
+ always result in an appropriate 500 response.
+ """
+
+ def __init__(
+ self,
+ app: ASGIApp,
+ handler: typing.Callable[[Request, Exception], typing.Any] | None = None,
+ debug: bool = False,
+ ) -> None:
+ self.app = app
+ self.handler = handler
+ self.debug = debug
+
+ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
+ if scope["type"] != "http":
+ await self.app(scope, receive, send)
+ return
+
+ response_started = False
+
+ async def _send(message: Message) -> None:
+ nonlocal response_started, send
+
+ if message["type"] == "http.response.start":
+ response_started = True
+ await send(message)
+
+ try:
+ await self.app(scope, receive, _send)
+ except Exception as exc:
+ request = Request(scope)
+ if self.debug:
+ # In debug mode, return traceback responses.
+ response = self.debug_response(request, exc)
+ elif self.handler is None:
+ # Use our default 500 error handler.
+ response = self.error_response(request, exc)
+ else:
+ # Use an installed 500 error handler.
+ if is_async_callable(self.handler):
+ response = await self.handler(request, exc)
+ else:
+ response = await run_in_threadpool(self.handler, request, exc)
+
+ if not response_started:
+ await response(scope, receive, send)
+
+ # We always continue to raise the exception.
+ # This allows servers to log the error, or allows test clients
+ # to optionally raise the error within the test case.
+ raise exc
+
+ def format_line(self, index: int, line: str, frame_lineno: int, frame_index: int) -> str:
+ values = {
+ # HTML escape - line could contain < or >
+ "line": html.escape(line).replace(" ", " "),
+ "lineno": (frame_lineno - frame_index) + index,
+ }
+
+ if index != frame_index:
+ return LINE.format(**values)
+ return CENTER_LINE.format(**values)
+
+ def generate_frame_html(self, frame: inspect.FrameInfo, is_collapsed: bool) -> str:
+ code_context = "".join(
+ self.format_line(
+ index,
+ line,
+ frame.lineno,
+ frame.index, # type: ignore[arg-type]
+ )
+ for index, line in enumerate(frame.code_context or [])
+ )
+
+ values = {
+ # HTML escape - filename could contain < or >, especially if it's a virtual
+ # file e.g. in the REPL
+ "frame_filename": html.escape(frame.filename),
+ "frame_lineno": frame.lineno,
+ # HTML escape - if you try very hard it's possible to name a function with <
+ # or >
+ "frame_name": html.escape(frame.function),
+ "code_context": code_context,
+ "collapsed": "collapsed" if is_collapsed else "",
+ "collapse_button": "+" if is_collapsed else "‒",
+ }
+ return FRAME_TEMPLATE.format(**values)
+
+ def generate_html(self, exc: Exception, limit: int = 7) -> str:
+ traceback_obj = traceback.TracebackException.from_exception(exc, capture_locals=True)
+
+ exc_html = ""
+ is_collapsed = False
+ exc_traceback = exc.__traceback__
+ if exc_traceback is not None:
+ frames = inspect.getinnerframes(exc_traceback, limit)
+ for frame in reversed(frames):
+ exc_html += self.generate_frame_html(frame, is_collapsed)
+ is_collapsed = True
+
+ if sys.version_info >= (3, 13): # pragma: no cover
+ exc_type_str = traceback_obj.exc_type_str
+ else: # pragma: no cover
+ exc_type_str = traceback_obj.exc_type.__name__
+
+ # escape error class and text
+ error = f"{html.escape(exc_type_str)}: {html.escape(str(traceback_obj))}"
+
+ return TEMPLATE.format(styles=STYLES, js=JS, error=error, exc_html=exc_html)
+
+ def generate_plain_text(self, exc: Exception) -> str:
+ return "".join(traceback.format_exception(type(exc), exc, exc.__traceback__))
+
+ def debug_response(self, request: Request, exc: Exception) -> Response:
+ accept = request.headers.get("accept", "")
+
+ if "text/html" in accept:
+ content = self.generate_html(exc)
+ return HTMLResponse(content, status_code=500)
+ content = self.generate_plain_text(exc)
+ return PlainTextResponse(content, status_code=500)
+
+ def error_response(self, request: Request, exc: Exception) -> Response:
+ return PlainTextResponse("Internal Server Error", status_code=500)
diff --git a/venv/Lib/site-packages/starlette/middleware/exceptions.py b/venv/Lib/site-packages/starlette/middleware/exceptions.py
new file mode 100644
index 00000000..981d2fca
--- /dev/null
+++ b/venv/Lib/site-packages/starlette/middleware/exceptions.py
@@ -0,0 +1,72 @@
+from __future__ import annotations
+
+import typing
+
+from starlette._exception_handler import (
+ ExceptionHandlers,
+ StatusHandlers,
+ wrap_app_handling_exceptions,
+)
+from starlette.exceptions import HTTPException, WebSocketException
+from starlette.requests import Request
+from starlette.responses import PlainTextResponse, Response
+from starlette.types import ASGIApp, Receive, Scope, Send
+from starlette.websockets import WebSocket
+
+
+class ExceptionMiddleware:
+ def __init__(
+ self,
+ app: ASGIApp,
+ handlers: typing.Mapping[typing.Any, typing.Callable[[Request, Exception], Response]] | None = None,
+ debug: bool = False,
+ ) -> None:
+ self.app = app
+ self.debug = debug # TODO: We ought to handle 404 cases if debug is set.
+ self._status_handlers: StatusHandlers = {}
+ self._exception_handlers: ExceptionHandlers = {
+ HTTPException: self.http_exception,
+ WebSocketException: self.websocket_exception,
+ }
+ if handlers is not None: # pragma: no branch
+ for key, value in handlers.items():
+ self.add_exception_handler(key, value)
+
+ def add_exception_handler(
+ self,
+ exc_class_or_status_code: int | type[Exception],
+ handler: typing.Callable[[Request, Exception], Response],
+ ) -> None:
+ if isinstance(exc_class_or_status_code, int):
+ self._status_handlers[exc_class_or_status_code] = handler
+ else:
+ assert issubclass(exc_class_or_status_code, Exception)
+ self._exception_handlers[exc_class_or_status_code] = handler
+
+ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
+ if scope["type"] not in ("http", "websocket"):
+ await self.app(scope, receive, send)
+ return
+
+ scope["starlette.exception_handlers"] = (
+ self._exception_handlers,
+ self._status_handlers,
+ )
+
+ conn: Request | WebSocket
+ if scope["type"] == "http":
+ conn = Request(scope, receive, send)
+ else:
+ conn = WebSocket(scope, receive, send)
+
+ await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
+
+ def http_exception(self, request: Request, exc: Exception) -> Response:
+ assert isinstance(exc, HTTPException)
+ if exc.status_code in {204, 304}:
+ return Response(status_code=exc.status_code, headers=exc.headers)
+ return PlainTextResponse(exc.detail, status_code=exc.status_code, headers=exc.headers)
+
+ async def websocket_exception(self, websocket: WebSocket, exc: Exception) -> None:
+ assert isinstance(exc, WebSocketException)
+ await websocket.close(code=exc.code, reason=exc.reason) # pragma: no cover
diff --git a/venv/Lib/site-packages/starlette/middleware/gzip.py b/venv/Lib/site-packages/starlette/middleware/gzip.py
new file mode 100644
index 00000000..c7fd5b77
--- /dev/null
+++ b/venv/Lib/site-packages/starlette/middleware/gzip.py
@@ -0,0 +1,141 @@
+import gzip
+import io
+import typing
+
+from starlette.datastructures import Headers, MutableHeaders
+from starlette.types import ASGIApp, Message, Receive, Scope, Send
+
+DEFAULT_EXCLUDED_CONTENT_TYPES = ("text/event-stream",)
+
+
+class GZipMiddleware:
+ def __init__(self, app: ASGIApp, minimum_size: int = 500, compresslevel: int = 9) -> None:
+ self.app = app
+ self.minimum_size = minimum_size
+ self.compresslevel = compresslevel
+
+ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
+ if scope["type"] != "http": # pragma: no cover
+ await self.app(scope, receive, send)
+ return
+
+ headers = Headers(scope=scope)
+ responder: ASGIApp
+ if "gzip" in headers.get("Accept-Encoding", ""):
+ responder = GZipResponder(self.app, self.minimum_size, compresslevel=self.compresslevel)
+ else:
+ responder = IdentityResponder(self.app, self.minimum_size)
+
+ await responder(scope, receive, send)
+
+
+class IdentityResponder:
+ content_encoding: str
+
+ def __init__(self, app: ASGIApp, minimum_size: int) -> None:
+ self.app = app
+ self.minimum_size = minimum_size
+ self.send: Send = unattached_send
+ self.initial_message: Message = {}
+ self.started = False
+ self.content_encoding_set = False
+ self.content_type_is_excluded = False
+
+ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
+ self.send = send
+ await self.app(scope, receive, self.send_with_compression)
+
+ async def send_with_compression(self, message: Message) -> None:
+ message_type = message["type"]
+ if message_type == "http.response.start":
+ # Don't send the initial message until we've determined how to
+ # modify the outgoing headers correctly.
+ self.initial_message = message
+ headers = Headers(raw=self.initial_message["headers"])
+ self.content_encoding_set = "content-encoding" in headers
+ self.content_type_is_excluded = headers.get("content-type", "").startswith(DEFAULT_EXCLUDED_CONTENT_TYPES)
+ elif message_type == "http.response.body" and (self.content_encoding_set or self.content_type_is_excluded):
+ if not self.started:
+ self.started = True
+ await self.send(self.initial_message)
+ await self.send(message)
+ elif message_type == "http.response.body" and not self.started:
+ self.started = True
+ body = message.get("body", b"")
+ more_body = message.get("more_body", False)
+ if len(body) < self.minimum_size and not more_body:
+ # Don't apply compression to small outgoing responses.
+ await self.send(self.initial_message)
+ await self.send(message)
+ elif not more_body:
+ # Standard response.
+ body = self.apply_compression(body, more_body=False)
+
+ headers = MutableHeaders(raw=self.initial_message["headers"])
+ headers.add_vary_header("Accept-Encoding")
+ if body != message["body"]:
+ headers["Content-Encoding"] = self.content_encoding
+ headers["Content-Length"] = str(len(body))
+ message["body"] = body
+
+ await self.send(self.initial_message)
+ await self.send(message)
+ else:
+ # Initial body in streaming response.
+ body = self.apply_compression(body, more_body=True)
+
+ headers = MutableHeaders(raw=self.initial_message["headers"])
+ headers.add_vary_header("Accept-Encoding")
+ if body != message["body"]:
+ headers["Content-Encoding"] = self.content_encoding
+ del headers["Content-Length"]
+ message["body"] = body
+
+ await self.send(self.initial_message)
+ await self.send(message)
+ elif message_type == "http.response.body": # pragma: no branch
+ # Remaining body in streaming response.
+ body = message.get("body", b"")
+ more_body = message.get("more_body", False)
+
+ message["body"] = self.apply_compression(body, more_body=more_body)
+
+ await self.send(message)
+
+ def apply_compression(self, body: bytes, *, more_body: bool) -> bytes:
+ """Apply compression on the response body.
+
+ If more_body is False, any compression file should be closed. If it
+ isn't, it won't be closed automatically until all background tasks
+ complete.
+ """
+ return body
+
+
+class GZipResponder(IdentityResponder):
+ content_encoding = "gzip"
+
+ def __init__(self, app: ASGIApp, minimum_size: int, compresslevel: int = 9) -> None:
+ super().__init__(app, minimum_size)
+
+ self.gzip_buffer = io.BytesIO()
+ self.gzip_file = gzip.GzipFile(mode="wb", fileobj=self.gzip_buffer, compresslevel=compresslevel)
+
+ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
+ with self.gzip_buffer, self.gzip_file:
+ await super().__call__(scope, receive, send)
+
+ def apply_compression(self, body: bytes, *, more_body: bool) -> bytes:
+ self.gzip_file.write(body)
+ if not more_body:
+ self.gzip_file.close()
+
+ body = self.gzip_buffer.getvalue()
+ self.gzip_buffer.seek(0)
+ self.gzip_buffer.truncate()
+
+ return body
+
+
+async def unattached_send(message: Message) -> typing.NoReturn:
+ raise RuntimeError("send awaitable not set") # pragma: no cover
diff --git a/venv/Lib/site-packages/starlette/middleware/httpsredirect.py b/venv/Lib/site-packages/starlette/middleware/httpsredirect.py
new file mode 100644
index 00000000..a8359067
--- /dev/null
+++ b/venv/Lib/site-packages/starlette/middleware/httpsredirect.py
@@ -0,0 +1,19 @@
+from starlette.datastructures import URL
+from starlette.responses import RedirectResponse
+from starlette.types import ASGIApp, Receive, Scope, Send
+
+
+class HTTPSRedirectMiddleware:
+ def __init__(self, app: ASGIApp) -> None:
+ self.app = app
+
+ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
+ if scope["type"] in ("http", "websocket") and scope["scheme"] in ("http", "ws"):
+ url = URL(scope=scope)
+ redirect_scheme = {"http": "https", "ws": "wss"}[url.scheme]
+ netloc = url.hostname if url.port in (80, 443) else url.netloc
+ url = url.replace(scheme=redirect_scheme, netloc=netloc)
+ response = RedirectResponse(url, status_code=307)
+ await response(scope, receive, send)
+ else:
+ await self.app(scope, receive, send)
diff --git a/venv/Lib/site-packages/starlette/middleware/sessions.py b/venv/Lib/site-packages/starlette/middleware/sessions.py
new file mode 100644
index 00000000..5f9fcd88
--- /dev/null
+++ b/venv/Lib/site-packages/starlette/middleware/sessions.py
@@ -0,0 +1,85 @@
+from __future__ import annotations
+
+import json
+import typing
+from base64 import b64decode, b64encode
+
+import itsdangerous
+from itsdangerous.exc import BadSignature
+
+from starlette.datastructures import MutableHeaders, Secret
+from starlette.requests import HTTPConnection
+from starlette.types import ASGIApp, Message, Receive, Scope, Send
+
+
+class SessionMiddleware:
+ def __init__(
+ self,
+ app: ASGIApp,
+ secret_key: str | Secret,
+ session_cookie: str = "session",
+ max_age: int | None = 14 * 24 * 60 * 60, # 14 days, in seconds
+ path: str = "/",
+ same_site: typing.Literal["lax", "strict", "none"] = "lax",
+ https_only: bool = False,
+ domain: str | None = None,
+ ) -> None:
+ self.app = app
+ self.signer = itsdangerous.TimestampSigner(str(secret_key))
+ self.session_cookie = session_cookie
+ self.max_age = max_age
+ self.path = path
+ self.security_flags = "httponly; samesite=" + same_site
+ if https_only: # Secure flag can be used with HTTPS only
+ self.security_flags += "; secure"
+ if domain is not None:
+ self.security_flags += f"; domain={domain}"
+
+ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
+ if scope["type"] not in ("http", "websocket"): # pragma: no cover
+ await self.app(scope, receive, send)
+ return
+
+ connection = HTTPConnection(scope)
+ initial_session_was_empty = True
+
+ if self.session_cookie in connection.cookies:
+ data = connection.cookies[self.session_cookie].encode("utf-8")
+ try:
+ data = self.signer.unsign(data, max_age=self.max_age)
+ scope["session"] = json.loads(b64decode(data))
+ initial_session_was_empty = False
+ except BadSignature:
+ scope["session"] = {}
+ else:
+ scope["session"] = {}
+
+ async def send_wrapper(message: Message) -> None:
+ if message["type"] == "http.response.start":
+ if scope["session"]:
+ # We have session data to persist.
+ data = b64encode(json.dumps(scope["session"]).encode("utf-8"))
+ data = self.signer.sign(data)
+ headers = MutableHeaders(scope=message)
+ header_value = "{session_cookie}={data}; path={path}; {max_age}{security_flags}".format(
+ session_cookie=self.session_cookie,
+ data=data.decode("utf-8"),
+ path=self.path,
+ max_age=f"Max-Age={self.max_age}; " if self.max_age else "",
+ security_flags=self.security_flags,
+ )
+ headers.append("Set-Cookie", header_value)
+ elif not initial_session_was_empty:
+ # The session has been cleared.
+ headers = MutableHeaders(scope=message)
+ header_value = "{session_cookie}={data}; path={path}; {expires}{security_flags}".format(
+ session_cookie=self.session_cookie,
+ data="null",
+ path=self.path,
+ expires="expires=Thu, 01 Jan 1970 00:00:00 GMT; ",
+ security_flags=self.security_flags,
+ )
+ headers.append("Set-Cookie", header_value)
+ await send(message)
+
+ await self.app(scope, receive, send_wrapper)
diff --git a/venv/Lib/site-packages/starlette/middleware/trustedhost.py b/venv/Lib/site-packages/starlette/middleware/trustedhost.py
new file mode 100644
index 00000000..2d1c999e
--- /dev/null
+++ b/venv/Lib/site-packages/starlette/middleware/trustedhost.py
@@ -0,0 +1,60 @@
+from __future__ import annotations
+
+import typing
+
+from starlette.datastructures import URL, Headers
+from starlette.responses import PlainTextResponse, RedirectResponse, Response
+from starlette.types import ASGIApp, Receive, Scope, Send
+
+ENFORCE_DOMAIN_WILDCARD = "Domain wildcard patterns must be like '*.example.com'."
+
+
+class TrustedHostMiddleware:
+ def __init__(
+ self,
+ app: ASGIApp,
+ allowed_hosts: typing.Sequence[str] | None = None,
+ www_redirect: bool = True,
+ ) -> None:
+ if allowed_hosts is None:
+ allowed_hosts = ["*"]
+
+ for pattern in allowed_hosts:
+ assert "*" not in pattern[1:], ENFORCE_DOMAIN_WILDCARD
+ if pattern.startswith("*") and pattern != "*":
+ assert pattern.startswith("*."), ENFORCE_DOMAIN_WILDCARD
+ self.app = app
+ self.allowed_hosts = list(allowed_hosts)
+ self.allow_any = "*" in allowed_hosts
+ self.www_redirect = www_redirect
+
+ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
+ if self.allow_any or scope["type"] not in (
+ "http",
+ "websocket",
+ ): # pragma: no cover
+ await self.app(scope, receive, send)
+ return
+
+ headers = Headers(scope=scope)
+ host = headers.get("host", "").split(":")[0]
+ is_valid_host = False
+ found_www_redirect = False
+ for pattern in self.allowed_hosts:
+ if host == pattern or (pattern.startswith("*") and host.endswith(pattern[1:])):
+ is_valid_host = True
+ break
+ elif "www." + host == pattern:
+ found_www_redirect = True
+
+ if is_valid_host:
+ await self.app(scope, receive, send)
+ else:
+ response: Response
+ if found_www_redirect and self.www_redirect:
+ url = URL(scope=scope)
+ redirect_url = url.replace(netloc="www." + url.netloc)
+ response = RedirectResponse(url=str(redirect_url))
+ else:
+ response = PlainTextResponse("Invalid host header", status_code=400)
+ await response(scope, receive, send)
diff --git a/venv/Lib/site-packages/starlette/middleware/wsgi.py b/venv/Lib/site-packages/starlette/middleware/wsgi.py
new file mode 100644
index 00000000..6e0a3fae
--- /dev/null
+++ b/venv/Lib/site-packages/starlette/middleware/wsgi.py
@@ -0,0 +1,152 @@
+from __future__ import annotations
+
+import io
+import math
+import sys
+import typing
+import warnings
+
+import anyio
+from anyio.abc import ObjectReceiveStream, ObjectSendStream
+
+from starlette.types import Receive, Scope, Send
+
+warnings.warn(
+ "starlette.middleware.wsgi is deprecated and will be removed in a future release. "
+ "Please refer to https://github.com/abersheeran/a2wsgi as a replacement.",
+ DeprecationWarning,
+)
+
+
+def build_environ(scope: Scope, body: bytes) -> dict[str, typing.Any]:
+ """
+ Builds a scope and request body into a WSGI environ object.
+ """
+
+ script_name = scope.get("root_path", "").encode("utf8").decode("latin1")
+ path_info = scope["path"].encode("utf8").decode("latin1")
+ if path_info.startswith(script_name):
+ path_info = path_info[len(script_name) :]
+
+ environ = {
+ "REQUEST_METHOD": scope["method"],
+ "SCRIPT_NAME": script_name,
+ "PATH_INFO": path_info,
+ "QUERY_STRING": scope["query_string"].decode("ascii"),
+ "SERVER_PROTOCOL": f"HTTP/{scope['http_version']}",
+ "wsgi.version": (1, 0),
+ "wsgi.url_scheme": scope.get("scheme", "http"),
+ "wsgi.input": io.BytesIO(body),
+ "wsgi.errors": sys.stdout,
+ "wsgi.multithread": True,
+ "wsgi.multiprocess": True,
+ "wsgi.run_once": False,
+ }
+
+ # Get server name and port - required in WSGI, not in ASGI
+ server = scope.get("server") or ("localhost", 80)
+ environ["SERVER_NAME"] = server[0]
+ environ["SERVER_PORT"] = server[1]
+
+ # Get client IP address
+ if scope.get("client"):
+ environ["REMOTE_ADDR"] = scope["client"][0]
+
+ # Go through headers and make them into environ entries
+ for name, value in scope.get("headers", []):
+ name = name.decode("latin1")
+ if name == "content-length":
+ corrected_name = "CONTENT_LENGTH"
+ elif name == "content-type":
+ corrected_name = "CONTENT_TYPE"
+ else:
+ corrected_name = f"HTTP_{name}".upper().replace("-", "_")
+ # HTTPbis say only ASCII chars are allowed in headers, but we latin1 just in
+ # case
+ value = value.decode("latin1")
+ if corrected_name in environ:
+ value = environ[corrected_name] + "," + value
+ environ[corrected_name] = value
+ return environ
+
+
+class WSGIMiddleware:
+ def __init__(self, app: typing.Callable[..., typing.Any]) -> None:
+ self.app = app
+
+ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
+ assert scope["type"] == "http"
+ responder = WSGIResponder(self.app, scope)
+ await responder(receive, send)
+
+
+class WSGIResponder:
+ stream_send: ObjectSendStream[typing.MutableMapping[str, typing.Any]]
+ stream_receive: ObjectReceiveStream[typing.MutableMapping[str, typing.Any]]
+
+ def __init__(self, app: typing.Callable[..., typing.Any], scope: Scope) -> None:
+ self.app = app
+ self.scope = scope
+ self.status = None
+ self.response_headers = None
+ self.stream_send, self.stream_receive = anyio.create_memory_object_stream(math.inf)
+ self.response_started = False
+ self.exc_info: typing.Any = None
+
+ async def __call__(self, receive: Receive, send: Send) -> None:
+ body = b""
+ more_body = True
+ while more_body:
+ message = await receive()
+ body += message.get("body", b"")
+ more_body = message.get("more_body", False)
+ environ = build_environ(self.scope, body)
+
+ async with anyio.create_task_group() as task_group:
+ task_group.start_soon(self.sender, send)
+ async with self.stream_send:
+ await anyio.to_thread.run_sync(self.wsgi, environ, self.start_response)
+ if self.exc_info is not None:
+ raise self.exc_info[0].with_traceback(self.exc_info[1], self.exc_info[2])
+
+ async def sender(self, send: Send) -> None:
+ async with self.stream_receive:
+ async for message in self.stream_receive:
+ await send(message)
+
+ def start_response(
+ self,
+ status: str,
+ response_headers: list[tuple[str, str]],
+ exc_info: typing.Any = None,
+ ) -> None:
+ self.exc_info = exc_info
+ if not self.response_started: # pragma: no branch
+ self.response_started = True
+ status_code_string, _ = status.split(" ", 1)
+ status_code = int(status_code_string)
+ headers = [
+ (name.strip().encode("ascii").lower(), value.strip().encode("ascii"))
+ for name, value in response_headers
+ ]
+ anyio.from_thread.run(
+ self.stream_send.send,
+ {
+ "type": "http.response.start",
+ "status": status_code,
+ "headers": headers,
+ },
+ )
+
+ def wsgi(
+ self,
+ environ: dict[str, typing.Any],
+ start_response: typing.Callable[..., typing.Any],
+ ) -> None:
+ for chunk in self.app(environ, start_response):
+ anyio.from_thread.run(
+ self.stream_send.send,
+ {"type": "http.response.body", "body": chunk, "more_body": True},
+ )
+
+ anyio.from_thread.run(self.stream_send.send, {"type": "http.response.body", "body": b""})
diff --git a/venv/Lib/site-packages/starlette/py.typed b/venv/Lib/site-packages/starlette/py.typed
new file mode 100644
index 00000000..e69de29b
diff --git a/venv/Lib/site-packages/starlette/requests.py b/venv/Lib/site-packages/starlette/requests.py
new file mode 100644
index 00000000..7dc04a74
--- /dev/null
+++ b/venv/Lib/site-packages/starlette/requests.py
@@ -0,0 +1,322 @@
+from __future__ import annotations
+
+import json
+import typing
+from http import cookies as http_cookies
+
+import anyio
+
+from starlette._utils import AwaitableOrContextManager, AwaitableOrContextManagerWrapper
+from starlette.datastructures import URL, Address, FormData, Headers, QueryParams, State
+from starlette.exceptions import HTTPException
+from starlette.formparsers import FormParser, MultiPartException, MultiPartParser
+from starlette.types import Message, Receive, Scope, Send
+
+if typing.TYPE_CHECKING:
+ from python_multipart.multipart import parse_options_header
+
+ from starlette.applications import Starlette
+ from starlette.routing import Router
+else:
+ try:
+ try:
+ from python_multipart.multipart import parse_options_header
+ except ModuleNotFoundError: # pragma: no cover
+ from multipart.multipart import parse_options_header
+ except ModuleNotFoundError: # pragma: no cover
+ parse_options_header = None
+
+
+SERVER_PUSH_HEADERS_TO_COPY = {
+ "accept",
+ "accept-encoding",
+ "accept-language",
+ "cache-control",
+ "user-agent",
+}
+
+
+def cookie_parser(cookie_string: str) -> dict[str, str]:
+ """
+ This function parses a ``Cookie`` HTTP header into a dict of key/value pairs.
+
+ It attempts to mimic browser cookie parsing behavior: browsers and web servers
+ frequently disregard the spec (RFC 6265) when setting and reading cookies,
+ so we attempt to suit the common scenarios here.
+
+ This function has been adapted from Django 3.1.0.
+ Note: we are explicitly _NOT_ using `SimpleCookie.load` because it is based
+ on an outdated spec and will fail on lots of input we want to support
+ """
+ cookie_dict: dict[str, str] = {}
+ for chunk in cookie_string.split(";"):
+ if "=" in chunk:
+ key, val = chunk.split("=", 1)
+ else:
+ # Assume an empty name per
+ # https://bugzilla.mozilla.org/show_bug.cgi?id=169091
+ key, val = "", chunk
+ key, val = key.strip(), val.strip()
+ if key or val:
+ # unquote using Python's algorithm.
+ cookie_dict[key] = http_cookies._unquote(val)
+ return cookie_dict
+
+
+class ClientDisconnect(Exception):
+ pass
+
+
+class HTTPConnection(typing.Mapping[str, typing.Any]):
+ """
+ A base class for incoming HTTP connections, that is used to provide
+ any functionality that is common to both `Request` and `WebSocket`.
+ """
+
+ def __init__(self, scope: Scope, receive: Receive | None = None) -> None:
+ assert scope["type"] in ("http", "websocket")
+ self.scope = scope
+
+ def __getitem__(self, key: str) -> typing.Any:
+ return self.scope[key]
+
+ def __iter__(self) -> typing.Iterator[str]:
+ return iter(self.scope)
+
+ def __len__(self) -> int:
+ return len(self.scope)
+
+ # Don't use the `abc.Mapping.__eq__` implementation.
+ # Connection instances should never be considered equal
+ # unless `self is other`.
+ __eq__ = object.__eq__
+ __hash__ = object.__hash__
+
+ @property
+ def app(self) -> typing.Any:
+ return self.scope["app"]
+
+ @property
+ def url(self) -> URL:
+ if not hasattr(self, "_url"): # pragma: no branch
+ self._url = URL(scope=self.scope)
+ return self._url
+
+ @property
+ def base_url(self) -> URL:
+ if not hasattr(self, "_base_url"):
+ base_url_scope = dict(self.scope)
+ # This is used by request.url_for, it might be used inside a Mount which
+ # would have its own child scope with its own root_path, but the base URL
+ # for url_for should still be the top level app root path.
+ app_root_path = base_url_scope.get("app_root_path", base_url_scope.get("root_path", ""))
+ path = app_root_path
+ if not path.endswith("/"):
+ path += "/"
+ base_url_scope["path"] = path
+ base_url_scope["query_string"] = b""
+ base_url_scope["root_path"] = app_root_path
+ self._base_url = URL(scope=base_url_scope)
+ return self._base_url
+
+ @property
+ def headers(self) -> Headers:
+ if not hasattr(self, "_headers"):
+ self._headers = Headers(scope=self.scope)
+ return self._headers
+
+ @property
+ def query_params(self) -> QueryParams:
+ if not hasattr(self, "_query_params"): # pragma: no branch
+ self._query_params = QueryParams(self.scope["query_string"])
+ return self._query_params
+
+ @property
+ def path_params(self) -> dict[str, typing.Any]:
+ return self.scope.get("path_params", {})
+
+ @property
+ def cookies(self) -> dict[str, str]:
+ if not hasattr(self, "_cookies"):
+ cookies: dict[str, str] = {}
+ cookie_header = self.headers.get("cookie")
+
+ if cookie_header:
+ cookies = cookie_parser(cookie_header)
+ self._cookies = cookies
+ return self._cookies
+
+ @property
+ def client(self) -> Address | None:
+ # client is a 2 item tuple of (host, port), None if missing
+ host_port = self.scope.get("client")
+ if host_port is not None:
+ return Address(*host_port)
+ return None
+
+ @property
+ def session(self) -> dict[str, typing.Any]:
+ assert "session" in self.scope, "SessionMiddleware must be installed to access request.session"
+ return self.scope["session"] # type: ignore[no-any-return]
+
+ @property
+ def auth(self) -> typing.Any:
+ assert "auth" in self.scope, "AuthenticationMiddleware must be installed to access request.auth"
+ return self.scope["auth"]
+
+ @property
+ def user(self) -> typing.Any:
+ assert "user" in self.scope, "AuthenticationMiddleware must be installed to access request.user"
+ return self.scope["user"]
+
+ @property
+ def state(self) -> State:
+ if not hasattr(self, "_state"):
+ # Ensure 'state' has an empty dict if it's not already populated.
+ self.scope.setdefault("state", {})
+ # Create a state instance with a reference to the dict in which it should
+ # store info
+ self._state = State(self.scope["state"])
+ return self._state
+
+ def url_for(self, name: str, /, **path_params: typing.Any) -> URL:
+ url_path_provider: Router | Starlette | None = self.scope.get("router") or self.scope.get("app")
+ if url_path_provider is None:
+ raise RuntimeError("The `url_for` method can only be used inside a Starlette application or with a router.")
+ url_path = url_path_provider.url_path_for(name, **path_params)
+ return url_path.make_absolute_url(base_url=self.base_url)
+
+
+async def empty_receive() -> typing.NoReturn:
+ raise RuntimeError("Receive channel has not been made available")
+
+
+async def empty_send(message: Message) -> typing.NoReturn:
+ raise RuntimeError("Send channel has not been made available")
+
+
+class Request(HTTPConnection):
+ _form: FormData | None
+
+ def __init__(self, scope: Scope, receive: Receive = empty_receive, send: Send = empty_send):
+ super().__init__(scope)
+ assert scope["type"] == "http"
+ self._receive = receive
+ self._send = send
+ self._stream_consumed = False
+ self._is_disconnected = False
+ self._form = None
+
+ @property
+ def method(self) -> str:
+ return typing.cast(str, self.scope["method"])
+
+ @property
+ def receive(self) -> Receive:
+ return self._receive
+
+ async def stream(self) -> typing.AsyncGenerator[bytes, None]:
+ if hasattr(self, "_body"):
+ yield self._body
+ yield b""
+ return
+ if self._stream_consumed:
+ raise RuntimeError("Stream consumed")
+ while not self._stream_consumed:
+ message = await self._receive()
+ if message["type"] == "http.request":
+ body = message.get("body", b"")
+ if not message.get("more_body", False):
+ self._stream_consumed = True
+ if body:
+ yield body
+ elif message["type"] == "http.disconnect": # pragma: no branch
+ self._is_disconnected = True
+ raise ClientDisconnect()
+ yield b""
+
+ async def body(self) -> bytes:
+ if not hasattr(self, "_body"):
+ chunks: list[bytes] = []
+ async for chunk in self.stream():
+ chunks.append(chunk)
+ self._body = b"".join(chunks)
+ return self._body
+
+ async def json(self) -> typing.Any:
+ if not hasattr(self, "_json"): # pragma: no branch
+ body = await self.body()
+ self._json = json.loads(body)
+ return self._json
+
+ async def _get_form(
+ self,
+ *,
+ max_files: int | float = 1000,
+ max_fields: int | float = 1000,
+ max_part_size: int = 1024 * 1024,
+ ) -> FormData:
+ if self._form is None: # pragma: no branch
+ assert parse_options_header is not None, (
+ "The `python-multipart` library must be installed to use form parsing."
+ )
+ content_type_header = self.headers.get("Content-Type")
+ content_type: bytes
+ content_type, _ = parse_options_header(content_type_header)
+ if content_type == b"multipart/form-data":
+ try:
+ multipart_parser = MultiPartParser(
+ self.headers,
+ self.stream(),
+ max_files=max_files,
+ max_fields=max_fields,
+ max_part_size=max_part_size,
+ )
+ self._form = await multipart_parser.parse()
+ except MultiPartException as exc:
+ if "app" in self.scope:
+ raise HTTPException(status_code=400, detail=exc.message)
+ raise exc
+ elif content_type == b"application/x-www-form-urlencoded":
+ form_parser = FormParser(self.headers, self.stream())
+ self._form = await form_parser.parse()
+ else:
+ self._form = FormData()
+ return self._form
+
+ def form(
+ self,
+ *,
+ max_files: int | float = 1000,
+ max_fields: int | float = 1000,
+ max_part_size: int = 1024 * 1024,
+ ) -> AwaitableOrContextManager[FormData]:
+ return AwaitableOrContextManagerWrapper(
+ self._get_form(max_files=max_files, max_fields=max_fields, max_part_size=max_part_size)
+ )
+
+ async def close(self) -> None:
+ if self._form is not None: # pragma: no branch
+ await self._form.close()
+
+ async def is_disconnected(self) -> bool:
+ if not self._is_disconnected:
+ message: Message = {}
+
+ # If message isn't immediately available, move on
+ with anyio.CancelScope() as cs:
+ cs.cancel()
+ message = await self._receive()
+
+ if message.get("type") == "http.disconnect":
+ self._is_disconnected = True
+
+ return self._is_disconnected
+
+ async def send_push_promise(self, path: str) -> None:
+ if "http.response.push" in self.scope.get("extensions", {}):
+ raw_headers: list[tuple[bytes, bytes]] = []
+ for name in SERVER_PUSH_HEADERS_TO_COPY:
+ for value in self.headers.getlist(name):
+ raw_headers.append((name.encode("latin-1"), value.encode("latin-1")))
+ await self._send({"type": "http.response.push", "path": path, "headers": raw_headers})
diff --git a/venv/Lib/site-packages/starlette/responses.py b/venv/Lib/site-packages/starlette/responses.py
new file mode 100644
index 00000000..81e89fae
--- /dev/null
+++ b/venv/Lib/site-packages/starlette/responses.py
@@ -0,0 +1,536 @@
+from __future__ import annotations
+
+import hashlib
+import http.cookies
+import json
+import os
+import re
+import stat
+import typing
+import warnings
+from datetime import datetime
+from email.utils import format_datetime, formatdate
+from functools import partial
+from mimetypes import guess_type
+from secrets import token_hex
+from urllib.parse import quote
+
+import anyio
+import anyio.to_thread
+
+from starlette._utils import collapse_excgroups
+from starlette.background import BackgroundTask
+from starlette.concurrency import iterate_in_threadpool
+from starlette.datastructures import URL, Headers, MutableHeaders
+from starlette.requests import ClientDisconnect
+from starlette.types import Receive, Scope, Send
+
+
+class Response:
+ media_type = None
+ charset = "utf-8"
+
+ def __init__(
+ self,
+ content: typing.Any = None,
+ status_code: int = 200,
+ headers: typing.Mapping[str, str] | None = None,
+ media_type: str | None = None,
+ background: BackgroundTask | None = None,
+ ) -> None:
+ self.status_code = status_code
+ if media_type is not None:
+ self.media_type = media_type
+ self.background = background
+ self.body = self.render(content)
+ self.init_headers(headers)
+
+ def render(self, content: typing.Any) -> bytes | memoryview:
+ if content is None:
+ return b""
+ if isinstance(content, (bytes, memoryview)):
+ return content
+ return content.encode(self.charset) # type: ignore
+
+ def init_headers(self, headers: typing.Mapping[str, str] | None = None) -> None:
+ if headers is None:
+ raw_headers: list[tuple[bytes, bytes]] = []
+ populate_content_length = True
+ populate_content_type = True
+ else:
+ raw_headers = [(k.lower().encode("latin-1"), v.encode("latin-1")) for k, v in headers.items()]
+ keys = [h[0] for h in raw_headers]
+ populate_content_length = b"content-length" not in keys
+ populate_content_type = b"content-type" not in keys
+
+ body = getattr(self, "body", None)
+ if (
+ body is not None
+ and populate_content_length
+ and not (self.status_code < 200 or self.status_code in (204, 304))
+ ):
+ content_length = str(len(body))
+ raw_headers.append((b"content-length", content_length.encode("latin-1")))
+
+ content_type = self.media_type
+ if content_type is not None and populate_content_type:
+ if content_type.startswith("text/") and "charset=" not in content_type.lower():
+ content_type += "; charset=" + self.charset
+ raw_headers.append((b"content-type", content_type.encode("latin-1")))
+
+ self.raw_headers = raw_headers
+
+ @property
+ def headers(self) -> MutableHeaders:
+ if not hasattr(self, "_headers"):
+ self._headers = MutableHeaders(raw=self.raw_headers)
+ return self._headers
+
+ def set_cookie(
+ self,
+ key: str,
+ value: str = "",
+ max_age: int | None = None,
+ expires: datetime | str | int | None = None,
+ path: str | None = "/",
+ domain: str | None = None,
+ secure: bool = False,
+ httponly: bool = False,
+ samesite: typing.Literal["lax", "strict", "none"] | None = "lax",
+ ) -> None:
+ cookie: http.cookies.BaseCookie[str] = http.cookies.SimpleCookie()
+ cookie[key] = value
+ if max_age is not None:
+ cookie[key]["max-age"] = max_age
+ if expires is not None:
+ if isinstance(expires, datetime):
+ cookie[key]["expires"] = format_datetime(expires, usegmt=True)
+ else:
+ cookie[key]["expires"] = expires
+ if path is not None:
+ cookie[key]["path"] = path
+ if domain is not None:
+ cookie[key]["domain"] = domain
+ if secure:
+ cookie[key]["secure"] = True
+ if httponly:
+ cookie[key]["httponly"] = True
+ if samesite is not None:
+ assert samesite.lower() in [
+ "strict",
+ "lax",
+ "none",
+ ], "samesite must be either 'strict', 'lax' or 'none'"
+ cookie[key]["samesite"] = samesite
+ cookie_val = cookie.output(header="").strip()
+ self.raw_headers.append((b"set-cookie", cookie_val.encode("latin-1")))
+
+ def delete_cookie(
+ self,
+ key: str,
+ path: str = "/",
+ domain: str | None = None,
+ secure: bool = False,
+ httponly: bool = False,
+ samesite: typing.Literal["lax", "strict", "none"] | None = "lax",
+ ) -> None:
+ self.set_cookie(
+ key,
+ max_age=0,
+ expires=0,
+ path=path,
+ domain=domain,
+ secure=secure,
+ httponly=httponly,
+ samesite=samesite,
+ )
+
+ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
+ prefix = "websocket." if scope["type"] == "websocket" else ""
+ await send(
+ {
+ "type": prefix + "http.response.start",
+ "status": self.status_code,
+ "headers": self.raw_headers,
+ }
+ )
+ await send({"type": prefix + "http.response.body", "body": self.body})
+
+ if self.background is not None:
+ await self.background()
+
+
+class HTMLResponse(Response):
+ media_type = "text/html"
+
+
+class PlainTextResponse(Response):
+ media_type = "text/plain"
+
+
+class JSONResponse(Response):
+ media_type = "application/json"
+
+ def __init__(
+ self,
+ content: typing.Any,
+ status_code: int = 200,
+ headers: typing.Mapping[str, str] | None = None,
+ media_type: str | None = None,
+ background: BackgroundTask | None = None,
+ ) -> None:
+ super().__init__(content, status_code, headers, media_type, background)
+
+ def render(self, content: typing.Any) -> bytes:
+ return json.dumps(
+ content,
+ ensure_ascii=False,
+ allow_nan=False,
+ indent=None,
+ separators=(",", ":"),
+ ).encode("utf-8")
+
+
+class RedirectResponse(Response):
+ def __init__(
+ self,
+ url: str | URL,
+ status_code: int = 307,
+ headers: typing.Mapping[str, str] | None = None,
+ background: BackgroundTask | None = None,
+ ) -> None:
+ super().__init__(content=b"", status_code=status_code, headers=headers, background=background)
+ self.headers["location"] = quote(str(url), safe=":/%#?=@[]!$&'()*+,;")
+
+
+Content = typing.Union[str, bytes, memoryview]
+SyncContentStream = typing.Iterable[Content]
+AsyncContentStream = typing.AsyncIterable[Content]
+ContentStream = typing.Union[AsyncContentStream, SyncContentStream]
+
+
+class StreamingResponse(Response):
+ body_iterator: AsyncContentStream
+
+ def __init__(
+ self,
+ content: ContentStream,
+ status_code: int = 200,
+ headers: typing.Mapping[str, str] | None = None,
+ media_type: str | None = None,
+ background: BackgroundTask | None = None,
+ ) -> None:
+ if isinstance(content, typing.AsyncIterable):
+ self.body_iterator = content
+ else:
+ self.body_iterator = iterate_in_threadpool(content)
+ self.status_code = status_code
+ self.media_type = self.media_type if media_type is None else media_type
+ self.background = background
+ self.init_headers(headers)
+
+ async def listen_for_disconnect(self, receive: Receive) -> None:
+ while True:
+ message = await receive()
+ if message["type"] == "http.disconnect":
+ break
+
+ async def stream_response(self, send: Send) -> None:
+ await send(
+ {
+ "type": "http.response.start",
+ "status": self.status_code,
+ "headers": self.raw_headers,
+ }
+ )
+ async for chunk in self.body_iterator:
+ if not isinstance(chunk, (bytes, memoryview)):
+ chunk = chunk.encode(self.charset)
+ await send({"type": "http.response.body", "body": chunk, "more_body": True})
+
+ await send({"type": "http.response.body", "body": b"", "more_body": False})
+
+ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
+ spec_version = tuple(map(int, scope.get("asgi", {}).get("spec_version", "2.0").split(".")))
+
+ if spec_version >= (2, 4):
+ try:
+ await self.stream_response(send)
+ except OSError:
+ raise ClientDisconnect()
+ else:
+ with collapse_excgroups():
+ async with anyio.create_task_group() as task_group:
+
+ async def wrap(func: typing.Callable[[], typing.Awaitable[None]]) -> None:
+ await func()
+ task_group.cancel_scope.cancel()
+
+ task_group.start_soon(wrap, partial(self.stream_response, send))
+ await wrap(partial(self.listen_for_disconnect, receive))
+
+ if self.background is not None:
+ await self.background()
+
+
+class MalformedRangeHeader(Exception):
+ def __init__(self, content: str = "Malformed range header.") -> None:
+ self.content = content
+
+
+class RangeNotSatisfiable(Exception):
+ def __init__(self, max_size: int) -> None:
+ self.max_size = max_size
+
+
+_RANGE_PATTERN = re.compile(r"(\d*)-(\d*)")
+
+
+class FileResponse(Response):
+ chunk_size = 64 * 1024
+
+ def __init__(
+ self,
+ path: str | os.PathLike[str],
+ status_code: int = 200,
+ headers: typing.Mapping[str, str] | None = None,
+ media_type: str | None = None,
+ background: BackgroundTask | None = None,
+ filename: str | None = None,
+ stat_result: os.stat_result | None = None,
+ method: str | None = None,
+ content_disposition_type: str = "attachment",
+ ) -> None:
+ self.path = path
+ self.status_code = status_code
+ self.filename = filename
+ if method is not None:
+ warnings.warn(
+ "The 'method' parameter is not used, and it will be removed.",
+ DeprecationWarning,
+ )
+ if media_type is None:
+ media_type = guess_type(filename or path)[0] or "text/plain"
+ self.media_type = media_type
+ self.background = background
+ self.init_headers(headers)
+ self.headers.setdefault("accept-ranges", "bytes")
+ if self.filename is not None:
+ content_disposition_filename = quote(self.filename)
+ if content_disposition_filename != self.filename:
+ content_disposition = f"{content_disposition_type}; filename*=utf-8''{content_disposition_filename}"
+ else:
+ content_disposition = f'{content_disposition_type}; filename="{self.filename}"'
+ self.headers.setdefault("content-disposition", content_disposition)
+ self.stat_result = stat_result
+ if stat_result is not None:
+ self.set_stat_headers(stat_result)
+
+ def set_stat_headers(self, stat_result: os.stat_result) -> None:
+ content_length = str(stat_result.st_size)
+ last_modified = formatdate(stat_result.st_mtime, usegmt=True)
+ etag_base = str(stat_result.st_mtime) + "-" + str(stat_result.st_size)
+ etag = f'"{hashlib.md5(etag_base.encode(), usedforsecurity=False).hexdigest()}"'
+
+ self.headers.setdefault("content-length", content_length)
+ self.headers.setdefault("last-modified", last_modified)
+ self.headers.setdefault("etag", etag)
+
+ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
+ send_header_only: bool = scope["method"].upper() == "HEAD"
+ if self.stat_result is None:
+ try:
+ stat_result = await anyio.to_thread.run_sync(os.stat, self.path)
+ self.set_stat_headers(stat_result)
+ except FileNotFoundError:
+ raise RuntimeError(f"File at path {self.path} does not exist.")
+ else:
+ mode = stat_result.st_mode
+ if not stat.S_ISREG(mode):
+ raise RuntimeError(f"File at path {self.path} is not a file.")
+ else:
+ stat_result = self.stat_result
+
+ headers = Headers(scope=scope)
+ http_range = headers.get("range")
+ http_if_range = headers.get("if-range")
+
+ if http_range is None or (http_if_range is not None and not self._should_use_range(http_if_range)):
+ await self._handle_simple(send, send_header_only)
+ else:
+ try:
+ ranges = self._parse_range_header(http_range, stat_result.st_size)
+ except MalformedRangeHeader as exc:
+ return await PlainTextResponse(exc.content, status_code=400)(scope, receive, send)
+ except RangeNotSatisfiable as exc:
+ response = PlainTextResponse(status_code=416, headers={"Content-Range": f"*/{exc.max_size}"})
+ return await response(scope, receive, send)
+
+ if len(ranges) == 1:
+ start, end = ranges[0]
+ await self._handle_single_range(send, start, end, stat_result.st_size, send_header_only)
+ else:
+ await self._handle_multiple_ranges(send, ranges, stat_result.st_size, send_header_only)
+
+ if self.background is not None:
+ await self.background()
+
+ async def _handle_simple(self, send: Send, send_header_only: bool) -> None:
+ await send({"type": "http.response.start", "status": self.status_code, "headers": self.raw_headers})
+ if send_header_only:
+ await send({"type": "http.response.body", "body": b"", "more_body": False})
+ else:
+ async with await anyio.open_file(self.path, mode="rb") as file:
+ more_body = True
+ while more_body:
+ chunk = await file.read(self.chunk_size)
+ more_body = len(chunk) == self.chunk_size
+ await send({"type": "http.response.body", "body": chunk, "more_body": more_body})
+
+ async def _handle_single_range(
+ self, send: Send, start: int, end: int, file_size: int, send_header_only: bool
+ ) -> None:
+ self.headers["content-range"] = f"bytes {start}-{end - 1}/{file_size}"
+ self.headers["content-length"] = str(end - start)
+ await send({"type": "http.response.start", "status": 206, "headers": self.raw_headers})
+ if send_header_only:
+ await send({"type": "http.response.body", "body": b"", "more_body": False})
+ else:
+ async with await anyio.open_file(self.path, mode="rb") as file:
+ await file.seek(start)
+ more_body = True
+ while more_body:
+ chunk = await file.read(min(self.chunk_size, end - start))
+ start += len(chunk)
+ more_body = len(chunk) == self.chunk_size and start < end
+ await send({"type": "http.response.body", "body": chunk, "more_body": more_body})
+
+ async def _handle_multiple_ranges(
+ self,
+ send: Send,
+ ranges: list[tuple[int, int]],
+ file_size: int,
+ send_header_only: bool,
+ ) -> None:
+ # In firefox and chrome, they use boundary with 95-96 bits entropy (that's roughly 13 bytes).
+ boundary = token_hex(13)
+ content_length, header_generator = self.generate_multipart(
+ ranges, boundary, file_size, self.headers["content-type"]
+ )
+ self.headers["content-range"] = f"multipart/byteranges; boundary={boundary}"
+ self.headers["content-length"] = str(content_length)
+ await send({"type": "http.response.start", "status": 206, "headers": self.raw_headers})
+ if send_header_only:
+ await send({"type": "http.response.body", "body": b"", "more_body": False})
+ else:
+ async with await anyio.open_file(self.path, mode="rb") as file:
+ for start, end in ranges:
+ await send({"type": "http.response.body", "body": header_generator(start, end), "more_body": True})
+ await file.seek(start)
+ while start < end:
+ chunk = await file.read(min(self.chunk_size, end - start))
+ start += len(chunk)
+ await send({"type": "http.response.body", "body": chunk, "more_body": True})
+ await send({"type": "http.response.body", "body": b"\n", "more_body": True})
+ await send(
+ {
+ "type": "http.response.body",
+ "body": f"\n--{boundary}--\n".encode("latin-1"),
+ "more_body": False,
+ }
+ )
+
+ def _should_use_range(self, http_if_range: str) -> bool:
+ return http_if_range == self.headers["last-modified"] or http_if_range == self.headers["etag"]
+
+ @staticmethod
+ def _parse_range_header(http_range: str, file_size: int) -> list[tuple[int, int]]:
+ ranges: list[tuple[int, int]] = []
+ try:
+ units, range_ = http_range.split("=", 1)
+ except ValueError:
+ raise MalformedRangeHeader()
+
+ units = units.strip().lower()
+
+ if units != "bytes":
+ raise MalformedRangeHeader("Only support bytes range")
+
+ ranges = [
+ (
+ int(_[0]) if _[0] else file_size - int(_[1]),
+ int(_[1]) + 1 if _[0] and _[1] and int(_[1]) < file_size else file_size,
+ )
+ for _ in _RANGE_PATTERN.findall(range_)
+ if _ != ("", "")
+ ]
+
+ if len(ranges) == 0:
+ raise MalformedRangeHeader("Range header: range must be requested")
+
+ if any(not (0 <= start < file_size) for start, _ in ranges):
+ raise RangeNotSatisfiable(file_size)
+
+ if any(start > end for start, end in ranges):
+ raise MalformedRangeHeader("Range header: start must be less than end")
+
+ if len(ranges) == 1:
+ return ranges
+
+ # Merge ranges
+ result: list[tuple[int, int]] = []
+ for start, end in ranges:
+ for p in range(len(result)):
+ p_start, p_end = result[p]
+ if start > p_end:
+ continue
+ elif end < p_start:
+ result.insert(p, (start, end)) # THIS IS NOT REACHED!
+ break
+ else:
+ result[p] = (min(start, p_start), max(end, p_end))
+ break
+ else:
+ result.append((start, end))
+
+ return result
+
+ def generate_multipart(
+ self,
+ ranges: typing.Sequence[tuple[int, int]],
+ boundary: str,
+ max_size: int,
+ content_type: str,
+ ) -> tuple[int, typing.Callable[[int, int], bytes]]:
+ r"""
+ Multipart response headers generator.
+
+ ```
+ --{boundary}\n
+ Content-Type: {content_type}\n
+ Content-Range: bytes {start}-{end-1}/{max_size}\n
+ \n
+ ..........content...........\n
+ --{boundary}\n
+ Content-Type: {content_type}\n
+ Content-Range: bytes {start}-{end-1}/{max_size}\n
+ \n
+ ..........content...........\n
+ --{boundary}--\n
+ ```
+ """
+ boundary_len = len(boundary)
+ static_header_part_len = 44 + boundary_len + len(content_type) + len(str(max_size))
+ content_length = sum(
+ (len(str(start)) + len(str(end - 1)) + static_header_part_len) # Headers
+ + (end - start) # Content
+ for start, end in ranges
+ ) + (
+ 5 + boundary_len # --boundary--\n
+ )
+ return (
+ content_length,
+ lambda start, end: (
+ f"--{boundary}\nContent-Type: {content_type}\nContent-Range: bytes {start}-{end - 1}/{max_size}\n\n"
+ ).encode("latin-1"),
+ )
diff --git a/venv/Lib/site-packages/starlette/routing.py b/venv/Lib/site-packages/starlette/routing.py
new file mode 100644
index 00000000..add7df0c
--- /dev/null
+++ b/venv/Lib/site-packages/starlette/routing.py
@@ -0,0 +1,874 @@
+from __future__ import annotations
+
+import contextlib
+import functools
+import inspect
+import re
+import traceback
+import types
+import typing
+import warnings
+from contextlib import asynccontextmanager
+from enum import Enum
+
+from starlette._exception_handler import wrap_app_handling_exceptions
+from starlette._utils import get_route_path, is_async_callable
+from starlette.concurrency import run_in_threadpool
+from starlette.convertors import CONVERTOR_TYPES, Convertor
+from starlette.datastructures import URL, Headers, URLPath
+from starlette.exceptions import HTTPException
+from starlette.middleware import Middleware
+from starlette.requests import Request
+from starlette.responses import PlainTextResponse, RedirectResponse, Response
+from starlette.types import ASGIApp, Lifespan, Receive, Scope, Send
+from starlette.websockets import WebSocket, WebSocketClose
+
+
+class NoMatchFound(Exception):
+ """
+ Raised by `.url_for(name, **path_params)` and `.url_path_for(name, **path_params)`
+ if no matching route exists.
+ """
+
+ def __init__(self, name: str, path_params: dict[str, typing.Any]) -> None:
+ params = ", ".join(list(path_params.keys()))
+ super().__init__(f'No route exists for name "{name}" and params "{params}".')
+
+
+class Match(Enum):
+ NONE = 0
+ PARTIAL = 1
+ FULL = 2
+
+
+def iscoroutinefunction_or_partial(obj: typing.Any) -> bool: # pragma: no cover
+ """
+ Correctly determines if an object is a coroutine function,
+ including those wrapped in functools.partial objects.
+ """
+ warnings.warn(
+ "iscoroutinefunction_or_partial is deprecated, and will be removed in a future release.",
+ DeprecationWarning,
+ )
+ while isinstance(obj, functools.partial):
+ obj = obj.func
+ return inspect.iscoroutinefunction(obj)
+
+
+def request_response(
+ func: typing.Callable[[Request], typing.Awaitable[Response] | Response],
+) -> ASGIApp:
+ """
+ Takes a function or coroutine `func(request) -> response`,
+ and returns an ASGI application.
+ """
+ f: typing.Callable[[Request], typing.Awaitable[Response]] = (
+ func if is_async_callable(func) else functools.partial(run_in_threadpool, func) # type:ignore
+ )
+
+ async def app(scope: Scope, receive: Receive, send: Send) -> None:
+ request = Request(scope, receive, send)
+
+ async def app(scope: Scope, receive: Receive, send: Send) -> None:
+ response = await f(request)
+ await response(scope, receive, send)
+
+ await wrap_app_handling_exceptions(app, request)(scope, receive, send)
+
+ return app
+
+
+def websocket_session(
+ func: typing.Callable[[WebSocket], typing.Awaitable[None]],
+) -> ASGIApp:
+ """
+ Takes a coroutine `func(session)`, and returns an ASGI application.
+ """
+ # assert asyncio.iscoroutinefunction(func), "WebSocket endpoints must be async"
+
+ async def app(scope: Scope, receive: Receive, send: Send) -> None:
+ session = WebSocket(scope, receive=receive, send=send)
+
+ async def app(scope: Scope, receive: Receive, send: Send) -> None:
+ await func(session)
+
+ await wrap_app_handling_exceptions(app, session)(scope, receive, send)
+
+ return app
+
+
+def get_name(endpoint: typing.Callable[..., typing.Any]) -> str:
+ return getattr(endpoint, "__name__", endpoint.__class__.__name__)
+
+
+def replace_params(
+ path: str,
+ param_convertors: dict[str, Convertor[typing.Any]],
+ path_params: dict[str, str],
+) -> tuple[str, dict[str, str]]:
+ for key, value in list(path_params.items()):
+ if "{" + key + "}" in path:
+ convertor = param_convertors[key]
+ value = convertor.to_string(value)
+ path = path.replace("{" + key + "}", value)
+ path_params.pop(key)
+ return path, path_params
+
+
+# Match parameters in URL paths, eg. '{param}', and '{param:int}'
+PARAM_REGEX = re.compile("{([a-zA-Z_][a-zA-Z0-9_]*)(:[a-zA-Z_][a-zA-Z0-9_]*)?}")
+
+
+def compile_path(
+ path: str,
+) -> tuple[typing.Pattern[str], str, dict[str, Convertor[typing.Any]]]:
+ """
+ Given a path string, like: "/{username:str}",
+ or a host string, like: "{subdomain}.mydomain.org", return a three-tuple
+ of (regex, format, {param_name:convertor}).
+
+ regex: "/(?P[^/]+)"
+ format: "/{username}"
+ convertors: {"username": StringConvertor()}
+ """
+ is_host = not path.startswith("/")
+
+ path_regex = "^"
+ path_format = ""
+ duplicated_params = set()
+
+ idx = 0
+ param_convertors = {}
+ for match in PARAM_REGEX.finditer(path):
+ param_name, convertor_type = match.groups("str")
+ convertor_type = convertor_type.lstrip(":")
+ assert convertor_type in CONVERTOR_TYPES, f"Unknown path convertor '{convertor_type}'"
+ convertor = CONVERTOR_TYPES[convertor_type]
+
+ path_regex += re.escape(path[idx : match.start()])
+ path_regex += f"(?P<{param_name}>{convertor.regex})"
+
+ path_format += path[idx : match.start()]
+ path_format += "{%s}" % param_name
+
+ if param_name in param_convertors:
+ duplicated_params.add(param_name)
+
+ param_convertors[param_name] = convertor
+
+ idx = match.end()
+
+ if duplicated_params:
+ names = ", ".join(sorted(duplicated_params))
+ ending = "s" if len(duplicated_params) > 1 else ""
+ raise ValueError(f"Duplicated param name{ending} {names} at path {path}")
+
+ if is_host:
+ # Align with `Host.matches()` behavior, which ignores port.
+ hostname = path[idx:].split(":")[0]
+ path_regex += re.escape(hostname) + "$"
+ else:
+ path_regex += re.escape(path[idx:]) + "$"
+
+ path_format += path[idx:]
+
+ return re.compile(path_regex), path_format, param_convertors
+
+
+class BaseRoute:
+ def matches(self, scope: Scope) -> tuple[Match, Scope]:
+ raise NotImplementedError() # pragma: no cover
+
+ def url_path_for(self, name: str, /, **path_params: typing.Any) -> URLPath:
+ raise NotImplementedError() # pragma: no cover
+
+ async def handle(self, scope: Scope, receive: Receive, send: Send) -> None:
+ raise NotImplementedError() # pragma: no cover
+
+ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
+ """
+ A route may be used in isolation as a stand-alone ASGI app.
+ This is a somewhat contrived case, as they'll almost always be used
+ within a Router, but could be useful for some tooling and minimal apps.
+ """
+ match, child_scope = self.matches(scope)
+ if match == Match.NONE:
+ if scope["type"] == "http":
+ response = PlainTextResponse("Not Found", status_code=404)
+ await response(scope, receive, send)
+ elif scope["type"] == "websocket": # pragma: no branch
+ websocket_close = WebSocketClose()
+ await websocket_close(scope, receive, send)
+ return
+
+ scope.update(child_scope)
+ await self.handle(scope, receive, send)
+
+
+class Route(BaseRoute):
+ def __init__(
+ self,
+ path: str,
+ endpoint: typing.Callable[..., typing.Any],
+ *,
+ methods: list[str] | None = None,
+ name: str | None = None,
+ include_in_schema: bool = True,
+ middleware: typing.Sequence[Middleware] | None = None,
+ ) -> None:
+ assert path.startswith("/"), "Routed paths must start with '/'"
+ self.path = path
+ self.endpoint = endpoint
+ self.name = get_name(endpoint) if name is None else name
+ self.include_in_schema = include_in_schema
+
+ endpoint_handler = endpoint
+ while isinstance(endpoint_handler, functools.partial):
+ endpoint_handler = endpoint_handler.func
+ if inspect.isfunction(endpoint_handler) or inspect.ismethod(endpoint_handler):
+ # Endpoint is function or method. Treat it as `func(request) -> response`.
+ self.app = request_response(endpoint)
+ if methods is None:
+ methods = ["GET"]
+ else:
+ # Endpoint is a class. Treat it as ASGI.
+ self.app = endpoint
+
+ if middleware is not None:
+ for cls, args, kwargs in reversed(middleware):
+ self.app = cls(self.app, *args, **kwargs)
+
+ if methods is None:
+ self.methods = None
+ else:
+ self.methods = {method.upper() for method in methods}
+ if "GET" in self.methods:
+ self.methods.add("HEAD")
+
+ self.path_regex, self.path_format, self.param_convertors = compile_path(path)
+
+ def matches(self, scope: Scope) -> tuple[Match, Scope]:
+ path_params: dict[str, typing.Any]
+ if scope["type"] == "http":
+ route_path = get_route_path(scope)
+ match = self.path_regex.match(route_path)
+ if match:
+ matched_params = match.groupdict()
+ for key, value in matched_params.items():
+ matched_params[key] = self.param_convertors[key].convert(value)
+ path_params = dict(scope.get("path_params", {}))
+ path_params.update(matched_params)
+ child_scope = {"endpoint": self.endpoint, "path_params": path_params}
+ if self.methods and scope["method"] not in self.methods:
+ return Match.PARTIAL, child_scope
+ else:
+ return Match.FULL, child_scope
+ return Match.NONE, {}
+
+ def url_path_for(self, name: str, /, **path_params: typing.Any) -> URLPath:
+ seen_params = set(path_params.keys())
+ expected_params = set(self.param_convertors.keys())
+
+ if name != self.name or seen_params != expected_params:
+ raise NoMatchFound(name, path_params)
+
+ path, remaining_params = replace_params(self.path_format, self.param_convertors, path_params)
+ assert not remaining_params
+ return URLPath(path=path, protocol="http")
+
+ async def handle(self, scope: Scope, receive: Receive, send: Send) -> None:
+ if self.methods and scope["method"] not in self.methods:
+ headers = {"Allow": ", ".join(self.methods)}
+ if "app" in scope:
+ raise HTTPException(status_code=405, headers=headers)
+ else:
+ response = PlainTextResponse("Method Not Allowed", status_code=405, headers=headers)
+ await response(scope, receive, send)
+ else:
+ await self.app(scope, receive, send)
+
+ def __eq__(self, other: typing.Any) -> bool:
+ return (
+ isinstance(other, Route)
+ and self.path == other.path
+ and self.endpoint == other.endpoint
+ and self.methods == other.methods
+ )
+
+ def __repr__(self) -> str:
+ class_name = self.__class__.__name__
+ methods = sorted(self.methods or [])
+ path, name = self.path, self.name
+ return f"{class_name}(path={path!r}, name={name!r}, methods={methods!r})"
+
+
+class WebSocketRoute(BaseRoute):
+ def __init__(
+ self,
+ path: str,
+ endpoint: typing.Callable[..., typing.Any],
+ *,
+ name: str | None = None,
+ middleware: typing.Sequence[Middleware] | None = None,
+ ) -> None:
+ assert path.startswith("/"), "Routed paths must start with '/'"
+ self.path = path
+ self.endpoint = endpoint
+ self.name = get_name(endpoint) if name is None else name
+
+ endpoint_handler = endpoint
+ while isinstance(endpoint_handler, functools.partial):
+ endpoint_handler = endpoint_handler.func
+ if inspect.isfunction(endpoint_handler) or inspect.ismethod(endpoint_handler):
+ # Endpoint is function or method. Treat it as `func(websocket)`.
+ self.app = websocket_session(endpoint)
+ else:
+ # Endpoint is a class. Treat it as ASGI.
+ self.app = endpoint
+
+ if middleware is not None:
+ for cls, args, kwargs in reversed(middleware):
+ self.app = cls(self.app, *args, **kwargs)
+
+ self.path_regex, self.path_format, self.param_convertors = compile_path(path)
+
+ def matches(self, scope: Scope) -> tuple[Match, Scope]:
+ path_params: dict[str, typing.Any]
+ if scope["type"] == "websocket":
+ route_path = get_route_path(scope)
+ match = self.path_regex.match(route_path)
+ if match:
+ matched_params = match.groupdict()
+ for key, value in matched_params.items():
+ matched_params[key] = self.param_convertors[key].convert(value)
+ path_params = dict(scope.get("path_params", {}))
+ path_params.update(matched_params)
+ child_scope = {"endpoint": self.endpoint, "path_params": path_params}
+ return Match.FULL, child_scope
+ return Match.NONE, {}
+
+ def url_path_for(self, name: str, /, **path_params: typing.Any) -> URLPath:
+ seen_params = set(path_params.keys())
+ expected_params = set(self.param_convertors.keys())
+
+ if name != self.name or seen_params != expected_params:
+ raise NoMatchFound(name, path_params)
+
+ path, remaining_params = replace_params(self.path_format, self.param_convertors, path_params)
+ assert not remaining_params
+ return URLPath(path=path, protocol="websocket")
+
+ async def handle(self, scope: Scope, receive: Receive, send: Send) -> None:
+ await self.app(scope, receive, send)
+
+ def __eq__(self, other: typing.Any) -> bool:
+ return isinstance(other, WebSocketRoute) and self.path == other.path and self.endpoint == other.endpoint
+
+ def __repr__(self) -> str:
+ return f"{self.__class__.__name__}(path={self.path!r}, name={self.name!r})"
+
+
+class Mount(BaseRoute):
+ def __init__(
+ self,
+ path: str,
+ app: ASGIApp | None = None,
+ routes: typing.Sequence[BaseRoute] | None = None,
+ name: str | None = None,
+ *,
+ middleware: typing.Sequence[Middleware] | None = None,
+ ) -> None:
+ assert path == "" or path.startswith("/"), "Routed paths must start with '/'"
+ assert app is not None or routes is not None, "Either 'app=...', or 'routes=' must be specified"
+ self.path = path.rstrip("/")
+ if app is not None:
+ self._base_app: ASGIApp = app
+ else:
+ self._base_app = Router(routes=routes)
+ self.app = self._base_app
+ if middleware is not None:
+ for cls, args, kwargs in reversed(middleware):
+ self.app = cls(self.app, *args, **kwargs)
+ self.name = name
+ self.path_regex, self.path_format, self.param_convertors = compile_path(self.path + "/{path:path}")
+
+ @property
+ def routes(self) -> list[BaseRoute]:
+ return getattr(self._base_app, "routes", [])
+
+ def matches(self, scope: Scope) -> tuple[Match, Scope]:
+ path_params: dict[str, typing.Any]
+ if scope["type"] in ("http", "websocket"): # pragma: no branch
+ root_path = scope.get("root_path", "")
+ route_path = get_route_path(scope)
+ match = self.path_regex.match(route_path)
+ if match:
+ matched_params = match.groupdict()
+ for key, value in matched_params.items():
+ matched_params[key] = self.param_convertors[key].convert(value)
+ remaining_path = "/" + matched_params.pop("path")
+ matched_path = route_path[: -len(remaining_path)]
+ path_params = dict(scope.get("path_params", {}))
+ path_params.update(matched_params)
+ child_scope = {
+ "path_params": path_params,
+ # app_root_path will only be set at the top level scope,
+ # initialized with the (optional) value of a root_path
+ # set above/before Starlette. And even though any
+ # mount will have its own child scope with its own respective
+ # root_path, the app_root_path will always be available in all
+ # the child scopes with the same top level value because it's
+ # set only once here with a default, any other child scope will
+ # just inherit that app_root_path default value stored in the
+ # scope. All this is needed to support Request.url_for(), as it
+ # uses the app_root_path to build the URL path.
+ "app_root_path": scope.get("app_root_path", root_path),
+ "root_path": root_path + matched_path,
+ "endpoint": self.app,
+ }
+ return Match.FULL, child_scope
+ return Match.NONE, {}
+
+ def url_path_for(self, name: str, /, **path_params: typing.Any) -> URLPath:
+ if self.name is not None and name == self.name and "path" in path_params:
+ # 'name' matches "".
+ path_params["path"] = path_params["path"].lstrip("/")
+ path, remaining_params = replace_params(self.path_format, self.param_convertors, path_params)
+ if not remaining_params:
+ return URLPath(path=path)
+ elif self.name is None or name.startswith(self.name + ":"):
+ if self.name is None:
+ # No mount name.
+ remaining_name = name
+ else:
+ # 'name' matches ":".
+ remaining_name = name[len(self.name) + 1 :]
+ path_kwarg = path_params.get("path")
+ path_params["path"] = ""
+ path_prefix, remaining_params = replace_params(self.path_format, self.param_convertors, path_params)
+ if path_kwarg is not None:
+ remaining_params["path"] = path_kwarg
+ for route in self.routes or []:
+ try:
+ url = route.url_path_for(remaining_name, **remaining_params)
+ return URLPath(path=path_prefix.rstrip("/") + str(url), protocol=url.protocol)
+ except NoMatchFound:
+ pass
+ raise NoMatchFound(name, path_params)
+
+ async def handle(self, scope: Scope, receive: Receive, send: Send) -> None:
+ await self.app(scope, receive, send)
+
+ def __eq__(self, other: typing.Any) -> bool:
+ return isinstance(other, Mount) and self.path == other.path and self.app == other.app
+
+ def __repr__(self) -> str:
+ class_name = self.__class__.__name__
+ name = self.name or ""
+ return f"{class_name}(path={self.path!r}, name={name!r}, app={self.app!r})"
+
+
+class Host(BaseRoute):
+ def __init__(self, host: str, app: ASGIApp, name: str | None = None) -> None:
+ assert not host.startswith("/"), "Host must not start with '/'"
+ self.host = host
+ self.app = app
+ self.name = name
+ self.host_regex, self.host_format, self.param_convertors = compile_path(host)
+
+ @property
+ def routes(self) -> list[BaseRoute]:
+ return getattr(self.app, "routes", [])
+
+ def matches(self, scope: Scope) -> tuple[Match, Scope]:
+ if scope["type"] in ("http", "websocket"): # pragma:no branch
+ headers = Headers(scope=scope)
+ host = headers.get("host", "").split(":")[0]
+ match = self.host_regex.match(host)
+ if match:
+ matched_params = match.groupdict()
+ for key, value in matched_params.items():
+ matched_params[key] = self.param_convertors[key].convert(value)
+ path_params = dict(scope.get("path_params", {}))
+ path_params.update(matched_params)
+ child_scope = {"path_params": path_params, "endpoint": self.app}
+ return Match.FULL, child_scope
+ return Match.NONE, {}
+
+ def url_path_for(self, name: str, /, **path_params: typing.Any) -> URLPath:
+ if self.name is not None and name == self.name and "path" in path_params:
+ # 'name' matches "".
+ path = path_params.pop("path")
+ host, remaining_params = replace_params(self.host_format, self.param_convertors, path_params)
+ if not remaining_params:
+ return URLPath(path=path, host=host)
+ elif self.name is None or name.startswith(self.name + ":"):
+ if self.name is None:
+ # No mount name.
+ remaining_name = name
+ else:
+ # 'name' matches ":".
+ remaining_name = name[len(self.name) + 1 :]
+ host, remaining_params = replace_params(self.host_format, self.param_convertors, path_params)
+ for route in self.routes or []:
+ try:
+ url = route.url_path_for(remaining_name, **remaining_params)
+ return URLPath(path=str(url), protocol=url.protocol, host=host)
+ except NoMatchFound:
+ pass
+ raise NoMatchFound(name, path_params)
+
+ async def handle(self, scope: Scope, receive: Receive, send: Send) -> None:
+ await self.app(scope, receive, send)
+
+ def __eq__(self, other: typing.Any) -> bool:
+ return isinstance(other, Host) and self.host == other.host and self.app == other.app
+
+ def __repr__(self) -> str:
+ class_name = self.__class__.__name__
+ name = self.name or ""
+ return f"{class_name}(host={self.host!r}, name={name!r}, app={self.app!r})"
+
+
+_T = typing.TypeVar("_T")
+
+
+class _AsyncLiftContextManager(typing.AsyncContextManager[_T]):
+ def __init__(self, cm: typing.ContextManager[_T]):
+ self._cm = cm
+
+ async def __aenter__(self) -> _T:
+ return self._cm.__enter__()
+
+ async def __aexit__(
+ self,
+ exc_type: type[BaseException] | None,
+ exc_value: BaseException | None,
+ traceback: types.TracebackType | None,
+ ) -> bool | None:
+ return self._cm.__exit__(exc_type, exc_value, traceback)
+
+
+def _wrap_gen_lifespan_context(
+ lifespan_context: typing.Callable[[typing.Any], typing.Generator[typing.Any, typing.Any, typing.Any]],
+) -> typing.Callable[[typing.Any], typing.AsyncContextManager[typing.Any]]:
+ cmgr = contextlib.contextmanager(lifespan_context)
+
+ @functools.wraps(cmgr)
+ def wrapper(app: typing.Any) -> _AsyncLiftContextManager[typing.Any]:
+ return _AsyncLiftContextManager(cmgr(app))
+
+ return wrapper
+
+
+class _DefaultLifespan:
+ def __init__(self, router: Router):
+ self._router = router
+
+ async def __aenter__(self) -> None:
+ await self._router.startup()
+
+ async def __aexit__(self, *exc_info: object) -> None:
+ await self._router.shutdown()
+
+ def __call__(self: _T, app: object) -> _T:
+ return self
+
+
+class Router:
+ def __init__(
+ self,
+ routes: typing.Sequence[BaseRoute] | None = None,
+ redirect_slashes: bool = True,
+ default: ASGIApp | None = None,
+ on_startup: typing.Sequence[typing.Callable[[], typing.Any]] | None = None,
+ on_shutdown: typing.Sequence[typing.Callable[[], typing.Any]] | None = None,
+ # the generic to Lifespan[AppType] is the type of the top level application
+ # which the router cannot know statically, so we use typing.Any
+ lifespan: Lifespan[typing.Any] | None = None,
+ *,
+ middleware: typing.Sequence[Middleware] | None = None,
+ ) -> None:
+ self.routes = [] if routes is None else list(routes)
+ self.redirect_slashes = redirect_slashes
+ self.default = self.not_found if default is None else default
+ self.on_startup = [] if on_startup is None else list(on_startup)
+ self.on_shutdown = [] if on_shutdown is None else list(on_shutdown)
+
+ if on_startup or on_shutdown:
+ warnings.warn(
+ "The on_startup and on_shutdown parameters are deprecated, and they "
+ "will be removed on version 1.0. Use the lifespan parameter instead. "
+ "See more about it on https://www.starlette.io/lifespan/.",
+ DeprecationWarning,
+ )
+ if lifespan:
+ warnings.warn(
+ "The `lifespan` parameter cannot be used with `on_startup` or "
+ "`on_shutdown`. Both `on_startup` and `on_shutdown` will be "
+ "ignored."
+ )
+
+ if lifespan is None:
+ self.lifespan_context: Lifespan[typing.Any] = _DefaultLifespan(self)
+
+ elif inspect.isasyncgenfunction(lifespan):
+ warnings.warn(
+ "async generator function lifespans are deprecated, "
+ "use an @contextlib.asynccontextmanager function instead",
+ DeprecationWarning,
+ )
+ self.lifespan_context = asynccontextmanager(
+ lifespan,
+ )
+ elif inspect.isgeneratorfunction(lifespan):
+ warnings.warn(
+ "generator function lifespans are deprecated, use an @contextlib.asynccontextmanager function instead",
+ DeprecationWarning,
+ )
+ self.lifespan_context = _wrap_gen_lifespan_context(
+ lifespan,
+ )
+ else:
+ self.lifespan_context = lifespan
+
+ self.middleware_stack = self.app
+ if middleware:
+ for cls, args, kwargs in reversed(middleware):
+ self.middleware_stack = cls(self.middleware_stack, *args, **kwargs)
+
+ async def not_found(self, scope: Scope, receive: Receive, send: Send) -> None:
+ if scope["type"] == "websocket":
+ websocket_close = WebSocketClose()
+ await websocket_close(scope, receive, send)
+ return
+
+ # If we're running inside a starlette application then raise an
+ # exception, so that the configurable exception handler can deal with
+ # returning the response. For plain ASGI apps, just return the response.
+ if "app" in scope:
+ raise HTTPException(status_code=404)
+ else:
+ response = PlainTextResponse("Not Found", status_code=404)
+ await response(scope, receive, send)
+
+ def url_path_for(self, name: str, /, **path_params: typing.Any) -> URLPath:
+ for route in self.routes:
+ try:
+ return route.url_path_for(name, **path_params)
+ except NoMatchFound:
+ pass
+ raise NoMatchFound(name, path_params)
+
+ async def startup(self) -> None:
+ """
+ Run any `.on_startup` event handlers.
+ """
+ for handler in self.on_startup:
+ if is_async_callable(handler):
+ await handler()
+ else:
+ handler()
+
+ async def shutdown(self) -> None:
+ """
+ Run any `.on_shutdown` event handlers.
+ """
+ for handler in self.on_shutdown:
+ if is_async_callable(handler):
+ await handler()
+ else:
+ handler()
+
+ async def lifespan(self, scope: Scope, receive: Receive, send: Send) -> None:
+ """
+ Handle ASGI lifespan messages, which allows us to manage application
+ startup and shutdown events.
+ """
+ started = False
+ app: typing.Any = scope.get("app")
+ await receive()
+ try:
+ async with self.lifespan_context(app) as maybe_state:
+ if maybe_state is not None:
+ if "state" not in scope:
+ raise RuntimeError('The server does not support "state" in the lifespan scope.')
+ scope["state"].update(maybe_state)
+ await send({"type": "lifespan.startup.complete"})
+ started = True
+ await receive()
+ except BaseException:
+ exc_text = traceback.format_exc()
+ if started:
+ await send({"type": "lifespan.shutdown.failed", "message": exc_text})
+ else:
+ await send({"type": "lifespan.startup.failed", "message": exc_text})
+ raise
+ else:
+ await send({"type": "lifespan.shutdown.complete"})
+
+ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
+ """
+ The main entry point to the Router class.
+ """
+ await self.middleware_stack(scope, receive, send)
+
+ async def app(self, scope: Scope, receive: Receive, send: Send) -> None:
+ assert scope["type"] in ("http", "websocket", "lifespan")
+
+ if "router" not in scope:
+ scope["router"] = self
+
+ if scope["type"] == "lifespan":
+ await self.lifespan(scope, receive, send)
+ return
+
+ partial = None
+
+ for route in self.routes:
+ # Determine if any route matches the incoming scope,
+ # and hand over to the matching route if found.
+ match, child_scope = route.matches(scope)
+ if match == Match.FULL:
+ scope.update(child_scope)
+ await route.handle(scope, receive, send)
+ return
+ elif match == Match.PARTIAL and partial is None:
+ partial = route
+ partial_scope = child_scope
+
+ if partial is not None:
+ # Handle partial matches. These are cases where an endpoint is
+ # able to handle the request, but is not a preferred option.
+ # We use this in particular to deal with "405 Method Not Allowed".
+ scope.update(partial_scope)
+ await partial.handle(scope, receive, send)
+ return
+
+ route_path = get_route_path(scope)
+ if scope["type"] == "http" and self.redirect_slashes and route_path != "/":
+ redirect_scope = dict(scope)
+ if route_path.endswith("/"):
+ redirect_scope["path"] = redirect_scope["path"].rstrip("/")
+ else:
+ redirect_scope["path"] = redirect_scope["path"] + "/"
+
+ for route in self.routes:
+ match, child_scope = route.matches(redirect_scope)
+ if match != Match.NONE:
+ redirect_url = URL(scope=redirect_scope)
+ response = RedirectResponse(url=str(redirect_url))
+ await response(scope, receive, send)
+ return
+
+ await self.default(scope, receive, send)
+
+ def __eq__(self, other: typing.Any) -> bool:
+ return isinstance(other, Router) and self.routes == other.routes
+
+ def mount(self, path: str, app: ASGIApp, name: str | None = None) -> None: # pragma: no cover
+ route = Mount(path, app=app, name=name)
+ self.routes.append(route)
+
+ def host(self, host: str, app: ASGIApp, name: str | None = None) -> None: # pragma: no cover
+ route = Host(host, app=app, name=name)
+ self.routes.append(route)
+
+ def add_route(
+ self,
+ path: str,
+ endpoint: typing.Callable[[Request], typing.Awaitable[Response] | Response],
+ methods: list[str] | None = None,
+ name: str | None = None,
+ include_in_schema: bool = True,
+ ) -> None: # pragma: no cover
+ route = Route(
+ path,
+ endpoint=endpoint,
+ methods=methods,
+ name=name,
+ include_in_schema=include_in_schema,
+ )
+ self.routes.append(route)
+
+ def add_websocket_route(
+ self,
+ path: str,
+ endpoint: typing.Callable[[WebSocket], typing.Awaitable[None]],
+ name: str | None = None,
+ ) -> None: # pragma: no cover
+ route = WebSocketRoute(path, endpoint=endpoint, name=name)
+ self.routes.append(route)
+
+ def route(
+ self,
+ path: str,
+ methods: list[str] | None = None,
+ name: str | None = None,
+ include_in_schema: bool = True,
+ ) -> typing.Callable: # type: ignore[type-arg]
+ """
+ We no longer document this decorator style API, and its usage is discouraged.
+ Instead you should use the following approach:
+
+ >>> routes = [Route(path, endpoint=...), ...]
+ >>> app = Starlette(routes=routes)
+ """
+ warnings.warn(
+ "The `route` decorator is deprecated, and will be removed in version 1.0.0."
+ "Refer to https://www.starlette.io/routing/#http-routing for the recommended approach.",
+ DeprecationWarning,
+ )
+
+ def decorator(func: typing.Callable) -> typing.Callable: # type: ignore[type-arg]
+ self.add_route(
+ path,
+ func,
+ methods=methods,
+ name=name,
+ include_in_schema=include_in_schema,
+ )
+ return func
+
+ return decorator
+
+ def websocket_route(self, path: str, name: str | None = None) -> typing.Callable: # type: ignore[type-arg]
+ """
+ We no longer document this decorator style API, and its usage is discouraged.
+ Instead you should use the following approach:
+
+ >>> routes = [WebSocketRoute(path, endpoint=...), ...]
+ >>> app = Starlette(routes=routes)
+ """
+ warnings.warn(
+ "The `websocket_route` decorator is deprecated, and will be removed in version 1.0.0. Refer to "
+ "https://www.starlette.io/routing/#websocket-routing for the recommended approach.",
+ DeprecationWarning,
+ )
+
+ def decorator(func: typing.Callable) -> typing.Callable: # type: ignore[type-arg]
+ self.add_websocket_route(path, func, name=name)
+ return func
+
+ return decorator
+
+ def add_event_handler(self, event_type: str, func: typing.Callable[[], typing.Any]) -> None: # pragma: no cover
+ assert event_type in ("startup", "shutdown")
+
+ if event_type == "startup":
+ self.on_startup.append(func)
+ else:
+ self.on_shutdown.append(func)
+
+ def on_event(self, event_type: str) -> typing.Callable: # type: ignore[type-arg]
+ warnings.warn(
+ "The `on_event` decorator is deprecated, and will be removed in version 1.0.0. "
+ "Refer to https://www.starlette.io/lifespan/ for recommended approach.",
+ DeprecationWarning,
+ )
+
+ def decorator(func: typing.Callable) -> typing.Callable: # type: ignore[type-arg]
+ self.add_event_handler(event_type, func)
+ return func
+
+ return decorator
diff --git a/venv/Lib/site-packages/starlette/schemas.py b/venv/Lib/site-packages/starlette/schemas.py
new file mode 100644
index 00000000..bfc40e2a
--- /dev/null
+++ b/venv/Lib/site-packages/starlette/schemas.py
@@ -0,0 +1,147 @@
+from __future__ import annotations
+
+import inspect
+import re
+import typing
+
+from starlette.requests import Request
+from starlette.responses import Response
+from starlette.routing import BaseRoute, Host, Mount, Route
+
+try:
+ import yaml
+except ModuleNotFoundError: # pragma: no cover
+ yaml = None # type: ignore[assignment]
+
+
+class OpenAPIResponse(Response):
+ media_type = "application/vnd.oai.openapi"
+
+ def render(self, content: typing.Any) -> bytes:
+ assert yaml is not None, "`pyyaml` must be installed to use OpenAPIResponse."
+ assert isinstance(content, dict), "The schema passed to OpenAPIResponse should be a dictionary."
+ return yaml.dump(content, default_flow_style=False).encode("utf-8")
+
+
+class EndpointInfo(typing.NamedTuple):
+ path: str
+ http_method: str
+ func: typing.Callable[..., typing.Any]
+
+
+_remove_converter_pattern = re.compile(r":\w+}")
+
+
+class BaseSchemaGenerator:
+ def get_schema(self, routes: list[BaseRoute]) -> dict[str, typing.Any]:
+ raise NotImplementedError() # pragma: no cover
+
+ def get_endpoints(self, routes: list[BaseRoute]) -> list[EndpointInfo]:
+ """
+ Given the routes, yields the following information:
+
+ - path
+ eg: /users/
+ - http_method
+ one of 'get', 'post', 'put', 'patch', 'delete', 'options'
+ - func
+ method ready to extract the docstring
+ """
+ endpoints_info: list[EndpointInfo] = []
+
+ for route in routes:
+ if isinstance(route, (Mount, Host)):
+ routes = route.routes or []
+ if isinstance(route, Mount):
+ path = self._remove_converter(route.path)
+ else:
+ path = ""
+ sub_endpoints = [
+ EndpointInfo(
+ path="".join((path, sub_endpoint.path)),
+ http_method=sub_endpoint.http_method,
+ func=sub_endpoint.func,
+ )
+ for sub_endpoint in self.get_endpoints(routes)
+ ]
+ endpoints_info.extend(sub_endpoints)
+
+ elif not isinstance(route, Route) or not route.include_in_schema:
+ continue
+
+ elif inspect.isfunction(route.endpoint) or inspect.ismethod(route.endpoint):
+ path = self._remove_converter(route.path)
+ for method in route.methods or ["GET"]:
+ if method == "HEAD":
+ continue
+ endpoints_info.append(EndpointInfo(path, method.lower(), route.endpoint))
+ else:
+ path = self._remove_converter(route.path)
+ for method in ["get", "post", "put", "patch", "delete", "options"]:
+ if not hasattr(route.endpoint, method):
+ continue
+ func = getattr(route.endpoint, method)
+ endpoints_info.append(EndpointInfo(path, method.lower(), func))
+
+ return endpoints_info
+
+ def _remove_converter(self, path: str) -> str:
+ """
+ Remove the converter from the path.
+ For example, a route like this:
+ Route("/users/{id:int}", endpoint=get_user, methods=["GET"])
+ Should be represented as `/users/{id}` in the OpenAPI schema.
+ """
+ return _remove_converter_pattern.sub("}", path)
+
+ def parse_docstring(self, func_or_method: typing.Callable[..., typing.Any]) -> dict[str, typing.Any]:
+ """
+ Given a function, parse the docstring as YAML and return a dictionary of info.
+ """
+ docstring = func_or_method.__doc__
+ if not docstring:
+ return {}
+
+ assert yaml is not None, "`pyyaml` must be installed to use parse_docstring."
+
+ # We support having regular docstrings before the schema
+ # definition. Here we return just the schema part from
+ # the docstring.
+ docstring = docstring.split("---")[-1]
+
+ parsed = yaml.safe_load(docstring)
+
+ if not isinstance(parsed, dict):
+ # A regular docstring (not yaml formatted) can return
+ # a simple string here, which wouldn't follow the schema.
+ return {}
+
+ return parsed
+
+ def OpenAPIResponse(self, request: Request) -> Response:
+ routes = request.app.routes
+ schema = self.get_schema(routes=routes)
+ return OpenAPIResponse(schema)
+
+
+class SchemaGenerator(BaseSchemaGenerator):
+ def __init__(self, base_schema: dict[str, typing.Any]) -> None:
+ self.base_schema = base_schema
+
+ def get_schema(self, routes: list[BaseRoute]) -> dict[str, typing.Any]:
+ schema = dict(self.base_schema)
+ schema.setdefault("paths", {})
+ endpoints_info = self.get_endpoints(routes)
+
+ for endpoint in endpoints_info:
+ parsed = self.parse_docstring(endpoint.func)
+
+ if not parsed:
+ continue
+
+ if endpoint.path not in schema["paths"]:
+ schema["paths"][endpoint.path] = {}
+
+ schema["paths"][endpoint.path][endpoint.http_method] = parsed
+
+ return schema
diff --git a/venv/Lib/site-packages/starlette/staticfiles.py b/venv/Lib/site-packages/starlette/staticfiles.py
new file mode 100644
index 00000000..637da648
--- /dev/null
+++ b/venv/Lib/site-packages/starlette/staticfiles.py
@@ -0,0 +1,220 @@
+from __future__ import annotations
+
+import errno
+import importlib.util
+import os
+import stat
+import typing
+from email.utils import parsedate
+
+import anyio
+import anyio.to_thread
+
+from starlette._utils import get_route_path
+from starlette.datastructures import URL, Headers
+from starlette.exceptions import HTTPException
+from starlette.responses import FileResponse, RedirectResponse, Response
+from starlette.types import Receive, Scope, Send
+
+PathLike = typing.Union[str, "os.PathLike[str]"]
+
+
+class NotModifiedResponse(Response):
+ NOT_MODIFIED_HEADERS = (
+ "cache-control",
+ "content-location",
+ "date",
+ "etag",
+ "expires",
+ "vary",
+ )
+
+ def __init__(self, headers: Headers):
+ super().__init__(
+ status_code=304,
+ headers={name: value for name, value in headers.items() if name in self.NOT_MODIFIED_HEADERS},
+ )
+
+
+class StaticFiles:
+ def __init__(
+ self,
+ *,
+ directory: PathLike | None = None,
+ packages: list[str | tuple[str, str]] | None = None,
+ html: bool = False,
+ check_dir: bool = True,
+ follow_symlink: bool = False,
+ ) -> None:
+ self.directory = directory
+ self.packages = packages
+ self.all_directories = self.get_directories(directory, packages)
+ self.html = html
+ self.config_checked = False
+ self.follow_symlink = follow_symlink
+ if check_dir and directory is not None and not os.path.isdir(directory):
+ raise RuntimeError(f"Directory '{directory}' does not exist")
+
+ def get_directories(
+ self,
+ directory: PathLike | None = None,
+ packages: list[str | tuple[str, str]] | None = None,
+ ) -> list[PathLike]:
+ """
+ Given `directory` and `packages` arguments, return a list of all the
+ directories that should be used for serving static files from.
+ """
+ directories = []
+ if directory is not None:
+ directories.append(directory)
+
+ for package in packages or []:
+ if isinstance(package, tuple):
+ package, statics_dir = package
+ else:
+ statics_dir = "statics"
+ spec = importlib.util.find_spec(package)
+ assert spec is not None, f"Package {package!r} could not be found."
+ assert spec.origin is not None, f"Package {package!r} could not be found."
+ package_directory = os.path.normpath(os.path.join(spec.origin, "..", statics_dir))
+ assert os.path.isdir(package_directory), (
+ f"Directory '{statics_dir!r}' in package {package!r} could not be found."
+ )
+ directories.append(package_directory)
+
+ return directories
+
+ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
+ """
+ The ASGI entry point.
+ """
+ assert scope["type"] == "http"
+
+ if not self.config_checked:
+ await self.check_config()
+ self.config_checked = True
+
+ path = self.get_path(scope)
+ response = await self.get_response(path, scope)
+ await response(scope, receive, send)
+
+ def get_path(self, scope: Scope) -> str:
+ """
+ Given the ASGI scope, return the `path` string to serve up,
+ with OS specific path separators, and any '..', '.' components removed.
+ """
+ route_path = get_route_path(scope)
+ return os.path.normpath(os.path.join(*route_path.split("/")))
+
+ async def get_response(self, path: str, scope: Scope) -> Response:
+ """
+ Returns an HTTP response, given the incoming path, method and request headers.
+ """
+ if scope["method"] not in ("GET", "HEAD"):
+ raise HTTPException(status_code=405)
+
+ try:
+ full_path, stat_result = await anyio.to_thread.run_sync(self.lookup_path, path)
+ except PermissionError:
+ raise HTTPException(status_code=401)
+ except OSError as exc:
+ # Filename is too long, so it can't be a valid static file.
+ if exc.errno == errno.ENAMETOOLONG:
+ raise HTTPException(status_code=404)
+
+ raise exc
+
+ if stat_result and stat.S_ISREG(stat_result.st_mode):
+ # We have a static file to serve.
+ return self.file_response(full_path, stat_result, scope)
+
+ elif stat_result and stat.S_ISDIR(stat_result.st_mode) and self.html:
+ # We're in HTML mode, and have got a directory URL.
+ # Check if we have 'index.html' file to serve.
+ index_path = os.path.join(path, "index.html")
+ full_path, stat_result = await anyio.to_thread.run_sync(self.lookup_path, index_path)
+ if stat_result is not None and stat.S_ISREG(stat_result.st_mode):
+ if not scope["path"].endswith("/"):
+ # Directory URLs should redirect to always end in "/".
+ url = URL(scope=scope)
+ url = url.replace(path=url.path + "/")
+ return RedirectResponse(url=url)
+ return self.file_response(full_path, stat_result, scope)
+
+ if self.html:
+ # Check for '404.html' if we're in HTML mode.
+ full_path, stat_result = await anyio.to_thread.run_sync(self.lookup_path, "404.html")
+ if stat_result and stat.S_ISREG(stat_result.st_mode):
+ return FileResponse(full_path, stat_result=stat_result, status_code=404)
+ raise HTTPException(status_code=404)
+
+ def lookup_path(self, path: str) -> tuple[str, os.stat_result | None]:
+ for directory in self.all_directories:
+ joined_path = os.path.join(directory, path)
+ if self.follow_symlink:
+ full_path = os.path.abspath(joined_path)
+ directory = os.path.abspath(directory)
+ else:
+ full_path = os.path.realpath(joined_path)
+ directory = os.path.realpath(directory)
+ if os.path.commonpath([full_path, directory]) != str(directory):
+ # Don't allow misbehaving clients to break out of the static files directory.
+ continue
+ try:
+ return full_path, os.stat(full_path)
+ except (FileNotFoundError, NotADirectoryError):
+ continue
+ return "", None
+
+ def file_response(
+ self,
+ full_path: PathLike,
+ stat_result: os.stat_result,
+ scope: Scope,
+ status_code: int = 200,
+ ) -> Response:
+ request_headers = Headers(scope=scope)
+
+ response = FileResponse(full_path, status_code=status_code, stat_result=stat_result)
+ if self.is_not_modified(response.headers, request_headers):
+ return NotModifiedResponse(response.headers)
+ return response
+
+ async def check_config(self) -> None:
+ """
+ Perform a one-off configuration check that StaticFiles is actually
+ pointed at a directory, so that we can raise loud errors rather than
+ just returning 404 responses.
+ """
+ if self.directory is None:
+ return
+
+ try:
+ stat_result = await anyio.to_thread.run_sync(os.stat, self.directory)
+ except FileNotFoundError:
+ raise RuntimeError(f"StaticFiles directory '{self.directory}' does not exist.")
+ if not (stat.S_ISDIR(stat_result.st_mode) or stat.S_ISLNK(stat_result.st_mode)):
+ raise RuntimeError(f"StaticFiles path '{self.directory}' is not a directory.")
+
+ def is_not_modified(self, response_headers: Headers, request_headers: Headers) -> bool:
+ """
+ Given the request and response headers, return `True` if an HTTP
+ "Not Modified" response could be returned instead.
+ """
+ try:
+ if_none_match = request_headers["if-none-match"]
+ etag = response_headers["etag"]
+ if etag in [tag.strip(" W/") for tag in if_none_match.split(",")]:
+ return True
+ except KeyError:
+ pass
+
+ try:
+ if_modified_since = parsedate(request_headers["if-modified-since"])
+ last_modified = parsedate(response_headers["last-modified"])
+ if if_modified_since is not None and last_modified is not None and if_modified_since >= last_modified:
+ return True
+ except KeyError:
+ pass
+
+ return False
diff --git a/venv/Lib/site-packages/starlette/status.py b/venv/Lib/site-packages/starlette/status.py
new file mode 100644
index 00000000..54c1fb7d
--- /dev/null
+++ b/venv/Lib/site-packages/starlette/status.py
@@ -0,0 +1,95 @@
+"""
+HTTP codes
+See HTTP Status Code Registry:
+https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
+
+And RFC 2324 - https://tools.ietf.org/html/rfc2324
+"""
+
+from __future__ import annotations
+
+HTTP_100_CONTINUE = 100
+HTTP_101_SWITCHING_PROTOCOLS = 101
+HTTP_102_PROCESSING = 102
+HTTP_103_EARLY_HINTS = 103
+HTTP_200_OK = 200
+HTTP_201_CREATED = 201
+HTTP_202_ACCEPTED = 202
+HTTP_203_NON_AUTHORITATIVE_INFORMATION = 203
+HTTP_204_NO_CONTENT = 204
+HTTP_205_RESET_CONTENT = 205
+HTTP_206_PARTIAL_CONTENT = 206
+HTTP_207_MULTI_STATUS = 207
+HTTP_208_ALREADY_REPORTED = 208
+HTTP_226_IM_USED = 226
+HTTP_300_MULTIPLE_CHOICES = 300
+HTTP_301_MOVED_PERMANENTLY = 301
+HTTP_302_FOUND = 302
+HTTP_303_SEE_OTHER = 303
+HTTP_304_NOT_MODIFIED = 304
+HTTP_305_USE_PROXY = 305
+HTTP_306_RESERVED = 306
+HTTP_307_TEMPORARY_REDIRECT = 307
+HTTP_308_PERMANENT_REDIRECT = 308
+HTTP_400_BAD_REQUEST = 400
+HTTP_401_UNAUTHORIZED = 401
+HTTP_402_PAYMENT_REQUIRED = 402
+HTTP_403_FORBIDDEN = 403
+HTTP_404_NOT_FOUND = 404
+HTTP_405_METHOD_NOT_ALLOWED = 405
+HTTP_406_NOT_ACCEPTABLE = 406
+HTTP_407_PROXY_AUTHENTICATION_REQUIRED = 407
+HTTP_408_REQUEST_TIMEOUT = 408
+HTTP_409_CONFLICT = 409
+HTTP_410_GONE = 410
+HTTP_411_LENGTH_REQUIRED = 411
+HTTP_412_PRECONDITION_FAILED = 412
+HTTP_413_REQUEST_ENTITY_TOO_LARGE = 413
+HTTP_414_REQUEST_URI_TOO_LONG = 414
+HTTP_415_UNSUPPORTED_MEDIA_TYPE = 415
+HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE = 416
+HTTP_417_EXPECTATION_FAILED = 417
+HTTP_418_IM_A_TEAPOT = 418
+HTTP_421_MISDIRECTED_REQUEST = 421
+HTTP_422_UNPROCESSABLE_ENTITY = 422
+HTTP_423_LOCKED = 423
+HTTP_424_FAILED_DEPENDENCY = 424
+HTTP_425_TOO_EARLY = 425
+HTTP_426_UPGRADE_REQUIRED = 426
+HTTP_428_PRECONDITION_REQUIRED = 428
+HTTP_429_TOO_MANY_REQUESTS = 429
+HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE = 431
+HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS = 451
+HTTP_500_INTERNAL_SERVER_ERROR = 500
+HTTP_501_NOT_IMPLEMENTED = 501
+HTTP_502_BAD_GATEWAY = 502
+HTTP_503_SERVICE_UNAVAILABLE = 503
+HTTP_504_GATEWAY_TIMEOUT = 504
+HTTP_505_HTTP_VERSION_NOT_SUPPORTED = 505
+HTTP_506_VARIANT_ALSO_NEGOTIATES = 506
+HTTP_507_INSUFFICIENT_STORAGE = 507
+HTTP_508_LOOP_DETECTED = 508
+HTTP_510_NOT_EXTENDED = 510
+HTTP_511_NETWORK_AUTHENTICATION_REQUIRED = 511
+
+
+"""
+WebSocket codes
+https://www.iana.org/assignments/websocket/websocket.xml#close-code-number
+https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent
+"""
+WS_1000_NORMAL_CLOSURE = 1000
+WS_1001_GOING_AWAY = 1001
+WS_1002_PROTOCOL_ERROR = 1002
+WS_1003_UNSUPPORTED_DATA = 1003
+WS_1005_NO_STATUS_RCVD = 1005
+WS_1006_ABNORMAL_CLOSURE = 1006
+WS_1007_INVALID_FRAME_PAYLOAD_DATA = 1007
+WS_1008_POLICY_VIOLATION = 1008
+WS_1009_MESSAGE_TOO_BIG = 1009
+WS_1010_MANDATORY_EXT = 1010
+WS_1011_INTERNAL_ERROR = 1011
+WS_1012_SERVICE_RESTART = 1012
+WS_1013_TRY_AGAIN_LATER = 1013
+WS_1014_BAD_GATEWAY = 1014
+WS_1015_TLS_HANDSHAKE = 1015
diff --git a/venv/Lib/site-packages/starlette/templating.py b/venv/Lib/site-packages/starlette/templating.py
new file mode 100644
index 00000000..f764858b
--- /dev/null
+++ b/venv/Lib/site-packages/starlette/templating.py
@@ -0,0 +1,216 @@
+from __future__ import annotations
+
+import typing
+import warnings
+from os import PathLike
+
+from starlette.background import BackgroundTask
+from starlette.datastructures import URL
+from starlette.requests import Request
+from starlette.responses import HTMLResponse
+from starlette.types import Receive, Scope, Send
+
+try:
+ import jinja2
+
+ # @contextfunction was renamed to @pass_context in Jinja 3.0, and was removed in 3.1
+ # hence we try to get pass_context (most installs will be >=3.1)
+ # and fall back to contextfunction,
+ # adding a type ignore for mypy to let us access an attribute that may not exist
+ if hasattr(jinja2, "pass_context"):
+ pass_context = jinja2.pass_context
+ else: # pragma: no cover
+ pass_context = jinja2.contextfunction # type: ignore[attr-defined]
+except ModuleNotFoundError: # pragma: no cover
+ jinja2 = None # type: ignore[assignment]
+
+
+class _TemplateResponse(HTMLResponse):
+ def __init__(
+ self,
+ template: typing.Any,
+ context: dict[str, typing.Any],
+ status_code: int = 200,
+ headers: typing.Mapping[str, str] | None = None,
+ media_type: str | None = None,
+ background: BackgroundTask | None = None,
+ ):
+ self.template = template
+ self.context = context
+ content = template.render(context)
+ super().__init__(content, status_code, headers, media_type, background)
+
+ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
+ request = self.context.get("request", {})
+ extensions = request.get("extensions", {})
+ if "http.response.debug" in extensions: # pragma: no branch
+ await send(
+ {
+ "type": "http.response.debug",
+ "info": {
+ "template": self.template,
+ "context": self.context,
+ },
+ }
+ )
+ await super().__call__(scope, receive, send)
+
+
+class Jinja2Templates:
+ """
+ templates = Jinja2Templates("templates")
+
+ return templates.TemplateResponse("index.html", {"request": request})
+ """
+
+ @typing.overload
+ def __init__(
+ self,
+ directory: str | PathLike[str] | typing.Sequence[str | PathLike[str]],
+ *,
+ context_processors: list[typing.Callable[[Request], dict[str, typing.Any]]] | None = None,
+ **env_options: typing.Any,
+ ) -> None: ...
+
+ @typing.overload
+ def __init__(
+ self,
+ *,
+ env: jinja2.Environment,
+ context_processors: list[typing.Callable[[Request], dict[str, typing.Any]]] | None = None,
+ ) -> None: ...
+
+ def __init__(
+ self,
+ directory: str | PathLike[str] | typing.Sequence[str | PathLike[str]] | None = None,
+ *,
+ context_processors: list[typing.Callable[[Request], dict[str, typing.Any]]] | None = None,
+ env: jinja2.Environment | None = None,
+ **env_options: typing.Any,
+ ) -> None:
+ if env_options:
+ warnings.warn(
+ "Extra environment options are deprecated. Use a preconfigured jinja2.Environment instead.",
+ DeprecationWarning,
+ )
+ assert jinja2 is not None, "jinja2 must be installed to use Jinja2Templates"
+ assert bool(directory) ^ bool(env), "either 'directory' or 'env' arguments must be passed"
+ self.context_processors = context_processors or []
+ if directory is not None:
+ self.env = self._create_env(directory, **env_options)
+ elif env is not None: # pragma: no branch
+ self.env = env
+
+ self._setup_env_defaults(self.env)
+
+ def _create_env(
+ self,
+ directory: str | PathLike[str] | typing.Sequence[str | PathLike[str]],
+ **env_options: typing.Any,
+ ) -> jinja2.Environment:
+ loader = jinja2.FileSystemLoader(directory)
+ env_options.setdefault("loader", loader)
+ env_options.setdefault("autoescape", True)
+
+ return jinja2.Environment(**env_options)
+
+ def _setup_env_defaults(self, env: jinja2.Environment) -> None:
+ @pass_context
+ def url_for(
+ context: dict[str, typing.Any],
+ name: str,
+ /,
+ **path_params: typing.Any,
+ ) -> URL:
+ request: Request = context["request"]
+ return request.url_for(name, **path_params)
+
+ env.globals.setdefault("url_for", url_for)
+
+ def get_template(self, name: str) -> jinja2.Template:
+ return self.env.get_template(name)
+
+ @typing.overload
+ def TemplateResponse(
+ self,
+ request: Request,
+ name: str,
+ context: dict[str, typing.Any] | None = None,
+ status_code: int = 200,
+ headers: typing.Mapping[str, str] | None = None,
+ media_type: str | None = None,
+ background: BackgroundTask | None = None,
+ ) -> _TemplateResponse: ...
+
+ @typing.overload
+ def TemplateResponse(
+ self,
+ name: str,
+ context: dict[str, typing.Any] | None = None,
+ status_code: int = 200,
+ headers: typing.Mapping[str, str] | None = None,
+ media_type: str | None = None,
+ background: BackgroundTask | None = None,
+ ) -> _TemplateResponse:
+ # Deprecated usage
+ ...
+
+ def TemplateResponse(self, *args: typing.Any, **kwargs: typing.Any) -> _TemplateResponse:
+ if args:
+ if isinstance(args[0], str): # the first argument is template name (old style)
+ warnings.warn(
+ "The `name` is not the first parameter anymore. "
+ "The first parameter should be the `Request` instance.\n"
+ 'Replace `TemplateResponse(name, {"request": request})` by `TemplateResponse(request, name)`.',
+ DeprecationWarning,
+ )
+
+ name = args[0]
+ context = args[1] if len(args) > 1 else kwargs.get("context", {})
+ status_code = args[2] if len(args) > 2 else kwargs.get("status_code", 200)
+ headers = args[3] if len(args) > 3 else kwargs.get("headers")
+ media_type = args[4] if len(args) > 4 else kwargs.get("media_type")
+ background = args[5] if len(args) > 5 else kwargs.get("background")
+
+ if "request" not in context:
+ raise ValueError('context must include a "request" key')
+ request = context["request"]
+ else: # the first argument is a request instance (new style)
+ request = args[0]
+ name = args[1] if len(args) > 1 else kwargs["name"]
+ context = args[2] if len(args) > 2 else kwargs.get("context", {})
+ status_code = args[3] if len(args) > 3 else kwargs.get("status_code", 200)
+ headers = args[4] if len(args) > 4 else kwargs.get("headers")
+ media_type = args[5] if len(args) > 5 else kwargs.get("media_type")
+ background = args[6] if len(args) > 6 else kwargs.get("background")
+ else: # all arguments are kwargs
+ if "request" not in kwargs:
+ warnings.warn(
+ "The `TemplateResponse` now requires the `request` argument.\n"
+ 'Replace `TemplateResponse(name, {"context": context})` by `TemplateResponse(request, name)`.',
+ DeprecationWarning,
+ )
+ if "request" not in kwargs.get("context", {}):
+ raise ValueError('context must include a "request" key')
+
+ context = kwargs.get("context", {})
+ request = kwargs.get("request", context.get("request"))
+ name = typing.cast(str, kwargs["name"])
+ status_code = kwargs.get("status_code", 200)
+ headers = kwargs.get("headers")
+ media_type = kwargs.get("media_type")
+ background = kwargs.get("background")
+
+ context.setdefault("request", request)
+ for context_processor in self.context_processors:
+ context.update(context_processor(request))
+
+ template = self.get_template(name)
+ return _TemplateResponse(
+ template,
+ context,
+ status_code=status_code,
+ headers=headers,
+ media_type=media_type,
+ background=background,
+ )
diff --git a/venv/Lib/site-packages/starlette/testclient.py b/venv/Lib/site-packages/starlette/testclient.py
new file mode 100644
index 00000000..d54025e5
--- /dev/null
+++ b/venv/Lib/site-packages/starlette/testclient.py
@@ -0,0 +1,731 @@
+from __future__ import annotations
+
+import contextlib
+import inspect
+import io
+import json
+import math
+import sys
+import typing
+import warnings
+from concurrent.futures import Future
+from types import GeneratorType
+from urllib.parse import unquote, urljoin
+
+import anyio
+import anyio.abc
+import anyio.from_thread
+from anyio.streams.stapled import StapledObjectStream
+
+from starlette._utils import is_async_callable
+from starlette.types import ASGIApp, Message, Receive, Scope, Send
+from starlette.websockets import WebSocketDisconnect
+
+if sys.version_info >= (3, 10): # pragma: no cover
+ from typing import TypeGuard
+else: # pragma: no cover
+ from typing_extensions import TypeGuard
+
+try:
+ import httpx
+except ModuleNotFoundError: # pragma: no cover
+ raise RuntimeError(
+ "The starlette.testclient module requires the httpx package to be installed.\n"
+ "You can install this with:\n"
+ " $ pip install httpx\n"
+ )
+_PortalFactoryType = typing.Callable[[], typing.ContextManager[anyio.abc.BlockingPortal]]
+
+ASGIInstance = typing.Callable[[Receive, Send], typing.Awaitable[None]]
+ASGI2App = typing.Callable[[Scope], ASGIInstance]
+ASGI3App = typing.Callable[[Scope, Receive, Send], typing.Awaitable[None]]
+
+
+_RequestData = typing.Mapping[str, typing.Union[str, typing.Iterable[str], bytes]]
+
+
+def _is_asgi3(app: ASGI2App | ASGI3App) -> TypeGuard[ASGI3App]:
+ if inspect.isclass(app):
+ return hasattr(app, "__await__")
+ return is_async_callable(app)
+
+
+class _WrapASGI2:
+ """
+ Provide an ASGI3 interface onto an ASGI2 app.
+ """
+
+ def __init__(self, app: ASGI2App) -> None:
+ self.app = app
+
+ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
+ instance = self.app(scope)
+ await instance(receive, send)
+
+
+class _AsyncBackend(typing.TypedDict):
+ backend: str
+ backend_options: dict[str, typing.Any]
+
+
+class _Upgrade(Exception):
+ def __init__(self, session: WebSocketTestSession) -> None:
+ self.session = session
+
+
+class WebSocketDenialResponse( # type: ignore[misc]
+ httpx.Response,
+ WebSocketDisconnect,
+):
+ """
+ A special case of `WebSocketDisconnect`, raised in the `TestClient` if the
+ `WebSocket` is closed before being accepted with a `send_denial_response()`.
+ """
+
+
+class WebSocketTestSession:
+ def __init__(
+ self,
+ app: ASGI3App,
+ scope: Scope,
+ portal_factory: _PortalFactoryType,
+ ) -> None:
+ self.app = app
+ self.scope = scope
+ self.accepted_subprotocol = None
+ self.portal_factory = portal_factory
+ self.extra_headers = None
+
+ def __enter__(self) -> WebSocketTestSession:
+ with contextlib.ExitStack() as stack:
+ self.portal = portal = stack.enter_context(self.portal_factory())
+ fut, cs = portal.start_task(self._run)
+ stack.callback(fut.result)
+ stack.callback(portal.call, cs.cancel)
+ self.send({"type": "websocket.connect"})
+ message = self.receive()
+ self._raise_on_close(message)
+ self.accepted_subprotocol = message.get("subprotocol", None)
+ self.extra_headers = message.get("headers", None)
+ stack.callback(self.close, 1000)
+ self.exit_stack = stack.pop_all()
+ return self
+
+ def __exit__(self, *args: typing.Any) -> bool | None:
+ return self.exit_stack.__exit__(*args)
+
+ async def _run(self, *, task_status: anyio.abc.TaskStatus[anyio.CancelScope]) -> None:
+ """
+ The sub-thread in which the websocket session runs.
+ """
+ send: anyio.create_memory_object_stream[Message] = anyio.create_memory_object_stream(math.inf)
+ send_tx, send_rx = send
+ receive: anyio.create_memory_object_stream[Message] = anyio.create_memory_object_stream(math.inf)
+ receive_tx, receive_rx = receive
+ with send_tx, send_rx, receive_tx, receive_rx, anyio.CancelScope() as cs:
+ self._receive_tx = receive_tx
+ self._send_rx = send_rx
+ task_status.started(cs)
+ await self.app(self.scope, receive_rx.receive, send_tx.send)
+
+ # wait for cs.cancel to be called before closing streams
+ await anyio.sleep_forever()
+
+ def _raise_on_close(self, message: Message) -> None:
+ if message["type"] == "websocket.close":
+ raise WebSocketDisconnect(code=message.get("code", 1000), reason=message.get("reason", ""))
+ elif message["type"] == "websocket.http.response.start":
+ status_code: int = message["status"]
+ headers: list[tuple[bytes, bytes]] = message["headers"]
+ body: list[bytes] = []
+ while True:
+ message = self.receive()
+ assert message["type"] == "websocket.http.response.body"
+ body.append(message["body"])
+ if not message.get("more_body", False):
+ break
+ raise WebSocketDenialResponse(status_code=status_code, headers=headers, content=b"".join(body))
+
+ def send(self, message: Message) -> None:
+ self.portal.call(self._receive_tx.send, message)
+
+ def send_text(self, data: str) -> None:
+ self.send({"type": "websocket.receive", "text": data})
+
+ def send_bytes(self, data: bytes) -> None:
+ self.send({"type": "websocket.receive", "bytes": data})
+
+ def send_json(self, data: typing.Any, mode: typing.Literal["text", "binary"] = "text") -> None:
+ text = json.dumps(data, separators=(",", ":"), ensure_ascii=False)
+ if mode == "text":
+ self.send({"type": "websocket.receive", "text": text})
+ else:
+ self.send({"type": "websocket.receive", "bytes": text.encode("utf-8")})
+
+ def close(self, code: int = 1000, reason: str | None = None) -> None:
+ self.send({"type": "websocket.disconnect", "code": code, "reason": reason})
+
+ def receive(self) -> Message:
+ return self.portal.call(self._send_rx.receive)
+
+ def receive_text(self) -> str:
+ message = self.receive()
+ self._raise_on_close(message)
+ return typing.cast(str, message["text"])
+
+ def receive_bytes(self) -> bytes:
+ message = self.receive()
+ self._raise_on_close(message)
+ return typing.cast(bytes, message["bytes"])
+
+ def receive_json(self, mode: typing.Literal["text", "binary"] = "text") -> typing.Any:
+ message = self.receive()
+ self._raise_on_close(message)
+ if mode == "text":
+ text = message["text"]
+ else:
+ text = message["bytes"].decode("utf-8")
+ return json.loads(text)
+
+
+class _TestClientTransport(httpx.BaseTransport):
+ def __init__(
+ self,
+ app: ASGI3App,
+ portal_factory: _PortalFactoryType,
+ raise_server_exceptions: bool = True,
+ root_path: str = "",
+ *,
+ client: tuple[str, int],
+ app_state: dict[str, typing.Any],
+ ) -> None:
+ self.app = app
+ self.raise_server_exceptions = raise_server_exceptions
+ self.root_path = root_path
+ self.portal_factory = portal_factory
+ self.app_state = app_state
+ self.client = client
+
+ def handle_request(self, request: httpx.Request) -> httpx.Response:
+ scheme = request.url.scheme
+ netloc = request.url.netloc.decode(encoding="ascii")
+ path = request.url.path
+ raw_path = request.url.raw_path
+ query = request.url.query.decode(encoding="ascii")
+
+ default_port = {"http": 80, "ws": 80, "https": 443, "wss": 443}[scheme]
+
+ if ":" in netloc:
+ host, port_string = netloc.split(":", 1)
+ port = int(port_string)
+ else:
+ host = netloc
+ port = default_port
+
+ # Include the 'host' header.
+ if "host" in request.headers:
+ headers: list[tuple[bytes, bytes]] = []
+ elif port == default_port: # pragma: no cover
+ headers = [(b"host", host.encode())]
+ else: # pragma: no cover
+ headers = [(b"host", (f"{host}:{port}").encode())]
+
+ # Include other request headers.
+ headers += [(key.lower().encode(), value.encode()) for key, value in request.headers.multi_items()]
+
+ scope: dict[str, typing.Any]
+
+ if scheme in {"ws", "wss"}:
+ subprotocol = request.headers.get("sec-websocket-protocol", None)
+ if subprotocol is None:
+ subprotocols: typing.Sequence[str] = []
+ else:
+ subprotocols = [value.strip() for value in subprotocol.split(",")]
+ scope = {
+ "type": "websocket",
+ "path": unquote(path),
+ "raw_path": raw_path.split(b"?", 1)[0],
+ "root_path": self.root_path,
+ "scheme": scheme,
+ "query_string": query.encode(),
+ "headers": headers,
+ "client": self.client,
+ "server": [host, port],
+ "subprotocols": subprotocols,
+ "state": self.app_state.copy(),
+ "extensions": {"websocket.http.response": {}},
+ }
+ session = WebSocketTestSession(self.app, scope, self.portal_factory)
+ raise _Upgrade(session)
+
+ scope = {
+ "type": "http",
+ "http_version": "1.1",
+ "method": request.method,
+ "path": unquote(path),
+ "raw_path": raw_path.split(b"?", 1)[0],
+ "root_path": self.root_path,
+ "scheme": scheme,
+ "query_string": query.encode(),
+ "headers": headers,
+ "client": self.client,
+ "server": [host, port],
+ "extensions": {"http.response.debug": {}},
+ "state": self.app_state.copy(),
+ }
+
+ request_complete = False
+ response_started = False
+ response_complete: anyio.Event
+ raw_kwargs: dict[str, typing.Any] = {"stream": io.BytesIO()}
+ template = None
+ context = None
+
+ async def receive() -> Message:
+ nonlocal request_complete
+
+ if request_complete:
+ if not response_complete.is_set():
+ await response_complete.wait()
+ return {"type": "http.disconnect"}
+
+ body = request.read()
+ if isinstance(body, str):
+ body_bytes: bytes = body.encode("utf-8") # pragma: no cover
+ elif body is None:
+ body_bytes = b"" # pragma: no cover
+ elif isinstance(body, GeneratorType):
+ try: # pragma: no cover
+ chunk = body.send(None)
+ if isinstance(chunk, str):
+ chunk = chunk.encode("utf-8")
+ return {"type": "http.request", "body": chunk, "more_body": True}
+ except StopIteration: # pragma: no cover
+ request_complete = True
+ return {"type": "http.request", "body": b""}
+ else:
+ body_bytes = body
+
+ request_complete = True
+ return {"type": "http.request", "body": body_bytes}
+
+ async def send(message: Message) -> None:
+ nonlocal raw_kwargs, response_started, template, context
+
+ if message["type"] == "http.response.start":
+ assert not response_started, 'Received multiple "http.response.start" messages.'
+ raw_kwargs["status_code"] = message["status"]
+ raw_kwargs["headers"] = [(key.decode(), value.decode()) for key, value in message.get("headers", [])]
+ response_started = True
+ elif message["type"] == "http.response.body":
+ assert response_started, 'Received "http.response.body" without "http.response.start".'
+ assert not response_complete.is_set(), 'Received "http.response.body" after response completed.'
+ body = message.get("body", b"")
+ more_body = message.get("more_body", False)
+ if request.method != "HEAD":
+ raw_kwargs["stream"].write(body)
+ if not more_body:
+ raw_kwargs["stream"].seek(0)
+ response_complete.set()
+ elif message["type"] == "http.response.debug":
+ template = message["info"]["template"]
+ context = message["info"]["context"]
+
+ try:
+ with self.portal_factory() as portal:
+ response_complete = portal.call(anyio.Event)
+ portal.call(self.app, scope, receive, send)
+ except BaseException as exc:
+ if self.raise_server_exceptions:
+ raise exc
+
+ if self.raise_server_exceptions:
+ assert response_started, "TestClient did not receive any response."
+ elif not response_started:
+ raw_kwargs = {
+ "status_code": 500,
+ "headers": [],
+ "stream": io.BytesIO(),
+ }
+
+ raw_kwargs["stream"] = httpx.ByteStream(raw_kwargs["stream"].read())
+
+ response = httpx.Response(**raw_kwargs, request=request)
+ if template is not None:
+ response.template = template # type: ignore[attr-defined]
+ response.context = context # type: ignore[attr-defined]
+ return response
+
+
+class TestClient(httpx.Client):
+ __test__ = False
+ task: Future[None]
+ portal: anyio.abc.BlockingPortal | None = None
+
+ def __init__(
+ self,
+ app: ASGIApp,
+ base_url: str = "http://testserver",
+ raise_server_exceptions: bool = True,
+ root_path: str = "",
+ backend: typing.Literal["asyncio", "trio"] = "asyncio",
+ backend_options: dict[str, typing.Any] | None = None,
+ cookies: httpx._types.CookieTypes | None = None,
+ headers: dict[str, str] | None = None,
+ follow_redirects: bool = True,
+ client: tuple[str, int] = ("testclient", 50000),
+ ) -> None:
+ self.async_backend = _AsyncBackend(backend=backend, backend_options=backend_options or {})
+ if _is_asgi3(app):
+ asgi_app = app
+ else:
+ app = typing.cast(ASGI2App, app) # type: ignore[assignment]
+ asgi_app = _WrapASGI2(app) # type: ignore[arg-type]
+ self.app = asgi_app
+ self.app_state: dict[str, typing.Any] = {}
+ transport = _TestClientTransport(
+ self.app,
+ portal_factory=self._portal_factory,
+ raise_server_exceptions=raise_server_exceptions,
+ root_path=root_path,
+ app_state=self.app_state,
+ client=client,
+ )
+ if headers is None:
+ headers = {}
+ headers.setdefault("user-agent", "testclient")
+ super().__init__(
+ base_url=base_url,
+ headers=headers,
+ transport=transport,
+ follow_redirects=follow_redirects,
+ cookies=cookies,
+ )
+
+ @contextlib.contextmanager
+ def _portal_factory(self) -> typing.Generator[anyio.abc.BlockingPortal, None, None]:
+ if self.portal is not None:
+ yield self.portal
+ else:
+ with anyio.from_thread.start_blocking_portal(**self.async_backend) as portal:
+ yield portal
+
+ def request( # type: ignore[override]
+ self,
+ method: str,
+ url: httpx._types.URLTypes,
+ *,
+ content: httpx._types.RequestContent | None = None,
+ data: _RequestData | None = None,
+ files: httpx._types.RequestFiles | None = None,
+ json: typing.Any = None,
+ params: httpx._types.QueryParamTypes | None = None,
+ headers: httpx._types.HeaderTypes | None = None,
+ cookies: httpx._types.CookieTypes | None = None,
+ auth: httpx._types.AuthTypes | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT,
+ follow_redirects: bool | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT,
+ timeout: httpx._types.TimeoutTypes | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT,
+ extensions: dict[str, typing.Any] | None = None,
+ ) -> httpx.Response:
+ if timeout is not httpx.USE_CLIENT_DEFAULT:
+ warnings.warn(
+ "You should not use the 'timeout' argument with the TestClient. "
+ "See https://github.com/encode/starlette/issues/1108 for more information.",
+ DeprecationWarning,
+ )
+ url = self._merge_url(url)
+ return super().request(
+ method,
+ url,
+ content=content,
+ data=data,
+ files=files,
+ json=json,
+ params=params,
+ headers=headers,
+ cookies=cookies,
+ auth=auth,
+ follow_redirects=follow_redirects,
+ timeout=timeout,
+ extensions=extensions,
+ )
+
+ def get( # type: ignore[override]
+ self,
+ url: httpx._types.URLTypes,
+ *,
+ params: httpx._types.QueryParamTypes | None = None,
+ headers: httpx._types.HeaderTypes | None = None,
+ cookies: httpx._types.CookieTypes | None = None,
+ auth: httpx._types.AuthTypes | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT,
+ follow_redirects: bool | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT,
+ timeout: httpx._types.TimeoutTypes | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT,
+ extensions: dict[str, typing.Any] | None = None,
+ ) -> httpx.Response:
+ return super().get(
+ url,
+ params=params,
+ headers=headers,
+ cookies=cookies,
+ auth=auth,
+ follow_redirects=follow_redirects,
+ timeout=timeout,
+ extensions=extensions,
+ )
+
+ def options( # type: ignore[override]
+ self,
+ url: httpx._types.URLTypes,
+ *,
+ params: httpx._types.QueryParamTypes | None = None,
+ headers: httpx._types.HeaderTypes | None = None,
+ cookies: httpx._types.CookieTypes | None = None,
+ auth: httpx._types.AuthTypes | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT,
+ follow_redirects: bool | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT,
+ timeout: httpx._types.TimeoutTypes | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT,
+ extensions: dict[str, typing.Any] | None = None,
+ ) -> httpx.Response:
+ return super().options(
+ url,
+ params=params,
+ headers=headers,
+ cookies=cookies,
+ auth=auth,
+ follow_redirects=follow_redirects,
+ timeout=timeout,
+ extensions=extensions,
+ )
+
+ def head( # type: ignore[override]
+ self,
+ url: httpx._types.URLTypes,
+ *,
+ params: httpx._types.QueryParamTypes | None = None,
+ headers: httpx._types.HeaderTypes | None = None,
+ cookies: httpx._types.CookieTypes | None = None,
+ auth: httpx._types.AuthTypes | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT,
+ follow_redirects: bool | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT,
+ timeout: httpx._types.TimeoutTypes | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT,
+ extensions: dict[str, typing.Any] | None = None,
+ ) -> httpx.Response:
+ return super().head(
+ url,
+ params=params,
+ headers=headers,
+ cookies=cookies,
+ auth=auth,
+ follow_redirects=follow_redirects,
+ timeout=timeout,
+ extensions=extensions,
+ )
+
+ def post( # type: ignore[override]
+ self,
+ url: httpx._types.URLTypes,
+ *,
+ content: httpx._types.RequestContent | None = None,
+ data: _RequestData | None = None,
+ files: httpx._types.RequestFiles | None = None,
+ json: typing.Any = None,
+ params: httpx._types.QueryParamTypes | None = None,
+ headers: httpx._types.HeaderTypes | None = None,
+ cookies: httpx._types.CookieTypes | None = None,
+ auth: httpx._types.AuthTypes | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT,
+ follow_redirects: bool | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT,
+ timeout: httpx._types.TimeoutTypes | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT,
+ extensions: dict[str, typing.Any] | None = None,
+ ) -> httpx.Response:
+ return super().post(
+ url,
+ content=content,
+ data=data,
+ files=files,
+ json=json,
+ params=params,
+ headers=headers,
+ cookies=cookies,
+ auth=auth,
+ follow_redirects=follow_redirects,
+ timeout=timeout,
+ extensions=extensions,
+ )
+
+ def put( # type: ignore[override]
+ self,
+ url: httpx._types.URLTypes,
+ *,
+ content: httpx._types.RequestContent | None = None,
+ data: _RequestData | None = None,
+ files: httpx._types.RequestFiles | None = None,
+ json: typing.Any = None,
+ params: httpx._types.QueryParamTypes | None = None,
+ headers: httpx._types.HeaderTypes | None = None,
+ cookies: httpx._types.CookieTypes | None = None,
+ auth: httpx._types.AuthTypes | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT,
+ follow_redirects: bool | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT,
+ timeout: httpx._types.TimeoutTypes | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT,
+ extensions: dict[str, typing.Any] | None = None,
+ ) -> httpx.Response:
+ return super().put(
+ url,
+ content=content,
+ data=data,
+ files=files,
+ json=json,
+ params=params,
+ headers=headers,
+ cookies=cookies,
+ auth=auth,
+ follow_redirects=follow_redirects,
+ timeout=timeout,
+ extensions=extensions,
+ )
+
+ def patch( # type: ignore[override]
+ self,
+ url: httpx._types.URLTypes,
+ *,
+ content: httpx._types.RequestContent | None = None,
+ data: _RequestData | None = None,
+ files: httpx._types.RequestFiles | None = None,
+ json: typing.Any = None,
+ params: httpx._types.QueryParamTypes | None = None,
+ headers: httpx._types.HeaderTypes | None = None,
+ cookies: httpx._types.CookieTypes | None = None,
+ auth: httpx._types.AuthTypes | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT,
+ follow_redirects: bool | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT,
+ timeout: httpx._types.TimeoutTypes | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT,
+ extensions: dict[str, typing.Any] | None = None,
+ ) -> httpx.Response:
+ return super().patch(
+ url,
+ content=content,
+ data=data,
+ files=files,
+ json=json,
+ params=params,
+ headers=headers,
+ cookies=cookies,
+ auth=auth,
+ follow_redirects=follow_redirects,
+ timeout=timeout,
+ extensions=extensions,
+ )
+
+ def delete( # type: ignore[override]
+ self,
+ url: httpx._types.URLTypes,
+ *,
+ params: httpx._types.QueryParamTypes | None = None,
+ headers: httpx._types.HeaderTypes | None = None,
+ cookies: httpx._types.CookieTypes | None = None,
+ auth: httpx._types.AuthTypes | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT,
+ follow_redirects: bool | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT,
+ timeout: httpx._types.TimeoutTypes | httpx._client.UseClientDefault = httpx._client.USE_CLIENT_DEFAULT,
+ extensions: dict[str, typing.Any] | None = None,
+ ) -> httpx.Response:
+ return super().delete(
+ url,
+ params=params,
+ headers=headers,
+ cookies=cookies,
+ auth=auth,
+ follow_redirects=follow_redirects,
+ timeout=timeout,
+ extensions=extensions,
+ )
+
+ def websocket_connect(
+ self,
+ url: str,
+ subprotocols: typing.Sequence[str] | None = None,
+ **kwargs: typing.Any,
+ ) -> WebSocketTestSession:
+ url = urljoin("ws://testserver", url)
+ headers = kwargs.get("headers", {})
+ headers.setdefault("connection", "upgrade")
+ headers.setdefault("sec-websocket-key", "testserver==")
+ headers.setdefault("sec-websocket-version", "13")
+ if subprotocols is not None:
+ headers.setdefault("sec-websocket-protocol", ", ".join(subprotocols))
+ kwargs["headers"] = headers
+ try:
+ super().request("GET", url, **kwargs)
+ except _Upgrade as exc:
+ session = exc.session
+ else:
+ raise RuntimeError("Expected WebSocket upgrade") # pragma: no cover
+
+ return session
+
+ def __enter__(self) -> TestClient:
+ with contextlib.ExitStack() as stack:
+ self.portal = portal = stack.enter_context(anyio.from_thread.start_blocking_portal(**self.async_backend))
+
+ @stack.callback
+ def reset_portal() -> None:
+ self.portal = None
+
+ send: anyio.create_memory_object_stream[typing.MutableMapping[str, typing.Any] | None] = (
+ anyio.create_memory_object_stream(math.inf)
+ )
+ receive: anyio.create_memory_object_stream[typing.MutableMapping[str, typing.Any]] = (
+ anyio.create_memory_object_stream(math.inf)
+ )
+ for channel in (*send, *receive):
+ stack.callback(channel.close)
+ self.stream_send = StapledObjectStream(*send)
+ self.stream_receive = StapledObjectStream(*receive)
+ self.task = portal.start_task_soon(self.lifespan)
+ portal.call(self.wait_startup)
+
+ @stack.callback
+ def wait_shutdown() -> None:
+ portal.call(self.wait_shutdown)
+
+ self.exit_stack = stack.pop_all()
+
+ return self
+
+ def __exit__(self, *args: typing.Any) -> None:
+ self.exit_stack.close()
+
+ async def lifespan(self) -> None:
+ scope = {"type": "lifespan", "state": self.app_state}
+ try:
+ await self.app(scope, self.stream_receive.receive, self.stream_send.send)
+ finally:
+ await self.stream_send.send(None)
+
+ async def wait_startup(self) -> None:
+ await self.stream_receive.send({"type": "lifespan.startup"})
+
+ async def receive() -> typing.Any:
+ message = await self.stream_send.receive()
+ if message is None:
+ self.task.result()
+ return message
+
+ message = await receive()
+ assert message["type"] in (
+ "lifespan.startup.complete",
+ "lifespan.startup.failed",
+ )
+ if message["type"] == "lifespan.startup.failed":
+ await receive()
+
+ async def wait_shutdown(self) -> None:
+ async def receive() -> typing.Any:
+ message = await self.stream_send.receive()
+ if message is None:
+ self.task.result()
+ return message
+
+ await self.stream_receive.send({"type": "lifespan.shutdown"})
+ message = await receive()
+ assert message["type"] in (
+ "lifespan.shutdown.complete",
+ "lifespan.shutdown.failed",
+ )
+ if message["type"] == "lifespan.shutdown.failed":
+ await receive()
diff --git a/venv/Lib/site-packages/starlette/types.py b/venv/Lib/site-packages/starlette/types.py
new file mode 100644
index 00000000..893f8729
--- /dev/null
+++ b/venv/Lib/site-packages/starlette/types.py
@@ -0,0 +1,24 @@
+import typing
+
+if typing.TYPE_CHECKING:
+ from starlette.requests import Request
+ from starlette.responses import Response
+ from starlette.websockets import WebSocket
+
+AppType = typing.TypeVar("AppType")
+
+Scope = typing.MutableMapping[str, typing.Any]
+Message = typing.MutableMapping[str, typing.Any]
+
+Receive = typing.Callable[[], typing.Awaitable[Message]]
+Send = typing.Callable[[Message], typing.Awaitable[None]]
+
+ASGIApp = typing.Callable[[Scope, Receive, Send], typing.Awaitable[None]]
+
+StatelessLifespan = typing.Callable[[AppType], typing.AsyncContextManager[None]]
+StatefulLifespan = typing.Callable[[AppType], typing.AsyncContextManager[typing.Mapping[str, typing.Any]]]
+Lifespan = typing.Union[StatelessLifespan[AppType], StatefulLifespan[AppType]]
+
+HTTPExceptionHandler = typing.Callable[["Request", Exception], "Response | typing.Awaitable[Response]"]
+WebSocketExceptionHandler = typing.Callable[["WebSocket", Exception], typing.Awaitable[None]]
+ExceptionHandler = typing.Union[HTTPExceptionHandler, WebSocketExceptionHandler]
diff --git a/venv/Lib/site-packages/starlette/websockets.py b/venv/Lib/site-packages/starlette/websockets.py
new file mode 100644
index 00000000..6b46f4ea
--- /dev/null
+++ b/venv/Lib/site-packages/starlette/websockets.py
@@ -0,0 +1,195 @@
+from __future__ import annotations
+
+import enum
+import json
+import typing
+
+from starlette.requests import HTTPConnection
+from starlette.responses import Response
+from starlette.types import Message, Receive, Scope, Send
+
+
+class WebSocketState(enum.Enum):
+ CONNECTING = 0
+ CONNECTED = 1
+ DISCONNECTED = 2
+ RESPONSE = 3
+
+
+class WebSocketDisconnect(Exception):
+ def __init__(self, code: int = 1000, reason: str | None = None) -> None:
+ self.code = code
+ self.reason = reason or ""
+
+
+class WebSocket(HTTPConnection):
+ def __init__(self, scope: Scope, receive: Receive, send: Send) -> None:
+ super().__init__(scope)
+ assert scope["type"] == "websocket"
+ self._receive = receive
+ self._send = send
+ self.client_state = WebSocketState.CONNECTING
+ self.application_state = WebSocketState.CONNECTING
+
+ async def receive(self) -> Message:
+ """
+ Receive ASGI websocket messages, ensuring valid state transitions.
+ """
+ if self.client_state == WebSocketState.CONNECTING:
+ message = await self._receive()
+ message_type = message["type"]
+ if message_type != "websocket.connect":
+ raise RuntimeError(f'Expected ASGI message "websocket.connect", but got {message_type!r}')
+ self.client_state = WebSocketState.CONNECTED
+ return message
+ elif self.client_state == WebSocketState.CONNECTED:
+ message = await self._receive()
+ message_type = message["type"]
+ if message_type not in {"websocket.receive", "websocket.disconnect"}:
+ raise RuntimeError(
+ f'Expected ASGI message "websocket.receive" or "websocket.disconnect", but got {message_type!r}'
+ )
+ if message_type == "websocket.disconnect":
+ self.client_state = WebSocketState.DISCONNECTED
+ return message
+ else:
+ raise RuntimeError('Cannot call "receive" once a disconnect message has been received.')
+
+ async def send(self, message: Message) -> None:
+ """
+ Send ASGI websocket messages, ensuring valid state transitions.
+ """
+ if self.application_state == WebSocketState.CONNECTING:
+ message_type = message["type"]
+ if message_type not in {"websocket.accept", "websocket.close", "websocket.http.response.start"}:
+ raise RuntimeError(
+ 'Expected ASGI message "websocket.accept", "websocket.close" or "websocket.http.response.start", '
+ f"but got {message_type!r}"
+ )
+ if message_type == "websocket.close":
+ self.application_state = WebSocketState.DISCONNECTED
+ elif message_type == "websocket.http.response.start":
+ self.application_state = WebSocketState.RESPONSE
+ else:
+ self.application_state = WebSocketState.CONNECTED
+ await self._send(message)
+ elif self.application_state == WebSocketState.CONNECTED:
+ message_type = message["type"]
+ if message_type not in {"websocket.send", "websocket.close"}:
+ raise RuntimeError(
+ f'Expected ASGI message "websocket.send" or "websocket.close", but got {message_type!r}'
+ )
+ if message_type == "websocket.close":
+ self.application_state = WebSocketState.DISCONNECTED
+ try:
+ await self._send(message)
+ except OSError:
+ self.application_state = WebSocketState.DISCONNECTED
+ raise WebSocketDisconnect(code=1006)
+ elif self.application_state == WebSocketState.RESPONSE:
+ message_type = message["type"]
+ if message_type != "websocket.http.response.body":
+ raise RuntimeError(f'Expected ASGI message "websocket.http.response.body", but got {message_type!r}')
+ if not message.get("more_body", False):
+ self.application_state = WebSocketState.DISCONNECTED
+ await self._send(message)
+ else:
+ raise RuntimeError('Cannot call "send" once a close message has been sent.')
+
+ async def accept(
+ self,
+ subprotocol: str | None = None,
+ headers: typing.Iterable[tuple[bytes, bytes]] | None = None,
+ ) -> None:
+ headers = headers or []
+
+ if self.client_state == WebSocketState.CONNECTING: # pragma: no branch
+ # If we haven't yet seen the 'connect' message, then wait for it first.
+ await self.receive()
+ await self.send({"type": "websocket.accept", "subprotocol": subprotocol, "headers": headers})
+
+ def _raise_on_disconnect(self, message: Message) -> None:
+ if message["type"] == "websocket.disconnect":
+ raise WebSocketDisconnect(message["code"], message.get("reason"))
+
+ async def receive_text(self) -> str:
+ if self.application_state != WebSocketState.CONNECTED:
+ raise RuntimeError('WebSocket is not connected. Need to call "accept" first.')
+ message = await self.receive()
+ self._raise_on_disconnect(message)
+ return typing.cast(str, message["text"])
+
+ async def receive_bytes(self) -> bytes:
+ if self.application_state != WebSocketState.CONNECTED:
+ raise RuntimeError('WebSocket is not connected. Need to call "accept" first.')
+ message = await self.receive()
+ self._raise_on_disconnect(message)
+ return typing.cast(bytes, message["bytes"])
+
+ async def receive_json(self, mode: str = "text") -> typing.Any:
+ if mode not in {"text", "binary"}:
+ raise RuntimeError('The "mode" argument should be "text" or "binary".')
+ if self.application_state != WebSocketState.CONNECTED:
+ raise RuntimeError('WebSocket is not connected. Need to call "accept" first.')
+ message = await self.receive()
+ self._raise_on_disconnect(message)
+
+ if mode == "text":
+ text = message["text"]
+ else:
+ text = message["bytes"].decode("utf-8")
+ return json.loads(text)
+
+ async def iter_text(self) -> typing.AsyncIterator[str]:
+ try:
+ while True:
+ yield await self.receive_text()
+ except WebSocketDisconnect:
+ pass
+
+ async def iter_bytes(self) -> typing.AsyncIterator[bytes]:
+ try:
+ while True:
+ yield await self.receive_bytes()
+ except WebSocketDisconnect:
+ pass
+
+ async def iter_json(self) -> typing.AsyncIterator[typing.Any]:
+ try:
+ while True:
+ yield await self.receive_json()
+ except WebSocketDisconnect:
+ pass
+
+ async def send_text(self, data: str) -> None:
+ await self.send({"type": "websocket.send", "text": data})
+
+ async def send_bytes(self, data: bytes) -> None:
+ await self.send({"type": "websocket.send", "bytes": data})
+
+ async def send_json(self, data: typing.Any, mode: str = "text") -> None:
+ if mode not in {"text", "binary"}:
+ raise RuntimeError('The "mode" argument should be "text" or "binary".')
+ text = json.dumps(data, separators=(",", ":"), ensure_ascii=False)
+ if mode == "text":
+ await self.send({"type": "websocket.send", "text": text})
+ else:
+ await self.send({"type": "websocket.send", "bytes": text.encode("utf-8")})
+
+ async def close(self, code: int = 1000, reason: str | None = None) -> None:
+ await self.send({"type": "websocket.close", "code": code, "reason": reason or ""})
+
+ async def send_denial_response(self, response: Response) -> None:
+ if "websocket.http.response" in self.scope.get("extensions", {}):
+ await response(self.scope, self.receive, self.send)
+ else:
+ raise RuntimeError("The server doesn't support the Websocket Denial Response extension.")
+
+
+class WebSocketClose:
+ def __init__(self, code: int = 1000, reason: str | None = None) -> None:
+ self.code = code
+ self.reason = reason or ""
+
+ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
+ await send({"type": "websocket.close", "code": self.code, "reason": self.reason})
diff --git a/venv/Lib/site-packages/twilio-9.6.3.dist-info/INSTALLER b/venv/Lib/site-packages/twilio-9.6.3.dist-info/INSTALLER
new file mode 100644
index 00000000..a1b589e3
--- /dev/null
+++ b/venv/Lib/site-packages/twilio-9.6.3.dist-info/INSTALLER
@@ -0,0 +1 @@
+pip
diff --git a/venv/Lib/site-packages/twilio-9.6.3.dist-info/METADATA b/venv/Lib/site-packages/twilio-9.6.3.dist-info/METADATA
new file mode 100644
index 00000000..268ccefc
--- /dev/null
+++ b/venv/Lib/site-packages/twilio-9.6.3.dist-info/METADATA
@@ -0,0 +1,362 @@
+Metadata-Version: 2.4
+Name: twilio
+Version: 9.6.3
+Summary: Twilio API client and TwiML generator
+Home-page: https://github.com/twilio/twilio-python/
+Author: Twilio
+License: MIT
+Keywords: twilio,twiml
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: 3.9
+Classifier: Programming Language :: Python :: 3.10
+Classifier: Programming Language :: Python :: 3.11
+Classifier: Programming Language :: Python :: Implementation :: CPython
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Classifier: Topic :: Communications :: Telephony
+Requires-Python: >=3.7.0
+Description-Content-Type: text/markdown
+License-File: LICENSE
+License-File: AUTHORS.md
+Requires-Dist: requests>=2.0.0
+Requires-Dist: PyJWT<3.0.0,>=2.0.0
+Requires-Dist: aiohttp>=3.8.4
+Requires-Dist: aiohttp-retry>=2.8.3
+Dynamic: author
+Dynamic: classifier
+Dynamic: description
+Dynamic: description-content-type
+Dynamic: home-page
+Dynamic: keywords
+Dynamic: license-file
+Dynamic: requires-dist
+Dynamic: requires-python
+Dynamic: summary
+
+# twilio-python
+
+[](https://github.com/twilio/twilio-python/actions/workflows/test-and-deploy.yml)
+[](https://pypi.python.org/pypi/twilio)
+[](https://pypi.python.org/pypi/twilio)
+[](https://twil.io/learn-open-source)
+
+## Documentation
+
+The documentation for the Twilio API can be found [here][apidocs].
+
+The Python library documentation can be found [here][libdocs].
+
+## Versions
+
+`twilio-python` uses a modified version of [Semantic Versioning](https://semver.org) for all changes. [See this document](VERSIONS.md) for details.
+
+### Supported Python Versions
+
+This library supports the following Python implementations:
+
+- Python 3.7
+- Python 3.8
+- Python 3.9
+- Python 3.10
+- Python 3.11
+
+## Installation
+
+Install from PyPi using [pip](https://pip.pypa.io/en/latest/), a
+package manager for Python.
+
+```shell
+pip3 install twilio
+```
+
+If pip install fails on Windows, check the path length of the directory. If it is greater 260 characters then enable [Long Paths](https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation) or choose other shorter location.
+
+Don't have pip installed? Try installing it, by running this from the command
+line:
+
+```shell
+curl https://bootstrap.pypa.io/get-pip.py | python
+```
+
+Or, you can [download the source code
+(ZIP)](https://github.com/twilio/twilio-python/zipball/main 'twilio-python
+source code') for `twilio-python`, and then run:
+
+```shell
+python3 setup.py install
+```
+
+> **Info**
+> If the command line gives you an error message that says Permission Denied, try running the above commands with `sudo` (e.g., `sudo pip3 install twilio`).
+
+### Test your installation
+
+Try sending yourself an SMS message. Save the following code sample to your computer with a text editor. Be sure to update the `account_sid`, `auth_token`, and `from_` phone number with values from your [Twilio account](https://console.twilio.com). The `to` phone number will be your own mobile phone.
+
+```python
+from twilio.rest import Client
+
+# Your Account SID and Auth Token from console.twilio.com
+account_sid = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+auth_token = "your_auth_token"
+
+client = Client(account_sid, auth_token)
+
+message = client.messages.create(
+ to="+15558675309",
+ from_="+15017250604",
+ body="Hello from Python!")
+
+print(message.sid)
+```
+
+Save the file as `send_sms.py`. In the terminal, `cd` to the directory containing the file you just saved then run:
+
+```shell
+python3 send_sms.py
+```
+
+After a brief delay, you will receive the text message on your phone.
+
+> **Warning**
+> It's okay to hardcode your credentials when testing locally, but you should use environment variables to keep them secret before committing any code or deploying to production. Check out [How to Set Environment Variables](https://www.twilio.com/blog/2017/01/how-to-set-environment-variables.html) for more information.
+
+## OAuth Feature for Twilio APIs
+We are introducing Client Credentials Flow-based OAuth 2.0 authentication. This feature is currently in beta and its implementation is subject to change.
+
+API examples [here](https://github.com/twilio/twilio-python/blob/main/examples/public_oauth.py)
+
+Organisation API examples [here](https://github.com/twilio/twilio-python/blob/main/examples/organization_api.py)
+
+## Use the helper library
+
+### API Credentials
+
+The `Twilio` client needs your Twilio credentials. You can either pass these directly to the constructor (see the code below) or via environment variables.
+
+Authenticating with Account SID and Auth Token:
+
+```python
+from twilio.rest import Client
+
+account_sid = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+auth_token = "your_auth_token"
+client = Client(account_sid, auth_token)
+```
+
+Authenticating with API Key and API Secret:
+
+```python
+from twilio.rest import Client
+
+api_key = "XXXXXXXXXXXXXXXXX"
+api_secret = "YYYYYYYYYYYYYYYYYY"
+account_sid = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+client = Client(api_key, api_secret, account_sid)
+```
+
+Alternatively, a `Client` constructor without these parameters will
+look for `TWILIO_ACCOUNT_SID` and `TWILIO_AUTH_TOKEN` variables inside the
+current environment.
+
+We suggest storing your credentials as environment variables. Why? You'll never
+have to worry about committing your credentials and accidentally posting them
+somewhere public.
+
+```python
+from twilio.rest import Client
+client = Client()
+```
+
+### Specify Region and/or Edge
+
+To take advantage of Twilio's [Global Infrastructure](https://www.twilio.com/docs/global-infrastructure), specify the target Region and Edge for the client:
+
+> **Note:** When specifying a `region` parameter for a helper library client, be sure to also specify the `edge` parameter. For backward compatibility purposes, specifying a `region` without specifying an `edge` will result in requests being routed to US1.
+
+```python
+from twilio.rest import Client
+
+client = Client(region='au1', edge='sydney')
+```
+
+A `Client` constructor without these parameters will also look for `TWILIO_REGION` and `TWILIO_EDGE` variables inside the current environment.
+
+Alternatively, you may specify the edge and/or region after constructing the Twilio client:
+
+```python
+from twilio.rest import Client
+
+client = Client()
+client.region = 'au1'
+client.edge = 'sydney'
+```
+
+This will result in the `hostname` transforming from `api.twilio.com` to `api.sydney.au1.twilio.com`.
+
+### Make a Call
+
+```python
+from twilio.rest import Client
+
+account_sid = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+auth_token = "your_auth_token"
+client = Client(account_sid, auth_token)
+
+call = client.calls.create(to="9991231234",
+ from_="9991231234",
+ url="http://twimlets.com/holdmusic?Bucket=com.twilio.music.ambient")
+print(call.sid)
+```
+
+### Get data about an existing call
+
+```python
+from twilio.rest import Client
+
+account_sid = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+auth_token = "your_auth_token"
+client = Client(account_sid, auth_token)
+
+call = client.calls.get("CA42ed11f93dc08b952027ffbc406d0868")
+print(call.to)
+```
+
+### Iterate through records
+
+The library automatically handles paging for you. Collections, such as `calls` and `messages`, have `list` and `stream` methods that page under the hood. With both `list` and `stream`, you can specify the number of records you want to receive (`limit`) and the maximum size you want each page fetch to be (`page_size`). The library will then handle the task for you.
+
+`list` eagerly fetches all records and returns them as a list, whereas `stream` returns an iterator and lazily retrieves pages of records as you iterate over the collection. You can also page manually using the `page` method.
+
+`page_size` as a parameter is used to tell how many records should we get in every page and `limit` parameter is used to limit the max number of records we want to fetch.
+
+#### Use the `list` method
+
+```python
+from twilio.rest import Client
+
+account_sid = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+auth_token = "your_auth_token"
+client = Client(account_sid, auth_token)
+
+for sms in client.messages.list():
+ print(sms.to)
+```
+
+```python
+client.messages.list(limit=20, page_size=20)
+```
+This will make 1 call that will fetch 20 records from backend service.
+
+```python
+client.messages.list(limit=20, page_size=10)
+```
+This will make 2 calls that will fetch 10 records each from backend service.
+
+```python
+client.messages.list(limit=20, page_size=100)
+```
+This will make 1 call which will fetch 100 records but user will get only 20 records.
+
+### Asynchronous API Requests
+
+By default, the Twilio Client will make synchronous requests to the Twilio API. To allow for asynchronous, non-blocking requests, we've included an optional asynchronous HTTP client. When used with the Client and the accompanying `*_async` methods, requests made to the Twilio API will be performed asynchronously.
+
+```python
+from twilio.http.async_http_client import AsyncTwilioHttpClient
+from twilio.rest import Client
+
+async def main():
+ account_sid = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+ auth_token = "your_auth_token"
+ http_client = AsyncTwilioHttpClient()
+ client = Client(account_sid, auth_token, http_client=http_client)
+
+ message = await client.messages.create_async(to="+12316851234", from_="+15555555555",
+ body="Hello there!")
+
+asyncio.run(main())
+```
+
+### Enable Debug Logging
+
+Log the API request and response data to the console:
+
+```python
+import logging
+
+client = Client(account_sid, auth_token)
+logging.basicConfig()
+client.http_client.logger.setLevel(logging.INFO)
+```
+
+Log the API request and response data to a file:
+
+```python
+import logging
+
+client = Client(account_sid, auth_token)
+logging.basicConfig(filename='./log.txt')
+client.http_client.logger.setLevel(logging.INFO)
+```
+
+### Handling Exceptions
+
+Version 8.x of `twilio-python` exports an exception class to help you handle exceptions that are specific to Twilio methods. To use it, import `TwilioRestException` and catch exceptions as follows:
+
+```python
+from twilio.rest import Client
+from twilio.base.exceptions import TwilioRestException
+
+account_sid = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+auth_token = "your_auth_token"
+client = Client(account_sid, auth_token)
+
+try:
+ message = client.messages.create(to="+12316851234", from_="+15555555555",
+ body="Hello there!")
+except TwilioRestException as e:
+ print(e)
+```
+
+### Generating TwiML
+
+To control phone calls, your application needs to output [TwiML][twiml].
+
+Use `twilio.twiml.Response` to easily create such responses.
+
+```python
+from twilio.twiml.voice_response import VoiceResponse
+
+r = VoiceResponse()
+r.say("Welcome to twilio!")
+print(str(r))
+```
+
+```xml
+
+Welcome to twilio!
+```
+
+### Other advanced examples
+
+- [Learn how to create your own custom HTTP client](./advanced-examples/custom-http-client.md)
+
+### Docker Image
+
+The `Dockerfile` present in this repository and its respective `twilio/twilio-python` Docker image are currently used by Twilio for testing purposes only.
+
+### Getting help
+
+If you need help installing or using the library, please check the [Twilio Support Help Center](https://support.twilio.com) first, and [file a support ticket](https://twilio.com/help/contact) if you don't find an answer to your question.
+
+If you've instead found a bug in the library or would like new features added, go ahead and open issues or pull requests against this repo!
+
+[apidocs]: https://www.twilio.com/docs/api
+[twiml]: https://www.twilio.com/docs/api/twiml
+[libdocs]: https://twilio.github.io/twilio-python
diff --git a/venv/Lib/site-packages/twilio-9.6.3.dist-info/RECORD b/venv/Lib/site-packages/twilio-9.6.3.dist-info/RECORD
new file mode 100644
index 00000000..1a4253f0
--- /dev/null
+++ b/venv/Lib/site-packages/twilio-9.6.3.dist-info/RECORD
@@ -0,0 +1,1368 @@
+twilio-9.6.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
+twilio-9.6.3.dist-info/METADATA,sha256=QJN1GFIpg-3TCVxgNQPspyhipDKWXVPejFVIbViJZXk,13510
+twilio-9.6.3.dist-info/RECORD,,
+twilio-9.6.3.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
+twilio-9.6.3.dist-info/WHEEL,sha256=JNWh1Fm1UdwIQV075glCn4MVuCRs0sotJIq-J6rbxCU,109
+twilio-9.6.3.dist-info/licenses/AUTHORS.md,sha256=o3292UoaDN3jrjNs-qzN7yDnhvH6TqV7EzSfJdnCf4Q,1387
+twilio-9.6.3.dist-info/licenses/LICENSE,sha256=8UK19n5LbVBeSP2SuveHtbmQ2BMV-Dat89xZ8As-YZ0,1108
+twilio-9.6.3.dist-info/top_level.txt,sha256=fAdnbTJw2Q-bY1dyTpCPQR9_kIISEW1tNn4jYb-g3Ic,7
+twilio/__init__.py,sha256=VcHftSjmpZe8gXTigvYpbaBJZm535eHadrPCB39HPZs,76
+twilio/__pycache__/__init__.cpython-312.pyc,,
+twilio/__pycache__/request_validator.cpython-312.pyc,,
+twilio/auth_strategy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
+twilio/auth_strategy/__pycache__/__init__.cpython-312.pyc,,
+twilio/auth_strategy/__pycache__/auth_strategy.cpython-312.pyc,,
+twilio/auth_strategy/__pycache__/auth_type.cpython-312.pyc,,
+twilio/auth_strategy/__pycache__/no_auth_strategy.cpython-312.pyc,,
+twilio/auth_strategy/__pycache__/token_auth_strategy.cpython-312.pyc,,
+twilio/auth_strategy/auth_strategy.py,sha256=fY6KQdzezUB5EE0mt5tKU01-pvi2u1ugxeyy3b62MnE,521
+twilio/auth_strategy/auth_type.py,sha256=IwG71YYNfc9TJPL-T-lgJH0l-CSDcEIVaTx6UDeNAJA,240
+twilio/auth_strategy/no_auth_strategy.py,sha256=i87zDWRF42wInZGhigHMepo7904I8CkHx-ozJvfpX7s,322
+twilio/auth_strategy/token_auth_strategy.py,sha256=z0OBeGTpZrhArWGXEVgB7uieNgLszNlMq6UL6YO6KpU,1894
+twilio/base/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
+twilio/base/__pycache__/__init__.cpython-312.pyc,,
+twilio/base/__pycache__/client_base.cpython-312.pyc,,
+twilio/base/__pycache__/deserialize.cpython-312.pyc,,
+twilio/base/__pycache__/domain.cpython-312.pyc,,
+twilio/base/__pycache__/exceptions.cpython-312.pyc,,
+twilio/base/__pycache__/instance_context.cpython-312.pyc,,
+twilio/base/__pycache__/instance_resource.cpython-312.pyc,,
+twilio/base/__pycache__/list_resource.cpython-312.pyc,,
+twilio/base/__pycache__/obsolete.cpython-312.pyc,,
+twilio/base/__pycache__/page.cpython-312.pyc,,
+twilio/base/__pycache__/serialize.cpython-312.pyc,,
+twilio/base/__pycache__/values.cpython-312.pyc,,
+twilio/base/__pycache__/version.cpython-312.pyc,,
+twilio/base/client_base.py,sha256=cTUD-570kA1nbg-eLAquYGwNvbMgazjFlMinFqHWsbU,9592
+twilio/base/deserialize.py,sha256=ro6hPYvNK1c7WrpWeS3PgM_p0ppjPwJxM2iYVhgCvDk,2005
+twilio/base/domain.py,sha256=z0ESHLf2LEQxfi1JJ2xEQk8tQheW0mU1Bt_r3ko41U4,2978
+twilio/base/exceptions.py,sha256=qYou_kqs04_0ybcVzcfpRqN88RYf41iINB4B8egok7Q,2890
+twilio/base/instance_context.py,sha256=ln0XUHSb6ByjV6oHx0sa7TknQ0ahe8yuk-mhmOM5fMU,147
+twilio/base/instance_resource.py,sha256=84FA89HN55_rSWUQ2rwRFGaABXRYoudcLaYvBQDbQmo,148
+twilio/base/list_resource.py,sha256=WLDg_ByCMR9P7YOHLuQxNjkZvToteF7A3k-ZCb853Xc,144
+twilio/base/obsolete.py,sha256=A5EqW8Nu4aLatse83CIxdrZXxXic8yhaXiQC16RyvVg,1417
+twilio/base/page.py,sha256=YTKd63kVfwb1OHmf74_PJ0ucXS_Vpp3f1IiQP2ZIBoc,5264
+twilio/base/serialize.py,sha256=TlIJtVfXArDLLmH8WyfGZmczffxWZNuUtOckd4d9aJ0,2316
+twilio/base/values.py,sha256=okdxSj7zc0tg_IfScuZYQKOX-fHu99ZXQcFh_XuBAuE,280
+twilio/base/version.py,sha256=eRnp96pRPim0KxdxZtf34phugQ9s-hhVeeOUI7tatn8,14611
+twilio/credential/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
+twilio/credential/__pycache__/__init__.cpython-312.pyc,,
+twilio/credential/__pycache__/client_credential_provider.cpython-312.pyc,,
+twilio/credential/__pycache__/credential_provider.cpython-312.pyc,,
+twilio/credential/__pycache__/orgs_credential_provider.cpython-312.pyc,,
+twilio/credential/client_credential_provider.py,sha256=VunG0k3knjK9t2UMCTnWxgjdMqerwP3bVu2thYb21Nk,1184
+twilio/credential/credential_provider.py,sha256=1cuNNjCoYBipYVDIfItc-r5HFz-ga5_SK8vPKkttogo,352
+twilio/credential/orgs_credential_provider.py,sha256=ETIthhf1u4OZYhPjoqrP0V2WA6Q1JPPPwojja-Aq10o,1174
+twilio/http/__init__.py,sha256=aklR5-Xl8fnZNgV3jxylkbCcJCBEKQM3nt024ttm-Gs,3434
+twilio/http/__pycache__/__init__.cpython-312.pyc,,
+twilio/http/__pycache__/async_http_client.cpython-312.pyc,,
+twilio/http/__pycache__/client_token_manager.cpython-312.pyc,,
+twilio/http/__pycache__/http_client.cpython-312.pyc,,
+twilio/http/__pycache__/orgs_token_manager.cpython-312.pyc,,
+twilio/http/__pycache__/request.cpython-312.pyc,,
+twilio/http/__pycache__/response.cpython-312.pyc,,
+twilio/http/__pycache__/token_manager.cpython-312.pyc,,
+twilio/http/__pycache__/validation_client.cpython-312.pyc,,
+twilio/http/async_http_client.py,sha256=Ei7OXkbp26n3MAtWsX-0mTVZcEOgBui4Y4y8T20l1x0,4503
+twilio/http/client_token_manager.py,sha256=p6CKaXjnPjYM9ku0n1puHgyFSIJLU2FN-31anjVqPUk,1154
+twilio/http/http_client.py,sha256=FxvtTb-EbuWMcPttpDzLe1BBZZu1P2KWjbWaNX-I6Bo,4141
+twilio/http/orgs_token_manager.py,sha256=WcxkMITQdJRkaT7t7AovdARNfc-_mdilacNIWEQBLUY,1149
+twilio/http/request.py,sha256=kVHsIN0kJQXRySE2VRVQwCPmp9ZycMxJ9zG7FnvArhM,2655
+twilio/http/response.py,sha256=BmDMxrJFDhgAxXQzoLwzO5pZSuw-y9KjEA-i3lz3yY4,518
+twilio/http/token_manager.py,sha256=pmt5lw3LsCGCIinmt7G8hq468TOJwYszYmy5-u8iMUE,128
+twilio/http/validation_client.py,sha256=ndVZrpcpG9i7db10mbrCjmU3ks8rqYu4EDWJeWnKFUM,4818
+twilio/jwt/__init__.py,sha256=MScUNrJ0oRY16IYehs1wYQVGlV5QKxLY0msD9xmjRpo,5085
+twilio/jwt/__pycache__/__init__.cpython-312.pyc,,
+twilio/jwt/access_token/__init__.py,sha256=RJOJBVlO4xm3hgiltdFNKOgInJVId3G8CYVkhx6vP54,2415
+twilio/jwt/access_token/__pycache__/__init__.cpython-312.pyc,,
+twilio/jwt/access_token/__pycache__/grants.cpython-312.pyc,,
+twilio/jwt/access_token/grants.py,sha256=CVuyFTkyRC9nCc8Z70KpBpyYPygYqku08l8hoXO6BOc,4902
+twilio/jwt/client/__init__.py,sha256=GCWbuOKucutdnMIMtTesx0qvjEs25ieB_0upacFT604,3982
+twilio/jwt/client/__pycache__/__init__.cpython-312.pyc,,
+twilio/jwt/taskrouter/__init__.py,sha256=2LIrC_6D4qvW278bKvqKM-VDBYLhwXxzwKfuri6LQ9I,5726
+twilio/jwt/taskrouter/__pycache__/__init__.cpython-312.pyc,,
+twilio/jwt/taskrouter/__pycache__/capabilities.cpython-312.pyc,,
+twilio/jwt/taskrouter/capabilities.py,sha256=TGE-YHo60LL-ubtu4JJitO0sviweqNPQjsRzBjWBzxo,4309
+twilio/jwt/validation/__init__.py,sha256=NSTRTHrEp5aoI-jbcc7KrKCRYIPMK5SITRMKj4y_sKQ,3156
+twilio/jwt/validation/__pycache__/__init__.cpython-312.pyc,,
+twilio/request_validator.py,sha256=ZeoQ7BbnPrDGTy-M_RzcLq0l8Hir64Il5VbiqyOJNdc,4100
+twilio/rest/__init__.py,sha256=u46sq9dnCH4fZWlghIxEMxSQfQclMYcKPpaoW7IvP_Q,22772
+twilio/rest/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/accounts/AccountsBase.py,sha256=AqLmd6aIbV985gG5b473bkD2DqejaY4S3lvZaiNwcwg,1211
+twilio/rest/accounts/__init__.py,sha256=Oj-WM5ZDQWaF-2jstKhWRRPpkuCLs5AlDBpQlGDfZ28,1168
+twilio/rest/accounts/__pycache__/AccountsBase.cpython-312.pyc,,
+twilio/rest/accounts/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/accounts/v1/__init__.py,sha256=R_igwYsDAEPd2evNtCQC7L1hyulyhJR-cC2_-5Hcm90,3035
+twilio/rest/accounts/v1/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/accounts/v1/__pycache__/auth_token_promotion.cpython-312.pyc,,
+twilio/rest/accounts/v1/__pycache__/bulk_consents.cpython-312.pyc,,
+twilio/rest/accounts/v1/__pycache__/bulk_contacts.cpython-312.pyc,,
+twilio/rest/accounts/v1/__pycache__/safelist.cpython-312.pyc,,
+twilio/rest/accounts/v1/__pycache__/secondary_auth_token.cpython-312.pyc,,
+twilio/rest/accounts/v1/auth_token_promotion.py,sha256=CEPC3tjgkDuq_qi1oGso40VWYuV9IXUu4ccMeFnZk3k,5693
+twilio/rest/accounts/v1/bulk_consents.py,sha256=luOHxVumkZ7CpCJInni3F8-xkVdh_gbxArWYa6gPWwk,5427
+twilio/rest/accounts/v1/bulk_contacts.py,sha256=aNvChaLiqiSgLPxCcZ6T6-TJcBz8B8KkAkjf5x6bthg,4673
+twilio/rest/accounts/v1/credential/__init__.py,sha256=NsXgoL4scQZKaq3Q1qIpWSGGbjPWF2KzOHfL6iwkLPo,1766
+twilio/rest/accounts/v1/credential/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/accounts/v1/credential/__pycache__/aws.cpython-312.pyc,,
+twilio/rest/accounts/v1/credential/__pycache__/public_key.cpython-312.pyc,,
+twilio/rest/accounts/v1/credential/aws.py,sha256=G9wy35gNqQwEMeLiqmsTwJzi4AGHBpftderkqEqdcWg,20690
+twilio/rest/accounts/v1/credential/public_key.py,sha256=XqkXV0xJv1In9T8uPea25gxj0ibhXSNcfUgY4uhu0fU,21208
+twilio/rest/accounts/v1/safelist.py,sha256=pT5xFckxFZ5yAPvqfesyjGUsjObQgcuDv_0qEnQFL3Y,6774
+twilio/rest/accounts/v1/secondary_auth_token.py,sha256=v6E6teddkZx0e6Mf8_wxMuYprtiab8VHjlUNg4yymSA,6605
+twilio/rest/api/ApiBase.py,sha256=1118YkG0wU9g7mMByeOtL4HfpUGvePUq4fK3_rpnsKU,1209
+twilio/rest/api/__init__.py,sha256=IF3HTJJA-JYCkkGZ_Mr6Js5AE3DVR7kVVfWZIbabN5Q,8255
+twilio/rest/api/__pycache__/ApiBase.cpython-312.pyc,,
+twilio/rest/api/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/api/v2010/__init__.py,sha256=G3bZ5wo8gF9DrYNnYOVztO-T2-vPg_mBvHNXBVAaiSM,1806
+twilio/rest/api/v2010/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/api/v2010/account/__init__.py,sha256=Sm9ZE-1zXfhgMPK7drfcsXPJsbQqljhyRf_0S6m4W2A,37355
+twilio/rest/api/v2010/account/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/api/v2010/account/__pycache__/application.cpython-312.pyc,,
+twilio/rest/api/v2010/account/__pycache__/authorized_connect_app.cpython-312.pyc,,
+twilio/rest/api/v2010/account/__pycache__/balance.cpython-312.pyc,,
+twilio/rest/api/v2010/account/__pycache__/connect_app.cpython-312.pyc,,
+twilio/rest/api/v2010/account/__pycache__/key.cpython-312.pyc,,
+twilio/rest/api/v2010/account/__pycache__/new_key.cpython-312.pyc,,
+twilio/rest/api/v2010/account/__pycache__/new_signing_key.cpython-312.pyc,,
+twilio/rest/api/v2010/account/__pycache__/notification.cpython-312.pyc,,
+twilio/rest/api/v2010/account/__pycache__/outgoing_caller_id.cpython-312.pyc,,
+twilio/rest/api/v2010/account/__pycache__/short_code.cpython-312.pyc,,
+twilio/rest/api/v2010/account/__pycache__/signing_key.cpython-312.pyc,,
+twilio/rest/api/v2010/account/__pycache__/token.cpython-312.pyc,,
+twilio/rest/api/v2010/account/__pycache__/transcription.cpython-312.pyc,,
+twilio/rest/api/v2010/account/__pycache__/validation_request.cpython-312.pyc,,
+twilio/rest/api/v2010/account/address/__init__.py,sha256=vdZk4EaH3fidb4Th3a_KTaZxTkWFKa2QvUd-hKWvDvw,39062
+twilio/rest/api/v2010/account/address/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/api/v2010/account/address/__pycache__/dependent_phone_number.cpython-312.pyc,,
+twilio/rest/api/v2010/account/address/dependent_phone_number.py,sha256=sMQLvzyiphrWC0VVjaCxgXBgyBRz94DjsQXzQfRRoJY,17366
+twilio/rest/api/v2010/account/application.py,sha256=TS8FsKf56PUiCE7B_abo0rvotD7xseg8dhRToypH0uc,49301
+twilio/rest/api/v2010/account/authorized_connect_app.py,sha256=F7PFVW5KZPz90UO3q0WTk1gR4uRJI7TyMVO8A0NyFWQ,17145
+twilio/rest/api/v2010/account/available_phone_number_country/__init__.py,sha256=sqW0aE7vhte9lavKlQyXC3ThpDrLrtvunpiix0peFw4,21896
+twilio/rest/api/v2010/account/available_phone_number_country/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/api/v2010/account/available_phone_number_country/__pycache__/local.cpython-312.pyc,,
+twilio/rest/api/v2010/account/available_phone_number_country/__pycache__/machine_to_machine.cpython-312.pyc,,
+twilio/rest/api/v2010/account/available_phone_number_country/__pycache__/mobile.cpython-312.pyc,,
+twilio/rest/api/v2010/account/available_phone_number_country/__pycache__/national.cpython-312.pyc,,
+twilio/rest/api/v2010/account/available_phone_number_country/__pycache__/shared_cost.cpython-312.pyc,,
+twilio/rest/api/v2010/account/available_phone_number_country/__pycache__/toll_free.cpython-312.pyc,,
+twilio/rest/api/v2010/account/available_phone_number_country/__pycache__/voip.cpython-312.pyc,,
+twilio/rest/api/v2010/account/available_phone_number_country/local.py,sha256=laEx-fN4FMB_KOpj_c1UGlxR_iE771gboTlULr6lOCc,47262
+twilio/rest/api/v2010/account/available_phone_number_country/machine_to_machine.py,sha256=qcOEMC5jSht_SIva5o4E9AQkVMYuNCFoWFtI9WyVKn0,47233
+twilio/rest/api/v2010/account/available_phone_number_country/mobile.py,sha256=mcgfpgsgv3IPUSLTvY2uxDQyZbUPwITtdl_uEkwR038,46883
+twilio/rest/api/v2010/account/available_phone_number_country/national.py,sha256=7lj-_Cz7YHFWFJlTEJBV--eXEdN9xfJ-V6O51jgrhtQ,46953
+twilio/rest/api/v2010/account/available_phone_number_country/shared_cost.py,sha256=tALZGWREUHPshZ7XHdc8Q8Pgk_VeROu1a1i08BqJy0I,47023
+twilio/rest/api/v2010/account/available_phone_number_country/toll_free.py,sha256=roXo-I5eMYGRo0io77CPNxmEvMxcMeHDO6n49Vc081g,46953
+twilio/rest/api/v2010/account/available_phone_number_country/voip.py,sha256=2YVwsl_2KLYqhaQiZUqveWBmE2y89oyfHz3nvzf0iGY,46813
+twilio/rest/api/v2010/account/balance.py,sha256=K_7BbuHsg8Aeixu1aTGvOxkXahrDrsZGmrHEj_sxaA4,3538
+twilio/rest/api/v2010/account/call/__init__.py,sha256=BYVO4Xk4qxSI07LGZdD8Ehuk9HiOql_nQKNKlfMkVyw,93513
+twilio/rest/api/v2010/account/call/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/api/v2010/account/call/__pycache__/event.cpython-312.pyc,,
+twilio/rest/api/v2010/account/call/__pycache__/notification.cpython-312.pyc,,
+twilio/rest/api/v2010/account/call/__pycache__/payment.cpython-312.pyc,,
+twilio/rest/api/v2010/account/call/__pycache__/recording.cpython-312.pyc,,
+twilio/rest/api/v2010/account/call/__pycache__/siprec.cpython-312.pyc,,
+twilio/rest/api/v2010/account/call/__pycache__/stream.cpython-312.pyc,,
+twilio/rest/api/v2010/account/call/__pycache__/transcription.cpython-312.pyc,,
+twilio/rest/api/v2010/account/call/__pycache__/user_defined_message.cpython-312.pyc,,
+twilio/rest/api/v2010/account/call/__pycache__/user_defined_message_subscription.cpython-312.pyc,,
+twilio/rest/api/v2010/account/call/event.py,sha256=35dC9vby41o3dpr2horEB_9T3y-lL0LcTpkZwkF5gJo,10978
+twilio/rest/api/v2010/account/call/notification.py,sha256=aXiBKdoenFitiDbLHonqdalRg1sv8bLPLkrsAFaatgM,28832
+twilio/rest/api/v2010/account/call/payment.py,sha256=hSxpKIPQvFAc3qj3YyiuQmXfNbGtWHXSo1C_WN3av8U,24310
+twilio/rest/api/v2010/account/call/recording.py,sha256=PopYJRkdLNWsOKneTjOyz20xWbBRjdVdB6qcWrR_1x4,39698
+twilio/rest/api/v2010/account/call/siprec.py,sha256=ih7ryOlR6EizYbaaZ3a9A-jgApmEFEloAd8RyqZRNjc,77906
+twilio/rest/api/v2010/account/call/stream.py,sha256=ZwtFxhtNzHKNIndruUTHb2zUgxJAtmdCHSf4vYmZwoc,77929
+twilio/rest/api/v2010/account/call/transcription.py,sha256=BmAAS6uyqMkYT5GFTSQo6nWTJRUZto5ir_FLpRuIEO0,17830
+twilio/rest/api/v2010/account/call/user_defined_message.py,sha256=lRrMjXP8vTJTd_AVOeNdu8o2qhbL8XDHlwn78fuYjLc,5667
+twilio/rest/api/v2010/account/call/user_defined_message_subscription.py,sha256=v7R8MBXAqZHO4AdojZfTOMRzDW2IlBDmOq-nv4xb8aw,11342
+twilio/rest/api/v2010/account/conference/__init__.py,sha256=tV6mKe9A4NdQdWWr5vPRGzjugsXaMgUwLdroBdSBGdk,47964
+twilio/rest/api/v2010/account/conference/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/api/v2010/account/conference/__pycache__/participant.cpython-312.pyc,,
+twilio/rest/api/v2010/account/conference/__pycache__/recording.cpython-312.pyc,,
+twilio/rest/api/v2010/account/conference/participant.py,sha256=9t2FkE75w-TWlUA3EmxGc3wwYikRjKHON-y4D3EJUTQ,79654
+twilio/rest/api/v2010/account/conference/recording.py,sha256=Nt715MUKsj1_UxedykHPGbKdTm3wvAfY1W8Fwgjc5nQ,33542
+twilio/rest/api/v2010/account/connect_app.py,sha256=lPHPbHrXq39lSyjfOr_MQZwTl4_aPRHtzj4mliJKJiI,27352
+twilio/rest/api/v2010/account/incoming_phone_number/__init__.py,sha256=X-oJqbA8oRk442_C5ISegdqsNy0oZd0XePub0nJ79sE,74914
+twilio/rest/api/v2010/account/incoming_phone_number/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/api/v2010/account/incoming_phone_number/__pycache__/local.cpython-312.pyc,,
+twilio/rest/api/v2010/account/incoming_phone_number/__pycache__/mobile.cpython-312.pyc,,
+twilio/rest/api/v2010/account/incoming_phone_number/__pycache__/toll_free.cpython-312.pyc,,
+twilio/rest/api/v2010/account/incoming_phone_number/assigned_add_on/__init__.py,sha256=dMaCWRPylUFGS-rCh7VPcodWv-TaiYYyHB9b6KU4tyI,21663
+twilio/rest/api/v2010/account/incoming_phone_number/assigned_add_on/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/api/v2010/account/incoming_phone_number/assigned_add_on/__pycache__/assigned_add_on_extension.cpython-312.pyc,,
+twilio/rest/api/v2010/account/incoming_phone_number/assigned_add_on/assigned_add_on_extension.py,sha256=FxyLuWNlPgPNzR2rbP4fH_VXp5ZNzdxFCa2ZjeRN4Pc,18810
+twilio/rest/api/v2010/account/incoming_phone_number/local.py,sha256=2V5X3oWot6bbrjccEFmq_dm7l8nNkft-Fk7RsmUaol0,37854
+twilio/rest/api/v2010/account/incoming_phone_number/mobile.py,sha256=R2rNjLg2J_Xu656cdw9sncT6uGXvty7t8RcptnWMY8I,37938
+twilio/rest/api/v2010/account/incoming_phone_number/toll_free.py,sha256=eKn4qqcxHadSlRKo89UWVGeZqymeOhjzi1CIMOJW8HY,38024
+twilio/rest/api/v2010/account/key.py,sha256=7o10k4zQXssQanG1hHN2ARlwx_LSETXyFzH4Q7ew2P8,18800
+twilio/rest/api/v2010/account/message/__init__.py,sha256=UuqQJGG4QWdXiEoVo9lxghbA_dm5an9l0pkO3sm94-M,58874
+twilio/rest/api/v2010/account/message/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/api/v2010/account/message/__pycache__/feedback.cpython-312.pyc,,
+twilio/rest/api/v2010/account/message/__pycache__/media.cpython-312.pyc,,
+twilio/rest/api/v2010/account/message/feedback.py,sha256=2gGH74VJbI9pICWkq1wzfokE6viCVg9FCh0nUOMhEIQ,5586
+twilio/rest/api/v2010/account/message/media.py,sha256=58JeQHU_XjVSkND6EZvFp6fvqmcqqZUXldP7m310jkA,28066
+twilio/rest/api/v2010/account/new_key.py,sha256=QQRwQ55JXp008p2VHbjtLcxu222aSYWIIrpOAqYCo7c,5174
+twilio/rest/api/v2010/account/new_signing_key.py,sha256=ml4mwDgkK06FUKJWFI4KSNMho1EmBGwXU4tKJ4u8wpY,5202
+twilio/rest/api/v2010/account/notification.py,sha256=ZzA_0h_ivRe2gRPZPXouJxW-lFBQlk763NdX5n0rcXw,27974
+twilio/rest/api/v2010/account/outgoing_caller_id.py,sha256=FBXTNqu9Fg5Xt34AIZU75rNIGkLH9mvUARzoVL7x--c,23010
+twilio/rest/api/v2010/account/queue/__init__.py,sha256=0NbAGOuAcf4bnSBex_71vxyruCB7p1w2h2Fex7FzQQ4,23629
+twilio/rest/api/v2010/account/queue/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/api/v2010/account/queue/__pycache__/member.cpython-312.pyc,,
+twilio/rest/api/v2010/account/queue/member.py,sha256=jVbeoDZ9eh3NgaMYwxqkK79NsMsxA0bqJ_e2YG6psqo,19888
+twilio/rest/api/v2010/account/recording/__init__.py,sha256=iwZNdf2cByvRvosP3MNbnaNllAFx6pYLP_hrHUXFbQE,38236
+twilio/rest/api/v2010/account/recording/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/api/v2010/account/recording/__pycache__/transcription.cpython-312.pyc,,
+twilio/rest/api/v2010/account/recording/add_on_result/__init__.py,sha256=SEcSdT9l8zz1FbtOk-BTtek4akBIJ7nq5gvbGHuLmA4,19764
+twilio/rest/api/v2010/account/recording/add_on_result/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/api/v2010/account/recording/add_on_result/payload/__init__.py,sha256=2P-YLw4EX98LXPlvSweN55l9Eh1O8_NIbaEOxFKMeyc,20438
+twilio/rest/api/v2010/account/recording/add_on_result/payload/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/api/v2010/account/recording/add_on_result/payload/__pycache__/data.cpython-312.pyc,,
+twilio/rest/api/v2010/account/recording/add_on_result/payload/data.py,sha256=l1XKqSpFwHr_FlWee9LSw83hWpk3DnIU3llAs94Oeu0,7986
+twilio/rest/api/v2010/account/recording/transcription.py,sha256=2Sd-gon5TzQ_VFxypJLzGscq77_Sc-SD-RWbpVe4rhA,19533
+twilio/rest/api/v2010/account/short_code.py,sha256=cGWy0l9ZEgWJ_LeYlyxHT9uxVBY1nGs4oQqPzWOpUUk,27163
+twilio/rest/api/v2010/account/signing_key.py,sha256=xlcskx0qnbRRHDb_-1wSazdVioI07TrflMNNZBVjFj0,18187
+twilio/rest/api/v2010/account/sip/__init__.py,sha256=UNiLJ1eMTojjpoUrhgnV4Pux6F4udK3U7eVOMOHp9ws,2871
+twilio/rest/api/v2010/account/sip/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/api/v2010/account/sip/credential_list/__init__.py,sha256=6Iz29WLYKKfzmqxGwQ00eYF1qR0KM2QH6GRNNTYRMuQ,22479
+twilio/rest/api/v2010/account/sip/credential_list/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/api/v2010/account/sip/credential_list/__pycache__/credential.cpython-312.pyc,,
+twilio/rest/api/v2010/account/sip/credential_list/credential.py,sha256=MqjBJV_lVJDBOXAiZPOsjIorJi6fT59y_rNAvWJE2ec,23958
+twilio/rest/api/v2010/account/sip/domain/__init__.py,sha256=N5Fg6CAZVWA0n_NpZWN4b5HDnL3ux3t8zFIeHhgBajY,46828
+twilio/rest/api/v2010/account/sip/domain/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/api/v2010/account/sip/domain/__pycache__/credential_list_mapping.cpython-312.pyc,,
+twilio/rest/api/v2010/account/sip/domain/__pycache__/ip_access_control_list_mapping.cpython-312.pyc,,
+twilio/rest/api/v2010/account/sip/domain/auth_types/__init__.py,sha256=9e9q4NNr8KnUwHdYNbh2fpuaAVUuZ2OeQCuRQc-gsco,2758
+twilio/rest/api/v2010/account/sip/domain/auth_types/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/api/v2010/account/sip/domain/auth_types/auth_type_calls/__init__.py,sha256=nolfbRsWWIcMstPOS1VXOH9gDrNceSCUQYfcM4OSIXo,3332
+twilio/rest/api/v2010/account/sip/domain/auth_types/auth_type_calls/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/api/v2010/account/sip/domain/auth_types/auth_type_calls/__pycache__/auth_calls_credential_list_mapping.cpython-312.pyc,,
+twilio/rest/api/v2010/account/sip/domain/auth_types/auth_type_calls/__pycache__/auth_calls_ip_access_control_list_mapping.cpython-312.pyc,,
+twilio/rest/api/v2010/account/sip/domain/auth_types/auth_type_calls/auth_calls_credential_list_mapping.py,sha256=-qOf-2WU1AxDwO7ASuA62MQ1I8TiXgOhfjpJKcn2uvs,21353
+twilio/rest/api/v2010/account/sip/domain/auth_types/auth_type_calls/auth_calls_ip_access_control_list_mapping.py,sha256=ddyvBSX5bi1rybHobzg-yrDfGyqT6yTgwZCiek9IdMM,21894
+twilio/rest/api/v2010/account/sip/domain/auth_types/auth_type_registrations/__init__.py,sha256=L0TAMoyPSClaHsol6TCehYLaBbNTf9EXMHSM2ipyDKA,2473
+twilio/rest/api/v2010/account/sip/domain/auth_types/auth_type_registrations/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/api/v2010/account/sip/domain/auth_types/auth_type_registrations/__pycache__/auth_registrations_credential_list_mapping.cpython-312.pyc,,
+twilio/rest/api/v2010/account/sip/domain/auth_types/auth_type_registrations/auth_registrations_credential_list_mapping.py,sha256=tGa7y9pBeZFyzTVea9MJlFzS8Hmo_QoyEAnlLF9m-Tg,21961
+twilio/rest/api/v2010/account/sip/domain/credential_list_mapping.py,sha256=xq5A5I1I_mY7uuAVQSrIXk0SXrTcvarSRDn_u9XPZfg,20806
+twilio/rest/api/v2010/account/sip/domain/ip_access_control_list_mapping.py,sha256=FAhe9JiJBX28oWKuBg7VmxyXjCb2IU-H4icW3s1IZbU,21077
+twilio/rest/api/v2010/account/sip/ip_access_control_list/__init__.py,sha256=a8zaJdVdF2pTtxiaCws9V0ktd-mbb3dCBwxP-pTTCIM,23009
+twilio/rest/api/v2010/account/sip/ip_access_control_list/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/api/v2010/account/sip/ip_access_control_list/__pycache__/ip_address.cpython-312.pyc,,
+twilio/rest/api/v2010/account/sip/ip_access_control_list/ip_address.py,sha256=jIYtlIx04iTR4dOJFEAyNfglGAKwJzCJ4g6QeTRplVE,27439
+twilio/rest/api/v2010/account/token.py,sha256=y4Qw6yQgr9uC2lbVxoTQ3YOXE6oEkv1Q8d56uf777D8,5212
+twilio/rest/api/v2010/account/transcription.py,sha256=k_P5_2VUd5CNgN5ia4zV3FoqW6KhMdYbZv_YYGtnDBE,18559
+twilio/rest/api/v2010/account/usage/__init__.py,sha256=uuxXF4PSniarhk76bNQxiOXKpBGhFXDVJhNiO-T69qI,2220
+twilio/rest/api/v2010/account/usage/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/api/v2010/account/usage/__pycache__/trigger.cpython-312.pyc,,
+twilio/rest/api/v2010/account/usage/record/__init__.py,sha256=9EjEEbxXJcIIUZjK5v6eQ-581RfhJreccq4lm0qymcc,68865
+twilio/rest/api/v2010/account/usage/record/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/api/v2010/account/usage/record/__pycache__/all_time.cpython-312.pyc,,
+twilio/rest/api/v2010/account/usage/record/__pycache__/daily.cpython-312.pyc,,
+twilio/rest/api/v2010/account/usage/record/__pycache__/last_month.cpython-312.pyc,,
+twilio/rest/api/v2010/account/usage/record/__pycache__/monthly.cpython-312.pyc,,
+twilio/rest/api/v2010/account/usage/record/__pycache__/this_month.cpython-312.pyc,,
+twilio/rest/api/v2010/account/usage/record/__pycache__/today.cpython-312.pyc,,
+twilio/rest/api/v2010/account/usage/record/__pycache__/yearly.cpython-312.pyc,,
+twilio/rest/api/v2010/account/usage/record/__pycache__/yesterday.cpython-312.pyc,,
+twilio/rest/api/v2010/account/usage/record/all_time.py,sha256=Qj2ph9VT3ezj5_ZK9ANXkT3wJZmLWEHHTEtSz6Xyzqk,65509
+twilio/rest/api/v2010/account/usage/record/daily.py,sha256=puhl_bIMspI9LOypZsupUVgymJ3_e-nbnWvTErCy_5o,65417
+twilio/rest/api/v2010/account/usage/record/last_month.py,sha256=UFnee7ZbLqBt-NbIYwgknLLWvibPFAIQnweFcPUfVZQ,65601
+twilio/rest/api/v2010/account/usage/record/monthly.py,sha256=xj_dsqBtHDm-7ydC2dDNy4zDPTB9h0S0j4K3wECfvyk,65509
+twilio/rest/api/v2010/account/usage/record/this_month.py,sha256=ZBmGSy6XNn2h04l_EY9zojjrKmA-c16DZIQFV_mS_0M,65601
+twilio/rest/api/v2010/account/usage/record/today.py,sha256=X-Tdd0CVL9VpCMbdgntzshadhHsTPcP0ozKj4NFsPZ0,65417
+twilio/rest/api/v2010/account/usage/record/yearly.py,sha256=fuzQdPbzKLB0bDWCHMx5Z2S-m6Edu0RDi5vZ36DkmE0,65463
+twilio/rest/api/v2010/account/usage/record/yesterday.py,sha256=vxoFxArKfrYhxgNh9f5LJIckv3xiZ39MEWJT3JwmeWQ,65601
+twilio/rest/api/v2010/account/usage/trigger.py,sha256=I8UTmyz9IZGKwQ_-RST3zzA1kZdeBoEOivstoCGCJqk,77238
+twilio/rest/api/v2010/account/validation_request.py,sha256=6ySMvEZxVIn5bPbD3j5l5XaUZEyncLkrWnlchEQRds0,7786
+twilio/rest/assistants/AssistantsBase.py,sha256=zEffT94q3Z61xfAO_L5x66CwpLTcwk9d47V8iBAQhyo,1225
+twilio/rest/assistants/__init__.py,sha256=4Wu-shnCXczxJryvZmphy2Zg7vppA4IFTnO-nXqQcrw,1578
+twilio/rest/assistants/__pycache__/AssistantsBase.cpython-312.pyc,,
+twilio/rest/assistants/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/assistants/v1/__init__.py,sha256=FHupHKV682ELSutx8B9JUMFqfaBO2X4ELcv0JgHLtqs,2407
+twilio/rest/assistants/v1/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/assistants/v1/__pycache__/policy.cpython-312.pyc,,
+twilio/rest/assistants/v1/__pycache__/tool.cpython-312.pyc,,
+twilio/rest/assistants/v1/assistant/__init__.py,sha256=Sx5ueNQP0JN19eCDcaME5RPu8jo-CQ6SRLI5glDUpkQ,36305
+twilio/rest/assistants/v1/assistant/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/assistants/v1/assistant/__pycache__/assistants_knowledge.cpython-312.pyc,,
+twilio/rest/assistants/v1/assistant/__pycache__/assistants_tool.cpython-312.pyc,,
+twilio/rest/assistants/v1/assistant/__pycache__/feedback.cpython-312.pyc,,
+twilio/rest/assistants/v1/assistant/__pycache__/message.cpython-312.pyc,,
+twilio/rest/assistants/v1/assistant/assistants_knowledge.py,sha256=_mYOFtWdPf6ovwWxuI-64qBSEKzWxIXkYPHDevq1nAs,18788
+twilio/rest/assistants/v1/assistant/assistants_tool.py,sha256=qAv-9ZkPB87A8rwkpsUrdlDkqz5oLsYe1dTl4Z_7WXY,18172
+twilio/rest/assistants/v1/assistant/feedback.py,sha256=hxJ-MMZy-6JuJvFOVVAbHNH0lwcQCLVpsFCCX6MPeh8,15127
+twilio/rest/assistants/v1/assistant/message.py,sha256=HXFkpnClfPGrv75P-XGnt2M8qQSRtecpabI57IOIih8,6751
+twilio/rest/assistants/v1/knowledge/__init__.py,sha256=UQJL3bmsmFhSdV8wC8UIqOLFcYraNHSqReBuwRi9acU,35246
+twilio/rest/assistants/v1/knowledge/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/assistants/v1/knowledge/__pycache__/chunk.cpython-312.pyc,,
+twilio/rest/assistants/v1/knowledge/__pycache__/knowledge_status.cpython-312.pyc,,
+twilio/rest/assistants/v1/knowledge/chunk.py,sha256=RT8yJBkvAHi828_ogPqFOgSbuLTfnpiXFw-k4dNM8Zc,11243
+twilio/rest/assistants/v1/knowledge/knowledge_status.py,sha256=gtY8hL5aUNCjf9UkUgE4EsMRM_C8mKX8PjWYpFJ2NNw,6049
+twilio/rest/assistants/v1/policy.py,sha256=9mFdp1Ze7cK8PfiU7m2hAj7IO-L1LkcOiNK7GuNJk1M,12955
+twilio/rest/assistants/v1/session/__init__.py,sha256=O_cTY3J_UbVtnPgECu53bM1csISk8nodZkCHcEOWrM0,14943
+twilio/rest/assistants/v1/session/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/assistants/v1/session/__pycache__/message.cpython-312.pyc,,
+twilio/rest/assistants/v1/session/message.py,sha256=sZicIuZYgGHv94-QyXJ7esWr65j9nJynzqddU7MhXrE,11964
+twilio/rest/assistants/v1/tool.py,sha256=CZpw1fwlWmRA7Dhoe4z7jdMhbrveigzZEm8EpLEahd8,32256
+twilio/rest/bulkexports/BulkexportsBase.py,sha256=zZVbqHt-GFEwknpCSTIkMnUiy0psGTVr707I65ppqRA,1232
+twilio/rest/bulkexports/__init__.py,sha256=W70NE5bxC2jLDmKtWWL5WUe_hYQeywBIlqfRrQQxsnU,792
+twilio/rest/bulkexports/__pycache__/BulkexportsBase.cpython-312.pyc,,
+twilio/rest/bulkexports/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/bulkexports/v1/__init__.py,sha256=17bpWiEa9ctnhyCFjXOlYLQNcrqMILJ28XTUY5MSeXc,1693
+twilio/rest/bulkexports/v1/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/bulkexports/v1/__pycache__/export_configuration.cpython-312.pyc,,
+twilio/rest/bulkexports/v1/export/__init__.py,sha256=bgpvSCEkYd2P3eq5vtQgLBrne_OBBECJ6_Okc25Ozjw,7262
+twilio/rest/bulkexports/v1/export/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/bulkexports/v1/export/__pycache__/day.cpython-312.pyc,,
+twilio/rest/bulkexports/v1/export/__pycache__/export_custom_job.cpython-312.pyc,,
+twilio/rest/bulkexports/v1/export/__pycache__/job.cpython-312.pyc,,
+twilio/rest/bulkexports/v1/export/day.py,sha256=IGG0nj_6-nwoUjIaD6o7G1g9DZSaWI8YJO_T-brJSog,14990
+twilio/rest/bulkexports/v1/export/export_custom_job.py,sha256=IWcqxrpR7k-KjL07G6lsYKgS-iV8FF7J7diw3reuVLg,17715
+twilio/rest/bulkexports/v1/export/job.py,sha256=kXTZ7jNMacOhtxVibodj8ZtPrT_pbD5B8H_PqnzxKU0,8457
+twilio/rest/bulkexports/v1/export_configuration.py,sha256=BpPQXqAqfj0eKRYZHLZaH5ZfSBae9wQjTCyIYpIqBaU,11316
+twilio/rest/chat/ChatBase.py,sha256=KD32OSHBJlk3FnRUTh5rYBgVCX-8Wd3FxMK-sMbwfCU,1701
+twilio/rest/chat/__init__.py,sha256=yqheEsHshStD2dZwRJIab6Vd7pJ8l99lx6I1D-SDLaA,970
+twilio/rest/chat/__pycache__/ChatBase.cpython-312.pyc,,
+twilio/rest/chat/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/chat/v1/__init__.py,sha256=pIPnbTMhwrC_TrSuEkGC1FMRoI9P0fl7auFCScLZs5g,1570
+twilio/rest/chat/v1/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/chat/v1/__pycache__/credential.cpython-312.pyc,,
+twilio/rest/chat/v1/credential.py,sha256=kSIXMoqKDnyASylYeK1AFS1Jg54UtkEf5NUMlTNNzX4,29186
+twilio/rest/chat/v1/service/__init__.py,sha256=lz04U3hL9dU_Qt1VPCFkG3YGsCO_SPzAS_xKvzovqhY,94603
+twilio/rest/chat/v1/service/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/chat/v1/service/__pycache__/role.cpython-312.pyc,,
+twilio/rest/chat/v1/service/channel/__init__.py,sha256=z4Hm7Wqpl2jj6svVwaZJnVIGS9bJ88K5E6wr_saEu2k,30170
+twilio/rest/chat/v1/service/channel/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/chat/v1/service/channel/__pycache__/invite.cpython-312.pyc,,
+twilio/rest/chat/v1/service/channel/__pycache__/member.cpython-312.pyc,,
+twilio/rest/chat/v1/service/channel/__pycache__/message.cpython-312.pyc,,
+twilio/rest/chat/v1/service/channel/invite.py,sha256=I1AsyjaFixkMSYORBeQzg_uQ2m3v0FZN7kQgVHzrJWg,23225
+twilio/rest/chat/v1/service/channel/member.py,sha256=YK1ZHjFhefjbSOVIpzygcf8YYCeoazPVpHvJyajPSGw,28912
+twilio/rest/chat/v1/service/channel/message.py,sha256=ppCuv00iaqkP9SSlF9GJWm0G8RRZ9zxhr6lwxBU3txw,27559
+twilio/rest/chat/v1/service/role.py,sha256=AirHxVzWEiFdMnZX3sedeYIMzmRBzEmcU6LWAel4TM0,23034
+twilio/rest/chat/v1/service/user/__init__.py,sha256=Bdihokzz7E0wCsRoufK-fZ8EcX62pYwiYzOtlsrJRKE,27518
+twilio/rest/chat/v1/service/user/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/chat/v1/service/user/__pycache__/user_channel.cpython-312.pyc,,
+twilio/rest/chat/v1/service/user/user_channel.py,sha256=7gq6lCWzKU9vknd3Axrqo58lGjKi_euTjoPsqyZ5i1Q,13247
+twilio/rest/chat/v2/__init__.py,sha256=2MmAILBGDLB1r-m1D9B3OuCk0N-b8XosRDGwinn32C0,1570
+twilio/rest/chat/v2/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/chat/v2/__pycache__/credential.cpython-312.pyc,,
+twilio/rest/chat/v2/credential.py,sha256=QyNZAtP6HqEvykxZiNXtcGSvugMufKRUEBeFiNQ4hX4,28816
+twilio/rest/chat/v2/service/__init__.py,sha256=DL8U0qjDj2ZCvIVatGdH-M_biqeOYaY9kFsBjQaJeTs,68767
+twilio/rest/chat/v2/service/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/chat/v2/service/__pycache__/binding.cpython-312.pyc,,
+twilio/rest/chat/v2/service/__pycache__/role.cpython-312.pyc,,
+twilio/rest/chat/v2/service/binding.py,sha256=-g6MZo7KlKODz0ups8aqfXeVW_xbwcvX0TXSknnOvEI,22643
+twilio/rest/chat/v2/service/channel/__init__.py,sha256=lb-UlGCc8j_7ih-LjK5lhXD8_Ur-ZuBuFAbiCT8H7hM,40660
+twilio/rest/chat/v2/service/channel/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/chat/v2/service/channel/__pycache__/invite.cpython-312.pyc,,
+twilio/rest/chat/v2/service/channel/__pycache__/member.cpython-312.pyc,,
+twilio/rest/chat/v2/service/channel/__pycache__/message.cpython-312.pyc,,
+twilio/rest/chat/v2/service/channel/__pycache__/webhook.cpython-312.pyc,,
+twilio/rest/chat/v2/service/channel/invite.py,sha256=EWJyb1ZH36q-e4sSgaUbO0eXWfBmwejRNZBuhg5iqCc,23205
+twilio/rest/chat/v2/service/channel/member.py,sha256=ybSJITkqTN6yGwRdWYuI0k54sIOwE1PR9zVd0Y3u578,42648
+twilio/rest/chat/v2/service/channel/message.py,sha256=WLMbljK0eo3SfeUpi67_vQDYgrrRfNA8FpdxwsKyt8k,39082
+twilio/rest/chat/v2/service/channel/webhook.py,sha256=U_NujpfO7Lg07UFZ3ACPJuXFHl8wUmoupi7cvoYpCTk,34973
+twilio/rest/chat/v2/service/role.py,sha256=YulJAE3beY2sR3ZzZVmdvXuPxGNl4dllNCXQz9kjCRI,23435
+twilio/rest/chat/v2/service/user/__init__.py,sha256=haouJvuAu3H-9L2dDmZyIWc1Y45PFOjNd8c84wHeRb0,30560
+twilio/rest/chat/v2/service/user/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/chat/v2/service/user/__pycache__/user_binding.cpython-312.pyc,,
+twilio/rest/chat/v2/service/user/__pycache__/user_channel.cpython-312.pyc,,
+twilio/rest/chat/v2/service/user/user_binding.py,sha256=0b6_z2ZRybkURNriatBLj6kpbPQSYrZbNkRt-L7Exw8,22434
+twilio/rest/chat/v2/service/user/user_channel.py,sha256=IhLMQn64a0hvrCiY_-29k5oIgG7a7x6wh6lHf71SG5A,27877
+twilio/rest/chat/v3/__init__.py,sha256=iNQ57HwS3IRB3wny2tHXgjL_qW8eN_c37SAGYYMRpAU,1269
+twilio/rest/chat/v3/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/chat/v3/__pycache__/channel.cpython-312.pyc,,
+twilio/rest/chat/v3/channel.py,sha256=poEyzBnZNliy4aS1lPXh024oDRnFHJXZ-1ZSYLgjV8A,12259
+twilio/rest/content/ContentBase.py,sha256=dQqMOWOjQ3xMGuDM2r1W9l2mkrxpxBCubglipq8ZdfM,1469
+twilio/rest/content/__init__.py,sha256=Q9Dc5LDsvNo1f1FttcKGP8uwMr2DDOoyrzdVHjgb5YA,1110
+twilio/rest/content/__pycache__/ContentBase.cpython-312.pyc,,
+twilio/rest/content/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/content/v1/__init__.py,sha256=OJ_jzAzh2Q0NcAQUb3l5ohrBR08wfwDYfLMNwoQZ4No,2025
+twilio/rest/content/v1/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/content/v1/__pycache__/content_and_approvals.cpython-312.pyc,,
+twilio/rest/content/v1/__pycache__/legacy_content.cpython-312.pyc,,
+twilio/rest/content/v1/content/__init__.py,sha256=o_f6Xr8Fttjqy5du6f3oYDoyFSXtB82CZkDLbpKHtP4,88781
+twilio/rest/content/v1/content/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/content/v1/content/__pycache__/approval_create.cpython-312.pyc,,
+twilio/rest/content/v1/content/__pycache__/approval_fetch.cpython-312.pyc,,
+twilio/rest/content/v1/content/approval_create.py,sha256=1LjKaTUSnQU1qCGo6PAv60DPaO6-Et8jeHXLvEmCEM4,5148
+twilio/rest/content/v1/content/approval_fetch.py,sha256=4G4JVwF7-wCC8Nq0vjcyDR-_Z8eAZWzoezXs-c3_z-E,6018
+twilio/rest/content/v1/content_and_approvals.py,sha256=9M0X55_Y-y0Jh-I_gum3c0xQ3oAQ6XYUVZVXIiBFE_4,12244
+twilio/rest/content/v1/legacy_content.py,sha256=icfgdpBAHNHpFqLstktL7e1xQd-siB2R_W6za8NV0k0,12443
+twilio/rest/content/v2/__init__.py,sha256=AEiqhEK9xMUccgKm_QcMCtHuk7cCO_bGTIu-icgBnZ4,1685
+twilio/rest/content/v2/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/content/v2/__pycache__/content.cpython-312.pyc,,
+twilio/rest/content/v2/__pycache__/content_and_approvals.cpython-312.pyc,,
+twilio/rest/content/v2/content.py,sha256=BRqYh2LROOZQMdcVh4OaP0X_8fd2LRqzU5EbFEqBBrw,22457
+twilio/rest/content/v2/content_and_approvals.py,sha256=KIId6S1cJ5rSYed6fPh78DnHzf4aA8QpKD6qe8qbj2g,22787
+twilio/rest/conversations/ConversationsBase.py,sha256=_xLX2JZyT_NNtyDsHn9NVE3LT3rh9x_gSlqFNE5zxyE,1246
+twilio/rest/conversations/__init__.py,sha256=wrtnbo04IMJ0dAyAXcBU2FPCV3fRFfDjjvQdGtNqbiA,2760
+twilio/rest/conversations/__pycache__/ConversationsBase.cpython-312.pyc,,
+twilio/rest/conversations/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/conversations/v1/__init__.py,sha256=8dH1CjGT_tk7xeq5ntTI2gOUnlOPVzVJdKZxIPUoFFE,4218
+twilio/rest/conversations/v1/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/conversations/v1/__pycache__/address_configuration.cpython-312.pyc,,
+twilio/rest/conversations/v1/__pycache__/conversation_with_participants.cpython-312.pyc,,
+twilio/rest/conversations/v1/__pycache__/credential.cpython-312.pyc,,
+twilio/rest/conversations/v1/__pycache__/participant_conversation.cpython-312.pyc,,
+twilio/rest/conversations/v1/__pycache__/role.cpython-312.pyc,,
+twilio/rest/conversations/v1/address_configuration.py,sha256=mk4leUh4m4KeWSVz6qVCscVdzwcBTXDna4L513apDaw,39180
+twilio/rest/conversations/v1/configuration/__init__.py,sha256=mrnQMOVnFnBd34XA_Gkad6lqnXtClH8aAYgNJGAIqNg,13003
+twilio/rest/conversations/v1/configuration/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/conversations/v1/configuration/__pycache__/webhook.cpython-312.pyc,,
+twilio/rest/conversations/v1/configuration/webhook.py,sha256=3MM5VvdVSiuoRZRMgs5nmkri-pzorOrO_ZEc3VT6oeI,13076
+twilio/rest/conversations/v1/conversation/__init__.py,sha256=f2AWwVwbtVxU0LH51yYmJ_bK0nYlcsYmUtnbeUixQpk,51446
+twilio/rest/conversations/v1/conversation/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/conversations/v1/conversation/__pycache__/participant.cpython-312.pyc,,
+twilio/rest/conversations/v1/conversation/__pycache__/webhook.cpython-312.pyc,,
+twilio/rest/conversations/v1/conversation/message/__init__.py,sha256=g5IAs5OQDbINqx3_JzHbSBeuDNYqKWZ2f3d0eR98XR8,37538
+twilio/rest/conversations/v1/conversation/message/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/conversations/v1/conversation/message/__pycache__/delivery_receipt.cpython-312.pyc,,
+twilio/rest/conversations/v1/conversation/message/delivery_receipt.py,sha256=T0yBAlBcYc8HNknohDaYJHwMFeNyHNjctCmKUYlEeYc,18534
+twilio/rest/conversations/v1/conversation/participant.py,sha256=9Wk0CAFor7iX0qgERR-424AssONStbXulEeUY_2N5tI,41653
+twilio/rest/conversations/v1/conversation/webhook.py,sha256=XTmVt7FEMoldiFQiW0KJsSADIOJwu-CE_Z8uR6q_11g,28439
+twilio/rest/conversations/v1/conversation_with_participants.py,sha256=hQfYR85cFKUH9JcFX9ftFj-XByCDAbBVqeL44f_DmnM,13383
+twilio/rest/conversations/v1/credential.py,sha256=AKUOd-i3kzGkvSAJ-5icaVjrP9OulDtluiiZH6fFPQA,29265
+twilio/rest/conversations/v1/participant_conversation.py,sha256=GQ2CBDQPmT2_QnVAtB7jzSzXPfRxDBAehXcD_GCp8RA,19067
+twilio/rest/conversations/v1/role.py,sha256=jBWZCQid-lAbhDiH6eIVeY7KCNUt69GBv0_aGwHU_To,22146
+twilio/rest/conversations/v1/service/__init__.py,sha256=ZwztACi4635N39jM6z87siFcnNjyKVzMxqwvMvH2z4k,21856
+twilio/rest/conversations/v1/service/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/conversations/v1/service/__pycache__/binding.cpython-312.pyc,,
+twilio/rest/conversations/v1/service/__pycache__/conversation_with_participants.cpython-312.pyc,,
+twilio/rest/conversations/v1/service/__pycache__/participant_conversation.cpython-312.pyc,,
+twilio/rest/conversations/v1/service/__pycache__/role.cpython-312.pyc,,
+twilio/rest/conversations/v1/service/binding.py,sha256=TKI13VFqXGLGoNG_gciR2QHoBOjg8vDFsIh-hSOTkEc,22814
+twilio/rest/conversations/v1/service/configuration/__init__.py,sha256=vU4xrwjBZX0xbMk_u-Sxm1_ISfgfrgHVV10O7x0uE1k,16599
+twilio/rest/conversations/v1/service/configuration/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/conversations/v1/service/configuration/__pycache__/notification.cpython-312.pyc,,
+twilio/rest/conversations/v1/service/configuration/__pycache__/webhook.cpython-312.pyc,,
+twilio/rest/conversations/v1/service/configuration/notification.py,sha256=B9Y8Oz1pzZtaPleMLHDsSqdRYHgHzuDaxaj2Bv3IzW4,25509
+twilio/rest/conversations/v1/service/configuration/webhook.py,sha256=cY9V3K2ByznSMatOQeKvpT7lrmfxqU42pmdFyQWlfvA,14319
+twilio/rest/conversations/v1/service/conversation/__init__.py,sha256=uYgWc-u_SLSx16a3oxQ3gv6eEtxs0WmnE7bN68yr0Ng,53297
+twilio/rest/conversations/v1/service/conversation/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/conversations/v1/service/conversation/__pycache__/participant.cpython-312.pyc,,
+twilio/rest/conversations/v1/service/conversation/__pycache__/webhook.cpython-312.pyc,,
+twilio/rest/conversations/v1/service/conversation/message/__init__.py,sha256=QPH2y1ttmlREN9c-m9gg34p0MZEBLj_SiSvAuTMNMzI,39195
+twilio/rest/conversations/v1/service/conversation/message/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/conversations/v1/service/conversation/message/__pycache__/delivery_receipt.cpython-312.pyc,,
+twilio/rest/conversations/v1/service/conversation/message/delivery_receipt.py,sha256=PpNlvz6SH6tsalMba69lkD7UL2Z3eqKi475Ig22SOZE,19869
+twilio/rest/conversations/v1/service/conversation/participant.py,sha256=M3blybA18uatyzT55fI5I45OzRoGkOWwLhczk1ia280,43630
+twilio/rest/conversations/v1/service/conversation/webhook.py,sha256=eJJQim1Q87xIMkNBOy9fXhR9WAhsiNqZnOXIFeY0AgU,30129
+twilio/rest/conversations/v1/service/conversation_with_participants.py,sha256=2MSv8o1xtWq2tlUd0JbR0K1-KAe8kMl4dkLmmGaAg2k,14204
+twilio/rest/conversations/v1/service/participant_conversation.py,sha256=1GCqZGj-BtLkEQlqJf1SWhXQCZcWjGhViIVaGBgJurc,19858
+twilio/rest/conversations/v1/service/role.py,sha256=Lz7PcgnuPvmBDLO7Ml1LmLpxaMFqZgN4jYas1Q9bpCs,23737
+twilio/rest/conversations/v1/service/user/__init__.py,sha256=fjp1dkaaQwL1KSQ0Yp1iIjSdjFO6mbXsb6Lfd_kmV74,31219
+twilio/rest/conversations/v1/service/user/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/conversations/v1/service/user/__pycache__/user_conversation.cpython-312.pyc,,
+twilio/rest/conversations/v1/service/user/user_conversation.py,sha256=SHiSIItso8VNGoU3h9_vxl82AG1GUj_U3mbvJn3hM3c,27325
+twilio/rest/conversations/v1/user/__init__.py,sha256=GGbwZDCEJeHoR-CyxYLb333-h3PvsWwhxd_-8-FzY5Q,29553
+twilio/rest/conversations/v1/user/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/conversations/v1/user/__pycache__/user_conversation.cpython-312.pyc,,
+twilio/rest/conversations/v1/user/user_conversation.py,sha256=10XdwEZeyEcaRg0XkKOB9qtbXDPbMq5JYm2laPESZAw,26030
+twilio/rest/events/EventsBase.py,sha256=VmnvvHtsOqJHgao-2Db4suiqZbpRmzlbR_0mkXyg-yg,1197
+twilio/rest/events/__init__.py,sha256=0c7O0oWx1KIrwS_tzCy8c34OkPJfqXCK_9lULiGi_7s,1277
+twilio/rest/events/__pycache__/EventsBase.cpython-312.pyc,,
+twilio/rest/events/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/events/v1/__init__.py,sha256=gxoinjjx5rqW0zUxOp6Ild8m1mNG8zayV5-nnlbCR-Q,2134
+twilio/rest/events/v1/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/events/v1/__pycache__/event_type.cpython-312.pyc,,
+twilio/rest/events/v1/event_type.py,sha256=LP6dyDkCj_SP237YQOAEPoqu1awzUYb51P6Y3vOSElo,16265
+twilio/rest/events/v1/schema/__init__.py,sha256=lY5TfjZ40DF7MTZuOzvUX992RBGlbH2roGhFxlYbmLE,6575
+twilio/rest/events/v1/schema/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/events/v1/schema/__pycache__/schema_version.cpython-312.pyc,,
+twilio/rest/events/v1/schema/schema_version.py,sha256=vPU4IXvWWi0lNSg96JaHFqG1lG1n4VJcaGZVQxl9ZRY,15389
+twilio/rest/events/v1/sink/__init__.py,sha256=V1SUPy4QT_rXFfZSOv61L8UPL6ziHfmpt8IswZMqWCc,24157
+twilio/rest/events/v1/sink/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/events/v1/sink/__pycache__/sink_test.cpython-312.pyc,,
+twilio/rest/events/v1/sink/__pycache__/sink_validate.cpython-312.pyc,,
+twilio/rest/events/v1/sink/sink_test.py,sha256=wqSIshtRm7x1gmDS7wfllqtGBm4vUqxrXxY9uNZnKcs,3048
+twilio/rest/events/v1/sink/sink_validate.py,sha256=px942vCIcWnG9uTd6l7sdUeGO535hoYUB34XfSKzbY0,3747
+twilio/rest/events/v1/subscription/__init__.py,sha256=oqYgQLe3aV_K4IJCBN_GOsXouhoRwQX7Wai8Ns3u0Zg,23810
+twilio/rest/events/v1/subscription/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/events/v1/subscription/__pycache__/subscribed_event.cpython-312.pyc,,
+twilio/rest/events/v1/subscription/subscribed_event.py,sha256=KKHkkPzKU5eGtTx8D-aD3JN4-TLaqj7CGTUCCYWOLL8,21483
+twilio/rest/flex_api/FlexApiBase.py,sha256=uej-QbJtfmiUEUj54Hs5nXUoUmeWUnebYCqlHZ__Nck,1472
+twilio/rest/flex_api/__init__.py,sha256=95CohrSn9QGa5NEMqi1FfZ0ojxuqK5rVvszrR0NQd9Q,6332
+twilio/rest/flex_api/__pycache__/FlexApiBase.cpython-312.pyc,,
+twilio/rest/flex_api/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/flex_api/v1/__init__.py,sha256=obnvo_MQ0rmSwmTbgQk7DEM9fxHwuMxmkJeL3_4BP30,10023
+twilio/rest/flex_api/v1/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/flex_api/v1/__pycache__/assessments.cpython-312.pyc,,
+twilio/rest/flex_api/v1/__pycache__/channel.cpython-312.pyc,,
+twilio/rest/flex_api/v1/__pycache__/configuration.cpython-312.pyc,,
+twilio/rest/flex_api/v1/__pycache__/flex_flow.cpython-312.pyc,,
+twilio/rest/flex_api/v1/__pycache__/insights_assessments_comment.cpython-312.pyc,,
+twilio/rest/flex_api/v1/__pycache__/insights_conversations.cpython-312.pyc,,
+twilio/rest/flex_api/v1/__pycache__/insights_questionnaires.cpython-312.pyc,,
+twilio/rest/flex_api/v1/__pycache__/insights_questionnaires_category.cpython-312.pyc,,
+twilio/rest/flex_api/v1/__pycache__/insights_questionnaires_question.cpython-312.pyc,,
+twilio/rest/flex_api/v1/__pycache__/insights_segments.cpython-312.pyc,,
+twilio/rest/flex_api/v1/__pycache__/insights_session.cpython-312.pyc,,
+twilio/rest/flex_api/v1/__pycache__/insights_settings_answer_sets.cpython-312.pyc,,
+twilio/rest/flex_api/v1/__pycache__/insights_settings_comment.cpython-312.pyc,,
+twilio/rest/flex_api/v1/__pycache__/insights_user_roles.cpython-312.pyc,,
+twilio/rest/flex_api/v1/__pycache__/plugin_archive.cpython-312.pyc,,
+twilio/rest/flex_api/v1/__pycache__/plugin_configuration_archive.cpython-312.pyc,,
+twilio/rest/flex_api/v1/__pycache__/plugin_release.cpython-312.pyc,,
+twilio/rest/flex_api/v1/__pycache__/plugin_version_archive.cpython-312.pyc,,
+twilio/rest/flex_api/v1/__pycache__/provisioning_status.cpython-312.pyc,,
+twilio/rest/flex_api/v1/__pycache__/web_channel.cpython-312.pyc,,
+twilio/rest/flex_api/v1/assessments.py,sha256=V9qcvA7siGHPibeVTZrHMFZ7M6x2LaHfMjjHgqFrMpc,24804
+twilio/rest/flex_api/v1/channel.py,sha256=yLGvmFX1n8wGcxYkMu1jtbesmwmwy7Dps3P_dv2mDKs,20775
+twilio/rest/flex_api/v1/configuration.py,sha256=4orBSh9VTT9XR3rXnk6sOtGTcoOgNYjmH7g_fPWI0lQ,16390
+twilio/rest/flex_api/v1/flex_flow.py,sha256=WEc_bJfuyuX6QMrxTYwlHbq6BaXvyMmI1khdAFzL4vA,48692
+twilio/rest/flex_api/v1/insights_assessments_comment.py,sha256=yWj0JBRafpvk2eY_E8RqQOcw_-TDai7AGniC4m8bZ2c,18263
+twilio/rest/flex_api/v1/insights_conversations.py,sha256=e4RDXZL5ixoxia9IMXOQH48pxkYxnikA0xcLfK8AfEE,13403
+twilio/rest/flex_api/v1/insights_questionnaires.py,sha256=YiGf1i74hxkJ0Av3k2f_UpAC7vXhrLEggbwLClWzVkY,29788
+twilio/rest/flex_api/v1/insights_questionnaires_category.py,sha256=9a7q2C35bIhYi9rQchkhBXTtDYfCADz6DyNjpTRA_gw,22522
+twilio/rest/flex_api/v1/insights_questionnaires_question.py,sha256=7WThQaMXdhYzP0BcgUVr-_2mZPKpC1Bm6lYyLvHfBU0,28319
+twilio/rest/flex_api/v1/insights_segments.py,sha256=UELfB0Mdnlm9qodiTh6OFDZPce90CnqEFfcHiYywLbw,16466
+twilio/rest/flex_api/v1/insights_session.py,sha256=bc4_hAx5exIgh0at-hmnAECjAh3ur33MguxMi4JjIRE,5688
+twilio/rest/flex_api/v1/insights_settings_answer_sets.py,sha256=-ti-THOVV7-H3GJyN3WLj1P5DfSMqXtPw9Kmg0Ri1Ao,3987
+twilio/rest/flex_api/v1/insights_settings_comment.py,sha256=CQ8a8-toTifomRxGJqsjiMEC0gMV8mGxU6Q-2N4CbzU,3568
+twilio/rest/flex_api/v1/insights_user_roles.py,sha256=KEmrtjjlSJdXIPqh4L5QwSNKDb7U3O5U9ufpX7CYiMo,5583
+twilio/rest/flex_api/v1/interaction/__init__.py,sha256=056bAYLNB5qkw5g1EAeLC1hzRQTBLhHPpRLP_liqjZk,12738
+twilio/rest/flex_api/v1/interaction/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/flex_api/v1/interaction/interaction_channel/__init__.py,sha256=4h-o492vXOZs1tM7JH5wTvUNbnjLY_ADG_AE_-6OIOE,23059
+twilio/rest/flex_api/v1/interaction/interaction_channel/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/flex_api/v1/interaction/interaction_channel/__pycache__/interaction_channel_invite.cpython-312.pyc,,
+twilio/rest/flex_api/v1/interaction/interaction_channel/__pycache__/interaction_channel_participant.cpython-312.pyc,,
+twilio/rest/flex_api/v1/interaction/interaction_channel/__pycache__/interaction_transfer.cpython-312.pyc,,
+twilio/rest/flex_api/v1/interaction/interaction_channel/interaction_channel_invite.py,sha256=r_9xfu6Cn2IzB8vjOCahqBOKOHRD2WJEXpaRnLy2i0w,14571
+twilio/rest/flex_api/v1/interaction/interaction_channel/interaction_channel_participant.py,sha256=rPlAhdDU4eg-GT4Jm9B_J2C1jXVrzcpgAwGgMHqU_gg,21534
+twilio/rest/flex_api/v1/interaction/interaction_channel/interaction_transfer.py,sha256=sMdG-j_Gqk1R_8bqEu-IV1KOWQ_7RSTHoxNiQ2JMSeI,13562
+twilio/rest/flex_api/v1/plugin/__init__.py,sha256=tDHboT1oPnJ-sqjDY_gZUcUlwNe-W0GFFdCbCIw3yt8,24859
+twilio/rest/flex_api/v1/plugin/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/flex_api/v1/plugin/__pycache__/plugin_versions.cpython-312.pyc,,
+twilio/rest/flex_api/v1/plugin/plugin_versions.py,sha256=jAUztORMeQqbKS7W7HzY5JahmEWA0zid4pD00IdJ8IQ,22650
+twilio/rest/flex_api/v1/plugin_archive.py,sha256=C9QY5HU6Ge48qKfVTwAPWo7hNR21gFgH0jS26jQe9eo,7951
+twilio/rest/flex_api/v1/plugin_configuration/__init__.py,sha256=NeTdo-f7C0iPYcV1xCEQbyoulbS6UQbB7ecyMxpEPko,21237
+twilio/rest/flex_api/v1/plugin_configuration/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/flex_api/v1/plugin_configuration/__pycache__/configured_plugin.cpython-312.pyc,,
+twilio/rest/flex_api/v1/plugin_configuration/configured_plugin.py,sha256=hXVC4o0uSWnIcq3ULPH7EMHjfBFRa92r-8qM6mRBEbI,20249
+twilio/rest/flex_api/v1/plugin_configuration_archive.py,sha256=6JAyPB76AgNmj290Mtwc4co7nPiVgzB0mpC0lKtBmrU,8094
+twilio/rest/flex_api/v1/plugin_release.py,sha256=DHWrxcVdJNaBofYRlBSxDb5knG39e_bFZndz9jdtrw0,18932
+twilio/rest/flex_api/v1/plugin_version_archive.py,sha256=-dxjlhquldQRPNascrY8TCWHdSlog7XNwGvN0tXzLt0,9101
+twilio/rest/flex_api/v1/provisioning_status.py,sha256=buD8d9ddh3mlingquoYGBQit0Ujuhuwo9CR__Vtu_vA,4918
+twilio/rest/flex_api/v1/web_channel.py,sha256=BxDf5RFPLu4stg9V8rX2tli_veY892He189T-ybdvJ4,22024
+twilio/rest/flex_api/v2/__init__.py,sha256=WMe1F3S9rix25wT-TMn9o4BdKxc65EeMjC1VyDUWgyE,1610
+twilio/rest/flex_api/v2/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/flex_api/v2/__pycache__/flex_user.cpython-312.pyc,,
+twilio/rest/flex_api/v2/__pycache__/web_channels.cpython-312.pyc,,
+twilio/rest/flex_api/v2/flex_user.py,sha256=atkcufDa6QwJPQM0C3Zk3RNiEs8wIwqjGmUaDQvDbw4,11739
+twilio/rest/flex_api/v2/web_channels.py,sha256=tgBOhRiHkdKKGabc6o0gMDIJSXkiqX2rvop21zJKQjY,6396
+twilio/rest/frontline_api/FrontlineApiBase.py,sha256=LxpGZeNOYqlqYNh8VxMXZoDR_z13_Nh36r-vRQYUDRE,1241
+twilio/rest/frontline_api/__init__.py,sha256=dY4Pp2907z2kTJJ3jaSt4pX9-qP3t36LRK1Zs8Yniog,410
+twilio/rest/frontline_api/__pycache__/FrontlineApiBase.cpython-312.pyc,,
+twilio/rest/frontline_api/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/frontline_api/v1/__init__.py,sha256=AcNIDcakdTFSUXD3AF55ot77IsixzC-rJAPP9Cs6A4I,1278
+twilio/rest/frontline_api/v1/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/frontline_api/v1/__pycache__/user.cpython-312.pyc,,
+twilio/rest/frontline_api/v1/user.py,sha256=IrXEAr_ZHznL6QlbTqe3RqnzthdiNLyoPfQMLqZo0D0,11329
+twilio/rest/iam/IamBase.py,sha256=2VtqB_DfMQWvBNKmGpnVIv7cFhU_210bV0X_WeP77Z4,1176
+twilio/rest/iam/__init__.py,sha256=LxDMjMsrLsWeQPOe8NPXEs39BB0ngAotZuntX9pew9E,679
+twilio/rest/iam/__pycache__/IamBase.cpython-312.pyc,,
+twilio/rest/iam/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/iam/v1/__init__.py,sha256=vMJItvxisyNy-OiJaIKOElhq2z5aUyCsjJvybTGrcNc,2104
+twilio/rest/iam/v1/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/iam/v1/__pycache__/api_key.cpython-312.pyc,,
+twilio/rest/iam/v1/__pycache__/get_api_keys.cpython-312.pyc,,
+twilio/rest/iam/v1/__pycache__/new_api_key.cpython-312.pyc,,
+twilio/rest/iam/v1/__pycache__/token.cpython-312.pyc,,
+twilio/rest/iam/v1/api_key.py,sha256=rGuFKiia8IQml7TxUMwdcs_9YNqZDCXm6JJ_UyyKDtk,11776
+twilio/rest/iam/v1/get_api_keys.py,sha256=4svxSithdku2x4NAWSNc9q819QEWJcPSw2ye02mrOq8,12220
+twilio/rest/iam/v1/new_api_key.py,sha256=V4aDUDMpSBdbmHZgG2rvTixnz0pXhLuFp5ASD87U6uk,6387
+twilio/rest/iam/v1/token.py,sha256=P-0XE0J6i2tEjl_W2_BXGjXu1wE_kCNjElN9bN0i_8Y,6048
+twilio/rest/insights/InsightsBase.py,sha256=E0d9cswKhgPZByiFy51V7AGE-TiQ7lZOB1hbGOczY7Q,1211
+twilio/rest/insights/__init__.py,sha256=quAZLguZrWAk1irDvVn1ChI9LgdMewLt9SO_YgfGkzQ,1579
+twilio/rest/insights/__pycache__/InsightsBase.cpython-312.pyc,,
+twilio/rest/insights/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/insights/v1/__init__.py,sha256=CQgywgxUWHdv3N_p5I_-SpoczEh6-Q2TvrQE7BZAJoQ,2420
+twilio/rest/insights/v1/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/insights/v1/__pycache__/call_summaries.cpython-312.pyc,,
+twilio/rest/insights/v1/__pycache__/setting.cpython-312.pyc,,
+twilio/rest/insights/v1/call/__init__.py,sha256=BwO0pCW0XHN3kPsb1cCRsj2l9Xay5mlWsxZEl9xsA-8,7160
+twilio/rest/insights/v1/call/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/insights/v1/call/__pycache__/annotation.cpython-312.pyc,,
+twilio/rest/insights/v1/call/__pycache__/call_summary.cpython-312.pyc,,
+twilio/rest/insights/v1/call/__pycache__/event.cpython-312.pyc,,
+twilio/rest/insights/v1/call/__pycache__/metric.cpython-312.pyc,,
+twilio/rest/insights/v1/call/annotation.py,sha256=2hQqz6BcQ9KUVqD4b-yi1x2snCBVvmalUieHkfnQC1Y,18056
+twilio/rest/insights/v1/call/call_summary.py,sha256=P7jJITDSrn5dAwrxWQazAh20OjZnchhKd4peQxKM9E0,11418
+twilio/rest/insights/v1/call/event.py,sha256=foL0V6owoVlDBt3f0Iz8CpCJc0f7QaI-qt8fyHZT0Lw,13972
+twilio/rest/insights/v1/call/metric.py,sha256=15TxR0D7bV-uKkoleu7G-1DuJQLqVSEdEna8WNgPSh0,15144
+twilio/rest/insights/v1/call_summaries.py,sha256=cINt0JH-X6b-56LxEn4_sckHqFYka8AUyPBa8_D5CNI,70422
+twilio/rest/insights/v1/conference/__init__.py,sha256=9aeY6AJKYAdLaQwR-SsomHllZ8wnKeEzQ5-ndYqZNMo,31953
+twilio/rest/insights/v1/conference/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/insights/v1/conference/__pycache__/conference_participant.cpython-312.pyc,,
+twilio/rest/insights/v1/conference/conference_participant.py,sha256=ZvkMdXmIS7XjvV6Yj6r-JKYrW6DL0UO3fHiO1rF_I5s,25819
+twilio/rest/insights/v1/room/__init__.py,sha256=Xa5uJ9BUT-RDugYk_tWw_PKZzMpsvrw52fX7-H9VevQ,26172
+twilio/rest/insights/v1/room/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/insights/v1/room/__pycache__/participant.cpython-312.pyc,,
+twilio/rest/insights/v1/room/participant.py,sha256=Y4sR3e8KrlqTAle4-QN40Uswn3hWcxhiI2EVxhXBC7E,18834
+twilio/rest/insights/v1/setting.py,sha256=nDlNCACxZwW7GHikDMq3NRmxqYuKfnRdODbpdD8n9iA,9670
+twilio/rest/intelligence/IntelligenceBase.py,sha256=IKwaNvPV9xaBmfpigqsK4zwhtfYDnV5pIf9mmonGVhs,1239
+twilio/rest/intelligence/__init__.py,sha256=F98_JVdUwFkjg-k58c8j6A45f_5HGYyW7mEoCziqMUk,417
+twilio/rest/intelligence/__pycache__/IntelligenceBase.cpython-312.pyc,,
+twilio/rest/intelligence/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/intelligence/v2/__init__.py,sha256=fSaSi1PPutIUr8tPsEWTaQ1jijDddwHuHVYjxzPSXPI,3757
+twilio/rest/intelligence/v2/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/intelligence/v2/__pycache__/custom_operator.cpython-312.pyc,,
+twilio/rest/intelligence/v2/__pycache__/operator.cpython-312.pyc,,
+twilio/rest/intelligence/v2/__pycache__/operator_attachment.cpython-312.pyc,,
+twilio/rest/intelligence/v2/__pycache__/operator_attachments.cpython-312.pyc,,
+twilio/rest/intelligence/v2/__pycache__/operator_type.cpython-312.pyc,,
+twilio/rest/intelligence/v2/__pycache__/prebuilt_operator.cpython-312.pyc,,
+twilio/rest/intelligence/v2/__pycache__/service.cpython-312.pyc,,
+twilio/rest/intelligence/v2/custom_operator.py,sha256=uctBMPQL810btmlS3LERqNaV5ZMLr0fu0DppbvoA2jQ,26696
+twilio/rest/intelligence/v2/operator.py,sha256=WKTNgW0Axck1mtS-Vah5HROLSE4p3jph4_c5b8H3_nc,18628
+twilio/rest/intelligence/v2/operator_attachment.py,sha256=ulpXpj5ZqtrUoVGIgF7op-UfHI_MPbnhmAXmwRGMqUU,7771
+twilio/rest/intelligence/v2/operator_attachments.py,sha256=XXB99Jvs_mKaH0zFcQ1tGWGplv0y8eT85L7dRm-ppZI,6005
+twilio/rest/intelligence/v2/operator_type.py,sha256=1c1BaUryfGKcANaADnVc-dmmgDZEBhrZwMDkYWM24Cw,16722
+twilio/rest/intelligence/v2/prebuilt_operator.py,sha256=5ymQj1za1_F2ZthxVh-0KL-BNo9gdDYVi1ITLAn2ev0,19605
+twilio/rest/intelligence/v2/service.py,sha256=XkJ20q3KxaQlQG0qrDNy91-Yy1CnEKg_6R9r6xfQ20w,35447
+twilio/rest/intelligence/v2/transcript/__init__.py,sha256=XX_LMUy-4YWJRQfCX2OEgcHkHYYIf8xvEwM4Nbv0k6M,29951
+twilio/rest/intelligence/v2/transcript/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/intelligence/v2/transcript/__pycache__/media.cpython-312.pyc,,
+twilio/rest/intelligence/v2/transcript/__pycache__/operator_result.cpython-312.pyc,,
+twilio/rest/intelligence/v2/transcript/__pycache__/sentence.cpython-312.pyc,,
+twilio/rest/intelligence/v2/transcript/media.py,sha256=FY-Z_NacoIjrwg2Y4QI84uh3aI8uwLGHWYc17KHrwjs,6730
+twilio/rest/intelligence/v2/transcript/operator_result.py,sha256=oqKPKHOG-xx0L3Hq015iClodq8Te_vQg7KKz-Qrpv00,21124
+twilio/rest/intelligence/v2/transcript/sentence.py,sha256=7kw4sl8RwWUVb7PwKgk6wAltu8m0QVOAatXNblX867I,14882
+twilio/rest/ip_messaging/IpMessagingBase.py,sha256=Auoz1W9XNlV8F6owgPNOKpYY93GZnvtpYzUAzYQXyws,1508
+twilio/rest/ip_messaging/__init__.py,sha256=9mxOrxP0A0GodgNQW2cfokhI3-Ejo3MiX9EcPzBrY9s,738
+twilio/rest/ip_messaging/__pycache__/IpMessagingBase.cpython-312.pyc,,
+twilio/rest/ip_messaging/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/ip_messaging/v1/__init__.py,sha256=NppQLF43kYaFcWw_ipWY9LDyWN1DH2b_lLbNm2H6okA,1616
+twilio/rest/ip_messaging/v1/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/ip_messaging/v1/__pycache__/credential.cpython-312.pyc,,
+twilio/rest/ip_messaging/v1/credential.py,sha256=Lnf1H1sbLUfvpwIQofouScgrobA5BZ6aSD-YE4ygUr8,22962
+twilio/rest/ip_messaging/v1/service/__init__.py,sha256=oY3Or2h1KK3KL8Y_Y5QQX-TnbhjotH21AUfg8nQw8Ic,64889
+twilio/rest/ip_messaging/v1/service/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/ip_messaging/v1/service/__pycache__/role.cpython-312.pyc,,
+twilio/rest/ip_messaging/v1/service/channel/__init__.py,sha256=Yo605xbth1i8z6D8VM2TJ3FeYb9urX6LZ_BoMAiN9Rk,25267
+twilio/rest/ip_messaging/v1/service/channel/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/ip_messaging/v1/service/channel/__pycache__/invite.cpython-312.pyc,,
+twilio/rest/ip_messaging/v1/service/channel/__pycache__/member.cpython-312.pyc,,
+twilio/rest/ip_messaging/v1/service/channel/__pycache__/message.cpython-312.pyc,,
+twilio/rest/ip_messaging/v1/service/channel/invite.py,sha256=J8jV8pnxqc0hG9fEZMYLYHBju6nSS0foRObiGne4T8A,19454
+twilio/rest/ip_messaging/v1/service/channel/member.py,sha256=0V9K59QUR7vk-lXwLmiwj3Y_ceneNM21pu-2Fl5KraE,22928
+twilio/rest/ip_messaging/v1/service/channel/message.py,sha256=gOoi_0Bl8VTLXiOLc-05ib4d2_Vaezh6twbUCYdocBY,23021
+twilio/rest/ip_messaging/v1/service/role.py,sha256=hJIZ4WiPVDL2edpLMo5utVzTI3MBN3-5YvMYfeanb2Y,20058
+twilio/rest/ip_messaging/v1/service/user/__init__.py,sha256=rIdOSPhxnSffqxTzLX0H1fG8nR0YeHP8tisppnexS-M,22566
+twilio/rest/ip_messaging/v1/service/user/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/ip_messaging/v1/service/user/__pycache__/user_channel.cpython-312.pyc,,
+twilio/rest/ip_messaging/v1/service/user/user_channel.py,sha256=__2mYHonWu6GkyJiXMMV2VEaMBru88OaMnvzL7cY3fc,11870
+twilio/rest/ip_messaging/v2/__init__.py,sha256=7jGoUJ93kos9yv2hkMzA5vflhMYUYzVY92S9Z9B6NlU,1616
+twilio/rest/ip_messaging/v2/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/ip_messaging/v2/__pycache__/credential.cpython-312.pyc,,
+twilio/rest/ip_messaging/v2/credential.py,sha256=H88g_73iSdVta78v5IJpLs4XBkTAnrt82Ub_bEUzAJQ,22962
+twilio/rest/ip_messaging/v2/service/__init__.py,sha256=Iu928DalMsJqC2d3BtW32luMh0g-8wgld3TdMftuz3Y,47587
+twilio/rest/ip_messaging/v2/service/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/ip_messaging/v2/service/__pycache__/binding.cpython-312.pyc,,
+twilio/rest/ip_messaging/v2/service/__pycache__/role.cpython-312.pyc,,
+twilio/rest/ip_messaging/v2/service/binding.py,sha256=gUCWroQ24j-BXqZE7LzTjhnKNCKM_cGJsOz6Q05GBqQ,18432
+twilio/rest/ip_messaging/v2/service/channel/__init__.py,sha256=o49rPokvhl8WjfK7PJ5nwrm3Laf6CQCQGrvVm_hh1GI,32105
+twilio/rest/ip_messaging/v2/service/channel/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/ip_messaging/v2/service/channel/__pycache__/invite.cpython-312.pyc,,
+twilio/rest/ip_messaging/v2/service/channel/__pycache__/member.cpython-312.pyc,,
+twilio/rest/ip_messaging/v2/service/channel/__pycache__/message.cpython-312.pyc,,
+twilio/rest/ip_messaging/v2/service/channel/__pycache__/webhook.cpython-312.pyc,,
+twilio/rest/ip_messaging/v2/service/channel/invite.py,sha256=7BYSk3PKypYrrhslndER3REoy70Rb-c9rubgsqeDbQo,19454
+twilio/rest/ip_messaging/v2/service/channel/member.py,sha256=2OgOiAqMWZEmoMHFWDAd5aSe84MS9s1tKMrUxSvJL_M,31059
+twilio/rest/ip_messaging/v2/service/channel/message.py,sha256=OgviUUENynQghtlezC9ZuqLZ-w4YGa6Nknf9cObp0ic,30335
+twilio/rest/ip_messaging/v2/service/channel/webhook.py,sha256=tTvnLCmwG9uia0oYURA12FCA9y6eD_zVqH6WUs0_2LM,27378
+twilio/rest/ip_messaging/v2/service/role.py,sha256=Ug1dUlCedwgJMXhbImwhtOEmMSYGYxF2gEjN72RxX-E,20058
+twilio/rest/ip_messaging/v2/service/user/__init__.py,sha256=nZlU7FtSmZ0CKjZ9Yaoa0_YGwElKmJzGwsRoPYWxnBI,25576
+twilio/rest/ip_messaging/v2/service/user/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/ip_messaging/v2/service/user/__pycache__/user_binding.cpython-312.pyc,,
+twilio/rest/ip_messaging/v2/service/user/__pycache__/user_channel.cpython-312.pyc,,
+twilio/rest/ip_messaging/v2/service/user/user_binding.py,sha256=u9YDRNfj-vA44eLFBp-yN_ywsJNlP5d2X5712dn7m3k,18717
+twilio/rest/ip_messaging/v2/service/user/user_channel.py,sha256=MVOYLEcKUWGX-1d_dpOEx2IlqzMDX-PWtPcfHUqegGw,22291
+twilio/rest/lookups/LookupsBase.py,sha256=mH77GksjdX4_ynK3OmtPAjMIboayKFZBTcx8fpQk544,1469
+twilio/rest/lookups/__init__.py,sha256=LDDJTWTOQ1TyhW8ZWS-XfJfF3zO93E5PPyaTzR_6j1g,432
+twilio/rest/lookups/__pycache__/LookupsBase.cpython-312.pyc,,
+twilio/rest/lookups/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/lookups/v1/__init__.py,sha256=2wsVTUfxrQaxpH18BvIJTnU-00nq-Y3bCOTymJjfTZk,1330
+twilio/rest/lookups/v1/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/lookups/v1/__pycache__/phone_number.cpython-312.pyc,,
+twilio/rest/lookups/v1/phone_number.py,sha256=FPgslzNCHuOzQs7q_pfn3h1nnw1RAxzO6OB6ZbC5Ybg,12790
+twilio/rest/lookups/v2/__init__.py,sha256=ngFacNsEH1hxQOpRWj4067Te6fxzhLYeQLr_gr0pBDU,1330
+twilio/rest/lookups/v2/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/lookups/v2/__pycache__/phone_number.cpython-312.pyc,,
+twilio/rest/lookups/v2/phone_number.py,sha256=i9HcLX1P6uljXBLvQOEExRDl_no2mdh2X1E_-swny_Q,26525
+twilio/rest/marketplace/MarketplaceBase.py,sha256=1mfggmVz9sJyhE8pjMrplw521ZbCvhDuHO8n1U8BC5A,1232
+twilio/rest/marketplace/__init__.py,sha256=kUvdmbOANktX1ZFzZtF4vuv0RzdDukVFO1IF-r0dSPA,255
+twilio/rest/marketplace/__pycache__/MarketplaceBase.cpython-312.pyc,,
+twilio/rest/marketplace/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/marketplace/v1/__init__.py,sha256=v9bI7ImeSQ7dY5szR6cuyQcXQM5nyVTMwkouirJUrqU,2859
+twilio/rest/marketplace/v1/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/marketplace/v1/__pycache__/module_data.cpython-312.pyc,,
+twilio/rest/marketplace/v1/__pycache__/module_data_management.cpython-312.pyc,,
+twilio/rest/marketplace/v1/__pycache__/referral_conversion.cpython-312.pyc,,
+twilio/rest/marketplace/v1/available_add_on/__init__.py,sha256=hY_5irnPG1mp84zp0n9NYAIS4p0FNn13xi0j6s8X2kU,15515
+twilio/rest/marketplace/v1/available_add_on/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/marketplace/v1/available_add_on/__pycache__/available_add_on_extension.cpython-312.pyc,,
+twilio/rest/marketplace/v1/available_add_on/available_add_on_extension.py,sha256=BViTDTPYR3hfsXjC-fk9KU-BTM1DqpICu9i3XuywOoQ,16616
+twilio/rest/marketplace/v1/installed_add_on/__init__.py,sha256=tkGiOOet4_rdBoVEmZb_rPzfC4l9Y4_Ch0zu-TIUkp0,25232
+twilio/rest/marketplace/v1/installed_add_on/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/marketplace/v1/installed_add_on/__pycache__/installed_add_on_extension.cpython-312.pyc,,
+twilio/rest/marketplace/v1/installed_add_on/__pycache__/installed_add_on_usage.cpython-312.pyc,,
+twilio/rest/marketplace/v1/installed_add_on/installed_add_on_extension.py,sha256=kpWthj74_ok2wf-FY_K34V5qTlP9lj8T0tFVB9q0jZk,19352
+twilio/rest/marketplace/v1/installed_add_on/installed_add_on_usage.py,sha256=LpDTGm1IxQxSyJ6CqF4yIQEMqleREOP2jjGPwMX80ss,8309
+twilio/rest/marketplace/v1/module_data.py,sha256=SeSgNjkzMIa6REYi18jtW6Uq344g-mpV1-HlEBnl2rs,6833
+twilio/rest/marketplace/v1/module_data_management.py,sha256=n5SP2hCyfgQ1SMjg-btAW3Qz7Nm5ltt5DjqKsv2ekrk,16162
+twilio/rest/marketplace/v1/referral_conversion.py,sha256=em9lnu-qLHXKhT_Q6EMyt5m_8M8ESBRDsuqPV85qksQ,4122
+twilio/rest/messaging/MessagingBase.py,sha256=X8EKE7NkpXB6ZFrJW6kFEaNCeaSaMgsR7f-qeBnSPUk,1487
+twilio/rest/messaging/__init__.py,sha256=b_aOOaeRTDPGh-xajYYKry13McI3bmeF050u6j2UXa8,3308
+twilio/rest/messaging/__pycache__/MessagingBase.cpython-312.pyc,,
+twilio/rest/messaging/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/messaging/v1/__init__.py,sha256=WdGN6ZanVxdTWNmYZBwmvQe5AcQnXbATRC7wMyhGwiA,6006
+twilio/rest/messaging/v1/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/messaging/v1/__pycache__/deactivations.cpython-312.pyc,,
+twilio/rest/messaging/v1/__pycache__/domain_certs.cpython-312.pyc,,
+twilio/rest/messaging/v1/__pycache__/domain_config.cpython-312.pyc,,
+twilio/rest/messaging/v1/__pycache__/domain_config_messaging_service.cpython-312.pyc,,
+twilio/rest/messaging/v1/__pycache__/external_campaign.cpython-312.pyc,,
+twilio/rest/messaging/v1/__pycache__/linkshortening_messaging_service.cpython-312.pyc,,
+twilio/rest/messaging/v1/__pycache__/linkshortening_messaging_service_domain_association.cpython-312.pyc,,
+twilio/rest/messaging/v1/__pycache__/request_managed_cert.cpython-312.pyc,,
+twilio/rest/messaging/v1/__pycache__/tollfree_verification.cpython-312.pyc,,
+twilio/rest/messaging/v1/__pycache__/usecase.cpython-312.pyc,,
+twilio/rest/messaging/v1/brand_registration/__init__.py,sha256=vwN1T13tXXqeTQXcnLfvsfXcM-UI0yPa72MgcQaIxjY,25786
+twilio/rest/messaging/v1/brand_registration/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/messaging/v1/brand_registration/__pycache__/brand_registration_otp.cpython-312.pyc,,
+twilio/rest/messaging/v1/brand_registration/__pycache__/brand_vetting.cpython-312.pyc,,
+twilio/rest/messaging/v1/brand_registration/brand_registration_otp.py,sha256=la1p4GyOQZCkRajdrceZaqPc62vgJQ7UJ7ArqVrY_oU,3863
+twilio/rest/messaging/v1/brand_registration/brand_vetting.py,sha256=0yvCpsT49B80d_vUB6yK_wED8TG6OIn2W8lPgxq67ys,20801
+twilio/rest/messaging/v1/deactivations.py,sha256=_xU8CL1GYSQnmPCm5Fogsy0FlsX4V8hHaE7irqMUpk8,6014
+twilio/rest/messaging/v1/domain_certs.py,sha256=s-DvT8cYizH9c6se-G4GD9OXgiRr0b-H1EpjSNPC1cs,10985
+twilio/rest/messaging/v1/domain_config.py,sha256=rtO1y97rtxBlvFCim4hEML1BRZLKU7vQovXEjme3kz0,14438
+twilio/rest/messaging/v1/domain_config_messaging_service.py,sha256=OnHPXrT7-2mo3l4QjM1N0cYJclhpVm756pn4w9FgSZE,8146
+twilio/rest/messaging/v1/external_campaign.py,sha256=DJ5e4CPCDn01fs9mzhH-yk0jYdf42NNL2Yr77nEhWek,5827
+twilio/rest/messaging/v1/linkshortening_messaging_service.py,sha256=HnbvZrSFQ3lV_qVgJmZZy0Sdv3ik3t8-RnJijv1XEbg,9270
+twilio/rest/messaging/v1/linkshortening_messaging_service_domain_association.py,sha256=F84pNV01Bbe5tn1eGP8CoPZTsEb17YLv0kV3d_xTFG8,7562
+twilio/rest/messaging/v1/request_managed_cert.py,sha256=fg0N6_uR4ygu3njHRE80X_JUFZTZg_GSYr8mn_-pt5k,7362
+twilio/rest/messaging/v1/service/__init__.py,sha256=qUd-KVBwVHa5ByTPn7e5IdxXtj4IgDcWcQ8jJNDM3e0,58925
+twilio/rest/messaging/v1/service/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/messaging/v1/service/__pycache__/alpha_sender.cpython-312.pyc,,
+twilio/rest/messaging/v1/service/__pycache__/channel_sender.cpython-312.pyc,,
+twilio/rest/messaging/v1/service/__pycache__/destination_alpha_sender.cpython-312.pyc,,
+twilio/rest/messaging/v1/service/__pycache__/phone_number.cpython-312.pyc,,
+twilio/rest/messaging/v1/service/__pycache__/short_code.cpython-312.pyc,,
+twilio/rest/messaging/v1/service/__pycache__/us_app_to_person.cpython-312.pyc,,
+twilio/rest/messaging/v1/service/__pycache__/us_app_to_person_usecase.cpython-312.pyc,,
+twilio/rest/messaging/v1/service/alpha_sender.py,sha256=YOuoL8KKN6QSRku1m0bG0NJIBBOGGsNxHyA62NjEBJM,19261
+twilio/rest/messaging/v1/service/channel_sender.py,sha256=wxBaS8d6PzBhS_PlHx8ODvxbDgWc29nfzSLfXu2dikk,19693
+twilio/rest/messaging/v1/service/destination_alpha_sender.py,sha256=5--4D-UPjnSIV8yp_6MlM7hBa_qgcpmrOo4zTuuUYJg,22713
+twilio/rest/messaging/v1/service/phone_number.py,sha256=0Bq5ntSJ2Uy_Bhl1c_SKFhbwrict9QbyraiWqXQcluw,19326
+twilio/rest/messaging/v1/service/short_code.py,sha256=E04lWux1kq2RXmKrAXU_DPPfny-dd6tnux9F_OHE1mc,19048
+twilio/rest/messaging/v1/service/us_app_to_person.py,sha256=Ghjh3ejPA7XY-c8xzVmfCn_ohylp4o-vMXtCHrRlNUo,45251
+twilio/rest/messaging/v1/service/us_app_to_person_usecase.py,sha256=OxYKFgTzChJ_o65jBzljNuXVN8dhnJZD4MONzsVzWMk,4517
+twilio/rest/messaging/v1/tollfree_verification.py,sha256=N4dzS_WXCFlMjwo_GuOnrsKRKWCx0poCrYpPhSjzqOs,63270
+twilio/rest/messaging/v1/usecase.py,sha256=nqg6oL7XY5RhV5pELB1VMcpTwhZexK-gHa9cxhSzIZU,2685
+twilio/rest/messaging/v2/__init__.py,sha256=tnGhnc1ogHpyPnkHAb6vn1W09UcqWuiUHlnu0gEcI9Y,1370
+twilio/rest/messaging/v2/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/messaging/v2/__pycache__/channels_sender.cpython-312.pyc,,
+twilio/rest/messaging/v2/channels_sender.py,sha256=R6Y8wjkdNf-pbOvzimNKcTF8WEW0YbhRv5_-5fUVPuI,42985
+twilio/rest/microvisor/MicrovisorBase.py,sha256=qAQUxPKy5T4sjQxS1QLzNwZUuHSVNA1R6ANInXmLo1Q,1225
+twilio/rest/microvisor/__init__.py,sha256=VvCLDiEovqv3pvNtlafvwWWGupHDSOqLg0fDFLg-jrQ,1321
+twilio/rest/microvisor/__pycache__/MicrovisorBase.cpython-312.pyc,,
+twilio/rest/microvisor/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/microvisor/v1/__init__.py,sha256=FpDCQcXn-wXd9-pDgvYRweUvclcQmcw7q9scbHbiYJU,2212
+twilio/rest/microvisor/v1/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/microvisor/v1/__pycache__/account_config.cpython-312.pyc,,
+twilio/rest/microvisor/v1/__pycache__/account_secret.cpython-312.pyc,,
+twilio/rest/microvisor/v1/account_config.py,sha256=KpL3ESLPFQ1aNo7x4Q-et796Y1Sf8hQ_B4fPGTt6fz0,19039
+twilio/rest/microvisor/v1/account_secret.py,sha256=8JXOcQlW8KSixp4HB5mjsd2U-Yc39USef4tOOute9hY,18924
+twilio/rest/microvisor/v1/app/__init__.py,sha256=_uNBLnpCjBSAU4M4I9wBPpREyATS6DFbKqAYXj3wuc8,16187
+twilio/rest/microvisor/v1/app/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/microvisor/v1/app/__pycache__/app_manifest.cpython-312.pyc,,
+twilio/rest/microvisor/v1/app/app_manifest.py,sha256=nRdO9A1p5m7D9qFFQaBWt55tB48e_yRHiN4-SYGePf0,5713
+twilio/rest/microvisor/v1/device/__init__.py,sha256=gmQZSVDDSK-IthXhM679eZWJTwLmflLHyW2R3r24XZA,21735
+twilio/rest/microvisor/v1/device/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/microvisor/v1/device/__pycache__/device_config.cpython-312.pyc,,
+twilio/rest/microvisor/v1/device/__pycache__/device_secret.cpython-312.pyc,,
+twilio/rest/microvisor/v1/device/device_config.py,sha256=0PAMSw7IVxoM_regmpfusGH7xzR3onaBE1o5o1H3HRY,20346
+twilio/rest/microvisor/v1/device/device_secret.py,sha256=6N__YRbPFhtwlSjidTbqjojSCHgdT6oxSQ38YjEwVOQ,20231
+twilio/rest/monitor/MonitorBase.py,sha256=ZUBQwu6h9-c-QsjqzqWOjAgKW0CLbhSzWkCaA6T9_I8,1204
+twilio/rest/monitor/__init__.py,sha256=qSQaNLR3BLW7RbTgo4-K5hyUs8WjFpQkejqdEmA1dgo,658
+twilio/rest/monitor/__pycache__/MonitorBase.cpython-312.pyc,,
+twilio/rest/monitor/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/monitor/v1/__init__.py,sha256=jKGc7sS5H9TlP4M_SYtRAlTBGuVTG_NHrsmMqKxLaKg,1518
+twilio/rest/monitor/v1/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/monitor/v1/__pycache__/alert.cpython-312.pyc,,
+twilio/rest/monitor/v1/__pycache__/event.cpython-312.pyc,,
+twilio/rest/monitor/v1/alert.py,sha256=Wbt-Koprj-Fr8v2iqEUm33dHJOeEW-HnYXcOTqW6W9w,23192
+twilio/rest/monitor/v1/event.py,sha256=U0G5AipPfHGHSrCbUydBrm1O0nELS5oFSr3E8lIfj50,26092
+twilio/rest/notify/NotifyBase.py,sha256=63iUENxBxbeJ-AfquhzrOnfHxjA1Oh_ZF4JzKXFjrZQ,1197
+twilio/rest/notify/__init__.py,sha256=fqpFtdtT21ai83xGyuIHVTFFp04n0XS3J2N20Ebn4rc,700
+twilio/rest/notify/__pycache__/NotifyBase.cpython-312.pyc,,
+twilio/rest/notify/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/notify/v1/__init__.py,sha256=w5j4Nxwc7PAmhImW90TEa38frEH3mjwUgAxT2Wn2iXA,1582
+twilio/rest/notify/v1/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/notify/v1/__pycache__/credential.cpython-312.pyc,,
+twilio/rest/notify/v1/credential.py,sha256=BvvrnWkHOgP8nvI8erdpwc_DmjRy3mgNNB0gKVmh0BQ,29291
+twilio/rest/notify/v1/service/__init__.py,sha256=_aght_AEruxM0zX7EjWfOApvmlC_-Xv2rOkmGL-f0js,48635
+twilio/rest/notify/v1/service/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/notify/v1/service/__pycache__/binding.cpython-312.pyc,,
+twilio/rest/notify/v1/service/__pycache__/notification.cpython-312.pyc,,
+twilio/rest/notify/v1/service/binding.py,sha256=css5If7sBQ_gMjiQeAWSw7-mL9sW7YxtmhyF2lvtlRI,31187
+twilio/rest/notify/v1/service/notification.py,sha256=uJPJGag_p-XzwIegypxzkBNpR7_r7m5vOdJAttGYt28,25875
+twilio/rest/numbers/NumbersBase.py,sha256=4QlX-Tsp953-WAZAJSdbn4b3hxx67pL_KI4N5rEbq0E,1469
+twilio/rest/numbers/__init__.py,sha256=wIjsaoiSWgzPPa5leWNXsOwttzjCbOg7NhVG0eGV2c8,491
+twilio/rest/numbers/__pycache__/NumbersBase.cpython-312.pyc,,
+twilio/rest/numbers/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/numbers/v1/__init__.py,sha256=WxUlp7QgaVdIDvjjCrCWvM_s3qgXuR7EIFfE8LIJoHk,5210
+twilio/rest/numbers/v1/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/numbers/v1/__pycache__/bulk_eligibility.cpython-312.pyc,,
+twilio/rest/numbers/v1/__pycache__/eligibility.cpython-312.pyc,,
+twilio/rest/numbers/v1/__pycache__/porting_port_in.cpython-312.pyc,,
+twilio/rest/numbers/v1/__pycache__/porting_port_in_phone_number.cpython-312.pyc,,
+twilio/rest/numbers/v1/__pycache__/porting_portability.cpython-312.pyc,,
+twilio/rest/numbers/v1/__pycache__/porting_webhook_configuration.cpython-312.pyc,,
+twilio/rest/numbers/v1/__pycache__/porting_webhook_configuration_delete.cpython-312.pyc,,
+twilio/rest/numbers/v1/__pycache__/porting_webhook_configuration_fetch.cpython-312.pyc,,
+twilio/rest/numbers/v1/__pycache__/signing_request_configuration.cpython-312.pyc,,
+twilio/rest/numbers/v1/bulk_eligibility.py,sha256=JaMLcdaH5-Z019koozU63L6XCbZrL0o97nMUut9bcZE,8657
+twilio/rest/numbers/v1/eligibility.py,sha256=-r6-FXwDgg1O1J_NRcUwiQYZOz71-ftdIPH56prVJIg,3686
+twilio/rest/numbers/v1/porting_port_in.py,sha256=tn5y-5Ko6VVP7tYpJxmbUJiAh6SeNuX4i68kSvScIf4,11509
+twilio/rest/numbers/v1/porting_port_in_phone_number.py,sha256=eINfYnzgw4K_0pQS1pDholToP4i5p6QXzeZS9J2ATVM,12813
+twilio/rest/numbers/v1/porting_portability.py,sha256=8vr5i2JmBGC1u-Z7M9IyRF6h7ZQaAw4aXQlOB0NKSlc,10479
+twilio/rest/numbers/v1/porting_webhook_configuration.py,sha256=Exqs-T-E8eZofodAdjC6vF1Hma1Zl-14EPdmbawLIqU,4046
+twilio/rest/numbers/v1/porting_webhook_configuration_delete.py,sha256=8KO4wKvyhEa55qK55Jlin7mAOI0lYLS3Nshx4QjCOO0,3849
+twilio/rest/numbers/v1/porting_webhook_configuration_fetch.py,sha256=VDXsAa8CR6b9AccGByzR-lARd2cqU6CWVRKCWj2eNT8,4288
+twilio/rest/numbers/v1/signing_request_configuration.py,sha256=X_l0ReZhhE2yzvo6NNaU7_o0da6uYDy-Bj-E5SH3H2c,16134
+twilio/rest/numbers/v2/__init__.py,sha256=Qv5QHA7dwnszYN-boixMR4llKlcmqPrB3a_8bjcani4,2968
+twilio/rest/numbers/v2/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/numbers/v2/__pycache__/bulk_hosted_number_order.cpython-312.pyc,,
+twilio/rest/numbers/v2/__pycache__/bundle_clone.cpython-312.pyc,,
+twilio/rest/numbers/v2/__pycache__/hosted_number_order.cpython-312.pyc,,
+twilio/rest/numbers/v2/authorization_document/__init__.py,sha256=q33XwBIEsKPmUV_I4QEM_-x-ucKRNB2Bnh3eb3RVFeA,26285
+twilio/rest/numbers/v2/authorization_document/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/numbers/v2/authorization_document/__pycache__/dependent_hosted_number_order.cpython-312.pyc,,
+twilio/rest/numbers/v2/authorization_document/dependent_hosted_number_order.py,sha256=we-we-lsyaJg102TGf4pB-_46WolSF289SsiwQt12fM,22570
+twilio/rest/numbers/v2/bulk_hosted_number_order.py,sha256=XaQRiDk8_b0p6QXJparOW9-j4HvgQrQcqQBtW3s3NYQ,11270
+twilio/rest/numbers/v2/bundle_clone.py,sha256=ifPMAzubZF73XdmpQxY0XNyTm4bO-l-RVIHZt3NtrJs,10336
+twilio/rest/numbers/v2/hosted_number_order.py,sha256=FBisjr-1qMoqHcTvolPhaoHxU-MFmdGiITdYnApCTaE,42405
+twilio/rest/numbers/v2/regulatory_compliance/__init__.py,sha256=om1Yd8YuZ5T0YX0OPdwl__lmeV3rf1uQI9a6VXnlPFo,3690
+twilio/rest/numbers/v2/regulatory_compliance/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/numbers/v2/regulatory_compliance/__pycache__/end_user.cpython-312.pyc,,
+twilio/rest/numbers/v2/regulatory_compliance/__pycache__/end_user_type.cpython-312.pyc,,
+twilio/rest/numbers/v2/regulatory_compliance/__pycache__/regulation.cpython-312.pyc,,
+twilio/rest/numbers/v2/regulatory_compliance/__pycache__/supporting_document.cpython-312.pyc,,
+twilio/rest/numbers/v2/regulatory_compliance/__pycache__/supporting_document_type.cpython-312.pyc,,
+twilio/rest/numbers/v2/regulatory_compliance/bundle/__init__.py,sha256=u6eUL_hiQNJe3poZMLxIyQiX01HEy4fUS2GPGY3UfkQ,49181
+twilio/rest/numbers/v2/regulatory_compliance/bundle/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/numbers/v2/regulatory_compliance/bundle/__pycache__/bundle_copy.cpython-312.pyc,,
+twilio/rest/numbers/v2/regulatory_compliance/bundle/__pycache__/evaluation.cpython-312.pyc,,
+twilio/rest/numbers/v2/regulatory_compliance/bundle/__pycache__/item_assignment.cpython-312.pyc,,
+twilio/rest/numbers/v2/regulatory_compliance/bundle/__pycache__/replace_items.cpython-312.pyc,,
+twilio/rest/numbers/v2/regulatory_compliance/bundle/bundle_copy.py,sha256=gp25rHvCL0z9POpX7ympvvDBzatQpLQx-myAZOad1R0,14592
+twilio/rest/numbers/v2/regulatory_compliance/bundle/evaluation.py,sha256=SaTEnlcZOKVVxlyW4_7jXBcayDDW9LeLaNjwqVY9-u0,16918
+twilio/rest/numbers/v2/regulatory_compliance/bundle/item_assignment.py,sha256=_tJzr1corQuIUB_sBeDcwmpJoEEl1JYq37Zud-JWT3I,18746
+twilio/rest/numbers/v2/regulatory_compliance/bundle/replace_items.py,sha256=NqXzEwGw45-YKNJOYWPuIPzLu_x5EIRR0R2LBpILR4U,6056
+twilio/rest/numbers/v2/regulatory_compliance/end_user.py,sha256=3f6kQrSV-3fKNT_Pc1dCMeAon_Ww80C1EcN-jW7oNRg,21703
+twilio/rest/numbers/v2/regulatory_compliance/end_user_type.py,sha256=IvvMK3UoH7JxdFxzgbLcPFG6ZOS7FN9GTxoQNqnPjO8,14620
+twilio/rest/numbers/v2/regulatory_compliance/regulation.py,sha256=rbezHBPfMT3pdVJGvLjT6DthiKNW7Juala2YifWyx9M,22156
+twilio/rest/numbers/v2/regulatory_compliance/supporting_document.py,sha256=rm6B0xzqpq5EeMqxMXjF_o-inMrNFmkD-SAwfApXvuE,23771
+twilio/rest/numbers/v2/regulatory_compliance/supporting_document_type.py,sha256=BPEX9r78rsoBHDYzq42SvDWN_bCgaYOkMS8Wwx3EvR8,15268
+twilio/rest/oauth/OauthBase.py,sha256=osnf61tFtaKzvSRec80nclNAGL2hjobh7cCzzM7yNnA,1190
+twilio/rest/oauth/__init__.py,sha256=NIyb2ajGCJ85V0wIoDgWvteT7TGUNYG9X3xLBE3RDaA,370
+twilio/rest/oauth/__pycache__/OauthBase.cpython-312.pyc,,
+twilio/rest/oauth/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/oauth/v1/__init__.py,sha256=_O7z9N65ZEXjX5DAiMDvj-Sw4rNHP4JvxFhx1_yhRCg,1536
+twilio/rest/oauth/v1/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/oauth/v1/__pycache__/authorize.cpython-312.pyc,,
+twilio/rest/oauth/v1/__pycache__/token.cpython-312.pyc,,
+twilio/rest/oauth/v1/authorize.py,sha256=Fqlo4Z2C_xVqVlV6R_CkZz20SCsZlDwvTQ2zu5N45ZY,4329
+twilio/rest/oauth/v1/token.py,sha256=X042V3dwmnEBHcDL-tQUa-KOyU-RC9yYTEAjCmHwZgk,6044
+twilio/rest/preview/PreviewBase.py,sha256=4FwwsIDgUAaBNRu0L3IPZuOJY0fmOs7rfqOpRfIvs1I,2027
+twilio/rest/preview/__init__.py,sha256=pPSeRmKwcqT27hzxO7-7ViMAeZcWsUSDVhKZL0cHcso,2889
+twilio/rest/preview/__pycache__/PreviewBase.cpython-312.pyc,,
+twilio/rest/preview/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/preview/hosted_numbers/__init__.py,sha256=Q0CYZWP0LWjme7cyzlNZFMMI6BDqN0Fa5uvNtGXcVq8,1893
+twilio/rest/preview/hosted_numbers/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/preview/hosted_numbers/__pycache__/hosted_number_order.cpython-312.pyc,,
+twilio/rest/preview/hosted_numbers/authorization_document/__init__.py,sha256=ba-SzDbDhe63CtLoXOi9eneraL_XT-I7X1Wyl85udk4,33527
+twilio/rest/preview/hosted_numbers/authorization_document/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/preview/hosted_numbers/authorization_document/__pycache__/dependent_hosted_number_order.cpython-312.pyc,,
+twilio/rest/preview/hosted_numbers/authorization_document/dependent_hosted_number_order.py,sha256=3GajRpiCDWS0yModzEcy8pRlp5VU05snSbQFviZkEAc,25401
+twilio/rest/preview/hosted_numbers/hosted_number_order.py,sha256=KpsnZ8nHYW-4NvNpEqh-ap-m8JL5lbeouJ4-PZR9kI4,49656
+twilio/rest/preview/marketplace/__init__.py,sha256=Z1ULxHOw4TLnAX6wXweELqxekmXLlhysuzjz34rOc9A,1776
+twilio/rest/preview/marketplace/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/preview/marketplace/available_add_on/__init__.py,sha256=kewAJJfdJtF1qLlFer6nLK2r20TnF7G5ehxSP4tZZ8A,15536
+twilio/rest/preview/marketplace/available_add_on/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/preview/marketplace/available_add_on/__pycache__/available_add_on_extension.cpython-312.pyc,,
+twilio/rest/preview/marketplace/available_add_on/available_add_on_extension.py,sha256=GG3Tx_OOFyovMG65zx9LqIRBOaWTfEg7T_2mdTfkUks,16632
+twilio/rest/preview/marketplace/installed_add_on/__init__.py,sha256=5DCmwA43LPeSmiMappzOgTYPJw-nU7nxCa2chn6Lnb8,24628
+twilio/rest/preview/marketplace/installed_add_on/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/preview/marketplace/installed_add_on/__pycache__/installed_add_on_extension.cpython-312.pyc,,
+twilio/rest/preview/marketplace/installed_add_on/installed_add_on_extension.py,sha256=qTx7ZtS5RUCftsf4YHXNtMUSY051PDVBYSWybOmkyNw,19368
+twilio/rest/preview/wireless/__init__.py,sha256=ZlKINNHwHiqAhehhMb7g_jGDFUNK6XWGzlhA8XdGfZY,1850
+twilio/rest/preview/wireless/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/preview/wireless/__pycache__/command.cpython-312.pyc,,
+twilio/rest/preview/wireless/__pycache__/rate_plan.cpython-312.pyc,,
+twilio/rest/preview/wireless/command.py,sha256=5OIhP5tj_D2omdixIaejAqrTAnGfMlHy2q0nHVHdsI0,19770
+twilio/rest/preview/wireless/rate_plan.py,sha256=lBlcBCeUKoTTfbXiYtufOaLu5Uyf9YJT-BdTDKa02Hc,23248
+twilio/rest/preview/wireless/sim/__init__.py,sha256=nGW4QXMc_l6qGcor5VHcM_o9ChoeCl3V4olUm8yzWfk,29624
+twilio/rest/preview/wireless/sim/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/preview/wireless/sim/__pycache__/usage.cpython-312.pyc,,
+twilio/rest/preview/wireless/sim/usage.py,sha256=ry8_Ney-F51nXRMje0P8mAv6wNpYqZVoI0F8UlGpY6k,6810
+twilio/rest/preview_iam/PreviewIamBase.py,sha256=PoU3blksO0afcjPCmHa_4JzVUD8PuyyZpa1EsjkwIPY,1227
+twilio/rest/preview_iam/__init__.py,sha256=abr7pyb5BO3J654krTvqpPWIqt762cN3G9MVaAwR-Xk,662
+twilio/rest/preview_iam/__pycache__/PreviewIamBase.cpython-312.pyc,,
+twilio/rest/preview_iam/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/preview_iam/v1/__init__.py,sha256=nMeH5PgNfXvKemg5wnYJldyrm9_jfOYWGmz9a4Q8Yp4,1644
+twilio/rest/preview_iam/v1/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/preview_iam/v1/__pycache__/authorize.cpython-312.pyc,,
+twilio/rest/preview_iam/v1/__pycache__/token.cpython-312.pyc,,
+twilio/rest/preview_iam/v1/authorize.py,sha256=vUSPtCJZwSnpoo4Sl7b8Szoh7S0-GaA7duhmOflxtKA,4425
+twilio/rest/preview_iam/v1/token.py,sha256=D9jGVlq-hgYPJoD4JDkTafeZoSXjrp4sqxtd2-R_mkw,6144
+twilio/rest/preview_iam/versionless/__init__.py,sha256=xFbC9PXTOvN9NLNEKOMh1n17dYTeHqR-yJO7fajYzjo,1468
+twilio/rest/preview_iam/versionless/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/preview_iam/versionless/organization/__init__.py,sha256=Mw08g47tZxDPm3DrCiO2aqau95h--xbbz6enOtrMeWw,3916
+twilio/rest/preview_iam/versionless/organization/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/preview_iam/versionless/organization/__pycache__/account.cpython-312.pyc,,
+twilio/rest/preview_iam/versionless/organization/__pycache__/role_assignment.cpython-312.pyc,,
+twilio/rest/preview_iam/versionless/organization/__pycache__/user.cpython-312.pyc,,
+twilio/rest/preview_iam/versionless/organization/account.py,sha256=Sst7OP0EUn6KKQCPdFKqRAdezjEAzxoo6a74WOG8stM,15149
+twilio/rest/preview_iam/versionless/organization/role_assignment.py,sha256=vtHw1f2FdzG6Jh5Dg5g_sN0AONPtD3dXgch8K5dzUF4,20400
+twilio/rest/preview_iam/versionless/organization/user.py,sha256=h-yRzU2OJ2lE9qRbBf1JE14HoncESylywXmLOLd7D1o,38114
+twilio/rest/pricing/PricingBase.py,sha256=NLCOp1P4eV2ZlQikfRsLHd1zUZyqms5HRsl4Y54QtZ8,1469
+twilio/rest/pricing/__init__.py,sha256=ge3TqYJHEMFblpBnfC9X4FW0d0SsO7I5b4qKGY-jkVU,1569
+twilio/rest/pricing/__pycache__/PricingBase.cpython-312.pyc,,
+twilio/rest/pricing/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/pricing/v1/__init__.py,sha256=CurnOGdO6y0wIWCGSGxgxt0YdszryeMAmdRbj7Ooeog,1868
+twilio/rest/pricing/v1/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/pricing/v1/messaging/__init__.py,sha256=rSOhH2QMvljfAGkFDYwomtLmOqPZwBjbOkcUfRbqXPA,1443
+twilio/rest/pricing/v1/messaging/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/pricing/v1/messaging/__pycache__/country.cpython-312.pyc,,
+twilio/rest/pricing/v1/messaging/country.py,sha256=ZnYb5Gy1xbHzkOGf1peO5jhpPP2N7SfwSanGw84l8wQ,14999
+twilio/rest/pricing/v1/phone_number/__init__.py,sha256=Y5i7NuFEchDtGXMSoTkFMonR8iyMVBzZM8Ud8xXW5ik,1455
+twilio/rest/pricing/v1/phone_number/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/pricing/v1/phone_number/__pycache__/country.cpython-312.pyc,,
+twilio/rest/pricing/v1/phone_number/country.py,sha256=OhcpWGvwz8fhGn-Lq7946ZxtTa8qOy9ZuXZkTCttO5c,14592
+twilio/rest/pricing/v1/voice/__init__.py,sha256=I_2ql8yNyelIDbO6xLw_YZOtvdVS4YsJ1_xA5inn4dI,1753
+twilio/rest/pricing/v1/voice/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/pricing/v1/voice/__pycache__/country.cpython-312.pyc,,
+twilio/rest/pricing/v1/voice/__pycache__/number.cpython-312.pyc,,
+twilio/rest/pricing/v1/voice/country.py,sha256=VwgIhuBsL8lhUcRzb8SsMpZHVe7jKBTS3oF3uVKrK7Y,14885
+twilio/rest/pricing/v1/voice/number.py,sha256=jPe0U15gAiRvUgvyg2EIrZpIho9g9Py1ZsOJJmS33pc,5880
+twilio/rest/pricing/v2/__init__.py,sha256=lt22Da-7bXFid4KEGWNLc5_R4u5Is6fDuYCoVa1wjj0,1802
+twilio/rest/pricing/v2/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/pricing/v2/__pycache__/country.cpython-312.pyc,,
+twilio/rest/pricing/v2/__pycache__/number.cpython-312.pyc,,
+twilio/rest/pricing/v2/country.py,sha256=7DLs2hvkX12BagctGEgghE129is26RfcmakHGjP3IgY,14939
+twilio/rest/pricing/v2/number.py,sha256=ZRRvI8-dlQ9KHpbYsUv19nl_heZ20V11PUHAQepdzD0,9184
+twilio/rest/pricing/v2/voice/__init__.py,sha256=EV0LqxLaOB0PgH7E182h0InT6g9wmJsoPSBC5e6WSVE,1753
+twilio/rest/pricing/v2/voice/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/pricing/v2/voice/__pycache__/country.cpython-312.pyc,,
+twilio/rest/pricing/v2/voice/__pycache__/number.cpython-312.pyc,,
+twilio/rest/pricing/v2/voice/country.py,sha256=H4p1Gk5PTSoSDMjbQuBodJpawEW3a3hVcvJ4E_yFieQ,14915
+twilio/rest/pricing/v2/voice/number.py,sha256=FZLh9qSfDJl0f6ndrf1w_Iv5x9uSvaF6nr7z2LO6IK0,9258
+twilio/rest/proxy/ProxyBase.py,sha256=U3nXl8igDx1PLplE9GdldvQ7-_1ZofMO8kPMoptnTPY,1190
+twilio/rest/proxy/__init__.py,sha256=t3suaVnvsgCHvrHOkPBshzKqaK0xZ0OAfoBvPsgS_MA,387
+twilio/rest/proxy/__pycache__/ProxyBase.cpython-312.pyc,,
+twilio/rest/proxy/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/proxy/v1/__init__.py,sha256=K_YLKgkAp-_QiAKKVb_RKJF1Bk2ge_6Z16uFrOqdq1Q,1274
+twilio/rest/proxy/v1/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/proxy/v1/service/__init__.py,sha256=ojVop07d0E7CrmQcdgXBTPyvpmrmC08dhvFM8T1GWNA,39366
+twilio/rest/proxy/v1/service/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/proxy/v1/service/__pycache__/phone_number.cpython-312.pyc,,
+twilio/rest/proxy/v1/service/__pycache__/short_code.cpython-312.pyc,,
+twilio/rest/proxy/v1/service/phone_number.py,sha256=3w1QA2Xk5A4PnHleevnQ1_5pxaHv3hIj5AqnmnpHkVE,25082
+twilio/rest/proxy/v1/service/session/__init__.py,sha256=Wn-cp_eQwBiYs1x_j9d_8qFeGDXNhEacpGhJxPju1wk,28970
+twilio/rest/proxy/v1/service/session/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/proxy/v1/service/session/__pycache__/interaction.cpython-312.pyc,,
+twilio/rest/proxy/v1/service/session/interaction.py,sha256=6cyaP98FMIibyCfYioOFxuHiWrQgvEqzkpP5BHE9IPM,21646
+twilio/rest/proxy/v1/service/session/participant/__init__.py,sha256=qGtO9flZ0mCtHza8SiUkBF00HIfY3Dg-4SlsOz580Og,23678
+twilio/rest/proxy/v1/service/session/participant/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/proxy/v1/service/session/participant/__pycache__/message_interaction.cpython-312.pyc,,
+twilio/rest/proxy/v1/service/session/participant/message_interaction.py,sha256=p23k8qBF9Bw1evIc2Vkoxa1diklfMR2EgQwn1Dr7y88,24103
+twilio/rest/proxy/v1/service/short_code.py,sha256=etcwcuRI8smorLFDdubKDjcJyZIeqpWeQVYkuoLVlss,22637
+twilio/rest/routes/RoutesBase.py,sha256=Wd7ZCiv13Jkec4cmQTcAEWgftoIU1m57bZ-qkzoriXg,1197
+twilio/rest/routes/__init__.py,sha256=2c-YFuPc4-lbnbloGWO0HBglvgusSEin0PqD7MhDKi4,1003
+twilio/rest/routes/__pycache__/RoutesBase.cpython-312.pyc,,
+twilio/rest/routes/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/routes/v2/__init__.py,sha256=yOGIyQHTtHeDgd-yu4LSv5AcLa2KT__TcSmWUYploSo,1877
+twilio/rest/routes/v2/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/routes/v2/__pycache__/phone_number.cpython-312.pyc,,
+twilio/rest/routes/v2/__pycache__/sip_domain.cpython-312.pyc,,
+twilio/rest/routes/v2/__pycache__/trunk.cpython-312.pyc,,
+twilio/rest/routes/v2/phone_number.py,sha256=lKVw4cbxRLYCkHFiOFgLodbbyR3CpsOt97rnuGn8p08,10163
+twilio/rest/routes/v2/sip_domain.py,sha256=UlgBl06DzAP5K4cyqBtd2LYUIP3mCnXKe6zdvUCSths,8755
+twilio/rest/routes/v2/trunk.py,sha256=NAacTltZwq8WjuN3XaIA3gbbmg1oj5bgWbFRCZxDIp8,9972
+twilio/rest/serverless/ServerlessBase.py,sha256=tkHMV_J34VboZ9KpnPZGKoWqoRvQmi7jUKNgGbQif_Y,1225
+twilio/rest/serverless/__init__.py,sha256=RSch0EvaZC7vInV-DXpUwtaitRhC1dpLXllzK-keHIQ,417
+twilio/rest/serverless/__pycache__/ServerlessBase.cpython-312.pyc,,
+twilio/rest/serverless/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/serverless/v1/__init__.py,sha256=FE26OpLcLc2D4bdUE9-madIxREcrRBOk8jPT-H99_zw,1299
+twilio/rest/serverless/v1/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/serverless/v1/service/__init__.py,sha256=m4QzN2phun9teH5wkVGB5tZCdZGtVR5jF4AkzQo0SlY,26954
+twilio/rest/serverless/v1/service/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/serverless/v1/service/asset/__init__.py,sha256=9oov6zyI3eOXrWnh-yvCKvxSjOk2mnavs-9x_Cf0jUY,21783
+twilio/rest/serverless/v1/service/asset/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/serverless/v1/service/asset/__pycache__/asset_version.cpython-312.pyc,,
+twilio/rest/serverless/v1/service/asset/asset_version.py,sha256=td0TPORDdf4mOEDDnCs03g8MnCI-DlLsBqgbb7ljllI,17185
+twilio/rest/serverless/v1/service/build/__init__.py,sha256=uUrHixsuYAgeb7sVjnMJWn-iTWJvLibR36VIo8U7mjE,21695
+twilio/rest/serverless/v1/service/build/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/serverless/v1/service/build/__pycache__/build_status.cpython-312.pyc,,
+twilio/rest/serverless/v1/service/build/build_status.py,sha256=T-gNHyQsiD_AatrctHKaNFm8hzF-yfULrqRggNs0jDA,6686
+twilio/rest/serverless/v1/service/environment/__init__.py,sha256=v_1yRUP5Oc9onosllPi6p3nP3s3wWOi6yLfQguh5GGQ,21922
+twilio/rest/serverless/v1/service/environment/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/serverless/v1/service/environment/__pycache__/deployment.cpython-312.pyc,,
+twilio/rest/serverless/v1/service/environment/__pycache__/log.cpython-312.pyc,,
+twilio/rest/serverless/v1/service/environment/__pycache__/variable.cpython-312.pyc,,
+twilio/rest/serverless/v1/service/environment/deployment.py,sha256=VnPee8tNRgGeIlbeWI_lSf0eV8T7BXAYyAsUCb40Cog,19307
+twilio/rest/serverless/v1/service/environment/log.py,sha256=DnAaJUInzoTTZqRwkHq6WpNwxT2PkUx-SwbKAVRoLVY,21397
+twilio/rest/serverless/v1/service/environment/variable.py,sha256=QN_eyxH-w6t0eKsqD7Btnl5d8dYG3fzqxOm35xZC9kA,23799
+twilio/rest/serverless/v1/service/function/__init__.py,sha256=uZxmjE1VB_UMCnoCD15cbccB4lFSJZgM1hJ6RMlMs1w,22129
+twilio/rest/serverless/v1/service/function/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/serverless/v1/service/function/function_version/__init__.py,sha256=xlZP3O8DVvnOHImF-_JAG6w2JwBrPwuAIdCgJk6Kj1o,18564
+twilio/rest/serverless/v1/service/function/function_version/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/serverless/v1/service/function/function_version/__pycache__/function_version_content.cpython-312.pyc,,
+twilio/rest/serverless/v1/service/function/function_version/function_version_content.py,sha256=v9C75LS4AFWf-Ac2r2sAvRqE-8msJAXQgUUd5IuMMh4,7915
+twilio/rest/studio/StudioBase.py,sha256=Ir8Bf4wI_qF2HPpL59i94svqiX_FB0g6Y3Tw02ZA4lQ,1460
+twilio/rest/studio/__init__.py,sha256=VF97OQEqJW5-ycSz4oqnGlxyvDEo-Hzxf0GZQzgv3ts,694
+twilio/rest/studio/__pycache__/StudioBase.cpython-312.pyc,,
+twilio/rest/studio/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/studio/v1/__init__.py,sha256=x63ZfUydLZEcampmW0D3vaSqnpCc2mMGH5zg4uckLTA,1249
+twilio/rest/studio/v1/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/studio/v1/flow/__init__.py,sha256=gkghYu5WGSbS2jVi2-NPkAr0bjIL00YASKpHDQ4TGRw,16929
+twilio/rest/studio/v1/flow/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/studio/v1/flow/engagement/__init__.py,sha256=fDQDSuqi92MzdQ__4hN6fqFbqF9FJbjNrz4yRS0RPm8,22281
+twilio/rest/studio/v1/flow/engagement/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/studio/v1/flow/engagement/__pycache__/engagement_context.cpython-312.pyc,,
+twilio/rest/studio/v1/flow/engagement/engagement_context.py,sha256=4D7a2a5dlsIF1rQR4LcORBti6v4XZ2C-8qq-kkvPFDk,6899
+twilio/rest/studio/v1/flow/engagement/step/__init__.py,sha256=Znrh_kCQM_YI3m9q9WQs6HlJ99sOHspWf8TkKo5zeLg,17820
+twilio/rest/studio/v1/flow/engagement/step/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/studio/v1/flow/engagement/step/__pycache__/step_context.cpython-312.pyc,,
+twilio/rest/studio/v1/flow/engagement/step/step_context.py,sha256=SHjKvjBN7LxxexCtFUvpT2aoZM-MSR-lmZg271MHQNQ,7574
+twilio/rest/studio/v1/flow/execution/__init__.py,sha256=UHcdqa2uGgr83Q_kUpKeN719v9qYGbtr78jFnXfwKZo,28473
+twilio/rest/studio/v1/flow/execution/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/studio/v1/flow/execution/__pycache__/execution_context.cpython-312.pyc,,
+twilio/rest/studio/v1/flow/execution/execution_context.py,sha256=PhVrZdllf1lwZJ-dfrZSaa31TQj7f9YUD-kx3c8nwco,7056
+twilio/rest/studio/v1/flow/execution/execution_step/__init__.py,sha256=HlSBUR_Q3Br4PNLnTKtmWueQiTq9ZHhmje0QoY_7iTk,18618
+twilio/rest/studio/v1/flow/execution/execution_step/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/studio/v1/flow/execution/execution_step/__pycache__/execution_step_context.cpython-312.pyc,,
+twilio/rest/studio/v1/flow/execution/execution_step/execution_step_context.py,sha256=K-kkFSodl-r5aDErRSlC7XvYbBA2bH0ZQit1ZlqI11Q,7895
+twilio/rest/studio/v2/__init__.py,sha256=W2t8U-5spMVgebzQZzLAkN8fOhceKLAPVTfJ3EWCXCo,1573
+twilio/rest/studio/v2/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/studio/v2/__pycache__/flow_validate.cpython-312.pyc,,
+twilio/rest/studio/v2/flow/__init__.py,sha256=OaZPTmOWOeAKrO7gnUp4zR9xvwunSOq4h2NTNy3rch0,24883
+twilio/rest/studio/v2/flow/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/studio/v2/flow/__pycache__/flow_revision.cpython-312.pyc,,
+twilio/rest/studio/v2/flow/__pycache__/flow_test_user.cpython-312.pyc,,
+twilio/rest/studio/v2/flow/execution/__init__.py,sha256=d6_WO6H3zXxxmrD_saxOkJd8XYjwDTxP08r_p0_mtaE,28357
+twilio/rest/studio/v2/flow/execution/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/studio/v2/flow/execution/__pycache__/execution_context.cpython-312.pyc,,
+twilio/rest/studio/v2/flow/execution/execution_context.py,sha256=mZ3_zssbsq-GZzYFLRSGFay_vs2fDLWWP34gJEfUKbM,7056
+twilio/rest/studio/v2/flow/execution/execution_step/__init__.py,sha256=5P-ueoYcoHTjedaGZY4dpb0KripB6L6EPh15Dor-I7g,18489
+twilio/rest/studio/v2/flow/execution/execution_step/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/studio/v2/flow/execution/execution_step/__pycache__/execution_step_context.cpython-312.pyc,,
+twilio/rest/studio/v2/flow/execution/execution_step/execution_step_context.py,sha256=mE3HYlu3d4GvynE_Ir4y7ll955q-5dCnnUKyuW2NBZ8,7895
+twilio/rest/studio/v2/flow/flow_revision.py,sha256=8xmJ-lgIRZHTz8itHMzfnSN9PqpNoizjnJ9EZv7c43Q,16541
+twilio/rest/studio/v2/flow/flow_test_user.py,sha256=waIZQz_LUlTJbZOemmi9espZZtaTdMYbzFZHlMhYXq8,7858
+twilio/rest/studio/v2/flow_validate.py,sha256=9YXzVhtkOCg3phCX9xkq9n_CQYsxayjeKXqYvtTtKRQ,4283
+twilio/rest/supersim/SupersimBase.py,sha256=tzDOW6QQb0M_HEBpS5SmrK9AN0FWPkMKxNRgN9bGoxQ,1211
+twilio/rest/supersim/__init__.py,sha256=dRLKZs5p-3LCF1VlFz1_jV9r338yrTYW7kzraj64vuc,2908
+twilio/rest/supersim/__pycache__/SupersimBase.cpython-312.pyc,,
+twilio/rest/supersim/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/supersim/v1/__init__.py,sha256=ExvMot1Mt7LpQfp5mlZgaOTf-yVEfZo9hL-lIgPc03Y,3801
+twilio/rest/supersim/v1/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/supersim/v1/__pycache__/esim_profile.cpython-312.pyc,,
+twilio/rest/supersim/v1/__pycache__/fleet.cpython-312.pyc,,
+twilio/rest/supersim/v1/__pycache__/ip_command.cpython-312.pyc,,
+twilio/rest/supersim/v1/__pycache__/network.cpython-312.pyc,,
+twilio/rest/supersim/v1/__pycache__/settings_update.cpython-312.pyc,,
+twilio/rest/supersim/v1/__pycache__/sms_command.cpython-312.pyc,,
+twilio/rest/supersim/v1/__pycache__/usage_record.cpython-312.pyc,,
+twilio/rest/supersim/v1/esim_profile.py,sha256=P43eGCYk0UO_A1NMgLqc3hu_vBjgKx-BSKKEgIYoIsM,24581
+twilio/rest/supersim/v1/fleet.py,sha256=IgQI3Bpuowy04j0PHdGsGoE-BhexndrUBlhMaiGi5aQ,36497
+twilio/rest/supersim/v1/ip_command.py,sha256=Y_J6thO-FE9Lt4zOGHXF7fpNaw_aVMNcmB0T9iH0UE8,27525
+twilio/rest/supersim/v1/network.py,sha256=aEtv-jepmc8AGSFfmwsczwOZ6PVskhWORtNIRrMMJaw,18062
+twilio/rest/supersim/v1/network_access_profile/__init__.py,sha256=HQDEuOUfHJx2tNzrR94fUjc7zA19mx79t_Yh6QxKNF0,21218
+twilio/rest/supersim/v1/network_access_profile/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/supersim/v1/network_access_profile/__pycache__/network_access_profile_network.cpython-312.pyc,,
+twilio/rest/supersim/v1/network_access_profile/network_access_profile_network.py,sha256=qf7x40ND6e56G4-JHZQiwn5IebrJacKjUfeQaTXy2K8,20283
+twilio/rest/supersim/v1/settings_update.py,sha256=2YQlT2fRw8HdaVtwAshrOaIWMqD_W2bwqU4wCVqPYI4,14539
+twilio/rest/supersim/v1/sim/__init__.py,sha256=qKQXvmEF0ITq495TKtdAcnAyl8233IPiIXB88-TJv18,29881
+twilio/rest/supersim/v1/sim/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/supersim/v1/sim/__pycache__/billing_period.cpython-312.pyc,,
+twilio/rest/supersim/v1/sim/__pycache__/sim_ip_address.cpython-312.pyc,,
+twilio/rest/supersim/v1/sim/billing_period.py,sha256=yuqyKSGlxodrRPckQNtlbUtaRqq6AoxNHWJIHlc1cuo,12352
+twilio/rest/supersim/v1/sim/sim_ip_address.py,sha256=8KTtLk6dmCnfynWcjPuLyQ7St_qC9uD-_lVcw_TV0w8,10949
+twilio/rest/supersim/v1/sms_command.py,sha256=t-YRhuJ_57y2ASSmKSnmhMYsdUqSrlepHQEYc3GofXw,23862
+twilio/rest/supersim/v1/usage_record.py,sha256=z0jxspCN-7YOtXIWAHGeroCR2GuMtiDOLBpWA-2u4is,27163
+twilio/rest/sync/SyncBase.py,sha256=qfnPzbBdwYLKn45ZV51XawiTF0J9LVVp7WoiWeNNuF8,1183
+twilio/rest/sync/__init__.py,sha256=IV4mK6fA37ohGhjUmJXQMoBrLYhbKu4rExsU7ZhBemI,381
+twilio/rest/sync/__pycache__/SyncBase.cpython-312.pyc,,
+twilio/rest/sync/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/sync/v1/__init__.py,sha256=lo8inAzFDENbjugimex6jV8cKsaekYSSdhfnVb-jK08,1269
+twilio/rest/sync/v1/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/sync/v1/service/__init__.py,sha256=fg8SJtsFXdU4Gk4Rqczy_1V-As-fDJY_bzDehzYWxL8,38755
+twilio/rest/sync/v1/service/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/sync/v1/service/document/__init__.py,sha256=Geh-Lsh7bX3V-03JR7puPkIKfSWodWlPl3QhnilOcxk,26694
+twilio/rest/sync/v1/service/document/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/sync/v1/service/document/__pycache__/document_permission.cpython-312.pyc,,
+twilio/rest/sync/v1/service/document/document_permission.py,sha256=T5GDe7N6RFKjKYp23YXtPkA9-FrZet_flMMnR61ezTs,22818
+twilio/rest/sync/v1/service/sync_list/__init__.py,sha256=B_og3ugqnSoVSM8WbvfeBGCbz-PpbeAkswbRTZiRgWA,26399
+twilio/rest/sync/v1/service/sync_list/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/sync/v1/service/sync_list/__pycache__/sync_list_item.cpython-312.pyc,,
+twilio/rest/sync/v1/service/sync_list/__pycache__/sync_list_permission.cpython-312.pyc,,
+twilio/rest/sync/v1/service/sync_list/sync_list_item.py,sha256=BgXaq75g3XseOCuCiLYjUomodmeWpYgn7uFK0VCJXtI,38006
+twilio/rest/sync/v1/service/sync_list/sync_list_permission.py,sha256=LWoy9ULPKi_6rx2QIlQF89z7pedN-NsIwf5B7UNUqoI,22822
+twilio/rest/sync/v1/service/sync_map/__init__.py,sha256=Dlea9vhxxccpECrsJBfJk7ysPkwqguw9xEOM5pzy5yY,26087
+twilio/rest/sync/v1/service/sync_map/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/sync/v1/service/sync_map/__pycache__/sync_map_item.cpython-312.pyc,,
+twilio/rest/sync/v1/service/sync_map/__pycache__/sync_map_permission.cpython-312.pyc,,
+twilio/rest/sync/v1/service/sync_map/sync_map_item.py,sha256=kglhoY3mqq3HZ3DKlRurNhUdfG-10RklhS_Vn6GUJlo,38565
+twilio/rest/sync/v1/service/sync_map/sync_map_permission.py,sha256=YQ-hUgWsfD_a4pa4xTQcF35c35vXq6edmBvA7Td7VDo,22750
+twilio/rest/sync/v1/service/sync_stream/__init__.py,sha256=GVIf6X8zTeQAE1Xq4NOc2OR45JxtfhJ4q3wpxScXrnA,24100
+twilio/rest/sync/v1/service/sync_stream/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/sync/v1/service/sync_stream/__pycache__/stream_message.cpython-312.pyc,,
+twilio/rest/sync/v1/service/sync_stream/stream_message.py,sha256=gPXLse1tM8XNj3bDwD1_24BnJygOkEvWlBzwImRzryA,4704
+twilio/rest/taskrouter/TaskrouterBase.py,sha256=0pduWi9gHRMDnWejrHNLhL1UFtnTbFTD7K4_uBvk698,1225
+twilio/rest/taskrouter/__init__.py,sha256=LsvpBhg8Cg-tYPzdacb1bKJ9fEAwRBd6sdH41_s-CGA,431
+twilio/rest/taskrouter/__pycache__/TaskrouterBase.cpython-312.pyc,,
+twilio/rest/taskrouter/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/taskrouter/v1/__init__.py,sha256=dgBlDHuEdkXOOBusvaS3DPEdV6KpgNdnRKPxRPxmvsc,1319
+twilio/rest/taskrouter/v1/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/taskrouter/v1/workspace/__init__.py,sha256=-kzAKagMxJtS1OErpphiFX_hyivFm2ZDYXpBa4GAly0,45784
+twilio/rest/taskrouter/v1/workspace/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/taskrouter/v1/workspace/__pycache__/activity.cpython-312.pyc,,
+twilio/rest/taskrouter/v1/workspace/__pycache__/event.cpython-312.pyc,,
+twilio/rest/taskrouter/v1/workspace/__pycache__/task_channel.cpython-312.pyc,,
+twilio/rest/taskrouter/v1/workspace/__pycache__/workspace_cumulative_statistics.cpython-312.pyc,,
+twilio/rest/taskrouter/v1/workspace/__pycache__/workspace_real_time_statistics.cpython-312.pyc,,
+twilio/rest/taskrouter/v1/workspace/__pycache__/workspace_statistics.cpython-312.pyc,,
+twilio/rest/taskrouter/v1/workspace/activity.py,sha256=caZQKdRCg3nRWNFCHcFa9iBo-Fliy2xfP8GrKWz7rGk,27256
+twilio/rest/taskrouter/v1/workspace/event.py,sha256=d8-bEDWXiml12ka6t38gRLfkd_L6FpscnjbPAgV5ZtI,33245
+twilio/rest/taskrouter/v1/workspace/task/__init__.py,sha256=5utVTRSw9M7ffEMUxsMlC1F6t3g2QUvC03D2w14JoK8,60103
+twilio/rest/taskrouter/v1/workspace/task/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/taskrouter/v1/workspace/task/__pycache__/reservation.cpython-312.pyc,,
+twilio/rest/taskrouter/v1/workspace/task/reservation.py,sha256=Su5uvemUYtURHuw-fXFuv_ASJJX-gDeIvG95uDNDNKc,82418
+twilio/rest/taskrouter/v1/workspace/task_channel.py,sha256=b4hteITkASJmfka_j1lKeA9DcTuWhhHwk_2Pki4Vb70,24950
+twilio/rest/taskrouter/v1/workspace/task_queue/__init__.py,sha256=EzzZTUJRbpN49fgRGF5_EX6hx5STB8yUT4ulEngd7qA,41127
+twilio/rest/taskrouter/v1/workspace/task_queue/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/taskrouter/v1/workspace/task_queue/__pycache__/task_queue_bulk_real_time_statistics.cpython-312.pyc,,
+twilio/rest/taskrouter/v1/workspace/task_queue/__pycache__/task_queue_cumulative_statistics.cpython-312.pyc,,
+twilio/rest/taskrouter/v1/workspace/task_queue/__pycache__/task_queue_real_time_statistics.cpython-312.pyc,,
+twilio/rest/taskrouter/v1/workspace/task_queue/__pycache__/task_queue_statistics.cpython-312.pyc,,
+twilio/rest/taskrouter/v1/workspace/task_queue/__pycache__/task_queues_statistics.cpython-312.pyc,,
+twilio/rest/taskrouter/v1/workspace/task_queue/task_queue_bulk_real_time_statistics.py,sha256=G-4CmLkSGkrors4P9_S_sbmVZXde-jRb2v1_HNclPxY,5533
+twilio/rest/taskrouter/v1/workspace/task_queue/task_queue_cumulative_statistics.py,sha256=Owzy2GLnZ2chsPZLsUJgFs7r1tHWYWhcLwXlgMDk_K8,18538
+twilio/rest/taskrouter/v1/workspace/task_queue/task_queue_real_time_statistics.py,sha256=oHvXO9ZRSB2HJ49LXE9yVk75CoovfxUbX9opTO1OOd0,11309
+twilio/rest/taskrouter/v1/workspace/task_queue/task_queue_statistics.py,sha256=0OEqLQlKjd6E_eitn_QfG3TyjLg7TNgiHLnZhiIwu4w,13598
+twilio/rest/taskrouter/v1/workspace/task_queue/task_queues_statistics.py,sha256=MsadNOzs6tSp7ihI30AULA5rG2vTbR2mVM3d7RFm-Nk,21635
+twilio/rest/taskrouter/v1/workspace/worker/__init__.py,sha256=UFtA2wNgCYKfwUINg2bGD2_oBbaMHZj8KCZFt1wc7xY,45390
+twilio/rest/taskrouter/v1/workspace/worker/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/taskrouter/v1/workspace/worker/__pycache__/reservation.cpython-312.pyc,,
+twilio/rest/taskrouter/v1/workspace/worker/__pycache__/worker_channel.cpython-312.pyc,,
+twilio/rest/taskrouter/v1/workspace/worker/__pycache__/worker_statistics.cpython-312.pyc,,
+twilio/rest/taskrouter/v1/workspace/worker/__pycache__/workers_cumulative_statistics.cpython-312.pyc,,
+twilio/rest/taskrouter/v1/workspace/worker/__pycache__/workers_real_time_statistics.cpython-312.pyc,,
+twilio/rest/taskrouter/v1/workspace/worker/__pycache__/workers_statistics.cpython-312.pyc,,
+twilio/rest/taskrouter/v1/workspace/worker/reservation.py,sha256=mUqm71lfxPzTtLvH_gvpVT8FHHmLQIZVMyxvXY004zE,80200
+twilio/rest/taskrouter/v1/workspace/worker/worker_channel.py,sha256=UkBLmPdLYTNxTZYjce8EjmYIAMLtXWDA7ZIoQiHOO6Y,22917
+twilio/rest/taskrouter/v1/workspace/worker/worker_statistics.py,sha256=W3IBjoY9k6Wj5GvHcHF6yXpa6QWIY6fLncyxb4XZSFw,11948
+twilio/rest/taskrouter/v1/workspace/worker/workers_cumulative_statistics.py,sha256=20N-BV-7b0J4zrr_9c9jnsZNXE6jYtfia5k3Krmptz8,13470
+twilio/rest/taskrouter/v1/workspace/worker/workers_real_time_statistics.py,sha256=HaJEWw4jqTX9egJFxlyK4gSNP3lcEPAd5idhzEyucJ4,8113
+twilio/rest/taskrouter/v1/workspace/worker/workers_statistics.py,sha256=3xP9S84x-L1czrTuWYt6J615VLkvmP2dbYgiB38M1KE,13763
+twilio/rest/taskrouter/v1/workspace/workflow/__init__.py,sha256=dZgoAfgMhhb8Yq8puZ1zMPIxHDYkGkOj2AHqn0l3qwU,35780
+twilio/rest/taskrouter/v1/workspace/workflow/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/taskrouter/v1/workspace/workflow/__pycache__/workflow_cumulative_statistics.cpython-312.pyc,,
+twilio/rest/taskrouter/v1/workspace/workflow/__pycache__/workflow_real_time_statistics.cpython-312.pyc,,
+twilio/rest/taskrouter/v1/workspace/workflow/__pycache__/workflow_statistics.cpython-312.pyc,,
+twilio/rest/taskrouter/v1/workspace/workflow/workflow_cumulative_statistics.py,sha256=SXjcPAejVN6AyR9Z1pMqOf7OyHfu5uR4-tHVgNf5tO0,19446
+twilio/rest/taskrouter/v1/workspace/workflow/workflow_real_time_statistics.py,sha256=ZzfRIIXLrfut803EK82QX_Y09PXERLpMi1G2O_8ITPo,9907
+twilio/rest/taskrouter/v1/workspace/workflow/workflow_statistics.py,sha256=KiR4khvRrjxHa51tbtag-Gp06l8ZugOQ7BHF9XiIxjE,14919
+twilio/rest/taskrouter/v1/workspace/workspace_cumulative_statistics.py,sha256=xJ_CVDVOZhNyqKxc7NLsmYJnQXglUBwLm_a7IyyoKpQ,18383
+twilio/rest/taskrouter/v1/workspace/workspace_real_time_statistics.py,sha256=o8V7VYUXWBrkKEI40gEcTApkYWk6Nc_KHVeeyJ1T8tE,9256
+twilio/rest/taskrouter/v1/workspace/workspace_statistics.py,sha256=svL4Jk3fU8ylmKBCdo3BUBimak6wTvHgUYtFo85PVyA,13782
+twilio/rest/trunking/TrunkingBase.py,sha256=KEpBtt8vyNLrV0C6xgPB0EJy5eEylY48LePvQKhEi4U,1211
+twilio/rest/trunking/__init__.py,sha256=VX22mT-YnOfya6CQBiGMPyk7rHQmYGnJF5oiGiU7Jlg,391
+twilio/rest/trunking/__pycache__/TrunkingBase.cpython-312.pyc,,
+twilio/rest/trunking/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/trunking/v1/__init__.py,sha256=qbIMhWiC4TsBoUrQJNtWBduHzJSNW7w0usKKrT1vWXE,1269
+twilio/rest/trunking/v1/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/trunking/v1/trunk/__init__.py,sha256=-0jEpyK6c4e2UEotMvRGLPYeY1_qwmGmeCk7IYMAcVg,41424
+twilio/rest/trunking/v1/trunk/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/trunking/v1/trunk/__pycache__/credential_list.cpython-312.pyc,,
+twilio/rest/trunking/v1/trunk/__pycache__/ip_access_control_list.cpython-312.pyc,,
+twilio/rest/trunking/v1/trunk/__pycache__/origination_url.cpython-312.pyc,,
+twilio/rest/trunking/v1/trunk/__pycache__/phone_number.cpython-312.pyc,,
+twilio/rest/trunking/v1/trunk/__pycache__/recording.cpython-312.pyc,,
+twilio/rest/trunking/v1/trunk/credential_list.py,sha256=DiaFxSeQHzQVUdQ443HryYev1H2xEguSfOM_o-ZBEXQ,19263
+twilio/rest/trunking/v1/trunk/ip_access_control_list.py,sha256=5w5vNMvcxS7bgAO90EXLuhEPh3FCXyZ3Fz1CTUvNSJ4,19633
+twilio/rest/trunking/v1/trunk/origination_url.py,sha256=wR1_hdm8NbEJsCf_6R0AYRRQ_J2LGYxPw44stYIf4fg,29067
+twilio/rest/trunking/v1/trunk/phone_number.py,sha256=CXghf3xUwyigxnUPpf5Qwv13SZCj7wuom4jH4ikbwOw,23374
+twilio/rest/trunking/v1/trunk/recording.py,sha256=mQy8EGrSX4Xjs11rRJlGZrwbYXeb9grlqMNX2MRYNq8,8619
+twilio/rest/trusthub/TrusthubBase.py,sha256=LSqCTPqT2RLzvjNzVcTXdvmVqwmyGa46Mvp8NmhsSjA,1211
+twilio/rest/trusthub/__init__.py,sha256=HF6EMXEDfJnPqcSZRYnkzrwMEARiFkTxX57LIuhl_uA,2483
+twilio/rest/trusthub/__pycache__/TrusthubBase.cpython-312.pyc,,
+twilio/rest/trusthub/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/trusthub/v1/__init__.py,sha256=ylVjXc_ydfpG1fHfAe_zPUENSRXRiFgYw4VlVQmvFcE,4926
+twilio/rest/trusthub/v1/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/trusthub/v1/__pycache__/compliance_inquiries.cpython-312.pyc,,
+twilio/rest/trusthub/v1/__pycache__/compliance_registration_inquiries.cpython-312.pyc,,
+twilio/rest/trusthub/v1/__pycache__/compliance_tollfree_inquiries.cpython-312.pyc,,
+twilio/rest/trusthub/v1/__pycache__/end_user.cpython-312.pyc,,
+twilio/rest/trusthub/v1/__pycache__/end_user_type.cpython-312.pyc,,
+twilio/rest/trusthub/v1/__pycache__/policies.cpython-312.pyc,,
+twilio/rest/trusthub/v1/__pycache__/supporting_document.cpython-312.pyc,,
+twilio/rest/trusthub/v1/__pycache__/supporting_document_type.cpython-312.pyc,,
+twilio/rest/trusthub/v1/compliance_inquiries.py,sha256=7N_DBUDEfQtTCbjx6s2N7jliKSSaRQbxvxEV_yVUqwk,11702
+twilio/rest/trusthub/v1/compliance_registration_inquiries.py,sha256=nmMqv3S49VTyZMHDXqpLbvcOVtPg_w_2pLmyPVIiGKU,28318
+twilio/rest/trusthub/v1/compliance_tollfree_inquiries.py,sha256=zd4iItGhbhUjVkiil8rJUODrRweyJHJUT_zQGkbt2BQ,14834
+twilio/rest/trusthub/v1/customer_profiles/__init__.py,sha256=tDyUmTRFNDQ7XpH_PY9ppn_KaBbqK6f9kcdkiMxmscY,32132
+twilio/rest/trusthub/v1/customer_profiles/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/trusthub/v1/customer_profiles/__pycache__/customer_profiles_channel_endpoint_assignment.cpython-312.pyc,,
+twilio/rest/trusthub/v1/customer_profiles/__pycache__/customer_profiles_entity_assignments.cpython-312.pyc,,
+twilio/rest/trusthub/v1/customer_profiles/__pycache__/customer_profiles_evaluations.cpython-312.pyc,,
+twilio/rest/trusthub/v1/customer_profiles/customer_profiles_channel_endpoint_assignment.py,sha256=6Bn2Cftxm7mGRjXIPkVCu_WfjoseN9CItbU6Sp0q9K8,24350
+twilio/rest/trusthub/v1/customer_profiles/customer_profiles_entity_assignments.py,sha256=Y9VoVi_dW7rhTWIDr7_fCRsRvcAko_A7lM6vVMVzXM4,22795
+twilio/rest/trusthub/v1/customer_profiles/customer_profiles_evaluations.py,sha256=MBv7dFnstEx-BK-4LMjUEDJ3_EDP2w_61ys5VQY4Ij0,19310
+twilio/rest/trusthub/v1/end_user.py,sha256=FzBSwDDmHdBktQnPKGcIbXBTduaDfBaYwNjLtjjQeRo,21761
+twilio/rest/trusthub/v1/end_user_type.py,sha256=AD37MAi6XDD0iJIxkgSyXHVMzwAabWzHmDif8A9hzlw,14583
+twilio/rest/trusthub/v1/policies.py,sha256=EPIg9jHa8Otq4_NalbxK0QQVYCSSwfnigq20LdFsCNQ,14011
+twilio/rest/trusthub/v1/supporting_document.py,sha256=a_u94ntENL7QZIQjhUB3Tyx8PBJLCTxUkrg8AZobglQ,23394
+twilio/rest/trusthub/v1/supporting_document_type.py,sha256=ZSEwsngIwbaeKBByPFLcgprAabOiK9wtjHtOsmS5gYE,15209
+twilio/rest/trusthub/v1/trust_products/__init__.py,sha256=_zv1dpHZTdjokT8GWLkm0F6D3tcfXB5FOab5mw3Kh48,31492
+twilio/rest/trusthub/v1/trust_products/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/trusthub/v1/trust_products/__pycache__/trust_products_channel_endpoint_assignment.cpython-312.pyc,,
+twilio/rest/trusthub/v1/trust_products/__pycache__/trust_products_entity_assignments.cpython-312.pyc,,
+twilio/rest/trusthub/v1/trust_products/__pycache__/trust_products_evaluations.cpython-312.pyc,,
+twilio/rest/trusthub/v1/trust_products/trust_products_channel_endpoint_assignment.py,sha256=FwxYxXryAXwYkoWGVnOkNRRaRhsZ6y2lw73MnP6234U,24044
+twilio/rest/trusthub/v1/trust_products/trust_products_entity_assignments.py,sha256=dmIQ_F2ZG_Z0uxgLfJXmJSg15Ho6MZk9ne4KPTiNPbs,22366
+twilio/rest/trusthub/v1/trust_products/trust_products_evaluations.py,sha256=rdTiKFlP-m29ZjRO4oC4xRFt3I44uZQ9-FzwTDelJBM,18929
+twilio/rest/verify/VerifyBase.py,sha256=slTn-f0x41HIoCytOvLLAYdWVdgh0Vfdno0Abcx0LC8,1197
+twilio/rest/verify/__init__.py,sha256=64lABdnh-2wHRS-ODTfyTpa3DHZlfAsSxsvLP5O9TK8,2056
+twilio/rest/verify/__pycache__/VerifyBase.cpython-312.pyc,,
+twilio/rest/verify/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/verify/v2/__init__.py,sha256=CRuH0It_FUkZwbFGIhF4HmqAvwABDjm1dMUApkLqlFI,2993
+twilio/rest/verify/v2/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/verify/v2/__pycache__/form.cpython-312.pyc,,
+twilio/rest/verify/v2/__pycache__/safelist.cpython-312.pyc,,
+twilio/rest/verify/v2/__pycache__/template.cpython-312.pyc,,
+twilio/rest/verify/v2/__pycache__/verification_attempt.cpython-312.pyc,,
+twilio/rest/verify/v2/__pycache__/verification_attempts_summary.cpython-312.pyc,,
+twilio/rest/verify/v2/form.py,sha256=909gfUJuAw_bW71J6HARQ4-ARsJ7o3vIstHEdguQC-o,5876
+twilio/rest/verify/v2/safelist.py,sha256=Ag90aA4SOTgXFluJv4Jj8a6vAztCI_yvs3hBCxURFhA,8628
+twilio/rest/verify/v2/service/__init__.py,sha256=WmL8y2Dasd-v80kz_lYjjdrY7gqsAFWNEDEOlHBeBSE,63600
+twilio/rest/verify/v2/service/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/verify/v2/service/__pycache__/access_token.cpython-312.pyc,,
+twilio/rest/verify/v2/service/__pycache__/messaging_configuration.cpython-312.pyc,,
+twilio/rest/verify/v2/service/__pycache__/verification.cpython-312.pyc,,
+twilio/rest/verify/v2/service/__pycache__/verification_check.cpython-312.pyc,,
+twilio/rest/verify/v2/service/__pycache__/webhook.cpython-312.pyc,,
+twilio/rest/verify/v2/service/access_token.py,sha256=1ZpaHFwwpjWMmXI7y3mJFeFDulTF2SMM-5q5k821jmU,10807
+twilio/rest/verify/v2/service/entity/__init__.py,sha256=itrroE7UTwKM03yPBfC_EnyCLiY_Ufqb_WyNGCC0-4s,21581
+twilio/rest/verify/v2/service/entity/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/verify/v2/service/entity/__pycache__/factor.cpython-312.pyc,,
+twilio/rest/verify/v2/service/entity/__pycache__/new_factor.cpython-312.pyc,,
+twilio/rest/verify/v2/service/entity/challenge/__init__.py,sha256=iZ_efdWSqqG0LzLZHSqfYCRQ14XrM6-RUsJvFYrsySg,35609
+twilio/rest/verify/v2/service/entity/challenge/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/verify/v2/service/entity/challenge/__pycache__/notification.cpython-312.pyc,,
+twilio/rest/verify/v2/service/entity/challenge/notification.py,sha256=jHoqJF5UV0c6BSJ17jf5yDkMXlSwicsdn8FvzgmJ_ns,6946
+twilio/rest/verify/v2/service/entity/factor.py,sha256=8M5KTGNV_myl89zhQh1peYEcPGt52BPcan02CUXPMzU,30406
+twilio/rest/verify/v2/service/entity/new_factor.py,sha256=ZQwCSA25oMDePqlWyhXLSpXfxR0NjO7ceAdWkeUXDKE,16555
+twilio/rest/verify/v2/service/messaging_configuration.py,sha256=10nFnWOIK2GsTc8M_vVGaJYpOqCcbLIMc-z1RLJjkkQ,24500
+twilio/rest/verify/v2/service/rate_limit/__init__.py,sha256=RDqM6xpir69k4fmKs4_s4pl_34nH9t6D2QqAnU-b4n0,22708
+twilio/rest/verify/v2/service/rate_limit/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/verify/v2/service/rate_limit/__pycache__/bucket.cpython-312.pyc,,
+twilio/rest/verify/v2/service/rate_limit/bucket.py,sha256=4UfvcaXif8peF_hjPLYazJgGmfqKah8rt28jEs_f-Wk,23443
+twilio/rest/verify/v2/service/verification.py,sha256=UbDYqseVvl265qsGh0PmyIYmTdxYQMU1nmS4M1ee_JQ,24228
+twilio/rest/verify/v2/service/verification_check.py,sha256=773bJ0nSXxC8gng-6sj1Bd-NtcChD5pIb73-kwD41qU,9418
+twilio/rest/verify/v2/service/webhook.py,sha256=h5jSWrl4iozfO7FW7Z3IL6qjnQc9BUcE1G8mKxKDUuk,26592
+twilio/rest/verify/v2/template.py,sha256=YCtBY-w6M6OwtENuBlgQhTxP80NGgFEwQV8yarjhjfM,12051
+twilio/rest/verify/v2/verification_attempt.py,sha256=2ToIzv1ZMa14aYeRQlEo9wnhBjZuFaavIff6-vSSC_0,30897
+twilio/rest/verify/v2/verification_attempts_summary.py,sha256=OHp1b9X1IFP-P4grVYk7illDA9KExQpQBM9bMlML3C0,13606
+twilio/rest/video/VideoBase.py,sha256=qDVCaYofOZ9GyWTLVAkIr-z20L7qJzK6UVkaoCSix7E,1190
+twilio/rest/video/__init__.py,sha256=n0lfmIKLLW72CaH5QxWw4PzNz9xs-sS7lcn3IVFNZZc,2050
+twilio/rest/video/__pycache__/VideoBase.cpython-312.pyc,,
+twilio/rest/video/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/video/v1/__init__.py,sha256=dkp1TkZI0FLmxCCZ3nLx3YOtDwdzlm940z3vnPQSwXg,2972
+twilio/rest/video/v1/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/video/v1/__pycache__/composition.cpython-312.pyc,,
+twilio/rest/video/v1/__pycache__/composition_hook.cpython-312.pyc,,
+twilio/rest/video/v1/__pycache__/composition_settings.cpython-312.pyc,,
+twilio/rest/video/v1/__pycache__/recording.cpython-312.pyc,,
+twilio/rest/video/v1/__pycache__/recording_settings.cpython-312.pyc,,
+twilio/rest/video/v1/composition.py,sha256=RCS6MKuTHXpK-TqoSMbhHs0uZ5BO3Ww5IFLd8H8vf-E,35950
+twilio/rest/video/v1/composition_hook.py,sha256=hMVK3E4orclhDG2rPdilugt7wLC4gOpBCrVXELOtSI0,56200
+twilio/rest/video/v1/composition_settings.py,sha256=kBu6WRkDoV-5YrvVAHXsPlsiGiB95cB_6YPWpmap9uk,14299
+twilio/rest/video/v1/recording.py,sha256=olKXsqVZbLTOUD0BZ_hK23lSF30KRTwBbxORB_N7Wpk,27838
+twilio/rest/video/v1/recording_settings.py,sha256=c8FiVzy4sKp9RIP55nT_zjijKttYTmtE0TzrO4N2WtQ,14130
+twilio/rest/video/v1/room/__init__.py,sha256=53xRHI10FMaa5dZ_qyOqyNr8W2C12Q9AOKLKQTd1q1I,40422
+twilio/rest/video/v1/room/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/video/v1/room/__pycache__/recording_rules.cpython-312.pyc,,
+twilio/rest/video/v1/room/__pycache__/room_recording.cpython-312.pyc,,
+twilio/rest/video/v1/room/participant/__init__.py,sha256=h9R1KpOb900lpxQctmbXyDXJUCLvdIqxXAfCEo70lzI,29495
+twilio/rest/video/v1/room/participant/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/video/v1/room/participant/__pycache__/anonymize.cpython-312.pyc,,
+twilio/rest/video/v1/room/participant/__pycache__/published_track.cpython-312.pyc,,
+twilio/rest/video/v1/room/participant/__pycache__/subscribe_rules.cpython-312.pyc,,
+twilio/rest/video/v1/room/participant/__pycache__/subscribed_track.cpython-312.pyc,,
+twilio/rest/video/v1/room/participant/anonymize.py,sha256=mkGn7zr3wEPVwsgezSyjzRSmGz5gTO47KtrR7P-MFeY,8053
+twilio/rest/video/v1/room/participant/published_track.py,sha256=WJPJep0V2N42HRNKSZhadI33af98Gw9x4MNtI8WV1FY,17358
+twilio/rest/video/v1/room/participant/subscribe_rules.py,sha256=wehmgUSun7ajqKKZj9uArlybLi7gJd90GVfYy8bRpPo,7102
+twilio/rest/video/v1/room/participant/subscribed_track.py,sha256=5g8bV91G-OUrckhHLzXIgdb7QwIo1FSIvBgKNZsJods,17550
+twilio/rest/video/v1/room/recording_rules.py,sha256=-9RUQb-7TRIVJwseEFG5r756rM1V5bsoYe_ztLPrNbw,5798
+twilio/rest/video/v1/room/room_recording.py,sha256=KWomK3OaiLF5ayzg-1JhgPcgfmR_2dAaOk7kx8j8gH4,25271
+twilio/rest/voice/VoiceBase.py,sha256=vx3BwrZ7ey2vqPrenZfgzIkoMV1txQR_vJlPGgMQLn4,1190
+twilio/rest/voice/__init__.py,sha256=mW4XcGaW44Uoa7eyNAKz4Nn4paB0Ck0Mkoub3XQYwwE,2099
+twilio/rest/voice/__pycache__/VoiceBase.cpython-312.pyc,,
+twilio/rest/voice/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/voice/v1/__init__.py,sha256=dEg-rToBdmoNw7zta9H53Krf2WCRRe43XEWTXXkf3Hg,3036
+twilio/rest/voice/v1/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/voice/v1/__pycache__/archived_call.cpython-312.pyc,,
+twilio/rest/voice/v1/__pycache__/byoc_trunk.cpython-312.pyc,,
+twilio/rest/voice/v1/__pycache__/ip_record.cpython-312.pyc,,
+twilio/rest/voice/v1/__pycache__/source_ip_mapping.cpython-312.pyc,,
+twilio/rest/voice/v1/archived_call.py,sha256=V_i84d8jCU9G-BLqSenCnoB7eLpE3vilbaj2n79rYkY,3402
+twilio/rest/voice/v1/byoc_trunk.py,sha256=WzGIcc7nJBwGfYcvspcU8B2wYbBXrzE3ufNJAxrzh7c,38687
+twilio/rest/voice/v1/connection_policy/__init__.py,sha256=rfdFRasVKd9yVFypPO9zaiBrtWJ5mvqNyvf_zVbLLT4,21685
+twilio/rest/voice/v1/connection_policy/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/voice/v1/connection_policy/__pycache__/connection_policy_target.cpython-312.pyc,,
+twilio/rest/voice/v1/connection_policy/connection_policy_target.py,sha256=1ZseM2OXJir4NBZV8xIZi9ggmN3IPkqHD7YBJ3T76a4,30498
+twilio/rest/voice/v1/dialing_permissions/__init__.py,sha256=SJbMDsLFYUD-mkvu8YVDhjUbloobBrKuQwEtRC-Yvgw,2327
+twilio/rest/voice/v1/dialing_permissions/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/voice/v1/dialing_permissions/__pycache__/bulk_country_update.cpython-312.pyc,,
+twilio/rest/voice/v1/dialing_permissions/__pycache__/settings.cpython-312.pyc,,
+twilio/rest/voice/v1/dialing_permissions/bulk_country_update.py,sha256=giefzUf5SmBDspVb9PWy_GbTCt9aLsfHnfidwIcPNKU,4226
+twilio/rest/voice/v1/dialing_permissions/country/__init__.py,sha256=xOuoc2YYOUFVSrVaRczP2ED5PB3J91R2R0IGjZKbXDI,27816
+twilio/rest/voice/v1/dialing_permissions/country/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/voice/v1/dialing_permissions/country/__pycache__/highrisk_special_prefix.cpython-312.pyc,,
+twilio/rest/voice/v1/dialing_permissions/country/highrisk_special_prefix.py,sha256=CG4hyNvOZOXh5C062bQsaimVPkPhhVH0ivBI9yskbMw,11448
+twilio/rest/voice/v1/dialing_permissions/settings.py,sha256=pezyWh8-p55k-CHnb2I0hBMFMpq0TrZgVKcz8yWnfOQ,7576
+twilio/rest/voice/v1/ip_record.py,sha256=meZcdGs5DgInal0HPeeEl-HADgFI76qK9gDM2lXVJlo,21614
+twilio/rest/voice/v1/source_ip_mapping.py,sha256=ATbg-FM9F3O9slFNuEB6kzZLrp3MUEVH0nmHuTbH7GA,20630
+twilio/rest/wireless/WirelessBase.py,sha256=VqCO0nP3Ox8WIkFHHdjMj-6bQeIWIBbW3_YnLYiyBMc,1211
+twilio/rest/wireless/__init__.py,sha256=37apinMOZa6Gr3Dl5SUnt5sy-fQE20i4bUBONAnhdGY,1261
+twilio/rest/wireless/__pycache__/WirelessBase.cpython-312.pyc,,
+twilio/rest/wireless/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/wireless/v1/__init__.py,sha256=V2ghA15n9ZpyofyFP0pUiQtAkoDX4-u1a4-PqluNojM,2136
+twilio/rest/wireless/v1/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/wireless/v1/__pycache__/command.cpython-312.pyc,,
+twilio/rest/wireless/v1/__pycache__/rate_plan.cpython-312.pyc,,
+twilio/rest/wireless/v1/__pycache__/usage_record.cpython-312.pyc,,
+twilio/rest/wireless/v1/command.py,sha256=dFVxuu00-yeLGIs26Rvm7LyyGNOm9pWzVKaEwMs3eQo,28457
+twilio/rest/wireless/v1/rate_plan.py,sha256=0NuRmFYBbaNC5jksOW5r_99IS2munT2EXuidh98JbC8,31676
+twilio/rest/wireless/v1/sim/__init__.py,sha256=E_nLykjUOfJRsZABVmm9eGuj0yJ5TqKc7ox6AinB9J4,47034
+twilio/rest/wireless/v1/sim/__pycache__/__init__.cpython-312.pyc,,
+twilio/rest/wireless/v1/sim/__pycache__/data_session.cpython-312.pyc,,
+twilio/rest/wireless/v1/sim/__pycache__/usage_record.cpython-312.pyc,,
+twilio/rest/wireless/v1/sim/data_session.py,sha256=cka3NNQ3laIkeeQ0J6XH90yxWKNq3V1sBDDjZUD9a3Y,14643
+twilio/rest/wireless/v1/sim/usage_record.py,sha256=crqO1JRUbp-T1XLGCIslGFYjB4ZLSpQu7zm6v011ijs,17801
+twilio/rest/wireless/v1/usage_record.py,sha256=COri6A7vFfzfGcB7Y9M3YtcZfs4Ehx9xU_PJG_MB43M,16389
+twilio/twiml/__init__.py,sha256=2RyXWXsT4Nv38P4Gc51drBxMNMVQzyp7Wzmny5G5QjI,3471
+twilio/twiml/__pycache__/__init__.cpython-312.pyc,,
+twilio/twiml/__pycache__/fax_response.cpython-312.pyc,,
+twilio/twiml/__pycache__/messaging_response.cpython-312.pyc,,
+twilio/twiml/__pycache__/voice_response.cpython-312.pyc,,
+twilio/twiml/fax_response.py,sha256=tIz38pGfUL6kj2CHGUxyP1CKQtdjJySVFiedm64exKI,1435
+twilio/twiml/messaging_response.py,sha256=R3SFGVbZpkQHKf4v5FOm7S_sj97OyrUfjH2z4X53DXk,3017
+twilio/twiml/voice_response.py,sha256=tNSHigGk7dU-tNcA43u_PnUDRlGEKUjJEbASS1Y6o0k,101574
diff --git a/venv/Lib/site-packages/twilio-9.6.3.dist-info/REQUESTED b/venv/Lib/site-packages/twilio-9.6.3.dist-info/REQUESTED
new file mode 100644
index 00000000..e69de29b
diff --git a/venv/Lib/site-packages/twilio-9.6.3.dist-info/WHEEL b/venv/Lib/site-packages/twilio-9.6.3.dist-info/WHEEL
new file mode 100644
index 00000000..5f133dbb
--- /dev/null
+++ b/venv/Lib/site-packages/twilio-9.6.3.dist-info/WHEEL
@@ -0,0 +1,6 @@
+Wheel-Version: 1.0
+Generator: setuptools (80.9.0)
+Root-Is-Purelib: true
+Tag: py2-none-any
+Tag: py3-none-any
+
diff --git a/venv/Lib/site-packages/twilio-9.6.3.dist-info/licenses/AUTHORS.md b/venv/Lib/site-packages/twilio-9.6.3.dist-info/licenses/AUTHORS.md
new file mode 100644
index 00000000..58eabd02
--- /dev/null
+++ b/venv/Lib/site-packages/twilio-9.6.3.dist-info/licenses/AUTHORS.md
@@ -0,0 +1,41 @@
+# Authors
+
+We'd like to thank the following people who have contributed to the
+`twilio-python` repository.
+
+- Adam Ballai
+- Alex Brinsmead
+- Alex Chan
+- Andrew Benton
+- Chad Selph
+- Comrade DOS
+- Dan Yang
+- Dennis Pilarinos
+- Doug Black
+- Evan Fossier
+- Fabian Topfstedt
+- Florian Le Goff
+- Frank Tobia
+- Frederik De Bleser
+- Guillaume BINET
+- Hunter Blanks
+- Joël Franusic
+- Justin Van Koten
+- Kenneth Reitz
+- Kevin Burke
+- Kyle Conroy
+- Michael Parker
+- Moses Palmér
+- Ryan Horn
+- Sam Kimbrel
+- Skylar Saveland
+- Tiberiu Ana
+- Zachary Voase
+- aes
+- dnathe4th
+- isbo
+- negeorge
+- Evan Cooke
+- tysonholub
+- Brodan
+- Kyle Jones
\ No newline at end of file
diff --git a/venv/Lib/site-packages/twilio-9.6.3.dist-info/licenses/LICENSE b/venv/Lib/site-packages/twilio-9.6.3.dist-info/licenses/LICENSE
new file mode 100644
index 00000000..6485c1f8
--- /dev/null
+++ b/venv/Lib/site-packages/twilio-9.6.3.dist-info/licenses/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (C) 2023, Twilio, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/venv/Lib/site-packages/twilio-9.6.3.dist-info/top_level.txt b/venv/Lib/site-packages/twilio-9.6.3.dist-info/top_level.txt
new file mode 100644
index 00000000..105a6864
--- /dev/null
+++ b/venv/Lib/site-packages/twilio-9.6.3.dist-info/top_level.txt
@@ -0,0 +1 @@
+twilio
diff --git a/venv/Lib/site-packages/twilio/__init__.py b/venv/Lib/site-packages/twilio/__init__.py
new file mode 100644
index 00000000..5ce3ed13
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/__init__.py
@@ -0,0 +1,2 @@
+__version_info__ = ("9", "6", "3")
+__version__ = ".".join(__version_info__)
diff --git a/venv/Lib/site-packages/twilio/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/twilio/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 00000000..17389793
Binary files /dev/null and b/venv/Lib/site-packages/twilio/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/__pycache__/request_validator.cpython-312.pyc b/venv/Lib/site-packages/twilio/__pycache__/request_validator.cpython-312.pyc
new file mode 100644
index 00000000..ca95a1dd
Binary files /dev/null and b/venv/Lib/site-packages/twilio/__pycache__/request_validator.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/auth_strategy/__init__.py b/venv/Lib/site-packages/twilio/auth_strategy/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/venv/Lib/site-packages/twilio/auth_strategy/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/twilio/auth_strategy/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 00000000..6e40f885
Binary files /dev/null and b/venv/Lib/site-packages/twilio/auth_strategy/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/auth_strategy/__pycache__/auth_strategy.cpython-312.pyc b/venv/Lib/site-packages/twilio/auth_strategy/__pycache__/auth_strategy.cpython-312.pyc
new file mode 100644
index 00000000..a293019c
Binary files /dev/null and b/venv/Lib/site-packages/twilio/auth_strategy/__pycache__/auth_strategy.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/auth_strategy/__pycache__/auth_type.cpython-312.pyc b/venv/Lib/site-packages/twilio/auth_strategy/__pycache__/auth_type.cpython-312.pyc
new file mode 100644
index 00000000..c9abb3c3
Binary files /dev/null and b/venv/Lib/site-packages/twilio/auth_strategy/__pycache__/auth_type.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/auth_strategy/__pycache__/no_auth_strategy.cpython-312.pyc b/venv/Lib/site-packages/twilio/auth_strategy/__pycache__/no_auth_strategy.cpython-312.pyc
new file mode 100644
index 00000000..ed704893
Binary files /dev/null and b/venv/Lib/site-packages/twilio/auth_strategy/__pycache__/no_auth_strategy.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/auth_strategy/__pycache__/token_auth_strategy.cpython-312.pyc b/venv/Lib/site-packages/twilio/auth_strategy/__pycache__/token_auth_strategy.cpython-312.pyc
new file mode 100644
index 00000000..da3a3932
Binary files /dev/null and b/venv/Lib/site-packages/twilio/auth_strategy/__pycache__/token_auth_strategy.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/auth_strategy/auth_strategy.py b/venv/Lib/site-packages/twilio/auth_strategy/auth_strategy.py
new file mode 100644
index 00000000..223cbff0
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/auth_strategy/auth_strategy.py
@@ -0,0 +1,19 @@
+from twilio.auth_strategy.auth_type import AuthType
+from abc import abstractmethod
+
+
+class AuthStrategy(object):
+ def __init__(self, auth_type: AuthType):
+ self._auth_type = auth_type
+
+ @property
+ def auth_type(self) -> AuthType:
+ return self._auth_type
+
+ @abstractmethod
+ def get_auth_string(self) -> str:
+ """Return the authentication string."""
+
+ @abstractmethod
+ def requires_authentication(self) -> bool:
+ """Return True if authentication is required, else False."""
diff --git a/venv/Lib/site-packages/twilio/auth_strategy/auth_type.py b/venv/Lib/site-packages/twilio/auth_strategy/auth_type.py
new file mode 100644
index 00000000..61886f92
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/auth_strategy/auth_type.py
@@ -0,0 +1,12 @@
+from enum import Enum
+
+
+class AuthType(Enum):
+ ORGS_TOKEN = "orgs_stoken"
+ NO_AUTH = "noauth"
+ BASIC = "basic"
+ API_KEY = "api_key"
+ CLIENT_CREDENTIALS = "client_credentials"
+
+ def __str__(self):
+ return self.value
diff --git a/venv/Lib/site-packages/twilio/auth_strategy/no_auth_strategy.py b/venv/Lib/site-packages/twilio/auth_strategy/no_auth_strategy.py
new file mode 100644
index 00000000..a5bfd6d2
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/auth_strategy/no_auth_strategy.py
@@ -0,0 +1,13 @@
+from auth_type import AuthType
+from twilio.auth_strategy.auth_strategy import AuthStrategy
+
+
+class NoAuthStrategy(AuthStrategy):
+ def __init__(self):
+ super().__init__(AuthType.NO_AUTH)
+
+ def get_auth_string(self) -> str:
+ return ""
+
+ def requires_authentication(self) -> bool:
+ return False
diff --git a/venv/Lib/site-packages/twilio/auth_strategy/token_auth_strategy.py b/venv/Lib/site-packages/twilio/auth_strategy/token_auth_strategy.py
new file mode 100644
index 00000000..33a8d385
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/auth_strategy/token_auth_strategy.py
@@ -0,0 +1,55 @@
+import jwt
+import threading
+import logging
+from datetime import datetime, timezone
+
+from twilio.auth_strategy.auth_type import AuthType
+from twilio.auth_strategy.auth_strategy import AuthStrategy
+from twilio.http.token_manager import TokenManager
+
+
+class TokenAuthStrategy(AuthStrategy):
+ def __init__(self, token_manager: TokenManager):
+ super().__init__(AuthType.ORGS_TOKEN)
+ self.token_manager = token_manager
+ self.token = None
+ self.lock = threading.Lock()
+ logging.basicConfig(level=logging.INFO)
+ self.logger = logging.getLogger(__name__)
+
+ def get_auth_string(self) -> str:
+ self.fetch_token()
+ return f"Bearer {self.token}"
+
+ def requires_authentication(self) -> bool:
+ return True
+
+ def fetch_token(self):
+ if self.token is None or self.token == "" or self.is_token_expired(self.token):
+ with self.lock:
+ if (
+ self.token is None
+ or self.token == ""
+ or self.is_token_expired(self.token)
+ ):
+ self.logger.info("New token fetched for accessing organization API")
+ self.token = self.token_manager.fetch_access_token()
+
+ def is_token_expired(self, token):
+ try:
+ decoded = jwt.decode(token, options={"verify_signature": False})
+ exp = decoded.get("exp")
+
+ if exp is None:
+ return True # No expiration time present, consider it expired
+
+ # Check if the expiration time has passed by using time-zone
+ return datetime.fromtimestamp(exp, tz=timezone.utc) < datetime.now(
+ timezone.utc
+ )
+
+ except jwt.DecodeError:
+ return True # Token is invalid
+ except Exception as e:
+ print(f"An error occurred: {e}")
+ return True
diff --git a/venv/Lib/site-packages/twilio/base/__init__.py b/venv/Lib/site-packages/twilio/base/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/venv/Lib/site-packages/twilio/base/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/twilio/base/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 00000000..ce0da162
Binary files /dev/null and b/venv/Lib/site-packages/twilio/base/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/base/__pycache__/client_base.cpython-312.pyc b/venv/Lib/site-packages/twilio/base/__pycache__/client_base.cpython-312.pyc
new file mode 100644
index 00000000..029a129b
Binary files /dev/null and b/venv/Lib/site-packages/twilio/base/__pycache__/client_base.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/base/__pycache__/deserialize.cpython-312.pyc b/venv/Lib/site-packages/twilio/base/__pycache__/deserialize.cpython-312.pyc
new file mode 100644
index 00000000..fc0e661f
Binary files /dev/null and b/venv/Lib/site-packages/twilio/base/__pycache__/deserialize.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/base/__pycache__/domain.cpython-312.pyc b/venv/Lib/site-packages/twilio/base/__pycache__/domain.cpython-312.pyc
new file mode 100644
index 00000000..7120c6ef
Binary files /dev/null and b/venv/Lib/site-packages/twilio/base/__pycache__/domain.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/base/__pycache__/exceptions.cpython-312.pyc b/venv/Lib/site-packages/twilio/base/__pycache__/exceptions.cpython-312.pyc
new file mode 100644
index 00000000..b9a77ed1
Binary files /dev/null and b/venv/Lib/site-packages/twilio/base/__pycache__/exceptions.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/base/__pycache__/instance_context.cpython-312.pyc b/venv/Lib/site-packages/twilio/base/__pycache__/instance_context.cpython-312.pyc
new file mode 100644
index 00000000..3ee6e9a8
Binary files /dev/null and b/venv/Lib/site-packages/twilio/base/__pycache__/instance_context.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/base/__pycache__/instance_resource.cpython-312.pyc b/venv/Lib/site-packages/twilio/base/__pycache__/instance_resource.cpython-312.pyc
new file mode 100644
index 00000000..b6f94e32
Binary files /dev/null and b/venv/Lib/site-packages/twilio/base/__pycache__/instance_resource.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/base/__pycache__/list_resource.cpython-312.pyc b/venv/Lib/site-packages/twilio/base/__pycache__/list_resource.cpython-312.pyc
new file mode 100644
index 00000000..3ef5467e
Binary files /dev/null and b/venv/Lib/site-packages/twilio/base/__pycache__/list_resource.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/base/__pycache__/obsolete.cpython-312.pyc b/venv/Lib/site-packages/twilio/base/__pycache__/obsolete.cpython-312.pyc
new file mode 100644
index 00000000..f46eb237
Binary files /dev/null and b/venv/Lib/site-packages/twilio/base/__pycache__/obsolete.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/base/__pycache__/page.cpython-312.pyc b/venv/Lib/site-packages/twilio/base/__pycache__/page.cpython-312.pyc
new file mode 100644
index 00000000..f427e27a
Binary files /dev/null and b/venv/Lib/site-packages/twilio/base/__pycache__/page.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/base/__pycache__/serialize.cpython-312.pyc b/venv/Lib/site-packages/twilio/base/__pycache__/serialize.cpython-312.pyc
new file mode 100644
index 00000000..ffae16b9
Binary files /dev/null and b/venv/Lib/site-packages/twilio/base/__pycache__/serialize.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/base/__pycache__/values.cpython-312.pyc b/venv/Lib/site-packages/twilio/base/__pycache__/values.cpython-312.pyc
new file mode 100644
index 00000000..35ea22b7
Binary files /dev/null and b/venv/Lib/site-packages/twilio/base/__pycache__/values.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/base/__pycache__/version.cpython-312.pyc b/venv/Lib/site-packages/twilio/base/__pycache__/version.cpython-312.pyc
new file mode 100644
index 00000000..c0df2b06
Binary files /dev/null and b/venv/Lib/site-packages/twilio/base/__pycache__/version.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/base/client_base.py b/venv/Lib/site-packages/twilio/base/client_base.py
new file mode 100644
index 00000000..b16f85bf
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/base/client_base.py
@@ -0,0 +1,271 @@
+import os
+import platform
+from typing import Dict, List, MutableMapping, Optional, Tuple
+from urllib.parse import urlparse, urlunparse
+
+from twilio import __version__
+from twilio.http import HttpClient
+from twilio.http.http_client import TwilioHttpClient
+from twilio.http.response import Response
+from twilio.credential.credential_provider import CredentialProvider
+
+
+class ClientBase(object):
+ """A client for accessing the Twilio API."""
+
+ def __init__(
+ self,
+ username: Optional[str] = None,
+ password: Optional[str] = None,
+ account_sid: Optional[str] = None,
+ region: Optional[str] = None,
+ http_client: Optional[HttpClient] = None,
+ environment: Optional[MutableMapping[str, str]] = None,
+ edge: Optional[str] = None,
+ user_agent_extensions: Optional[List[str]] = None,
+ credential_provider: Optional[CredentialProvider] = None,
+ ):
+ """
+ Initializes the Twilio Client
+
+ :param username: Username to authenticate with
+ :param password: Password to authenticate with
+ :param account_sid: Account SID, defaults to Username
+ :param region: Twilio Region to make requests to, defaults to 'us1' if an edge is provided
+ :param http_client: HttpClient, defaults to TwilioHttpClient
+ :param environment: Environment to look for auth details, defaults to os.environ
+ :param edge: Twilio Edge to make requests to, defaults to None
+ :param user_agent_extensions: Additions to the user agent string
+ :param credential_provider: credential provider for authentication method that needs to be used
+ """
+
+ environment = environment or os.environ
+
+ self.username = username or environment.get("TWILIO_ACCOUNT_SID")
+ """ :type : str """
+ self.password = password or environment.get("TWILIO_AUTH_TOKEN")
+ """ :type : str """
+ self.edge = edge or environment.get("TWILIO_EDGE")
+ """ :type : str """
+ self.region = region or environment.get("TWILIO_REGION")
+ """ :type : str """
+ self.user_agent_extensions = user_agent_extensions or []
+ """ :type : list[str] """
+ self.credential_provider = credential_provider or None
+ """ :type : CredentialProvider """
+
+ self.account_sid = account_sid or self.username
+ """ :type : str """
+ self.auth = (self.username, self.password)
+ """ :type : tuple(str, str) """
+ self.http_client: HttpClient = http_client or TwilioHttpClient()
+ """ :type : HttpClient """
+
+ def request(
+ self,
+ method: str,
+ uri: str,
+ params: Optional[Dict[str, object]] = None,
+ data: Optional[Dict[str, object]] = None,
+ headers: Optional[Dict[str, str]] = None,
+ auth: Optional[Tuple[str, str]] = None,
+ timeout: Optional[float] = None,
+ allow_redirects: bool = False,
+ ) -> Response:
+ """
+ Makes a request to the Twilio API using the configured http client
+ Authentication information is automatically added if none is provided
+
+ :param method: HTTP Method
+ :param uri: Fully qualified url
+ :param params: Query string parameters
+ :param data: POST body data
+ :param headers: HTTP Headers
+ :param auth: Authentication
+ :param timeout: Timeout in seconds
+ :param allow_redirects: Should the client follow redirects
+
+ :returns: Response from the Twilio API
+ """
+ headers = self.get_headers(method, headers)
+
+ if self.credential_provider:
+
+ auth_strategy = self.credential_provider.to_auth_strategy()
+ headers["Authorization"] = auth_strategy.get_auth_string()
+ elif self.username is not None and self.password is not None:
+ auth = self.get_auth(auth)
+ else:
+ auth = None
+
+ if method == "DELETE":
+ del headers["Accept"]
+
+ uri = self.get_hostname(uri)
+ filtered_data = self.copy_non_none_values(data)
+ return self.http_client.request(
+ method,
+ uri,
+ params=params,
+ data=filtered_data,
+ headers=headers,
+ auth=auth,
+ timeout=timeout,
+ allow_redirects=allow_redirects,
+ )
+
+ async def request_async(
+ self,
+ method: str,
+ uri: str,
+ params: Optional[Dict[str, object]] = None,
+ data: Optional[Dict[str, object]] = None,
+ headers: Optional[Dict[str, str]] = None,
+ auth: Optional[Tuple[str, str]] = None,
+ timeout: Optional[float] = None,
+ allow_redirects: bool = False,
+ ) -> Response:
+ """
+ Asynchronously makes a request to the Twilio API using the configured http client
+ The configured http client must be an asynchronous http client
+ Authentication information is automatically added if none is provided
+
+ :param method: HTTP Method
+ :param uri: Fully qualified url
+ :param params: Query string parameters
+ :param data: POST body data
+ :param headers: HTTP Headers
+ :param auth: Authentication
+ :param timeout: Timeout in seconds
+ :param allow_redirects: Should the client follow redirects
+
+ :returns: Response from the Twilio API
+ """
+ if not self.http_client.is_async:
+ raise RuntimeError(
+ "http_client must be asynchronous to support async API requests"
+ )
+
+ headers = self.get_headers(method, headers)
+ if method == "DELETE":
+ del headers["Accept"]
+
+ if self.credential_provider:
+ auth_strategy = self.credential_provider.to_auth_strategy()
+ headers["Authorization"] = auth_strategy.get_auth_string()
+ elif self.username is not None and self.password is not None:
+ auth = self.get_auth(auth)
+ else:
+ auth = None
+
+ uri = self.get_hostname(uri)
+ filtered_data = self.copy_non_none_values(data)
+ return await self.http_client.request(
+ method,
+ uri,
+ params=params,
+ data=filtered_data,
+ headers=headers,
+ auth=auth,
+ timeout=timeout,
+ allow_redirects=allow_redirects,
+ )
+
+ def copy_non_none_values(self, data):
+ if isinstance(data, dict):
+ return {
+ k: self.copy_non_none_values(v)
+ for k, v in data.items()
+ if v is not None
+ }
+ elif isinstance(data, list):
+ return [
+ self.copy_non_none_values(item) for item in data if item is not None
+ ]
+ return data
+
+ def get_auth(self, auth: Optional[Tuple[str, str]]) -> Tuple[str, str]:
+ """
+ Get the request authentication object
+ :param auth: Authentication (username, password)
+ :returns: The authentication object
+ """
+ return auth or self.auth
+
+ def get_headers(
+ self, method: str, headers: Optional[Dict[str, str]]
+ ) -> Dict[str, str]:
+ """
+ Get the request headers including user-agent, extensions, encoding, content-type, MIME type
+ :param method: HTTP method
+ :param headers: HTTP headers
+ :returns: HTTP headers
+ """
+ headers = headers or {}
+
+ # Set User-Agent
+ pkg_version = __version__
+ os_name = platform.system()
+ os_arch = platform.machine()
+ python_version = platform.python_version()
+ headers["User-Agent"] = "twilio-python/{} ({} {}) Python/{}".format(
+ pkg_version,
+ os_name,
+ os_arch,
+ python_version,
+ )
+ # Extensions
+ for extension in self.user_agent_extensions:
+ headers["User-Agent"] += " {}".format(extension)
+ headers["X-Twilio-Client"] = "python-{}".format(__version__)
+
+ # Types, encodings, etc.
+ headers["Accept-Charset"] = "utf-8"
+ if (method == "POST" or method == "PUT") and ("Content-Type" not in headers):
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+ if "Accept" not in headers:
+ headers["Accept"] = "application/json"
+
+ return headers
+
+ def get_hostname(self, uri: str) -> str:
+ """
+ Determines the proper hostname given edge and region preferences
+ via client configuration or uri.
+
+ :param uri: Fully qualified url
+
+ :returns: The final uri used to make the request
+ """
+ if not self.edge and not self.region:
+ return uri
+
+ parsed_url = urlparse(uri)
+ pieces = parsed_url.netloc.split(".")
+ prefix = pieces[0]
+ suffix = ".".join(pieces[-2:])
+ region = None
+ edge = None
+ if len(pieces) == 4:
+ # product.region.twilio.com
+ region = pieces[1]
+ elif len(pieces) == 5:
+ # product.edge.region.twilio.com
+ edge = pieces[1]
+ region = pieces[2]
+
+ edge = self.edge or edge
+ region = self.region or region or (edge and "us1")
+
+ parsed_url = parsed_url._replace(
+ netloc=".".join([part for part in [prefix, edge, region, suffix] if part])
+ )
+ return str(urlunparse(parsed_url))
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return "".format(self.account_sid)
diff --git a/venv/Lib/site-packages/twilio/base/deserialize.py b/venv/Lib/site-packages/twilio/base/deserialize.py
new file mode 100644
index 00000000..71226c08
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/base/deserialize.py
@@ -0,0 +1,75 @@
+import datetime
+from decimal import BasicContext, Decimal
+from email.utils import parsedate
+from typing import Optional, Union
+
+ISO8601_DATE_FORMAT = "%Y-%m-%d"
+ISO8601_DATETIME_FORMAT = "%Y-%m-%dT%H:%M:%SZ"
+
+
+def iso8601_date(s: str) -> Union[datetime.date, str]:
+ """
+ Parses an ISO 8601 date string and returns a UTC date object or the string
+ if the parsing failed.
+ :param s: ISO 8601-formatted date string (2015-01-25)
+ :return:
+ """
+ try:
+ return (
+ datetime.datetime.strptime(s, ISO8601_DATE_FORMAT)
+ .replace(tzinfo=datetime.timezone.utc)
+ .date()
+ )
+ except (TypeError, ValueError):
+ return s
+
+
+def iso8601_datetime(
+ s: str,
+) -> Union[datetime.datetime, str]:
+ """
+ Parses an ISO 8601 datetime string and returns a UTC datetime object,
+ or the string if parsing failed.
+ :param s: ISO 8601-formatted datetime string (2015-01-25T12:34:56Z)
+ """
+ try:
+ return datetime.datetime.strptime(s, ISO8601_DATETIME_FORMAT).replace(
+ tzinfo=datetime.timezone.utc
+ )
+ except (TypeError, ValueError):
+ return s
+
+
+def rfc2822_datetime(s: str) -> Optional[datetime.datetime]:
+ """
+ Parses an RFC 2822 date string and returns a UTC datetime object,
+ or the string if parsing failed.
+ :param s: RFC 2822-formatted string date
+ :return: datetime or str
+ """
+ date_tuple = parsedate(s)
+ if date_tuple is None:
+ return None
+ return datetime.datetime(*date_tuple[:6]).replace(tzinfo=datetime.timezone.utc)
+
+
+def decimal(d: Optional[str]) -> Union[Decimal, str]:
+ """
+ Parses a decimal string into a Decimal
+ :param d: decimal string
+ """
+ if not d:
+ return d
+ return Decimal(d, BasicContext)
+
+
+def integer(i: str) -> Union[int, str]:
+ """
+ Parses an integer string into an int
+ :param i: integer string
+ :return: int
+ """
+ try:
+ return int(i)
+ except (TypeError, ValueError):
+ return i
diff --git a/venv/Lib/site-packages/twilio/base/domain.py b/venv/Lib/site-packages/twilio/base/domain.py
new file mode 100644
index 00000000..4f8395dd
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/base/domain.py
@@ -0,0 +1,93 @@
+from typing import Dict, Optional, Tuple
+from twilio.http.response import Response
+from twilio.rest import Client
+
+
+class Domain(object):
+ """
+ This represents at Twilio API subdomain.
+
+ Like, `api.twilio.com` or `lookups.twilio.com'.
+ """
+
+ def __init__(self, twilio: Client, base_url: str):
+ self.twilio = twilio
+ self.base_url = base_url
+
+ def absolute_url(self, uri: str) -> str:
+ """
+ Converts a relative `uri` to an absolute url.
+ :param string uri: The relative uri to make absolute.
+ :return: An absolute url (based off this domain)
+ """
+ return "{}/{}".format(self.base_url.strip("/"), uri.strip("/"))
+
+ def request(
+ self,
+ method: str,
+ uri: str,
+ params: Optional[Dict[str, object]] = None,
+ data: Optional[Dict[str, object]] = None,
+ headers: Optional[Dict[str, str]] = None,
+ auth: Optional[Tuple[str, str]] = None,
+ timeout: Optional[float] = None,
+ allow_redirects: bool = False,
+ ) -> Response:
+ """
+ Makes an HTTP request to this domain.
+ :param method: The HTTP method.
+ :param uri: The HTTP uri.
+ :param params: Query parameters.
+ :param data: The request body.
+ :param headers: The HTTP headers.
+ :param auth: Basic auth tuple of (username, password)
+ :param timeout: The request timeout.
+ :param allow_redirects: True if the client should follow HTTP
+ redirects.
+ """
+ url = self.absolute_url(uri)
+ return self.twilio.request(
+ method,
+ url,
+ params=params,
+ data=data,
+ headers=headers,
+ auth=auth,
+ timeout=timeout,
+ allow_redirects=allow_redirects,
+ )
+
+ async def request_async(
+ self,
+ method: str,
+ uri: str,
+ params: Optional[Dict[str, object]] = None,
+ data: Optional[Dict[str, object]] = None,
+ headers: Optional[Dict[str, str]] = None,
+ auth: Optional[Tuple[str, str]] = None,
+ timeout: Optional[float] = None,
+ allow_redirects: bool = False,
+ ) -> Response:
+ """
+ Makes an asynchronous HTTP request to this domain.
+ :param method: The HTTP method.
+ :param uri: The HTTP uri.
+ :param params: Query parameters.
+ :param data: The request body.
+ :param headers: The HTTP headers.
+ :param auth: Basic auth tuple of (username, password)
+ :param timeout: The request timeout.
+ :param allow_redirects: True if the client should follow HTTP
+ redirects.
+ """
+ url = self.absolute_url(uri)
+ return await self.twilio.request_async(
+ method,
+ url,
+ params=params,
+ data=data,
+ headers=headers,
+ auth=auth,
+ timeout=timeout,
+ allow_redirects=allow_redirects,
+ )
diff --git a/venv/Lib/site-packages/twilio/base/exceptions.py b/venv/Lib/site-packages/twilio/base/exceptions.py
new file mode 100644
index 00000000..8f3b7cc7
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/base/exceptions.py
@@ -0,0 +1,82 @@
+# -*- coding: utf-8 -*-
+import sys
+from typing import Optional
+
+
+class TwilioException(Exception):
+ pass
+
+
+class TwilioRestException(TwilioException):
+ """A generic 400 or 500 level exception from the Twilio API
+
+ :param int status: the HTTP status that was returned for the exception
+ :param str uri: The URI that caused the exception
+ :param str msg: A human-readable message for the error
+ :param int|None code: A Twilio-specific error code for the error. This is
+ not available for all errors.
+ :param method: The HTTP method used to make the request
+ :param details: Additional error details returned for the exception
+ """
+
+ def __init__(
+ self,
+ status: int,
+ uri: str,
+ msg: str = "",
+ code: Optional[int] = None,
+ method: str = "GET",
+ details: Optional[object] = None,
+ ):
+ self.uri = uri
+ self.status = status
+ self.msg = msg
+ self.code = code
+ self.method = method
+ self.details = details
+
+ def __str__(self) -> str:
+ """Try to pretty-print the exception, if this is going on screen."""
+
+ def red(words: str) -> str:
+ return "\033[31m\033[49m%s\033[0m" % words
+
+ def white(words: str) -> str:
+ return "\033[37m\033[49m%s\033[0m" % words
+
+ def blue(words: str) -> str:
+ return "\033[34m\033[49m%s\033[0m" % words
+
+ def teal(words: str) -> str:
+ return "\033[36m\033[49m%s\033[0m" % words
+
+ def get_uri(code: int) -> str:
+ return "https://www.twilio.com/docs/errors/{0}".format(code)
+
+ # If it makes sense to print a human readable error message, try to
+ # do it. The one problem is that someone might catch this error and
+ # try to display the message from it to an end user.
+ if hasattr(sys.stderr, "isatty") and sys.stderr.isatty():
+ msg = (
+ "\n{red_error} {request_was}\n\n{http_line}"
+ "\n\n{twilio_returned}\n\n{message}\n".format(
+ red_error=red("HTTP Error"),
+ request_was=white("Your request was:"),
+ http_line=teal("%s %s" % (self.method, self.uri)),
+ twilio_returned=white("Twilio returned the following information:"),
+ message=blue(str(self.msg)),
+ )
+ )
+ if self.code:
+ msg = "".join(
+ [
+ msg,
+ "\n{more_info}\n\n{uri}\n\n".format(
+ more_info=white("More information may be available here:"),
+ uri=blue(get_uri(self.code)),
+ ),
+ ]
+ )
+ return msg
+ else:
+ return "HTTP {0} error: {1}".format(self.status, self.msg)
diff --git a/venv/Lib/site-packages/twilio/base/instance_context.py b/venv/Lib/site-packages/twilio/base/instance_context.py
new file mode 100644
index 00000000..44ff9a38
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/base/instance_context.py
@@ -0,0 +1,6 @@
+from twilio.base.version import Version
+
+
+class InstanceContext(object):
+ def __init__(self, version: Version):
+ self._version = version
diff --git a/venv/Lib/site-packages/twilio/base/instance_resource.py b/venv/Lib/site-packages/twilio/base/instance_resource.py
new file mode 100644
index 00000000..a05aac37
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/base/instance_resource.py
@@ -0,0 +1,6 @@
+from twilio.base.version import Version
+
+
+class InstanceResource(object):
+ def __init__(self, version: Version):
+ self._version = version
diff --git a/venv/Lib/site-packages/twilio/base/list_resource.py b/venv/Lib/site-packages/twilio/base/list_resource.py
new file mode 100644
index 00000000..e3eb176d
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/base/list_resource.py
@@ -0,0 +1,6 @@
+from twilio.base.version import Version
+
+
+class ListResource(object):
+ def __init__(self, version: Version):
+ self._version = version
diff --git a/venv/Lib/site-packages/twilio/base/obsolete.py b/venv/Lib/site-packages/twilio/base/obsolete.py
new file mode 100644
index 00000000..e0f4a033
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/base/obsolete.py
@@ -0,0 +1,47 @@
+import warnings
+import functools
+
+
+class ObsoleteException(Exception):
+ """Base class for warnings about obsolete features."""
+
+
+def obsolete_client(func):
+ """This is a decorator which can be used to mark Client classes as
+ obsolete. It will result in an error being emitted when the class is
+ instantiated."""
+
+ @functools.wraps(func)
+ def new_func(*args, **kwargs):
+ raise ObsoleteException(
+ "{} has been removed from this version of the library. "
+ "Please refer to current documentation for guidance.".format(func.__name__)
+ )
+
+ return new_func
+
+
+def deprecated_method(new_func=None):
+ """
+ This is a decorator which can be used to mark deprecated methods.
+ It will report in a DeprecationWarning being emitted to stderr when the deprecated method is used.
+ """
+
+ def deprecated_method_wrapper(func):
+ @functools.wraps(func)
+ def wrapper(*args, **kwargs):
+ msg = "Function method .{}() is deprecated".format(func.__name__)
+ msg += (
+ " in favor of .{}()".format(new_func)
+ if isinstance(new_func, str)
+ else ""
+ )
+ warnings.warn(msg, DeprecationWarning)
+ return func(*args, **kwargs)
+
+ return wrapper
+
+ if callable(new_func):
+ return deprecated_method_wrapper(new_func)
+
+ return deprecated_method_wrapper
diff --git a/venv/Lib/site-packages/twilio/base/page.py b/venv/Lib/site-packages/twilio/base/page.py
new file mode 100644
index 00000000..b5b2da7b
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/base/page.py
@@ -0,0 +1,173 @@
+import json
+from typing import Any, Dict, Optional
+
+from twilio.base.exceptions import TwilioException
+from twilio.http.response import Response
+
+
+class Page(object):
+ """
+ Represents a page of records in a collection.
+
+ A `Page` lets you iterate over its records and fetch the next and previous
+ pages in the collection.
+ """
+
+ META_KEYS = {
+ "end",
+ "first_page_uri",
+ "next_page_uri",
+ "last_page_uri",
+ "page",
+ "page_size",
+ "previous_page_uri",
+ "total",
+ "num_pages",
+ "start",
+ "uri",
+ }
+
+ def __init__(self, version, response: Response, solution={}):
+ payload = self.process_response(response)
+
+ self._version = version
+ self._payload = payload
+ self._solution = solution
+ self._records = iter(self.load_page(payload))
+
+ def __iter__(self):
+ """
+ A `Page` is a valid iterator.
+ """
+ return self
+
+ def __next__(self):
+ return self.next()
+
+ def next(self):
+ """
+ Returns the next record in the `Page`.
+ """
+ return self.get_instance(next(self._records))
+
+ @classmethod
+ def process_response(cls, response: Response) -> Any:
+ """
+ Load a JSON response.
+
+ :param response: The HTTP response.
+ :return The JSON-loaded content.
+ """
+ if response.status_code != 200:
+ raise TwilioException("Unable to fetch page", response)
+
+ return json.loads(response.text)
+
+ def load_page(self, payload: Dict[str, Any]):
+ """
+ Parses the collection of records out of a list payload.
+
+ :param payload: The JSON-loaded content.
+ :return list: The list of records.
+ """
+ if "meta" in payload and "key" in payload["meta"]:
+ return payload[payload["meta"]["key"]]
+ else:
+ keys = set(payload.keys())
+ key = keys - self.META_KEYS
+ if len(key) == 1:
+ return payload[key.pop()]
+ if "Resources" in payload:
+ return payload["Resources"]
+
+ raise TwilioException("Page Records can not be deserialized")
+
+ @property
+ def previous_page_url(self) -> Optional[str]:
+ """
+ :return str: Returns a link to the previous_page_url or None if doesn't exist.
+ """
+ if "meta" in self._payload and "previous_page_url" in self._payload["meta"]:
+ return self._payload["meta"]["previous_page_url"]
+ elif (
+ "previous_page_uri" in self._payload and self._payload["previous_page_uri"]
+ ):
+ return self._version.domain.absolute_url(self._payload["previous_page_uri"])
+
+ return None
+
+ @property
+ def next_page_url(self) -> Optional[str]:
+ """
+ :return str: Returns a link to the next_page_url or None if doesn't exist.
+ """
+ if "meta" in self._payload and "next_page_url" in self._payload["meta"]:
+ return self._payload["meta"]["next_page_url"]
+ elif "next_page_uri" in self._payload and self._payload["next_page_uri"]:
+ return self._version.domain.absolute_url(self._payload["next_page_uri"])
+
+ return None
+
+ def get_instance(self, payload: Dict[str, Any]) -> Any:
+ """
+ :param dict payload: A JSON-loaded representation of an instance record.
+ :return: A rich, resource-dependent object.
+ """
+ raise TwilioException(
+ "Page.get_instance() must be implemented in the derived class"
+ )
+
+ def next_page(self) -> Optional["Page"]:
+ """
+ Return the `Page` after this one.
+ :return The next page.
+ """
+ if not self.next_page_url:
+ return None
+
+ response = self._version.domain.twilio.request("GET", self.next_page_url)
+ cls = type(self)
+ return cls(self._version, response, self._solution)
+
+ async def next_page_async(self) -> Optional["Page"]:
+ """
+ Asynchronously return the `Page` after this one.
+ :return The next page.
+ """
+ if not self.next_page_url:
+ return None
+
+ response = await self._version.domain.twilio.request_async(
+ "GET", self.next_page_url
+ )
+ cls = type(self)
+ return cls(self._version, response, self._solution)
+
+ def previous_page(self) -> Optional["Page"]:
+ """
+ Return the `Page` before this one.
+ :return The previous page.
+ """
+ if not self.previous_page_url:
+ return None
+
+ response = self._version.domain.twilio.request("GET", self.previous_page_url)
+ cls = type(self)
+ return cls(self._version, response, self._solution)
+
+ async def previous_page_async(self) -> Optional["Page"]:
+ """
+ Asynchronously return the `Page` before this one.
+ :return The previous page.
+ """
+ if not self.previous_page_url:
+ return None
+
+ response = await self._version.domain.twilio.request_async(
+ "GET", self.previous_page_url
+ )
+ cls = type(self)
+ return cls(self._version, response, self._solution)
+
+ def __repr__(self) -> str:
+ return ""
diff --git a/venv/Lib/site-packages/twilio/base/serialize.py b/venv/Lib/site-packages/twilio/base/serialize.py
new file mode 100644
index 00000000..cea91b04
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/base/serialize.py
@@ -0,0 +1,93 @@
+import datetime
+import json
+
+from twilio.base import values
+
+
+def iso8601_date(d):
+ """
+ Return a string representation of a date that the Twilio API understands
+ Format is YYYY-MM-DD. Returns None if d is not a string, datetime, or date
+ """
+ if d == values.unset:
+ return d
+ elif isinstance(d, datetime.datetime):
+ return str(d.date())
+ elif isinstance(d, datetime.date):
+ return str(d)
+ elif isinstance(d, str):
+ return d
+
+
+def iso8601_datetime(d):
+ """
+ Return a string representation of a date that the Twilio API understands
+ Format is YYYY-MM-DD. Returns None if d is not a string, datetime, or date
+ """
+ if d == values.unset:
+ return d
+ elif isinstance(d, datetime.datetime) or isinstance(d, datetime.date):
+ return d.strftime("%Y-%m-%dT%H:%M:%SZ")
+ elif isinstance(d, str):
+ return d
+
+
+def prefixed_collapsible_map(m, prefix):
+ """
+ Return a dict of params corresponding to those in m with the added prefix
+ """
+ if m == values.unset:
+ return {}
+
+ def flatten_dict(d, result=None, prv_keys=None):
+ if result is None:
+ result = {}
+
+ if prv_keys is None:
+ prv_keys = []
+
+ for k, v in d.items():
+ if isinstance(v, dict):
+ flatten_dict(v, result, prv_keys + [k])
+ else:
+ result[".".join(prv_keys + [k])] = v
+
+ return result
+
+ if isinstance(m, dict):
+ flattened = flatten_dict(m)
+ return {"{}.{}".format(prefix, k): v for k, v in flattened.items()}
+
+ return {}
+
+
+def boolean_to_string(bool_or_str):
+ if bool_or_str == values.unset:
+ return bool_or_str
+
+ if bool_or_str is None:
+ return bool_or_str
+
+ if isinstance(bool_or_str, str):
+ return bool_or_str.lower()
+
+ return "true" if bool_or_str else "false"
+
+
+def object(obj):
+ """
+ Return a jsonified string represenation of obj if obj is jsonifiable else
+ return obj untouched
+ """
+ if isinstance(obj, dict) or isinstance(obj, list):
+ return json.dumps(obj)
+ return obj
+
+
+def map(lst, serialize_func):
+ """
+ Applies serialize_func to every element in lst
+ """
+ if not isinstance(lst, list):
+ return lst
+ return [serialize_func(e) for e in lst]
diff --git a/venv/Lib/site-packages/twilio/base/values.py b/venv/Lib/site-packages/twilio/base/values.py
new file mode 100644
index 00000000..16032b11
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/base/values.py
@@ -0,0 +1,13 @@
+from typing import Dict
+
+unset = object()
+
+
+def of(d: Dict[str, object]) -> Dict[str, object]:
+ """
+ Remove unset values from a dict.
+
+ :param d: A dict to strip.
+ :return A dict with unset values removed.
+ """
+ return {k: v for k, v in d.items() if v != unset}
diff --git a/venv/Lib/site-packages/twilio/base/version.py b/venv/Lib/site-packages/twilio/base/version.py
new file mode 100644
index 00000000..ed7e86f4
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/base/version.py
@@ -0,0 +1,489 @@
+import json
+from typing import Any, AsyncIterator, Dict, Iterator, Optional, Tuple
+
+from twilio.base import values
+from twilio.base.domain import Domain
+from twilio.base.exceptions import TwilioRestException
+from twilio.base.page import Page
+from twilio.http.response import Response
+
+
+class Version(object):
+ """
+ Represents an API version.
+ """
+
+ def __init__(self, domain: Domain, version: str):
+ self.domain = domain
+ self.version = version
+
+ def absolute_url(self, uri: str) -> str:
+ """
+ Turns a relative uri into an absolute url.
+ """
+ return self.domain.absolute_url(self.relative_uri(uri))
+
+ def relative_uri(self, uri: str) -> str:
+ """
+ Turns a relative uri into a versioned relative uri.
+ """
+ return "{}/{}".format(self.version.strip("/"), uri.strip("/"))
+
+ def request(
+ self,
+ method: str,
+ uri: str,
+ params: Optional[Dict[str, object]] = None,
+ data: Optional[Dict[str, object]] = None,
+ headers: Optional[Dict[str, str]] = None,
+ auth: Optional[Tuple[str, str]] = None,
+ timeout: Optional[float] = None,
+ allow_redirects: bool = False,
+ ) -> Response:
+ """
+ Make an HTTP request.
+ """
+ url = self.relative_uri(uri)
+ return self.domain.request(
+ method,
+ url,
+ params=params,
+ data=data,
+ headers=headers,
+ auth=auth,
+ timeout=timeout,
+ allow_redirects=allow_redirects,
+ )
+
+ async def request_async(
+ self,
+ method: str,
+ uri: str,
+ params: Optional[Dict[str, object]] = None,
+ data: Optional[Dict[str, object]] = None,
+ headers: Optional[Dict[str, str]] = None,
+ auth: Optional[Tuple[str, str]] = None,
+ timeout: Optional[float] = None,
+ allow_redirects: bool = False,
+ ) -> Response:
+ """
+ Make an asynchronous HTTP request
+ """
+ url = self.relative_uri(uri)
+ return await self.domain.request_async(
+ method,
+ url,
+ params=params,
+ data=data,
+ headers=headers,
+ auth=auth,
+ timeout=timeout,
+ allow_redirects=allow_redirects,
+ )
+
+ @classmethod
+ def exception(
+ cls, method: str, uri: str, response: Response, message: str
+ ) -> TwilioRestException:
+ """
+ Wraps an exceptional response in a `TwilioRestException`.
+ """
+ # noinspection PyBroadException
+ try:
+ error_payload = json.loads(response.text)
+ if "message" in error_payload:
+ message = "{}: {}".format(message, error_payload["message"])
+ details = error_payload.get("details")
+ code = error_payload.get("code", response.status_code)
+ return TwilioRestException(
+ response.status_code, uri, message, code, method, details
+ )
+ except Exception:
+ return TwilioRestException(
+ response.status_code, uri, message, response.status_code, method
+ )
+
+ def _parse_fetch(self, method: str, uri: str, response: Response) -> Any:
+ """
+ Parses fetch response JSON
+ """
+ # Note that 3XX response codes are allowed for fetches.
+ if response.status_code < 200 or response.status_code >= 400:
+ raise self.exception(method, uri, response, "Unable to fetch record")
+
+ return json.loads(response.text)
+
+ def fetch(
+ self,
+ method: str,
+ uri: str,
+ params: Optional[Dict[str, object]] = None,
+ data: Optional[Dict[str, object]] = None,
+ headers: Optional[Dict[str, str]] = None,
+ auth: Optional[Tuple[str, str]] = None,
+ timeout: Optional[float] = None,
+ allow_redirects: bool = False,
+ ) -> Any:
+ """
+ Fetch a resource instance.
+ """
+ response = self.request(
+ method,
+ uri,
+ params=params,
+ data=data,
+ headers=headers,
+ auth=auth,
+ timeout=timeout,
+ allow_redirects=allow_redirects,
+ )
+
+ return self._parse_fetch(method, uri, response)
+
+ async def fetch_async(
+ self,
+ method: str,
+ uri: str,
+ params: Optional[Dict[str, object]] = None,
+ data: Optional[Dict[str, object]] = None,
+ headers: Optional[Dict[str, str]] = None,
+ auth: Optional[Tuple[str, str]] = None,
+ timeout: Optional[float] = None,
+ allow_redirects: bool = False,
+ ) -> Any:
+ """
+ Asynchronously fetch a resource instance.
+ """
+ response = await self.request_async(
+ method,
+ uri,
+ params=params,
+ data=data,
+ headers=headers,
+ auth=auth,
+ timeout=timeout,
+ allow_redirects=allow_redirects,
+ )
+ return self._parse_fetch(method, uri, response)
+
+ def _parse_update(self, method: str, uri: str, response: Response) -> Any:
+ """
+ Parses update response JSON
+ """
+ if response.status_code < 200 or response.status_code >= 300:
+ raise self.exception(method, uri, response, "Unable to update record")
+
+ return json.loads(response.text)
+
+ def update(
+ self,
+ method: str,
+ uri: str,
+ params: Optional[Dict[str, object]] = None,
+ data: Optional[Dict[str, object]] = None,
+ headers: Optional[Dict[str, str]] = None,
+ auth: Optional[Tuple[str, str]] = None,
+ timeout: Optional[float] = None,
+ allow_redirects: bool = False,
+ ) -> Any:
+ """
+ Update a resource instance.
+ """
+ response = self.request(
+ method,
+ uri,
+ params=params,
+ data=data,
+ headers=headers,
+ auth=auth,
+ timeout=timeout,
+ allow_redirects=allow_redirects,
+ )
+
+ return self._parse_update(method, uri, response)
+
+ async def update_async(
+ self,
+ method: str,
+ uri: str,
+ params: Optional[Dict[str, object]] = None,
+ data: Optional[Dict[str, object]] = None,
+ headers: Optional[Dict[str, str]] = None,
+ auth: Optional[Tuple[str, str]] = None,
+ timeout: Optional[float] = None,
+ allow_redirects: bool = False,
+ ) -> Any:
+ """
+ Asynchronously update a resource instance.
+ """
+ response = await self.request_async(
+ method,
+ uri,
+ params=params,
+ data=data,
+ headers=headers,
+ auth=auth,
+ timeout=timeout,
+ allow_redirects=allow_redirects,
+ )
+
+ return self._parse_update(method, uri, response)
+
+ def _parse_delete(self, method: str, uri: str, response: Response) -> bool:
+ """
+ Parses delete response JSON
+ """
+ if response.status_code < 200 or response.status_code >= 300:
+ raise self.exception(method, uri, response, "Unable to delete record")
+
+ return response.status_code == 204
+
+ def delete(
+ self,
+ method: str,
+ uri: str,
+ params: Optional[Dict[str, object]] = None,
+ data: Optional[Dict[str, object]] = None,
+ headers: Optional[Dict[str, str]] = None,
+ auth: Optional[Tuple[str, str]] = None,
+ timeout: Optional[float] = None,
+ allow_redirects: bool = False,
+ ) -> bool:
+ """
+ Delete a resource.
+ """
+ response = self.request(
+ method,
+ uri,
+ params=params,
+ data=data,
+ headers=headers,
+ auth=auth,
+ timeout=timeout,
+ allow_redirects=allow_redirects,
+ )
+
+ return self._parse_delete(method, uri, response)
+
+ async def delete_async(
+ self,
+ method: str,
+ uri: str,
+ params: Optional[Dict[str, object]] = None,
+ data: Optional[Dict[str, object]] = None,
+ headers: Optional[Dict[str, str]] = None,
+ auth: Optional[Tuple[str, str]] = None,
+ timeout: Optional[float] = None,
+ allow_redirects: bool = False,
+ ) -> bool:
+ """
+ Asynchronously delete a resource.
+ """
+ response = await self.request_async(
+ method,
+ uri,
+ params=params,
+ data=data,
+ headers=headers,
+ auth=auth,
+ timeout=timeout,
+ allow_redirects=allow_redirects,
+ )
+
+ return self._parse_delete(method, uri, response)
+
+ def read_limits(
+ self, limit: Optional[int] = None, page_size: Optional[int] = None
+ ) -> Dict[str, object]:
+ """
+ Takes a limit on the max number of records to read and a max page_size
+ and calculates the max number of pages to read.
+
+ :param limit: Max number of records to read.
+ :param page_size: Max page size.
+ :return A dictionary of paging limits.
+ """
+ if limit is not None and page_size is None:
+ page_size = limit
+
+ return {
+ "limit": limit or values.unset,
+ "page_size": page_size or values.unset,
+ }
+
+ def page(
+ self,
+ method: str,
+ uri: str,
+ params: Optional[Dict[str, object]] = None,
+ data: Optional[Dict[str, object]] = None,
+ headers: Optional[Dict[str, str]] = None,
+ auth: Optional[Tuple[str, str]] = None,
+ timeout: Optional[float] = None,
+ allow_redirects: bool = False,
+ ) -> Response:
+ """
+ Makes an HTTP request.
+ """
+ return self.request(
+ method,
+ uri,
+ params=params,
+ data=data,
+ headers=headers,
+ auth=auth,
+ timeout=timeout,
+ allow_redirects=allow_redirects,
+ )
+
+ async def page_async(
+ self,
+ method: str,
+ uri: str,
+ params: Optional[Dict[str, object]] = None,
+ data: Optional[Dict[str, object]] = None,
+ headers: Optional[Dict[str, str]] = None,
+ auth: Optional[Tuple[str, str]] = None,
+ timeout: Optional[float] = None,
+ allow_redirects: bool = False,
+ ) -> Response:
+ """
+ Makes an asynchronous HTTP request.
+ """
+ return await self.request_async(
+ method,
+ uri,
+ params=params,
+ data=data,
+ headers=headers,
+ auth=auth,
+ timeout=timeout,
+ allow_redirects=allow_redirects,
+ )
+
+ def stream(
+ self,
+ page: Optional[Page],
+ limit: Optional[int] = None,
+ page_limit: Optional[int] = None,
+ ) -> Iterator[Any]:
+ """
+ Generates records one a time from a page, stopping at prescribed limits.
+
+ :param page: The page to stream.
+ :param limit: The max number of records to read.
+ :param page_limit: The max number of pages to read.
+ """
+ current_record = 1
+ current_page = 1
+
+ while page is not None:
+ for record in page:
+ yield record
+ current_record += 1
+ if limit and limit is not values.unset and limit < current_record:
+ return
+
+ current_page += 1
+ if (
+ page_limit
+ and page_limit is not values.unset
+ and page_limit < current_page
+ ):
+ return
+
+ page = page.next_page()
+
+ async def stream_async(
+ self,
+ page: Optional[Page],
+ limit: Optional[int] = None,
+ page_limit: Optional[int] = None,
+ ) -> AsyncIterator[Any]:
+ """
+ Generates records one a time from a page, stopping at prescribed limits.
+
+ :param page: The page to stream.
+ :param limit: The max number of records to read.
+ :param page_limit: The max number of pages to read.
+ """
+ current_record = 1
+ current_page = 1
+
+ while page is not None:
+ for record in page:
+ yield record
+ current_record += 1
+ if limit and limit is not values.unset and limit < current_record:
+ return
+
+ current_page += 1
+ if (
+ page_limit
+ and page_limit is not values.unset
+ and page_limit < current_page
+ ):
+ return
+
+ page = await page.next_page_async()
+
+ def _parse_create(self, method: str, uri: str, response: Response) -> Any:
+ """
+ Parse create response JSON
+ """
+ if response.status_code < 200 or response.status_code >= 300:
+ raise self.exception(method, uri, response, "Unable to create record")
+
+ return json.loads(response.text)
+
+ def create(
+ self,
+ method: str,
+ uri: str,
+ params: Optional[Dict[str, object]] = None,
+ data: Optional[Dict[str, object]] = None,
+ headers: Optional[Dict[str, str]] = None,
+ auth: Optional[Tuple[str, str]] = None,
+ timeout: Optional[float] = None,
+ allow_redirects: bool = False,
+ ) -> Any:
+ """
+ Create a resource instance.
+ """
+ response = self.request(
+ method,
+ uri,
+ params=params,
+ data=data,
+ headers=headers,
+ auth=auth,
+ timeout=timeout,
+ allow_redirects=allow_redirects,
+ )
+ return self._parse_create(method, uri, response)
+
+ async def create_async(
+ self,
+ method: str,
+ uri: str,
+ params: Optional[Dict[str, object]] = None,
+ data: Optional[Dict[str, object]] = None,
+ headers: Optional[Dict[str, str]] = None,
+ auth: Optional[Tuple[str, str]] = None,
+ timeout: Optional[float] = None,
+ allow_redirects: bool = False,
+ ) -> Any:
+ """
+ Asynchronously create a resource instance.
+ """
+ response = await self.request_async(
+ method,
+ uri,
+ params=params,
+ data=data,
+ headers=headers,
+ auth=auth,
+ timeout=timeout,
+ allow_redirects=allow_redirects,
+ )
+ return self._parse_create(method, uri, response)
diff --git a/venv/Lib/site-packages/twilio/credential/__init__.py b/venv/Lib/site-packages/twilio/credential/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/venv/Lib/site-packages/twilio/credential/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/twilio/credential/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 00000000..58130f53
Binary files /dev/null and b/venv/Lib/site-packages/twilio/credential/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/credential/__pycache__/client_credential_provider.cpython-312.pyc b/venv/Lib/site-packages/twilio/credential/__pycache__/client_credential_provider.cpython-312.pyc
new file mode 100644
index 00000000..31a956b1
Binary files /dev/null and b/venv/Lib/site-packages/twilio/credential/__pycache__/client_credential_provider.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/credential/__pycache__/credential_provider.cpython-312.pyc b/venv/Lib/site-packages/twilio/credential/__pycache__/credential_provider.cpython-312.pyc
new file mode 100644
index 00000000..be723eff
Binary files /dev/null and b/venv/Lib/site-packages/twilio/credential/__pycache__/credential_provider.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/credential/__pycache__/orgs_credential_provider.cpython-312.pyc b/venv/Lib/site-packages/twilio/credential/__pycache__/orgs_credential_provider.cpython-312.pyc
new file mode 100644
index 00000000..1bbd2e7e
Binary files /dev/null and b/venv/Lib/site-packages/twilio/credential/__pycache__/orgs_credential_provider.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/credential/client_credential_provider.py b/venv/Lib/site-packages/twilio/credential/client_credential_provider.py
new file mode 100644
index 00000000..656d4463
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/credential/client_credential_provider.py
@@ -0,0 +1,28 @@
+from twilio.http.client_token_manager import ClientTokenManager
+from twilio.base.exceptions import TwilioException
+from twilio.credential.credential_provider import CredentialProvider
+from twilio.auth_strategy.auth_type import AuthType
+from twilio.auth_strategy.token_auth_strategy import TokenAuthStrategy
+
+
+class ClientCredentialProvider(CredentialProvider):
+ def __init__(self, client_id: str, client_secret: str, token_manager=None):
+ super().__init__(AuthType.CLIENT_CREDENTIALS)
+
+ if client_id is None or client_secret is None:
+ raise TwilioException("Client id and Client secret are mandatory")
+
+ self.grant_type = "client_credentials"
+ self.client_id = client_id
+ self.client_secret = client_secret
+ self.token_manager = token_manager
+ self.auth_strategy = None
+
+ def to_auth_strategy(self):
+ if self.token_manager is None:
+ self.token_manager = ClientTokenManager(
+ self.grant_type, self.client_id, self.client_secret
+ )
+ if self.auth_strategy is None:
+ self.auth_strategy = TokenAuthStrategy(self.token_manager)
+ return self.auth_strategy
diff --git a/venv/Lib/site-packages/twilio/credential/credential_provider.py b/venv/Lib/site-packages/twilio/credential/credential_provider.py
new file mode 100644
index 00000000..72aafeed
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/credential/credential_provider.py
@@ -0,0 +1,13 @@
+from twilio.auth_strategy.auth_type import AuthType
+
+
+class CredentialProvider:
+ def __init__(self, auth_type: AuthType):
+ self._auth_type = auth_type
+
+ @property
+ def auth_type(self) -> AuthType:
+ return self._auth_type
+
+ def to_auth_strategy(self):
+ raise NotImplementedError("Subclasses must implement this method")
diff --git a/venv/Lib/site-packages/twilio/credential/orgs_credential_provider.py b/venv/Lib/site-packages/twilio/credential/orgs_credential_provider.py
new file mode 100644
index 00000000..e623f523
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/credential/orgs_credential_provider.py
@@ -0,0 +1,28 @@
+from twilio.http.orgs_token_manager import OrgTokenManager
+from twilio.base.exceptions import TwilioException
+from twilio.credential.credential_provider import CredentialProvider
+from twilio.auth_strategy.auth_type import AuthType
+from twilio.auth_strategy.token_auth_strategy import TokenAuthStrategy
+
+
+class OrgsCredentialProvider(CredentialProvider):
+ def __init__(self, client_id: str, client_secret: str, token_manager=None):
+ super().__init__(AuthType.CLIENT_CREDENTIALS)
+
+ if client_id is None or client_secret is None:
+ raise TwilioException("Client id and Client secret are mandatory")
+
+ self.grant_type = "client_credentials"
+ self.client_id = client_id
+ self.client_secret = client_secret
+ self.token_manager = token_manager
+ self.auth_strategy = None
+
+ def to_auth_strategy(self):
+ if self.token_manager is None:
+ self.token_manager = OrgTokenManager(
+ self.grant_type, self.client_id, self.client_secret
+ )
+ if self.auth_strategy is None:
+ self.auth_strategy = TokenAuthStrategy(self.token_manager)
+ return self.auth_strategy
diff --git a/venv/Lib/site-packages/twilio/http/__init__.py b/venv/Lib/site-packages/twilio/http/__init__.py
new file mode 100644
index 00000000..3e248270
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/http/__init__.py
@@ -0,0 +1,104 @@
+from logging import Logger
+from typing import Any, Dict, Optional, Tuple
+from urllib.parse import urlencode
+
+from requests import Response
+
+from twilio.base.exceptions import TwilioException
+from twilio.http.request import Request as TwilioRequest
+from twilio.http.response import Response as TwilioResponse
+
+
+class HttpClient(object):
+ def __init__(self, logger: Logger, is_async: bool, timeout: Optional[float] = None):
+ """
+ Constructor for the abstract HTTP client
+
+ :param logger
+ :param is_async: Whether the client supports async request calls.
+ :param timeout: Timeout for the requests.
+ Timeout should never be zero (0) or less.
+ """
+ self.logger = logger
+ self.is_async = is_async
+
+ if timeout is not None and timeout <= 0:
+ raise ValueError(timeout)
+ self.timeout = timeout
+
+ self._test_only_last_request: Optional[TwilioRequest] = None
+ self._test_only_last_response: Optional[TwilioResponse] = None
+
+ """
+ An abstract class representing an HTTP client.
+ """
+
+ def request(
+ self,
+ method: str,
+ uri: str,
+ params: Optional[Dict[str, object]] = None,
+ data: Optional[Dict[str, object]] = None,
+ headers: Optional[Dict[str, str]] = None,
+ auth: Optional[Tuple[str, str]] = None,
+ timeout: Optional[float] = None,
+ allow_redirects: bool = False,
+ ) -> TwilioResponse:
+ """
+ Make an HTTP request.
+ """
+ raise TwilioException("HttpClient is an abstract class")
+
+ def log_request(self, kwargs: Dict[str, Any]) -> None:
+ """
+ Logs the HTTP request
+ """
+ self.logger.info("-- BEGIN Twilio API Request --")
+
+ if kwargs["params"]:
+ self.logger.info(
+ "{} Request: {}?{}".format(
+ kwargs["method"], kwargs["url"], urlencode(kwargs["params"])
+ )
+ )
+ self.logger.info("Query Params: {}".format(kwargs["params"]))
+ else:
+ self.logger.info("{} Request: {}".format(kwargs["method"], kwargs["url"]))
+
+ if kwargs["headers"]:
+ self.logger.info("Headers:")
+ for key, value in kwargs["headers"].items():
+ # Do not log authorization headers
+ if "authorization" not in key.lower():
+ self.logger.info("{} : {}".format(key, value))
+
+ self.logger.info("-- END Twilio API Request --")
+
+ def log_response(self, status_code: int, response: Response) -> None:
+ """
+ Logs the HTTP response
+ """
+ self.logger.info("Response Status Code: {}".format(status_code))
+ self.logger.info("Response Headers: {}".format(response.headers))
+
+
+class AsyncHttpClient(HttpClient):
+ """
+ An abstract class representing an asynchronous HTTP client.
+ """
+
+ async def request(
+ self,
+ method: str,
+ uri: str,
+ params: Optional[Dict[str, object]] = None,
+ data: Optional[Dict[str, object]] = None,
+ headers: Optional[Dict[str, str]] = None,
+ auth: Optional[Tuple[str, str]] = None,
+ timeout: Optional[float] = None,
+ allow_redirects: bool = False,
+ ) -> TwilioResponse:
+ """
+ Make an asynchronous HTTP request.
+ """
+ raise TwilioException("AsyncHttpClient is an abstract class")
diff --git a/venv/Lib/site-packages/twilio/http/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/twilio/http/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 00000000..c01cec1a
Binary files /dev/null and b/venv/Lib/site-packages/twilio/http/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/http/__pycache__/async_http_client.cpython-312.pyc b/venv/Lib/site-packages/twilio/http/__pycache__/async_http_client.cpython-312.pyc
new file mode 100644
index 00000000..dcaf5b81
Binary files /dev/null and b/venv/Lib/site-packages/twilio/http/__pycache__/async_http_client.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/http/__pycache__/client_token_manager.cpython-312.pyc b/venv/Lib/site-packages/twilio/http/__pycache__/client_token_manager.cpython-312.pyc
new file mode 100644
index 00000000..bfe10a24
Binary files /dev/null and b/venv/Lib/site-packages/twilio/http/__pycache__/client_token_manager.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/http/__pycache__/http_client.cpython-312.pyc b/venv/Lib/site-packages/twilio/http/__pycache__/http_client.cpython-312.pyc
new file mode 100644
index 00000000..ffcfa0ee
Binary files /dev/null and b/venv/Lib/site-packages/twilio/http/__pycache__/http_client.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/http/__pycache__/orgs_token_manager.cpython-312.pyc b/venv/Lib/site-packages/twilio/http/__pycache__/orgs_token_manager.cpython-312.pyc
new file mode 100644
index 00000000..9da20314
Binary files /dev/null and b/venv/Lib/site-packages/twilio/http/__pycache__/orgs_token_manager.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/http/__pycache__/request.cpython-312.pyc b/venv/Lib/site-packages/twilio/http/__pycache__/request.cpython-312.pyc
new file mode 100644
index 00000000..3269e48e
Binary files /dev/null and b/venv/Lib/site-packages/twilio/http/__pycache__/request.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/http/__pycache__/response.cpython-312.pyc b/venv/Lib/site-packages/twilio/http/__pycache__/response.cpython-312.pyc
new file mode 100644
index 00000000..ebfe3098
Binary files /dev/null and b/venv/Lib/site-packages/twilio/http/__pycache__/response.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/http/__pycache__/token_manager.cpython-312.pyc b/venv/Lib/site-packages/twilio/http/__pycache__/token_manager.cpython-312.pyc
new file mode 100644
index 00000000..b217865a
Binary files /dev/null and b/venv/Lib/site-packages/twilio/http/__pycache__/token_manager.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/http/__pycache__/validation_client.cpython-312.pyc b/venv/Lib/site-packages/twilio/http/__pycache__/validation_client.cpython-312.pyc
new file mode 100644
index 00000000..37f23efa
Binary files /dev/null and b/venv/Lib/site-packages/twilio/http/__pycache__/validation_client.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/http/async_http_client.py b/venv/Lib/site-packages/twilio/http/async_http_client.py
new file mode 100644
index 00000000..ecd5d4de
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/http/async_http_client.py
@@ -0,0 +1,135 @@
+import logging
+from typing import Dict, Optional, Tuple
+
+from aiohttp import BasicAuth, ClientSession
+from aiohttp_retry import ExponentialRetry, RetryClient
+
+from twilio.http import AsyncHttpClient
+from twilio.http.request import Request as TwilioRequest
+from twilio.http.response import Response
+
+_logger = logging.getLogger("twilio.async_http_client")
+
+
+class AsyncTwilioHttpClient(AsyncHttpClient):
+ """
+ General purpose asynchronous HTTP Client for interacting with the Twilio API
+ """
+
+ def __init__(
+ self,
+ pool_connections: bool = True,
+ trace_configs=None,
+ timeout: Optional[float] = None,
+ logger: logging.Logger = _logger,
+ proxy_url: Optional[str] = None,
+ max_retries: Optional[int] = None,
+ ):
+ """
+ Constructor for the AsyncTwilioHttpClient
+
+ :param pool_connections: Creates a client session for making requests from.
+ :param trace_configs: Configuration used to trace request lifecycle events. See aiohttp library TraceConfig
+ documentation for more info.
+ :param timeout: Timeout for the requests (seconds)
+ :param logger
+ :param proxy_url: Proxy URL
+ :param max_retries: Maximum number of retries each request should attempt
+ """
+ super().__init__(logger, True, timeout)
+ self.proxy_url = proxy_url
+ self.trace_configs = trace_configs
+ self.session = (
+ ClientSession(trace_configs=self.trace_configs)
+ if pool_connections
+ else None
+ )
+ if max_retries is not None:
+ retry_options = ExponentialRetry(attempts=max_retries)
+ self.session = RetryClient(
+ client_session=self.session, retry_options=retry_options
+ )
+
+ async def request(
+ self,
+ method: str,
+ url: str,
+ params: Optional[Dict[str, object]] = None,
+ data: Optional[Dict[str, object]] = None,
+ headers: Optional[Dict[str, str]] = None,
+ auth: Optional[Tuple[str, str]] = None,
+ timeout: Optional[float] = None,
+ allow_redirects: bool = False,
+ ) -> Response:
+ """
+ Make an asynchronous HTTP Request with parameters provided.
+
+ :param method: The HTTP method to use
+ :param url: The URL to request
+ :param params: Query parameters to append to the URL
+ :param data: Parameters to go in the body of the HTTP request
+ :param headers: HTTP Headers to send with the request
+ :param auth: Basic Auth arguments (username, password entries)
+ :param timeout: Socket/Read timeout for the request. Overrides the timeout if set on the client.
+ :param allow_redirects: Whether or not to allow redirects
+ See the requests documentation for explanation of all these parameters
+
+ :return: An http response
+ """
+ if timeout is not None and timeout <= 0:
+ raise ValueError(timeout)
+
+ basic_auth = None
+ if auth is not None:
+ basic_auth = BasicAuth(login=auth[0], password=auth[1])
+
+ kwargs = {
+ "method": method.upper(),
+ "url": url,
+ "params": params,
+ "data": data,
+ "headers": headers,
+ "auth": basic_auth,
+ "timeout": timeout,
+ "allow_redirects": allow_redirects,
+ }
+
+ self.log_request(kwargs)
+ self._test_only_last_response = None
+
+ temp = False
+ session = None
+ if self.session:
+ session = self.session
+ else:
+ session = ClientSession()
+ temp = True
+ self._test_only_last_request = TwilioRequest(**kwargs)
+ response = await session.request(**kwargs)
+ self.log_response(response.status, response)
+ self._test_only_last_response = Response(
+ response.status, await response.text(), response.headers
+ )
+ if temp:
+ await session.close()
+ return self._test_only_last_response
+
+ async def close(self):
+ """
+ Closes the HTTP client session
+ """
+ if self.session:
+ await self.session.close()
+
+ async def __aenter__(self):
+ """
+ Async context manager setup
+ """
+ return self
+
+ async def __aexit__(self, *excinfo):
+ """
+ Async context manager exit
+ """
+ if self.session:
+ await self.session.close()
diff --git a/venv/Lib/site-packages/twilio/http/client_token_manager.py b/venv/Lib/site-packages/twilio/http/client_token_manager.py
new file mode 100644
index 00000000..0d42428a
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/http/client_token_manager.py
@@ -0,0 +1,41 @@
+from twilio.http.token_manager import TokenManager
+from twilio.rest import Client
+
+
+class ClientTokenManager(TokenManager):
+ """
+ Client Token Manager
+ """
+
+ def __init__(
+ self,
+ grant_type: str,
+ client_id: str,
+ client_secret: str,
+ code: str = None,
+ redirect_uri: str = None,
+ audience: str = None,
+ refreshToken: str = None,
+ scope: str = None,
+ ):
+ self.grant_type = grant_type
+ self.client_id = client_id
+ self.client_secret = client_secret
+ self.code = code
+ self.redirect_uri = redirect_uri
+ self.audience = audience
+ self.refreshToken = refreshToken
+ self.scope = scope
+ self.client = Client()
+
+ def fetch_access_token(self):
+ token_instance = self.client.iam.v1.token.create(
+ grant_type=self.grant_type,
+ client_id=self.client_id,
+ client_secret=self.client_secret,
+ code=self.code,
+ redirect_uri=self.redirect_uri,
+ audience=self.audience,
+ scope=self.scope,
+ )
+ return token_instance.access_token
diff --git a/venv/Lib/site-packages/twilio/http/http_client.py b/venv/Lib/site-packages/twilio/http/http_client.py
new file mode 100644
index 00000000..2f2d3635
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/http/http_client.py
@@ -0,0 +1,119 @@
+import os
+import logging
+from typing import Dict, Optional, Tuple
+
+from requests import Request, Session, hooks
+from requests.adapters import HTTPAdapter
+
+from twilio.http import HttpClient
+from twilio.http.request import Request as TwilioRequest
+from twilio.http.response import Response
+
+_logger = logging.getLogger("twilio.http_client")
+
+
+class TwilioHttpClient(HttpClient):
+ """
+ General purpose HTTP Client for interacting with the Twilio API
+ """
+
+ def __init__(
+ self,
+ pool_connections: bool = True,
+ request_hooks: Optional[Dict[str, object]] = None,
+ timeout: Optional[float] = None,
+ logger: logging.Logger = _logger,
+ proxy: Optional[Dict[str, str]] = None,
+ max_retries: Optional[int] = None,
+ ):
+ """
+ Constructor for the TwilioHttpClient
+ :param pool_connections
+ :param request_hooks
+ :param timeout: Timeout for the requests.
+ Timeout should never be zero (0) or less
+ :param logger
+ :param proxy: Http proxy for the requests session
+ :param max_retries: Maximum number of retries each request should attempt
+ """
+ super().__init__(logger, False, timeout)
+ self.session = Session() if pool_connections else None
+ if self.session and max_retries is not None:
+ self.session.mount("https://", HTTPAdapter(max_retries=max_retries))
+ elif self.session is not None:
+ self.session.mount(
+ "https://", HTTPAdapter(pool_maxsize=min(32, os.cpu_count() + 4))
+ )
+ self.request_hooks = request_hooks or hooks.default_hooks()
+ self.proxy = proxy if proxy else {}
+
+ def request(
+ self,
+ method: str,
+ url: str,
+ params: Optional[Dict[str, object]] = None,
+ data: Optional[Dict[str, object]] = None,
+ headers: Optional[Dict[str, str]] = None,
+ auth: Optional[Tuple[str, str]] = None,
+ timeout: Optional[float] = None,
+ allow_redirects: bool = False,
+ ) -> Response:
+ """
+ Make an HTTP Request with parameters provided.
+
+ :param method: The HTTP method to use
+ :param url: The URL to request
+ :param params: Query parameters to append to the URL
+ :param data: Parameters to go in the body of the HTTP request
+ :param headers: HTTP Headers to send with the request
+ :param auth: Basic Auth arguments
+ :param timeout: Socket/Read timeout for the request
+ :param allow_redirects: Whether to allow redirects
+ See the requests documentation for explanation of all these parameters
+
+ :return: An HTTP response
+ """
+ if timeout is None:
+ timeout = self.timeout
+ elif timeout <= 0:
+ raise ValueError(timeout)
+
+ kwargs = {
+ "method": method.upper(),
+ "url": url,
+ "params": params,
+ "headers": headers,
+ "auth": auth,
+ "hooks": self.request_hooks,
+ }
+ if headers and headers.get("Content-Type") == "application/json":
+ kwargs["json"] = data
+ elif headers and headers.get("Content-Type") == "application/scim+json":
+ kwargs["json"] = data
+ else:
+ kwargs["data"] = data
+ self.log_request(kwargs)
+ self._test_only_last_response = None
+ session = self.session or Session()
+ request = Request(**kwargs)
+ self._test_only_last_request = TwilioRequest(**kwargs)
+
+ prepped_request = session.prepare_request(request)
+
+ settings = session.merge_environment_settings(
+ prepped_request.url, self.proxy, None, None, None
+ )
+ response = session.send(
+ prepped_request,
+ allow_redirects=allow_redirects,
+ timeout=timeout,
+ **settings,
+ )
+
+ self.log_response(response.status_code, response)
+
+ self._test_only_last_response = Response(
+ int(response.status_code), response.text, response.headers
+ )
+
+ return self._test_only_last_response
diff --git a/venv/Lib/site-packages/twilio/http/orgs_token_manager.py b/venv/Lib/site-packages/twilio/http/orgs_token_manager.py
new file mode 100644
index 00000000..76fad521
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/http/orgs_token_manager.py
@@ -0,0 +1,41 @@
+from twilio.http.token_manager import TokenManager
+from twilio.rest import Client
+
+
+class OrgTokenManager(TokenManager):
+ """
+ Orgs Token Manager
+ """
+
+ def __init__(
+ self,
+ grant_type: str,
+ client_id: str,
+ client_secret: str,
+ code: str = None,
+ redirect_uri: str = None,
+ audience: str = None,
+ refreshToken: str = None,
+ scope: str = None,
+ ):
+ self.grant_type = grant_type
+ self.client_id = client_id
+ self.client_secret = client_secret
+ self.code = code
+ self.redirect_uri = redirect_uri
+ self.audience = audience
+ self.refreshToken = refreshToken
+ self.scope = scope
+ self.client = Client()
+
+ def fetch_access_token(self):
+ token_instance = self.client.iam.v1.token.create(
+ grant_type=self.grant_type,
+ client_id=self.client_id,
+ client_secret=self.client_secret,
+ code=self.code,
+ redirect_uri=self.redirect_uri,
+ audience=self.audience,
+ scope=self.scope,
+ )
+ return token_instance.access_token
diff --git a/venv/Lib/site-packages/twilio/http/request.py b/venv/Lib/site-packages/twilio/http/request.py
new file mode 100644
index 00000000..e75cf12b
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/http/request.py
@@ -0,0 +1,91 @@
+from enum import Enum
+from typing import Any, Dict, Tuple, Union
+from urllib.parse import urlencode
+
+
+class Match(Enum):
+ ANY = "*"
+
+
+class Request(object):
+ """
+ An HTTP request.
+ """
+
+ def __init__(
+ self,
+ method: Union[str, Match] = Match.ANY,
+ url: Union[str, Match] = Match.ANY,
+ auth: Union[Tuple[str, str], Match] = Match.ANY,
+ params: Union[Dict[str, str], Match] = Match.ANY,
+ data: Union[Dict[str, str], Match] = Match.ANY,
+ headers: Union[Dict[str, str], Match] = Match.ANY,
+ **kwargs: Any
+ ):
+ self.method = method
+ if method and method is not Match.ANY:
+ self.method = method.upper()
+ self.url = url
+ self.auth = auth
+ self.params = params
+ self.data = data
+ self.headers = headers
+
+ @classmethod
+ def attribute_equal(cls, lhs, rhs) -> bool:
+ if lhs == Match.ANY or rhs == Match.ANY:
+ # ANY matches everything
+ return True
+
+ lhs = lhs or None
+ rhs = rhs or None
+
+ return lhs == rhs
+
+ def __eq__(self, other) -> bool:
+ if not isinstance(other, Request):
+ return False
+
+ return (
+ self.attribute_equal(self.method, other.method)
+ and self.attribute_equal(self.url, other.url)
+ and self.attribute_equal(self.auth, other.auth)
+ and self.attribute_equal(self.params, other.params)
+ and self.attribute_equal(self.data, other.data)
+ and self.attribute_equal(self.headers, other.headers)
+ )
+
+ def __str__(self) -> str:
+ auth = ""
+ if self.auth and self.auth != Match.ANY:
+ auth = "{} ".format(self.auth)
+
+ params = ""
+ if self.params and self.params != Match.ANY:
+ params = "?{}".format(urlencode(self.params, doseq=True))
+
+ data = ""
+ if self.data and self.data != Match.ANY:
+ if self.method == "GET":
+ data = "\n -G"
+ data += "\n{}".format(
+ "\n".join(' -d "{}={}"'.format(k, v) for k, v in self.data.items())
+ )
+
+ headers = ""
+ if self.headers and self.headers != Match.ANY:
+ headers = "\n{}".format(
+ "\n".join(' -H "{}: {}"'.format(k, v) for k, v in self.headers.items())
+ )
+
+ return "{auth}{method} {url}{params}{data}{headers}".format(
+ auth=auth,
+ method=self.method,
+ url=self.url,
+ params=params,
+ data=data,
+ headers=headers,
+ )
+
+ def __repr__(self) -> str:
+ return str(self)
diff --git a/venv/Lib/site-packages/twilio/http/response.py b/venv/Lib/site-packages/twilio/http/response.py
new file mode 100644
index 00000000..af5a3b17
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/http/response.py
@@ -0,0 +1,22 @@
+from typing import Any, Optional
+
+
+class Response(object):
+ def __init__(
+ self,
+ status_code: int,
+ text: str,
+ headers: Optional[Any] = None,
+ ):
+ self.content = text
+ self.headers = headers
+ self.cached = False
+ self.status_code = status_code
+ self.ok = self.status_code < 400
+
+ @property
+ def text(self) -> str:
+ return self.content
+
+ def __repr__(self) -> str:
+ return "HTTP {} {}".format(self.status_code, self.content)
diff --git a/venv/Lib/site-packages/twilio/http/token_manager.py b/venv/Lib/site-packages/twilio/http/token_manager.py
new file mode 100644
index 00000000..28cc7310
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/http/token_manager.py
@@ -0,0 +1,7 @@
+from twilio.base.version import Version
+
+
+class TokenManager:
+
+ def fetch_access_token(self, version: Version):
+ pass
diff --git a/venv/Lib/site-packages/twilio/http/validation_client.py b/venv/Lib/site-packages/twilio/http/validation_client.py
new file mode 100644
index 00000000..1a4a83f0
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/http/validation_client.py
@@ -0,0 +1,138 @@
+from collections import namedtuple
+
+from requests import Request, Session
+
+from twilio.base.exceptions import TwilioRestException
+from urllib.parse import urlparse
+from twilio.http import HttpClient
+from twilio.http.response import Response
+from twilio.jwt.validation import ClientValidationJwt
+
+
+ValidationPayload = namedtuple(
+ "ValidationPayload",
+ ["method", "path", "query_string", "all_headers", "signed_headers", "body"],
+)
+
+
+class ValidationClient(HttpClient):
+ __SIGNED_HEADERS = ["authorization", "host"]
+
+ def __init__(
+ self,
+ account_sid,
+ api_key_sid,
+ credential_sid,
+ private_key,
+ pool_connections=True,
+ ):
+ """
+ Build a ValidationClient which signs requests with private_key and allows Twilio to
+ validate request has not been tampered with.
+
+ :param str account_sid: A Twilio Account Sid starting with 'AC'
+ :param str api_key_sid: A Twilio API Key Sid starting with 'SK'
+ :param str credential_sid: A Credential Sid starting with 'CR',
+ corresponds to public key Twilio will use to verify the JWT.
+ :param str private_key: The private key used to sign the Client Validation JWT.
+ """
+ self.account_sid = account_sid
+ self.credential_sid = credential_sid
+ self.api_key_sid = api_key_sid
+ self.private_key = private_key
+ self.session = Session() if pool_connections else None
+
+ def request(
+ self,
+ method,
+ url,
+ params=None,
+ data=None,
+ headers=None,
+ auth=None,
+ timeout=None,
+ allow_redirects=False,
+ ):
+ """
+ Make a signed HTTP Request
+
+ :param str method: The HTTP method to use
+ :param str url: The URL to request
+ :param dict params: Query parameters to append to the URL
+ :param dict data: Parameters to go in the body of the HTTP request
+ :param dict headers: HTTP Headers to send with the request
+ :param tuple auth: Basic Auth arguments
+ :param float timeout: Socket/Read timeout for the request
+ :param boolean allow_redirects: Whether or not to allow redirects
+ See the requests documentation for explanation of all these parameters
+
+ :return: An http response
+ :rtype: A :class:`Response ` object
+ """
+ session = self.session or Session()
+ request = Request(
+ method.upper(), url, params=params, data=data, headers=headers, auth=auth
+ )
+ prepared_request = session.prepare_request(request)
+
+ if (
+ "Host" not in prepared_request.headers
+ and "host" not in prepared_request.headers
+ ):
+ prepared_request.headers["Host"] = self._get_host(prepared_request)
+
+ validation_payload = self._build_validation_payload(prepared_request)
+ jwt = ClientValidationJwt(
+ self.account_sid,
+ self.api_key_sid,
+ self.credential_sid,
+ self.private_key,
+ validation_payload,
+ )
+ prepared_request.headers["Twilio-Client-Validation"] = jwt.to_jwt()
+
+ response = session.send(
+ prepared_request,
+ allow_redirects=allow_redirects,
+ timeout=timeout,
+ )
+
+ return Response(int(response.status_code), response.text)
+
+ def _build_validation_payload(self, request):
+ """
+ Extract relevant information from request to build a ClientValidationJWT
+ :param PreparedRequest request: request we will extract information from.
+ :return: ValidationPayload
+ """
+ parsed = urlparse(request.url)
+ path = parsed.path
+ query_string = parsed.query or ""
+
+ return ValidationPayload(
+ method=request.method,
+ path=path,
+ query_string=query_string,
+ all_headers=request.headers,
+ signed_headers=ValidationClient.__SIGNED_HEADERS,
+ body=request.body or "",
+ )
+
+ def _get_host(self, request):
+ """Pull the Host out of the request"""
+ parsed = urlparse(request.url)
+ return str(parsed.netloc)
+
+ def validate_ssl_certificate(self, client):
+ """
+ Validate that a request to the new SSL certificate is successful
+ :return: null on success, raise TwilioRestException if the request fails
+ """
+ response = client.request("GET", "https://tls-test.twilio.com:443")
+
+ if response.status_code < 200 or response.status_code >= 300:
+ raise TwilioRestException(
+ response.status_code,
+ "https://tls-test.twilio.com:443",
+ "Failed to validate SSL certificate",
+ )
diff --git a/venv/Lib/site-packages/twilio/jwt/__init__.py b/venv/Lib/site-packages/twilio/jwt/__init__.py
new file mode 100644
index 00000000..7a51ea70
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/jwt/__init__.py
@@ -0,0 +1,161 @@
+import jwt as jwt_lib
+import time
+
+
+__all__ = ["Jwt", "JwtDecodeError"]
+
+
+class JwtDecodeError(Exception):
+ pass
+
+
+class Jwt(object):
+ """Base class for building a Json Web Token"""
+
+ GENERATE = object()
+ ALGORITHM = "HS256"
+
+ def __init__(
+ self,
+ secret_key,
+ issuer,
+ subject=None,
+ algorithm=None,
+ nbf=GENERATE,
+ ttl=3600,
+ valid_until=None,
+ ):
+ self.secret_key = secret_key
+ """:type str: The secret used to encode the JWT"""
+ self.issuer = issuer
+ """:type str: The issuer of this JWT"""
+ self.subject = subject
+ """:type str: The subject of this JWT, omitted from payload by default"""
+ self.algorithm = algorithm or self.ALGORITHM
+ """:type str: The algorithm used to encode the JWT, defaults to 'HS256'"""
+ self.nbf = nbf
+ """:type int: Time in secs since epoch before which this JWT is invalid. Defaults to now."""
+ self.ttl = ttl
+ """:type int: Time to live of the JWT in seconds, defaults to 1 hour"""
+ self.valid_until = valid_until
+ """:type int: Time in secs since epoch this JWT is valid for. Overrides ttl if provided."""
+
+ self.__decoded_payload = None
+ self.__decoded_headers = None
+
+ def _generate_payload(self):
+ """:rtype: dict the payload of the JWT to send"""
+ raise NotImplementedError("Subclass must provide a payload.")
+
+ def _generate_headers(self):
+ """:rtype dict: Additional headers to include in the JWT, defaults to an empty dict"""
+ return {}
+
+ @classmethod
+ def _from_jwt(cls, headers, payload, key=None):
+ """
+ Class specific implementation of from_jwt which should take jwt components and return
+ and instance of this Class with jwt information loaded.
+ :return: Jwt object containing the headers, payload and key
+ """
+ jwt = Jwt(
+ secret_key=key,
+ issuer=payload.get("iss", None),
+ subject=payload.get("sub", None),
+ algorithm=headers.get("alg", None),
+ valid_until=payload.get("exp", None),
+ nbf=payload.get("nbf", None),
+ )
+ jwt.__decoded_payload = payload
+ jwt.__decoded_headers = headers
+ return jwt
+
+ @property
+ def payload(self):
+ if self.__decoded_payload:
+ return self.__decoded_payload
+
+ payload = self._generate_payload().copy()
+ payload["iss"] = self.issuer
+ payload["exp"] = int(time.time()) + self.ttl
+ if self.nbf is not None:
+ if self.nbf == self.GENERATE:
+ payload["nbf"] = int(time.time())
+ else:
+ payload["nbf"] = self.nbf
+ if self.valid_until:
+ payload["exp"] = self.valid_until
+ if self.subject:
+ payload["sub"] = self.subject
+
+ return payload
+
+ @property
+ def headers(self):
+ if self.__decoded_headers:
+ return self.__decoded_headers
+
+ headers = self._generate_headers().copy()
+ headers["typ"] = "JWT"
+ headers["alg"] = self.algorithm
+ return headers
+
+ def to_jwt(self, ttl=None):
+ """
+ Encode this JWT object into a JWT string
+ :param int ttl: override the ttl configured in the constructor
+ :rtype: str The JWT string
+ """
+
+ if not self.secret_key:
+ raise ValueError("JWT does not have a signing key configured.")
+
+ headers = self.headers.copy()
+
+ payload = self.payload.copy()
+ if ttl:
+ payload["exp"] = int(time.time()) + ttl
+
+ return jwt_lib.encode(
+ payload, self.secret_key, algorithm=self.algorithm, headers=headers
+ )
+
+ @classmethod
+ def from_jwt(cls, jwt, key=""):
+ """
+ Decode a JWT string into a Jwt object
+ :param str jwt: JWT string
+ :param Optional[str] key: key used to verify JWT signature, if not provided then validation
+ is skipped.
+ :raises JwtDecodeError if decoding JWT fails for any reason.
+ :return: A DecodedJwt object containing the jwt information.
+ """
+ verify = True if key else False
+
+ try:
+ headers = jwt_lib.get_unverified_header(jwt)
+
+ alg = headers.get("alg")
+ if alg != cls.ALGORITHM:
+ raise ValueError(
+ f"Incorrect decoding algorithm {alg}, "
+ f"expecting {cls.ALGORITHM}."
+ )
+
+ payload = jwt_lib.decode(
+ jwt,
+ key,
+ algorithms=[cls.ALGORITHM],
+ options={
+ "verify_signature": verify,
+ "verify_exp": True,
+ "verify_nbf": True,
+ },
+ )
+ except Exception as e:
+ raise JwtDecodeError(getattr(e, "message", str(e)))
+
+ return cls._from_jwt(headers, payload, key)
+
+ def __str__(self):
+ return "".format(self.to_jwt())
diff --git a/venv/Lib/site-packages/twilio/jwt/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/twilio/jwt/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 00000000..b45af854
Binary files /dev/null and b/venv/Lib/site-packages/twilio/jwt/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/jwt/access_token/__init__.py b/venv/Lib/site-packages/twilio/jwt/access_token/__init__.py
new file mode 100644
index 00000000..764b2a02
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/jwt/access_token/__init__.py
@@ -0,0 +1,81 @@
+import time
+
+from twilio.jwt import Jwt
+
+
+class AccessTokenGrant(object):
+ """A Grant giving access to a Twilio Resource"""
+
+ @property
+ def key(self):
+ """:rtype str Grant's twilio specific key"""
+ raise NotImplementedError("Grant must have a key property.")
+
+ def to_payload(self):
+ """:return: dict something"""
+ raise NotImplementedError("Grant must implement to_payload.")
+
+ def __str__(self):
+ return "<{} {}>".format(self.__class__.__name__, self.to_payload())
+
+
+class AccessToken(Jwt):
+ """Access Token containing one or more AccessTokenGrants used to access Twilio Resources"""
+
+ ALGORITHM = "HS256"
+
+ def __init__(
+ self,
+ account_sid,
+ signing_key_sid,
+ secret,
+ grants=None,
+ identity=None,
+ nbf=Jwt.GENERATE,
+ ttl=3600,
+ valid_until=None,
+ region=None,
+ ):
+ grants = grants or []
+ if any(not isinstance(g, AccessTokenGrant) for g in grants):
+ raise ValueError("Grants must be instances of AccessTokenGrant.")
+
+ self.account_sid = account_sid
+ self.signing_key_sid = signing_key_sid
+ self.identity = identity
+ self.region = region
+ self.grants = grants
+ super(AccessToken, self).__init__(
+ secret_key=secret,
+ algorithm=self.ALGORITHM,
+ issuer=signing_key_sid,
+ subject=self.account_sid,
+ nbf=nbf,
+ ttl=ttl,
+ valid_until=valid_until,
+ )
+
+ def add_grant(self, grant):
+ """Add a grant to this AccessToken"""
+ if not isinstance(grant, AccessTokenGrant):
+ raise ValueError("Grant must be an instance of AccessTokenGrant.")
+ self.grants.append(grant)
+
+ def _generate_headers(self):
+ headers = {"cty": "twilio-fpa;v=1"}
+ if self.region and isinstance(self.region, str):
+ headers["twr"] = self.region
+ return headers
+
+ def _generate_payload(self):
+ now = int(time.time())
+ payload = {
+ "jti": "{}-{}".format(self.signing_key_sid, now),
+ "grants": {grant.key: grant.to_payload() for grant in self.grants},
+ }
+ if self.identity:
+ payload["grants"]["identity"] = self.identity
+ return payload
+
+ def __str__(self):
+ return "<{} {}>".format(self.__class__.__name__, self.to_jwt())
diff --git a/venv/Lib/site-packages/twilio/jwt/access_token/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/twilio/jwt/access_token/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 00000000..258b6d35
Binary files /dev/null and b/venv/Lib/site-packages/twilio/jwt/access_token/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/jwt/access_token/__pycache__/grants.cpython-312.pyc b/venv/Lib/site-packages/twilio/jwt/access_token/__pycache__/grants.cpython-312.pyc
new file mode 100644
index 00000000..c2aa5411
Binary files /dev/null and b/venv/Lib/site-packages/twilio/jwt/access_token/__pycache__/grants.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/jwt/access_token/grants.py b/venv/Lib/site-packages/twilio/jwt/access_token/grants.py
new file mode 100644
index 00000000..16d19aa3
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/jwt/access_token/grants.py
@@ -0,0 +1,183 @@
+from twilio.jwt.access_token import AccessTokenGrant
+import warnings
+import functools
+
+
+def deprecated(func):
+ """This is a decorator which can be used to mark functions
+ as deprecated. It will result in a warning being emitted
+ when the function is used."""
+
+ @functools.wraps(func)
+ def new_func(*args, **kwargs):
+ warnings.simplefilter("always", DeprecationWarning)
+ warnings.warn(
+ "Call to deprecated function {}.".format(func.__name__),
+ category=DeprecationWarning,
+ stacklevel=2,
+ )
+ warnings.simplefilter("default", DeprecationWarning)
+ return func(*args, **kwargs)
+
+ return new_func
+
+
+class ChatGrant(AccessTokenGrant):
+ """Grant to access Twilio Chat"""
+
+ def __init__(
+ self,
+ service_sid=None,
+ endpoint_id=None,
+ deployment_role_sid=None,
+ push_credential_sid=None,
+ ):
+ self.service_sid = service_sid
+ self.endpoint_id = endpoint_id
+ self.deployment_role_sid = deployment_role_sid
+ self.push_credential_sid = push_credential_sid
+
+ @property
+ def key(self):
+ return "chat"
+
+ def to_payload(self):
+ grant = {}
+ if self.service_sid:
+ grant["service_sid"] = self.service_sid
+ if self.endpoint_id:
+ grant["endpoint_id"] = self.endpoint_id
+ if self.deployment_role_sid:
+ grant["deployment_role_sid"] = self.deployment_role_sid
+ if self.push_credential_sid:
+ grant["push_credential_sid"] = self.push_credential_sid
+
+ return grant
+
+
+class SyncGrant(AccessTokenGrant):
+ """Grant to access Twilio Sync"""
+
+ def __init__(self, service_sid=None, endpoint_id=None):
+ self.service_sid = service_sid
+ self.endpoint_id = endpoint_id
+
+ @property
+ def key(self):
+ return "data_sync"
+
+ def to_payload(self):
+ grant = {}
+ if self.service_sid:
+ grant["service_sid"] = self.service_sid
+ if self.endpoint_id:
+ grant["endpoint_id"] = self.endpoint_id
+
+ return grant
+
+
+class VoiceGrant(AccessTokenGrant):
+ """Grant to access Twilio Programmable Voice"""
+
+ def __init__(
+ self,
+ incoming_allow=None,
+ outgoing_application_sid=None,
+ outgoing_application_params=None,
+ push_credential_sid=None,
+ endpoint_id=None,
+ ):
+ self.incoming_allow = incoming_allow
+ """ :type : bool """
+ self.outgoing_application_sid = outgoing_application_sid
+ """ :type : str """
+ self.outgoing_application_params = outgoing_application_params
+ """ :type : dict """
+ self.push_credential_sid = push_credential_sid
+ """ :type : str """
+ self.endpoint_id = endpoint_id
+ """ :type : str """
+
+ @property
+ def key(self):
+ return "voice"
+
+ def to_payload(self):
+ grant = {}
+ if self.incoming_allow is True:
+ grant["incoming"] = {}
+ grant["incoming"]["allow"] = True
+
+ if self.outgoing_application_sid:
+ grant["outgoing"] = {}
+ grant["outgoing"]["application_sid"] = self.outgoing_application_sid
+
+ if self.outgoing_application_params:
+ grant["outgoing"]["params"] = self.outgoing_application_params
+
+ if self.push_credential_sid:
+ grant["push_credential_sid"] = self.push_credential_sid
+
+ if self.endpoint_id:
+ grant["endpoint_id"] = self.endpoint_id
+
+ return grant
+
+
+class VideoGrant(AccessTokenGrant):
+ """Grant to access Twilio Video"""
+
+ def __init__(self, room=None):
+ self.room = room
+
+ @property
+ def key(self):
+ return "video"
+
+ def to_payload(self):
+ grant = {}
+ if self.room:
+ grant["room"] = self.room
+
+ return grant
+
+
+class TaskRouterGrant(AccessTokenGrant):
+ """Grant to access Twilio TaskRouter"""
+
+ def __init__(self, workspace_sid=None, worker_sid=None, role=None):
+ self.workspace_sid = workspace_sid
+ self.worker_sid = worker_sid
+ self.role = role
+
+ @property
+ def key(self):
+ return "task_router"
+
+ def to_payload(self):
+ grant = {}
+ if self.workspace_sid:
+ grant["workspace_sid"] = self.workspace_sid
+ if self.worker_sid:
+ grant["worker_sid"] = self.worker_sid
+ if self.role:
+ grant["role"] = self.role
+
+ return grant
+
+
+class PlaybackGrant(AccessTokenGrant):
+ """Grant to access Twilio Live stream"""
+
+ def __init__(self, grant=None):
+ """Initialize a PlaybackGrant with a grant retrieved from the Twilio API."""
+ self.grant = grant
+
+ @property
+ def key(self):
+ """Return the grant's key."""
+ return "player"
+
+ def to_payload(self):
+ """Return the grant."""
+ return self.grant
diff --git a/venv/Lib/site-packages/twilio/jwt/client/__init__.py b/venv/Lib/site-packages/twilio/jwt/client/__init__.py
new file mode 100644
index 00000000..d5c38c47
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/jwt/client/__init__.py
@@ -0,0 +1,117 @@
+from twilio.jwt import Jwt
+
+from urllib.parse import urlencode
+
+
+class ClientCapabilityToken(Jwt):
+ """A token to control permissions with Twilio Client"""
+
+ ALGORITHM = "HS256"
+
+ def __init__(
+ self,
+ account_sid,
+ auth_token,
+ nbf=Jwt.GENERATE,
+ ttl=3600,
+ valid_until=None,
+ **kwargs
+ ):
+ """
+ :param str account_sid: The account sid to which this token is granted access.
+ :param str auth_token: The secret key used to sign the token. Note, this auth token is not
+ visible to the user of the token.
+ :param int nbf: Time in secs from epic before which this token is considered invalid.
+ :param int ttl: the amount of time in seconds from generation that this token is valid for.
+ :param kwargs:
+
+
+ :returns: A new CapabilityToken with zero permissions
+ """
+ super(ClientCapabilityToken, self).__init__(
+ algorithm=self.ALGORITHM,
+ secret_key=auth_token,
+ issuer=account_sid,
+ nbf=nbf,
+ ttl=ttl,
+ valid_until=None,
+ )
+
+ self.account_sid = account_sid
+ self.auth_token = auth_token
+ self.client_name = None
+ self.capabilities = {}
+
+ if "allow_client_outgoing" in kwargs:
+ self.allow_client_outgoing(**kwargs["allow_client_outgoing"])
+ if "allow_client_incoming" in kwargs:
+ self.allow_client_incoming(**kwargs["allow_client_incoming"])
+ if "allow_event_stream" in kwargs:
+ self.allow_event_stream(**kwargs["allow_event_stream"])
+
+ def allow_client_outgoing(self, application_sid, **kwargs):
+ """
+ Allow the user of this token to make outgoing connections. Keyword arguments are passed
+ to the application.
+
+ :param str application_sid: Application to contact
+ """
+ scope = ScopeURI("client", "outgoing", {"appSid": application_sid})
+ if kwargs:
+ scope.add_param("appParams", urlencode(kwargs, doseq=True))
+
+ self.capabilities["outgoing"] = scope
+
+ def allow_client_incoming(self, client_name):
+ """
+ Allow the user of this token to accept incoming connections.
+
+ :param str client_name: Client name to accept calls from
+ """
+ self.client_name = client_name
+ self.capabilities["incoming"] = ScopeURI(
+ "client", "incoming", {"clientName": client_name}
+ )
+
+ def allow_event_stream(self, **kwargs):
+ """
+ Allow the user of this token to access their event stream.
+ """
+ scope = ScopeURI("stream", "subscribe", {"path": "/2010-04-01/Events"})
+ if kwargs:
+ scope.add_param("params", urlencode(kwargs, doseq=True))
+
+ self.capabilities["events"] = scope
+
+ def _generate_payload(self):
+ if "outgoing" in self.capabilities and self.client_name is not None:
+ self.capabilities["outgoing"].add_param("clientName", self.client_name)
+
+ scope_uris = [
+ scope_uri.to_payload() for scope_uri in self.capabilities.values()
+ ]
+ return {"scope": " ".join(scope_uris)}
+
+
+class ScopeURI(object):
+ """A single capability granted to Twilio Client and scoped to a service"""
+
+ def __init__(self, service, privilege, params=None):
+ self.service = service
+ self.privilege = privilege
+ self.params = params or {}
+
+ def add_param(self, key, value):
+ self.params[key] = value
+
+ def to_payload(self):
+ if self.params:
+ sorted_params = sorted([(k, v) for k, v in self.params.items()])
+ encoded_params = urlencode(sorted_params)
+ param_string = "?{}".format(encoded_params)
+ else:
+ param_string = ""
+ return "scope:{}:{}{}".format(self.service, self.privilege, param_string)
+
+ def __str__(self):
+ return "".format(self.to_payload())
diff --git a/venv/Lib/site-packages/twilio/jwt/client/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/twilio/jwt/client/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 00000000..5efe8cda
Binary files /dev/null and b/venv/Lib/site-packages/twilio/jwt/client/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/jwt/taskrouter/__init__.py b/venv/Lib/site-packages/twilio/jwt/taskrouter/__init__.py
new file mode 100644
index 00000000..5a01560d
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/jwt/taskrouter/__init__.py
@@ -0,0 +1,142 @@
+from twilio.jwt import Jwt
+
+
+class TaskRouterCapabilityToken(Jwt):
+ VERSION = "v1"
+ DOMAIN = "https://taskrouter.twilio.com"
+ EVENTS_BASE_URL = "https://event-bridge.twilio.com/v1/wschannels"
+ ALGORITHM = "HS256"
+
+ def __init__(self, account_sid, auth_token, workspace_sid, channel_id, **kwargs):
+ """
+ :param str account_sid: Twilio account sid
+ :param str auth_token: Twilio auth token used to sign the JWT
+ :param str workspace_sid: TaskRouter workspace sid
+ :param str channel_id: TaskRouter channel sid
+ :param kwargs:
+ :param bool allow_web_sockets: shortcut to calling allow_web_sockets, defaults to True
+ :param bool allow_fetch_self: shortcut to calling allow_fetch_self, defaults to True
+ :param bool allow_update_self: shortcut to calling allow_update_self, defaults to False
+ :param bool allow_delete_self: shortcut to calling allow_delete_self, defaults to False
+ :param bool allow_fetch_subresources: shortcut to calling allow_fetch_subresources,
+ defaults to False
+ :param bool allow_update_subresources: shortcut to calling allow_update_subresources,
+ defaults to False
+ :param bool allow_delete_subresources: shortcut to calling allow_delete_subresources,
+ defaults to False
+ :returns a new TaskRouterCapabilityToken with capabilities set depending on kwargs.
+ """
+ super(TaskRouterCapabilityToken, self).__init__(
+ secret_key=auth_token,
+ issuer=account_sid,
+ algorithm=self.ALGORITHM,
+ nbf=kwargs.get("nbf", Jwt.GENERATE),
+ ttl=kwargs.get("ttl", 3600),
+ valid_until=kwargs.get("valid_until", None),
+ )
+
+ self._validate_inputs(account_sid, workspace_sid, channel_id)
+
+ self.account_sid = account_sid
+ self.auth_token = auth_token
+ self.workspace_sid = workspace_sid
+ self.channel_id = channel_id
+ self.policies = []
+
+ if kwargs.get("allow_web_sockets", True):
+ self.allow_web_sockets()
+ if kwargs.get("allow_fetch_self", True):
+ self.allow_fetch_self()
+ if kwargs.get("allow_update_self", False):
+ self.allow_update_self()
+ if kwargs.get("allow_delete_self", False):
+ self.allow_delete_self()
+ if kwargs.get("allow_fetch_subresources", False):
+ self.allow_fetch_subresources()
+ if kwargs.get("allow_delete_subresources", False):
+ self.allow_delete_subresources()
+ if kwargs.get("allow_update_subresources", False):
+ self.allow_update_subresources()
+
+ @property
+ def workspace_url(self):
+ return "{}/{}/Workspaces/{}".format(
+ self.DOMAIN, self.VERSION, self.workspace_sid
+ )
+
+ @property
+ def resource_url(self):
+ raise NotImplementedError("Subclass must set its specific resource_url.")
+
+ @property
+ def channel_prefix(self):
+ raise NotImplementedError(
+ "Subclass must set its specific channel_id sid prefix."
+ )
+
+ def allow_fetch_self(self):
+ self._make_policy(self.resource_url, "GET", True)
+
+ def allow_update_self(self):
+ self._make_policy(self.resource_url, "POST", True)
+
+ def allow_delete_self(self):
+ self._make_policy(self.resource_url, "DELETE", True)
+
+ def allow_fetch_subresources(self):
+ self._make_policy(self.resource_url + "/**", "GET", True)
+
+ def allow_update_subresources(self):
+ self._make_policy(self.resource_url + "/**", "POST", True)
+
+ def allow_delete_subresources(self):
+ self._make_policy(self.resource_url + "/**", "DELETE", True)
+
+ def allow_web_sockets(self, channel_id=None):
+ channel_id = channel_id or self.channel_id
+ web_socket_url = "{}/{}/{}".format(
+ self.EVENTS_BASE_URL, self.account_sid, channel_id
+ )
+ self._make_policy(web_socket_url, "GET", True)
+ self._make_policy(web_socket_url, "POST", True)
+
+ def _generate_payload(self):
+ payload = {
+ "account_sid": self.account_sid,
+ "workspace_sid": self.workspace_sid,
+ "channel": self.channel_id,
+ "version": self.VERSION,
+ "friendly_name": self.channel_id,
+ "policies": self.policies,
+ }
+
+ if self.channel_id.startswith("WK"):
+ payload["worker_sid"] = self.channel_id
+ elif self.channel_id.startswith("WQ"):
+ payload["taskqueue_sid"] = self.channel_id
+
+ return payload
+
+ def _make_policy(self, url, method, allowed, query_filter=None, post_filter=None):
+ self.policies.append(
+ {
+ "url": url,
+ "method": method.upper(),
+ "allow": allowed,
+ "query_filter": query_filter or {},
+ "post_filter": post_filter or {},
+ }
+ )
+
+ def _validate_inputs(self, account_sid, workspace_sid, channel_id):
+ if not account_sid or not account_sid.startswith("AC"):
+ raise ValueError("Invalid account sid provided {}".format(account_sid))
+
+ if not workspace_sid or not workspace_sid.startswith("WS"):
+ raise ValueError("Invalid workspace sid provided {}".format(workspace_sid))
+
+ if not channel_id or not channel_id.startswith(self.channel_prefix):
+ raise ValueError("Invalid channel id provided {}".format(channel_id))
+
+ def __str__(self):
+ return "".format(self.to_jwt())
diff --git a/venv/Lib/site-packages/twilio/jwt/taskrouter/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/twilio/jwt/taskrouter/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 00000000..5a37d506
Binary files /dev/null and b/venv/Lib/site-packages/twilio/jwt/taskrouter/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/jwt/taskrouter/__pycache__/capabilities.cpython-312.pyc b/venv/Lib/site-packages/twilio/jwt/taskrouter/__pycache__/capabilities.cpython-312.pyc
new file mode 100644
index 00000000..c0e6ec99
Binary files /dev/null and b/venv/Lib/site-packages/twilio/jwt/taskrouter/__pycache__/capabilities.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/jwt/taskrouter/capabilities.py b/venv/Lib/site-packages/twilio/jwt/taskrouter/capabilities.py
new file mode 100644
index 00000000..468a0270
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/jwt/taskrouter/capabilities.py
@@ -0,0 +1,116 @@
+from twilio.jwt.taskrouter import TaskRouterCapabilityToken
+
+
+class WorkerCapabilityToken(TaskRouterCapabilityToken):
+ def __init__(
+ self, account_sid, auth_token, workspace_sid, worker_sid, ttl=3600, **kwargs
+ ):
+ """
+ :param kwargs:
+ All kwarg parameters supported by TaskRouterCapabilityToken
+ :param bool allow_fetch_activities: shortcut to calling allow_fetch_activities,
+ defaults to True
+ :param bool allow_fetch_reservations: shortcut to calling allow_fetch_reservations,
+ defaults to True
+ :param bool allow_fetch_worker_reservations: shortcut to calling allow_fetch_worker_reservations,
+ defaults to True
+ :param bool allow_update_activities: shortcut to calling allow_update_activities,
+ defaults to False
+ :param bool allow_update_reservations: shortcut to calling allow_update_reservations,
+ defaults to False
+ """
+ super(WorkerCapabilityToken, self).__init__(
+ account_sid=account_sid,
+ auth_token=auth_token,
+ workspace_sid=workspace_sid,
+ channel_id=worker_sid,
+ ttl=ttl,
+ **kwargs
+ )
+
+ if kwargs.get("allow_fetch_activities", True):
+ self.allow_fetch_activities()
+ if kwargs.get("allow_fetch_reservations", True):
+ self.allow_fetch_reservations()
+ if kwargs.get("allow_fetch_worker_reservations", True):
+ self.allow_fetch_worker_reservations()
+ if kwargs.get("allow_update_activities", False):
+ self.allow_update_activities()
+ if kwargs.get("allow_update_reservations", False):
+ self.allow_update_reservations()
+
+ @property
+ def resource_url(self):
+ return "{}/Workers/{}".format(self.workspace_url, self.channel_id)
+
+ @property
+ def channel_prefix(self):
+ return "WK"
+
+ def allow_fetch_activities(self):
+ self._make_policy(self.workspace_url + "/Activities", "GET", True)
+
+ def allow_fetch_reservations(self):
+ self._make_policy(self.workspace_url + "/Tasks/**", "GET", True)
+
+ def allow_fetch_worker_reservations(self):
+ self._make_policy(self.resource_url + "/Reservations/**", "GET", True)
+
+ def allow_update_activities(self):
+ post_filter = {"ActivitySid": {"required": True}}
+ self._make_policy(self.resource_url, "POST", True, post_filter=post_filter)
+
+ def allow_update_reservations(self):
+ self._make_policy(self.workspace_url + "/Tasks/**", "POST", True)
+ self._make_policy(self.resource_url + "/Reservations/**", "POST", True)
+
+ def __str__(self):
+ return "".format(self.to_jwt())
+
+
+class TaskQueueCapabilityToken(TaskRouterCapabilityToken):
+ def __init__(
+ self, account_sid, auth_token, workspace_sid, task_queue_sid, ttl=3600, **kwargs
+ ):
+ super(TaskQueueCapabilityToken, self).__init__(
+ account_sid=account_sid,
+ auth_token=auth_token,
+ workspace_sid=workspace_sid,
+ channel_id=task_queue_sid,
+ ttl=ttl,
+ **kwargs
+ )
+
+ @property
+ def resource_url(self):
+ return "{}/TaskQueues/{}".format(self.workspace_url, self.channel_id)
+
+ @property
+ def channel_prefix(self):
+ return "WQ"
+
+ def __str__(self):
+ return "".format(self.to_jwt())
+
+
+class WorkspaceCapabilityToken(TaskRouterCapabilityToken):
+ def __init__(self, account_sid, auth_token, workspace_sid, ttl=3600, **kwargs):
+ super(WorkspaceCapabilityToken, self).__init__(
+ account_sid=account_sid,
+ auth_token=auth_token,
+ workspace_sid=workspace_sid,
+ channel_id=workspace_sid,
+ ttl=ttl,
+ **kwargs
+ )
+
+ @property
+ def resource_url(self):
+ return self.workspace_url
+
+ @property
+ def channel_prefix(self):
+ return "WS"
+
+ def __str__(self):
+ return "".format(self.to_jwt())
diff --git a/venv/Lib/site-packages/twilio/jwt/validation/__init__.py b/venv/Lib/site-packages/twilio/jwt/validation/__init__.py
new file mode 100644
index 00000000..837d6196
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/jwt/validation/__init__.py
@@ -0,0 +1,92 @@
+from hashlib import sha256
+
+from twilio.jwt import Jwt
+
+
+class ClientValidationJwt(Jwt):
+ """A JWT included on requests so that Twilio can verify request authenticity"""
+
+ __CTY = "twilio-pkrv;v=1"
+ ALGORITHM = "RS256"
+
+ def __init__(
+ self, account_sid, api_key_sid, credential_sid, private_key, validation_payload
+ ):
+ """
+ Create a new ClientValidationJwt
+ :param str account_sid: A Twilio Account Sid starting with 'AC'
+ :param str api_key_sid: A Twilio API Key Sid starting with 'SK'
+ :param str credential_sid: A Credential Sid starting with 'CR',
+ public key Twilio will use to verify the JWT.
+ :param str private_key: The private key used to sign the JWT.
+ :param ValidationPayload validation_payload: information from the request to sign
+ """
+ super(ClientValidationJwt, self).__init__(
+ secret_key=private_key,
+ issuer=api_key_sid,
+ subject=account_sid,
+ algorithm=self.ALGORITHM,
+ ttl=300, # 5 minute ttl
+ )
+ self.credential_sid = credential_sid
+ self.validation_payload = validation_payload
+
+ def _generate_headers(self):
+ return {"cty": ClientValidationJwt.__CTY, "kid": self.credential_sid}
+
+ def _generate_payload(self):
+ # Lowercase header keys, combine and sort headers with list values
+ all_headers = {
+ k.lower(): self._sort_and_join(v, ",")
+ for k, v in self.validation_payload.all_headers.items()
+ }
+ # Names of headers we are signing in the jwt
+ signed_headers = sorted(self.validation_payload.signed_headers)
+
+ # Stringify headers, only include headers in signed_headers
+ headers_str = [
+ "{}:{}".format(h, all_headers[h])
+ for h in signed_headers
+ if h in all_headers
+ ]
+ headers_str = "\n".join(headers_str)
+
+ # Sort query string parameters
+ query_string = self.validation_payload.query_string.split("&")
+ query_string = self._sort_and_join(query_string, "&")
+
+ req_body_hash = self._hash(self.validation_payload.body) or ""
+
+ signed_headers_str = ";".join(signed_headers)
+
+ signed_payload = [
+ self.validation_payload.method,
+ self.validation_payload.path,
+ query_string,
+ ]
+
+ if headers_str:
+ signed_payload.append(headers_str)
+ signed_payload.append("")
+ signed_payload.append(signed_headers_str)
+ signed_payload.append(req_body_hash)
+
+ signed_payload = "\n".join(signed_payload)
+
+ return {"hrh": signed_headers_str, "rqh": self._hash(signed_payload)}
+
+ @classmethod
+ def _sort_and_join(cls, values, joiner):
+ if isinstance(values, str):
+ return values
+ return joiner.join(sorted(values))
+
+ @classmethod
+ def _hash(cls, input_str):
+ if not input_str:
+ return input_str
+
+ if not isinstance(input_str, bytes):
+ input_str = input_str.encode("utf-8")
+
+ return sha256(input_str).hexdigest()
diff --git a/venv/Lib/site-packages/twilio/jwt/validation/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/twilio/jwt/validation/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 00000000..f3986565
Binary files /dev/null and b/venv/Lib/site-packages/twilio/jwt/validation/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/request_validator.py b/venv/Lib/site-packages/twilio/request_validator.py
new file mode 100644
index 00000000..f7a0db36
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/request_validator.py
@@ -0,0 +1,137 @@
+import base64
+import hmac
+from hashlib import sha1, sha256
+
+from urllib.parse import urlparse, parse_qs
+
+
+def compare(string1, string2):
+ """Compare two strings while protecting against timing attacks
+
+ :param str string1: the first string
+ :param str string2: the second string
+
+ :returns: True if the strings are equal, False if not
+ :rtype: :obj:`bool`
+ """
+ if len(string1) != len(string2):
+ return False
+ result = True
+ for c1, c2 in zip(string1, string2):
+ result &= c1 == c2
+
+ return result
+
+
+def remove_port(uri):
+ """Remove the port number from a URI
+
+ :param uri: parsed URI that Twilio requested on your server
+
+ :returns: full URI without a port number
+ :rtype: str
+ """
+ if not uri.port:
+ return uri.geturl()
+
+ new_netloc = uri.netloc.split(":")[0]
+ new_uri = uri._replace(netloc=new_netloc)
+
+ return new_uri.geturl()
+
+
+def add_port(uri):
+ """Add the port number to a URI
+
+ :param uri: parsed URI that Twilio requested on your server
+
+ :returns: full URI with a port number
+ :rtype: str
+ """
+ if uri.port:
+ return uri.geturl()
+
+ port = 443 if uri.scheme == "https" else 80
+ new_netloc = uri.netloc + ":" + str(port)
+ new_uri = uri._replace(netloc=new_netloc)
+
+ return new_uri.geturl()
+
+
+class RequestValidator(object):
+ def __init__(self, token):
+ self.token = token.encode("utf-8")
+
+ def compute_signature(self, uri, params):
+ """Compute the signature for a given request
+
+ :param uri: full URI that Twilio requested on your server
+ :param params: post vars that Twilio sent with the request
+
+ :returns: The computed signature
+ """
+ s = uri
+ if params:
+ for param_name in sorted(set(params)):
+ values = self.get_values(params, param_name)
+
+ for value in sorted(set(values)):
+ s += param_name + value
+
+ # compute signature and compare signatures
+ mac = hmac.new(self.token, s.encode("utf-8"), sha1)
+ computed = base64.b64encode(mac.digest())
+ computed = computed.decode("utf-8")
+
+ return computed.strip()
+
+ def get_values(self, param_dict, param_name):
+ try:
+ # Support MultiDict used by Flask.
+ return param_dict.getall(param_name)
+ except AttributeError:
+ try:
+ # Support QueryDict used by Django.
+ return param_dict.getlist(param_name)
+ except AttributeError:
+ # Fallback to a standard dict.
+ return [param_dict[param_name]]
+
+ def compute_hash(self, body):
+ computed = sha256(body.encode("utf-8")).hexdigest()
+
+ return computed.strip()
+
+ def validate(self, uri, params, signature):
+ """Validate a request from Twilio
+
+ :param uri: full URI that Twilio requested on your server
+ :param params: dictionary of POST variables or string of POST body for JSON requests
+ :param signature: expected signature in HTTP X-Twilio-Signature header
+
+ :returns: True if the request passes validation, False if not
+ """
+ if params is None:
+ params = {}
+
+ parsed_uri = urlparse(uri)
+ uri_with_port = add_port(parsed_uri)
+ uri_without_port = remove_port(parsed_uri)
+
+ valid_body_hash = True # May not receive body hash, so default succeed
+
+ query = parse_qs(parsed_uri.query)
+ if "bodySHA256" in query and isinstance(params, str):
+ valid_body_hash = compare(self.compute_hash(params), query["bodySHA256"][0])
+ params = {}
+
+ # check signature of uri with and without port,
+ # since sig generation on back end is inconsistent
+ valid_signature = compare(
+ self.compute_signature(uri_without_port, params), signature
+ )
+ valid_signature_with_port = compare(
+ self.compute_signature(uri_with_port, params), signature
+ )
+
+ return valid_body_hash and (valid_signature or valid_signature_with_port)
diff --git a/venv/Lib/site-packages/twilio/rest/__init__.py b/venv/Lib/site-packages/twilio/rest/__init__.py
new file mode 100644
index 00000000..dc774118
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/__init__.py
@@ -0,0 +1,772 @@
+r"""
+ This code was generated by
+ ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __
+ | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/
+ | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ https://openapi-generator.tech
+ Do not edit the class manually.
+"""
+
+from typing import TYPE_CHECKING, Optional
+
+from twilio.base.client_base import ClientBase
+
+if TYPE_CHECKING:
+ from twilio.rest.accounts import Accounts
+ from twilio.rest.api import Api
+ from twilio.rest.assistants import Assistants
+ from twilio.rest.bulkexports import Bulkexports
+ from twilio.rest.chat import Chat
+ from twilio.rest.content import Content
+ from twilio.rest.conversations import Conversations
+ from twilio.rest.events import Events
+ from twilio.rest.flex_api import FlexApi
+ from twilio.rest.frontline_api import FrontlineApi
+ from twilio.rest.preview_iam import PreviewIam
+ from twilio.rest.iam import Iam
+ from twilio.rest.insights import Insights
+ from twilio.rest.intelligence import Intelligence
+ from twilio.rest.ip_messaging import IpMessaging
+ from twilio.rest.knowledge import Knowledge
+ from twilio.rest.lookups import Lookups
+ from twilio.rest.marketplace import Marketplace
+ from twilio.rest.messaging import Messaging
+ from twilio.rest.microvisor import Microvisor
+ from twilio.rest.monitor import Monitor
+ from twilio.rest.notify import Notify
+ from twilio.rest.numbers import Numbers
+ from twilio.rest.oauth import Oauth
+ from twilio.rest.preview import Preview
+ from twilio.rest.pricing import Pricing
+ from twilio.rest.proxy import Proxy
+ from twilio.rest.routes import Routes
+ from twilio.rest.serverless import Serverless
+ from twilio.rest.studio import Studio
+ from twilio.rest.supersim import Supersim
+ from twilio.rest.sync import Sync
+ from twilio.rest.taskrouter import Taskrouter
+ from twilio.rest.trunking import Trunking
+ from twilio.rest.trusthub import Trusthub
+ from twilio.rest.verify import Verify
+ from twilio.rest.video import Video
+ from twilio.rest.voice import Voice
+ from twilio.rest.wireless import Wireless
+ from twilio.rest.api.v2010.account.address import AddressList
+ from twilio.rest.api.v2010.account.application import ApplicationList
+ from twilio.rest.api.v2010.account.authorized_connect_app import (
+ AuthorizedConnectAppList,
+ )
+ from twilio.rest.api.v2010.account.available_phone_number_country import (
+ AvailablePhoneNumberCountryList,
+ )
+ from twilio.rest.api.v2010.account.balance import BalanceList
+ from twilio.rest.api.v2010.account.call import CallList
+ from twilio.rest.api.v2010.account.conference import ConferenceList
+ from twilio.rest.api.v2010.account.connect_app import ConnectAppList
+ from twilio.rest.api.v2010.account.incoming_phone_number import (
+ IncomingPhoneNumberList,
+ )
+ from twilio.rest.api.v2010.account.key import KeyList
+ from twilio.rest.api.v2010.account.new_key import NewKeyList
+ from twilio.rest.api.v2010.account.message import MessageList
+ from twilio.rest.api.v2010.account.signing_key import SigningKeyList
+ from twilio.rest.api.v2010.account.new_signing_key import NewSigningKeyList
+ from twilio.rest.api.v2010.account.notification import NotificationList
+ from twilio.rest.api.v2010.account.outgoing_caller_id import OutgoingCallerIdList
+ from twilio.rest.api.v2010.account.validation_request import ValidationRequestList
+ from twilio.rest.api.v2010.account.queue import QueueList
+ from twilio.rest.api.v2010.account.recording import RecordingList
+ from twilio.rest.api.v2010.account.short_code import ShortCodeList
+ from twilio.rest.api.v2010.account.sip import SipList
+ from twilio.rest.api.v2010.account.token import TokenList
+ from twilio.rest.api.v2010.account.transcription import TranscriptionList
+ from twilio.rest.api.v2010.account.usage import UsageList
+
+
+class Client(ClientBase):
+ """A client for accessing the Twilio API."""
+
+ def __init__(
+ self,
+ username=None,
+ password=None,
+ account_sid=None,
+ region=None,
+ http_client=None,
+ environment=None,
+ edge=None,
+ user_agent_extensions=None,
+ credential_provider=None,
+ ):
+ """
+ Initializes the Twilio Client
+
+ :param str username: Username to authenticate with, either account_sid or api_key
+ :param str password: Password to authenticate with, auth_token (if using account_sid) or api_secret (if using api_key)
+ :param str account_sid: Account SID, required if using api_key to authenticate.
+ :param str region: Twilio Region to make requests to, defaults to 'us1' if an edge is provided
+ :param HttpClient http_client: HttpClient, defaults to TwilioHttpClient
+ :param dict environment: Environment to look for auth details, defaults to os.environ
+ :param str edge: Twilio Edge to make requests to, defaults to None
+ :param list[str] user_agent_extensions: Additions to the user agent string
+
+ :returns: Twilio Client
+ :rtype: twilio.rest.Client
+ """
+ super().__init__(
+ username,
+ password,
+ account_sid,
+ region,
+ http_client,
+ environment,
+ edge,
+ user_agent_extensions,
+ credential_provider,
+ )
+
+ # Domains
+ self._accounts: Optional["Accounts"] = None
+ self._api: Optional["Api"] = None
+ self._assistants: Optional["Assistants"] = None
+ self._bulkexports: Optional["Bulkexports"] = None
+ self._chat: Optional["Chat"] = None
+ self._content: Optional["Content"] = None
+ self._conversations: Optional["Conversations"] = None
+ self._events: Optional["Events"] = None
+ self._flex_api: Optional["FlexApi"] = None
+ self._frontline_api: Optional["FrontlineApi"] = None
+ self._preview_iam: Optional["PreviewIam"] = None
+ self._iam: Optional["Iam"] = None
+ self._insights: Optional["Insights"] = None
+ self._intelligence: Optional["Intelligence"] = None
+ self._ip_messaging: Optional["IpMessaging"] = None
+ self._knowledge: Optional["Knowledge"] = None
+ self._lookups: Optional["Lookups"] = None
+ self._marketplace: Optional["Marketplace"] = None
+ self._messaging: Optional["Messaging"] = None
+ self._microvisor: Optional["Microvisor"] = None
+ self._monitor: Optional["Monitor"] = None
+ self._notify: Optional["Notify"] = None
+ self._numbers: Optional["Numbers"] = None
+ self._oauth: Optional["Oauth"] = None
+ self._preview: Optional["Preview"] = None
+ self._pricing: Optional["Pricing"] = None
+ self._proxy: Optional["Proxy"] = None
+ self._routes: Optional["Routes"] = None
+ self._serverless: Optional["Serverless"] = None
+ self._studio: Optional["Studio"] = None
+ self._supersim: Optional["Supersim"] = None
+ self._sync: Optional["Sync"] = None
+ self._taskrouter: Optional["Taskrouter"] = None
+ self._trunking: Optional["Trunking"] = None
+ self._trusthub: Optional["Trusthub"] = None
+ self._verify: Optional["Verify"] = None
+ self._video: Optional["Video"] = None
+ self._voice: Optional["Voice"] = None
+ self._wireless: Optional["Wireless"] = None
+
+ @property
+ def accounts(self) -> "Accounts":
+ """
+ Access the Accounts Twilio Domain
+
+ :returns: Accounts Twilio Domain
+ """
+ if self._accounts is None:
+ from twilio.rest.accounts import Accounts
+
+ self._accounts = Accounts(self)
+ return self._accounts
+
+ @property
+ def api(self) -> "Api":
+ """
+ Access the Api Twilio Domain
+
+ :returns: Api Twilio Domain
+ """
+ if self._api is None:
+ from twilio.rest.api import Api
+
+ self._api = Api(self)
+ return self._api
+
+ @property
+ def assistants(self) -> "Assistants":
+ """
+ Access the Assistants Twilio Domain
+
+ :returns: Assistants Twilio Domain
+ """
+ if self._assistants is None:
+ from twilio.rest.assistants import Assistants
+
+ self._assistants = Assistants(self)
+ return self._assistants
+
+ @property
+ def bulkexports(self) -> "Bulkexports":
+ """
+ Access the Bulkexports Twilio Domain
+
+ :returns: Bulkexports Twilio Domain
+ """
+ if self._bulkexports is None:
+ from twilio.rest.bulkexports import Bulkexports
+
+ self._bulkexports = Bulkexports(self)
+ return self._bulkexports
+
+ @property
+ def chat(self) -> "Chat":
+ """
+ Access the Chat Twilio Domain
+
+ :returns: Chat Twilio Domain
+ """
+ if self._chat is None:
+ from twilio.rest.chat import Chat
+
+ self._chat = Chat(self)
+ return self._chat
+
+ @property
+ def content(self) -> "Content":
+ """
+ Access the Content Twilio Domain
+
+ :returns: Content Twilio Domain
+ """
+ if self._content is None:
+ from twilio.rest.content import Content
+
+ self._content = Content(self)
+ return self._content
+
+ @property
+ def conversations(self) -> "Conversations":
+ """
+ Access the Conversations Twilio Domain
+
+ :returns: Conversations Twilio Domain
+ """
+ if self._conversations is None:
+ from twilio.rest.conversations import Conversations
+
+ self._conversations = Conversations(self)
+ return self._conversations
+
+ @property
+ def events(self) -> "Events":
+ """
+ Access the Events Twilio Domain
+
+ :returns: Events Twilio Domain
+ """
+ if self._events is None:
+ from twilio.rest.events import Events
+
+ self._events = Events(self)
+ return self._events
+
+ @property
+ def flex_api(self) -> "FlexApi":
+ """
+ Access the FlexApi Twilio Domain
+
+ :returns: FlexApi Twilio Domain
+ """
+ if self._flex_api is None:
+ from twilio.rest.flex_api import FlexApi
+
+ self._flex_api = FlexApi(self)
+ return self._flex_api
+
+ @property
+ def frontline_api(self) -> "FrontlineApi":
+ """
+ Access the FrontlineApi Twilio Domain
+
+ :returns: FrontlineApi Twilio Domain
+ """
+ if self._frontline_api is None:
+ from twilio.rest.frontline_api import FrontlineApi
+
+ self._frontline_api = FrontlineApi(self)
+ return self._frontline_api
+
+ @property
+ def preview_iam(self) -> "PreviewIam":
+ """
+ Access the PreviewIam Twilio Domain
+
+ :returns: PreviewIam Twilio Domain
+ """
+ if self._preview_iam is None:
+ from twilio.rest.preview_iam import PreviewIam
+
+ self._preview_iam = PreviewIam(self)
+ return self._preview_iam
+
+ @property
+ def iam(self) -> "Iam":
+ """
+ Access the Iam Twilio Domain
+
+ :returns: Iam Twilio Domain
+ """
+ if self._iam is None:
+ from twilio.rest.iam import Iam
+
+ self._iam = Iam(self)
+ return self._iam
+
+ @property
+ def insights(self) -> "Insights":
+ """
+ Access the Insights Twilio Domain
+
+ :returns: Insights Twilio Domain
+ """
+ if self._insights is None:
+ from twilio.rest.insights import Insights
+
+ self._insights = Insights(self)
+ return self._insights
+
+ @property
+ def intelligence(self) -> "Intelligence":
+ """
+ Access the Intelligence Twilio Domain
+
+ :returns: Intelligence Twilio Domain
+ """
+ if self._intelligence is None:
+ from twilio.rest.intelligence import Intelligence
+
+ self._intelligence = Intelligence(self)
+ return self._intelligence
+
+ @property
+ def ip_messaging(self) -> "IpMessaging":
+ """
+ Access the IpMessaging Twilio Domain
+
+ :returns: IpMessaging Twilio Domain
+ """
+ if self._ip_messaging is None:
+ from twilio.rest.ip_messaging import IpMessaging
+
+ self._ip_messaging = IpMessaging(self)
+ return self._ip_messaging
+
+ @property
+ def knowledge(self) -> "Knowledge":
+ """
+ Access the Knowledge Twilio Domain
+
+ :returns: Knowledge Twilio Domain
+ """
+ if self._knowledge is None:
+ from twilio.rest.knowledge import Knowledge
+
+ self._knowledge = Knowledge(self)
+ return self._knowledge
+
+ @property
+ def lookups(self) -> "Lookups":
+ """
+ Access the Lookups Twilio Domain
+
+ :returns: Lookups Twilio Domain
+ """
+ if self._lookups is None:
+ from twilio.rest.lookups import Lookups
+
+ self._lookups = Lookups(self)
+ return self._lookups
+
+ @property
+ def marketplace(self) -> "Marketplace":
+ """
+ Access the Marketplace Twilio Domain
+
+ :returns: Marketplace Twilio Domain
+ """
+ if self._marketplace is None:
+ from twilio.rest.marketplace import Marketplace
+
+ self._marketplace = Marketplace(self)
+ return self._marketplace
+
+ @property
+ def messaging(self) -> "Messaging":
+ """
+ Access the Messaging Twilio Domain
+
+ :returns: Messaging Twilio Domain
+ """
+ if self._messaging is None:
+ from twilio.rest.messaging import Messaging
+
+ self._messaging = Messaging(self)
+ return self._messaging
+
+ @property
+ def microvisor(self) -> "Microvisor":
+ """
+ Access the Microvisor Twilio Domain
+
+ :returns: Microvisor Twilio Domain
+ """
+ if self._microvisor is None:
+ from twilio.rest.microvisor import Microvisor
+
+ self._microvisor = Microvisor(self)
+ return self._microvisor
+
+ @property
+ def monitor(self) -> "Monitor":
+ """
+ Access the Monitor Twilio Domain
+
+ :returns: Monitor Twilio Domain
+ """
+ if self._monitor is None:
+ from twilio.rest.monitor import Monitor
+
+ self._monitor = Monitor(self)
+ return self._monitor
+
+ @property
+ def notify(self) -> "Notify":
+ """
+ Access the Notify Twilio Domain
+
+ :returns: Notify Twilio Domain
+ """
+ if self._notify is None:
+ from twilio.rest.notify import Notify
+
+ self._notify = Notify(self)
+ return self._notify
+
+ @property
+ def numbers(self) -> "Numbers":
+ """
+ Access the Numbers Twilio Domain
+
+ :returns: Numbers Twilio Domain
+ """
+ if self._numbers is None:
+ from twilio.rest.numbers import Numbers
+
+ self._numbers = Numbers(self)
+ return self._numbers
+
+ @property
+ def oauth(self) -> "Oauth":
+ """
+ Access the Oauth Twilio Domain
+
+ :returns: Oauth Twilio Domain
+ """
+ if self._oauth is None:
+ from twilio.rest.oauth import Oauth
+
+ self._oauth = Oauth(self)
+ return self._oauth
+
+ @property
+ def preview(self) -> "Preview":
+ """
+ Access the Preview Twilio Domain
+
+ :returns: Preview Twilio Domain
+ """
+ if self._preview is None:
+ from twilio.rest.preview import Preview
+
+ self._preview = Preview(self)
+ return self._preview
+
+ @property
+ def pricing(self) -> "Pricing":
+ """
+ Access the Pricing Twilio Domain
+
+ :returns: Pricing Twilio Domain
+ """
+ if self._pricing is None:
+ from twilio.rest.pricing import Pricing
+
+ self._pricing = Pricing(self)
+ return self._pricing
+
+ @property
+ def proxy(self) -> "Proxy":
+ """
+ Access the Proxy Twilio Domain
+
+ :returns: Proxy Twilio Domain
+ """
+ if self._proxy is None:
+ from twilio.rest.proxy import Proxy
+
+ self._proxy = Proxy(self)
+ return self._proxy
+
+ @property
+ def routes(self) -> "Routes":
+ """
+ Access the Routes Twilio Domain
+
+ :returns: Routes Twilio Domain
+ """
+ if self._routes is None:
+ from twilio.rest.routes import Routes
+
+ self._routes = Routes(self)
+ return self._routes
+
+ @property
+ def serverless(self) -> "Serverless":
+ """
+ Access the Serverless Twilio Domain
+
+ :returns: Serverless Twilio Domain
+ """
+ if self._serverless is None:
+ from twilio.rest.serverless import Serverless
+
+ self._serverless = Serverless(self)
+ return self._serverless
+
+ @property
+ def studio(self) -> "Studio":
+ """
+ Access the Studio Twilio Domain
+
+ :returns: Studio Twilio Domain
+ """
+ if self._studio is None:
+ from twilio.rest.studio import Studio
+
+ self._studio = Studio(self)
+ return self._studio
+
+ @property
+ def supersim(self) -> "Supersim":
+ """
+ Access the Supersim Twilio Domain
+
+ :returns: Supersim Twilio Domain
+ """
+ if self._supersim is None:
+ from twilio.rest.supersim import Supersim
+
+ self._supersim = Supersim(self)
+ return self._supersim
+
+ @property
+ def sync(self) -> "Sync":
+ """
+ Access the Sync Twilio Domain
+
+ :returns: Sync Twilio Domain
+ """
+ if self._sync is None:
+ from twilio.rest.sync import Sync
+
+ self._sync = Sync(self)
+ return self._sync
+
+ @property
+ def taskrouter(self) -> "Taskrouter":
+ """
+ Access the Taskrouter Twilio Domain
+
+ :returns: Taskrouter Twilio Domain
+ """
+ if self._taskrouter is None:
+ from twilio.rest.taskrouter import Taskrouter
+
+ self._taskrouter = Taskrouter(self)
+ return self._taskrouter
+
+ @property
+ def trunking(self) -> "Trunking":
+ """
+ Access the Trunking Twilio Domain
+
+ :returns: Trunking Twilio Domain
+ """
+ if self._trunking is None:
+ from twilio.rest.trunking import Trunking
+
+ self._trunking = Trunking(self)
+ return self._trunking
+
+ @property
+ def trusthub(self) -> "Trusthub":
+ """
+ Access the Trusthub Twilio Domain
+
+ :returns: Trusthub Twilio Domain
+ """
+ if self._trusthub is None:
+ from twilio.rest.trusthub import Trusthub
+
+ self._trusthub = Trusthub(self)
+ return self._trusthub
+
+ @property
+ def verify(self) -> "Verify":
+ """
+ Access the Verify Twilio Domain
+
+ :returns: Verify Twilio Domain
+ """
+ if self._verify is None:
+ from twilio.rest.verify import Verify
+
+ self._verify = Verify(self)
+ return self._verify
+
+ @property
+ def video(self) -> "Video":
+ """
+ Access the Video Twilio Domain
+
+ :returns: Video Twilio Domain
+ """
+ if self._video is None:
+ from twilio.rest.video import Video
+
+ self._video = Video(self)
+ return self._video
+
+ @property
+ def voice(self) -> "Voice":
+ """
+ Access the Voice Twilio Domain
+
+ :returns: Voice Twilio Domain
+ """
+ if self._voice is None:
+ from twilio.rest.voice import Voice
+
+ self._voice = Voice(self)
+ return self._voice
+
+ @property
+ def wireless(self) -> "Wireless":
+ """
+ Access the Wireless Twilio Domain
+
+ :returns: Wireless Twilio Domain
+ """
+ if self._wireless is None:
+ from twilio.rest.wireless import Wireless
+
+ self._wireless = Wireless(self)
+ return self._wireless
+
+ @property
+ def addresses(self) -> "AddressList":
+ return self.api.account.addresses
+
+ @property
+ def applications(self) -> "ApplicationList":
+ return self.api.account.applications
+
+ @property
+ def authorized_connect_apps(self) -> "AuthorizedConnectAppList":
+ return self.api.account.authorized_connect_apps
+
+ @property
+ def available_phone_numbers(self) -> "AvailablePhoneNumberCountryList":
+ return self.api.account.available_phone_numbers
+
+ @property
+ def balance(self) -> "BalanceList":
+ return self.api.account.balance
+
+ @property
+ def calls(self) -> "CallList":
+ return self.api.account.calls
+
+ @property
+ def conferences(self) -> "ConferenceList":
+ return self.api.account.conferences
+
+ @property
+ def connect_apps(self) -> "ConnectAppList":
+ return self.api.account.connect_apps
+
+ @property
+ def incoming_phone_numbers(self) -> "IncomingPhoneNumberList":
+ return self.api.account.incoming_phone_numbers
+
+ @property
+ def keys(self) -> "KeyList":
+ return self.api.account.keys
+
+ @property
+ def new_keys(self) -> "NewKeyList":
+ return self.api.account.new_keys
+
+ @property
+ def messages(self) -> "MessageList":
+ return self.api.account.messages
+
+ @property
+ def signing_keys(self) -> "SigningKeyList":
+ return self.api.account.signing_keys
+
+ @property
+ def new_signing_keys(self) -> "NewSigningKeyList":
+ return self.api.account.new_signing_keys
+
+ @property
+ def notifications(self) -> "NotificationList":
+ return self.api.account.notifications
+
+ @property
+ def outgoing_caller_ids(self) -> "OutgoingCallerIdList":
+ return self.api.account.outgoing_caller_ids
+
+ @property
+ def validation_requests(self) -> "ValidationRequestList":
+ return self.api.account.validation_requests
+
+ @property
+ def queues(self) -> "QueueList":
+ return self.api.account.queues
+
+ @property
+ def recordings(self) -> "RecordingList":
+ return self.api.account.recordings
+
+ @property
+ def short_codes(self) -> "ShortCodeList":
+ return self.api.account.short_codes
+
+ @property
+ def sip(self) -> "SipList":
+ return self.api.account.sip
+
+ @property
+ def tokens(self) -> "TokenList":
+ return self.api.account.tokens
+
+ @property
+ def transcriptions(self) -> "TranscriptionList":
+ return self.api.account.transcriptions
+
+ @property
+ def usage(self) -> "UsageList":
+ return self.api.account.usage
diff --git a/venv/Lib/site-packages/twilio/rest/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 00000000..5d1fc5c3
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/accounts/AccountsBase.py b/venv/Lib/site-packages/twilio/rest/accounts/AccountsBase.py
new file mode 100644
index 00000000..e9ac0d58
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/accounts/AccountsBase.py
@@ -0,0 +1,44 @@
+r"""
+ This code was generated by
+ ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __
+ | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/
+ | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ https://openapi-generator.tech
+ Do not edit the class manually.
+"""
+
+from typing import Optional
+
+from twilio.base.domain import Domain
+from twilio.rest import Client
+from twilio.rest.accounts.v1 import V1
+
+
+class AccountsBase(Domain):
+
+ def __init__(self, twilio: Client):
+ """
+ Initialize the Accounts Domain
+
+ :returns: Domain for Accounts
+ """
+ super().__init__(twilio, "https://accounts.twilio.com")
+ self._v1: Optional[V1] = None
+
+ @property
+ def v1(self) -> V1:
+ """
+ :returns: Versions v1 of Accounts
+ """
+ if self._v1 is None:
+ self._v1 = V1(self)
+ return self._v1
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+ :returns: Machine friendly representation
+ """
+ return ""
diff --git a/venv/Lib/site-packages/twilio/rest/accounts/__init__.py b/venv/Lib/site-packages/twilio/rest/accounts/__init__.py
new file mode 100644
index 00000000..e2275aea
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/accounts/__init__.py
@@ -0,0 +1,35 @@
+from warnings import warn
+
+from twilio.rest.accounts.AccountsBase import AccountsBase
+from twilio.rest.accounts.v1.auth_token_promotion import AuthTokenPromotionList
+from twilio.rest.accounts.v1.credential import CredentialList
+from twilio.rest.accounts.v1.secondary_auth_token import SecondaryAuthTokenList
+
+
+class Accounts(AccountsBase):
+ @property
+ def auth_token_promotion(self) -> AuthTokenPromotionList:
+ warn(
+ "auth_token_promotion is deprecated. Use v1.auth_token_promotion instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ return self.v1.auth_token_promotion
+
+ @property
+ def credentials(self) -> CredentialList:
+ warn(
+ "credentials is deprecated. Use v1.credentials instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ return self.v1.credentials
+
+ @property
+ def secondary_auth_token(self) -> SecondaryAuthTokenList:
+ warn(
+ "secondary_auth_token is deprecated. Use v1.secondary_auth_token instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ return self.v1.secondary_auth_token
diff --git a/venv/Lib/site-packages/twilio/rest/accounts/__pycache__/AccountsBase.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/accounts/__pycache__/AccountsBase.cpython-312.pyc
new file mode 100644
index 00000000..7a2a3229
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/accounts/__pycache__/AccountsBase.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/accounts/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/accounts/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 00000000..e0340a0c
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/accounts/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/accounts/v1/__init__.py b/venv/Lib/site-packages/twilio/rest/accounts/v1/__init__.py
new file mode 100644
index 00000000..6f5012d0
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/accounts/v1/__init__.py
@@ -0,0 +1,83 @@
+r"""
+ This code was generated by
+ ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __
+ | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/
+ | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \
+
+ Twilio - Accounts
+ This is the public Twilio REST API.
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ https://openapi-generator.tech
+ Do not edit the class manually.
+"""
+
+from typing import Optional
+from twilio.base.version import Version
+from twilio.base.domain import Domain
+from twilio.rest.accounts.v1.auth_token_promotion import AuthTokenPromotionList
+from twilio.rest.accounts.v1.bulk_consents import BulkConsentsList
+from twilio.rest.accounts.v1.bulk_contacts import BulkContactsList
+from twilio.rest.accounts.v1.credential import CredentialList
+from twilio.rest.accounts.v1.safelist import SafelistList
+from twilio.rest.accounts.v1.secondary_auth_token import SecondaryAuthTokenList
+
+
+class V1(Version):
+
+ def __init__(self, domain: Domain):
+ """
+ Initialize the V1 version of Accounts
+
+ :param domain: The Twilio.accounts domain
+ """
+ super().__init__(domain, "v1")
+ self._auth_token_promotion: Optional[AuthTokenPromotionList] = None
+ self._bulk_consents: Optional[BulkConsentsList] = None
+ self._bulk_contacts: Optional[BulkContactsList] = None
+ self._credentials: Optional[CredentialList] = None
+ self._safelist: Optional[SafelistList] = None
+ self._secondary_auth_token: Optional[SecondaryAuthTokenList] = None
+
+ @property
+ def auth_token_promotion(self) -> AuthTokenPromotionList:
+ if self._auth_token_promotion is None:
+ self._auth_token_promotion = AuthTokenPromotionList(self)
+ return self._auth_token_promotion
+
+ @property
+ def bulk_consents(self) -> BulkConsentsList:
+ if self._bulk_consents is None:
+ self._bulk_consents = BulkConsentsList(self)
+ return self._bulk_consents
+
+ @property
+ def bulk_contacts(self) -> BulkContactsList:
+ if self._bulk_contacts is None:
+ self._bulk_contacts = BulkContactsList(self)
+ return self._bulk_contacts
+
+ @property
+ def credentials(self) -> CredentialList:
+ if self._credentials is None:
+ self._credentials = CredentialList(self)
+ return self._credentials
+
+ @property
+ def safelist(self) -> SafelistList:
+ if self._safelist is None:
+ self._safelist = SafelistList(self)
+ return self._safelist
+
+ @property
+ def secondary_auth_token(self) -> SecondaryAuthTokenList:
+ if self._secondary_auth_token is None:
+ self._secondary_auth_token = SecondaryAuthTokenList(self)
+ return self._secondary_auth_token
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+ :returns: Machine friendly representation
+ """
+ return ""
diff --git a/venv/Lib/site-packages/twilio/rest/accounts/v1/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/accounts/v1/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 00000000..54d27eee
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/accounts/v1/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/accounts/v1/__pycache__/auth_token_promotion.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/accounts/v1/__pycache__/auth_token_promotion.cpython-312.pyc
new file mode 100644
index 00000000..b69eacf2
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/accounts/v1/__pycache__/auth_token_promotion.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/accounts/v1/__pycache__/bulk_consents.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/accounts/v1/__pycache__/bulk_consents.cpython-312.pyc
new file mode 100644
index 00000000..82885b82
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/accounts/v1/__pycache__/bulk_consents.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/accounts/v1/__pycache__/bulk_contacts.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/accounts/v1/__pycache__/bulk_contacts.cpython-312.pyc
new file mode 100644
index 00000000..17a7d28c
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/accounts/v1/__pycache__/bulk_contacts.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/accounts/v1/__pycache__/safelist.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/accounts/v1/__pycache__/safelist.cpython-312.pyc
new file mode 100644
index 00000000..a68abf84
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/accounts/v1/__pycache__/safelist.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/accounts/v1/__pycache__/secondary_auth_token.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/accounts/v1/__pycache__/secondary_auth_token.cpython-312.pyc
new file mode 100644
index 00000000..c807318a
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/accounts/v1/__pycache__/secondary_auth_token.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/accounts/v1/auth_token_promotion.py b/venv/Lib/site-packages/twilio/rest/accounts/v1/auth_token_promotion.py
new file mode 100644
index 00000000..8580538a
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/accounts/v1/auth_token_promotion.py
@@ -0,0 +1,181 @@
+r"""
+ This code was generated by
+ ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __
+ | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/
+ | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \
+
+ Twilio - Accounts
+ This is the public Twilio REST API.
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ https://openapi-generator.tech
+ Do not edit the class manually.
+"""
+
+from datetime import datetime
+from typing import Any, Dict, Optional
+from twilio.base import deserialize, values
+from twilio.base.instance_context import InstanceContext
+from twilio.base.instance_resource import InstanceResource
+from twilio.base.list_resource import ListResource
+from twilio.base.version import Version
+
+
+class AuthTokenPromotionInstance(InstanceResource):
+ """
+ :ivar account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that the secondary Auth Token was created for.
+ :ivar auth_token: The promoted Auth Token that must be used to authenticate future API requests.
+ :ivar date_created: The date and time in UTC when the resource was created specified in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format.
+ :ivar date_updated: The date and time in GMT when the resource was last updated specified in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format.
+ :ivar url: The URI for this resource, relative to `https://accounts.twilio.com`
+ """
+
+ def __init__(self, version: Version, payload: Dict[str, Any]):
+ super().__init__(version)
+
+ self.account_sid: Optional[str] = payload.get("account_sid")
+ self.auth_token: Optional[str] = payload.get("auth_token")
+ self.date_created: Optional[datetime] = deserialize.iso8601_datetime(
+ payload.get("date_created")
+ )
+ self.date_updated: Optional[datetime] = deserialize.iso8601_datetime(
+ payload.get("date_updated")
+ )
+ self.url: Optional[str] = payload.get("url")
+
+ self._context: Optional[AuthTokenPromotionContext] = None
+
+ @property
+ def _proxy(self) -> "AuthTokenPromotionContext":
+ """
+ Generate an instance context for the instance, the context is capable of
+ performing various actions. All instance actions are proxied to the context
+
+ :returns: AuthTokenPromotionContext for this AuthTokenPromotionInstance
+ """
+ if self._context is None:
+ self._context = AuthTokenPromotionContext(
+ self._version,
+ )
+ return self._context
+
+ def update(self) -> "AuthTokenPromotionInstance":
+ """
+ Update the AuthTokenPromotionInstance
+
+
+ :returns: The updated AuthTokenPromotionInstance
+ """
+ return self._proxy.update()
+
+ async def update_async(self) -> "AuthTokenPromotionInstance":
+ """
+ Asynchronous coroutine to update the AuthTokenPromotionInstance
+
+
+ :returns: The updated AuthTokenPromotionInstance
+ """
+ return await self._proxy.update_async()
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+
+ return ""
+
+
+class AuthTokenPromotionContext(InstanceContext):
+
+ def __init__(self, version: Version):
+ """
+ Initialize the AuthTokenPromotionContext
+
+ :param version: Version that contains the resource
+ """
+ super().__init__(version)
+
+ self._uri = "/AuthTokens/Promote"
+
+ def update(self) -> AuthTokenPromotionInstance:
+ """
+ Update the AuthTokenPromotionInstance
+
+
+ :returns: The updated AuthTokenPromotionInstance
+ """
+
+ data = values.of({})
+ headers = values.of({})
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.update(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return AuthTokenPromotionInstance(self._version, payload)
+
+ async def update_async(self) -> AuthTokenPromotionInstance:
+ """
+ Asynchronous coroutine to update the AuthTokenPromotionInstance
+
+
+ :returns: The updated AuthTokenPromotionInstance
+ """
+
+ data = values.of({})
+ headers = values.of({})
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.update_async(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return AuthTokenPromotionInstance(self._version, payload)
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+
+ return ""
+
+
+class AuthTokenPromotionList(ListResource):
+
+ def __init__(self, version: Version):
+ """
+ Initialize the AuthTokenPromotionList
+
+ :param version: Version that contains the resource
+
+ """
+ super().__init__(version)
+
+ def get(self) -> AuthTokenPromotionContext:
+ """
+ Constructs a AuthTokenPromotionContext
+
+ """
+ return AuthTokenPromotionContext(self._version)
+
+ def __call__(self) -> AuthTokenPromotionContext:
+ """
+ Constructs a AuthTokenPromotionContext
+
+ """
+ return AuthTokenPromotionContext(self._version)
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
diff --git a/venv/Lib/site-packages/twilio/rest/accounts/v1/bulk_consents.py b/venv/Lib/site-packages/twilio/rest/accounts/v1/bulk_consents.py
new file mode 100644
index 00000000..9e242552
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/accounts/v1/bulk_consents.py
@@ -0,0 +1,114 @@
+r"""
+ This code was generated by
+ ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __
+ | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/
+ | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \
+
+ Twilio - Accounts
+ This is the public Twilio REST API.
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ https://openapi-generator.tech
+ Do not edit the class manually.
+"""
+
+from typing import Any, Dict, List, Optional
+from twilio.base import serialize, values
+
+from twilio.base.instance_resource import InstanceResource
+from twilio.base.list_resource import ListResource
+from twilio.base.version import Version
+
+
+class BulkConsentsInstance(InstanceResource):
+ """
+ :ivar items: A list of objects where each object represents the result of processing a `correlation_id`. Each object contains the following fields: `correlation_id`, a unique 32-character UUID that maps the response to the original request; `error_code`, an integer where 0 indicates success and any non-zero value represents an error; and `error_messages`, an array of strings describing specific validation errors encountered. If the request is successful, the error_messages array will be empty.
+ """
+
+ def __init__(self, version: Version, payload: Dict[str, Any]):
+ super().__init__(version)
+
+ self.items: Optional[Dict[str, object]] = payload.get("items")
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+
+ return ""
+
+
+class BulkConsentsList(ListResource):
+
+ def __init__(self, version: Version):
+ """
+ Initialize the BulkConsentsList
+
+ :param version: Version that contains the resource
+
+ """
+ super().__init__(version)
+
+ self._uri = "/Consents/Bulk"
+
+ def create(self, items: List[object]) -> BulkConsentsInstance:
+ """
+ Create the BulkConsentsInstance
+
+ :param items: This is a list of objects that describes a contact's opt-in status. Each object contains the following fields: `contact_id`, which must be a string representing phone number in [E.164 format](https://www.twilio.com/docs/glossary/what-e164); `correlation_id`, a unique 32-character UUID used to uniquely map the request item with the response item; `sender_id`, which can be either a valid messaging service SID or a from phone number; `status`, a string representing the consent status. Can be one of [`opt-in`, `opt-out`]; `source`, a string indicating the medium through which the consent was collected. Can be one of [`website`, `offline`, `opt-in-message`, `opt-out-message`, `others`]; `date_of_consent`, an optional datetime string field in ISO-8601 format that captures the exact date and time when the user gave or revoked consent. If not provided, it will be empty.
+
+ :returns: The created BulkConsentsInstance
+ """
+
+ data = values.of(
+ {
+ "Items": serialize.map(items, lambda e: serialize.object(e)),
+ }
+ )
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.create(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return BulkConsentsInstance(self._version, payload)
+
+ async def create_async(self, items: List[object]) -> BulkConsentsInstance:
+ """
+ Asynchronously create the BulkConsentsInstance
+
+ :param items: This is a list of objects that describes a contact's opt-in status. Each object contains the following fields: `contact_id`, which must be a string representing phone number in [E.164 format](https://www.twilio.com/docs/glossary/what-e164); `correlation_id`, a unique 32-character UUID used to uniquely map the request item with the response item; `sender_id`, which can be either a valid messaging service SID or a from phone number; `status`, a string representing the consent status. Can be one of [`opt-in`, `opt-out`]; `source`, a string indicating the medium through which the consent was collected. Can be one of [`website`, `offline`, `opt-in-message`, `opt-out-message`, `others`]; `date_of_consent`, an optional datetime string field in ISO-8601 format that captures the exact date and time when the user gave or revoked consent. If not provided, it will be empty.
+
+ :returns: The created BulkConsentsInstance
+ """
+
+ data = values.of(
+ {
+ "Items": serialize.map(items, lambda e: serialize.object(e)),
+ }
+ )
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.create_async(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return BulkConsentsInstance(self._version, payload)
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
diff --git a/venv/Lib/site-packages/twilio/rest/accounts/v1/bulk_contacts.py b/venv/Lib/site-packages/twilio/rest/accounts/v1/bulk_contacts.py
new file mode 100644
index 00000000..17b6da33
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/accounts/v1/bulk_contacts.py
@@ -0,0 +1,114 @@
+r"""
+ This code was generated by
+ ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __
+ | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/
+ | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \
+
+ Twilio - Accounts
+ This is the public Twilio REST API.
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ https://openapi-generator.tech
+ Do not edit the class manually.
+"""
+
+from typing import Any, Dict, List, Optional
+from twilio.base import serialize, values
+
+from twilio.base.instance_resource import InstanceResource
+from twilio.base.list_resource import ListResource
+from twilio.base.version import Version
+
+
+class BulkContactsInstance(InstanceResource):
+ """
+ :ivar items: A list of objects where each object represents the result of processing a `correlation_id`. Each object contains the following fields: `correlation_id`, a unique 32-character UUID that maps the response to the original request; `error_code`, an integer where 0 indicates success and any non-zero value represents an error; and `error_messages`, an array of strings describing specific validation errors encountered. If the request is successful, the error_messages array will be empty.
+ """
+
+ def __init__(self, version: Version, payload: Dict[str, Any]):
+ super().__init__(version)
+
+ self.items: Optional[Dict[str, object]] = payload.get("items")
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+
+ return ""
+
+
+class BulkContactsList(ListResource):
+
+ def __init__(self, version: Version):
+ """
+ Initialize the BulkContactsList
+
+ :param version: Version that contains the resource
+
+ """
+ super().__init__(version)
+
+ self._uri = "/Contacts/Bulk"
+
+ def create(self, items: List[object]) -> BulkContactsInstance:
+ """
+ Create the BulkContactsInstance
+
+ :param items: A list of objects where each object represents a contact's details. Each object includes the following fields: `contact_id`, which must be a string representing phone number in [E.164 format](https://www.twilio.com/docs/glossary/what-e164); `correlation_id`, a unique 32-character UUID that maps the response to the original request; `country_iso_code`, a string representing the country using the ISO format (e.g., US for the United States); and `zip_code`, a string representing the postal code.
+
+ :returns: The created BulkContactsInstance
+ """
+
+ data = values.of(
+ {
+ "Items": serialize.map(items, lambda e: serialize.object(e)),
+ }
+ )
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.create(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return BulkContactsInstance(self._version, payload)
+
+ async def create_async(self, items: List[object]) -> BulkContactsInstance:
+ """
+ Asynchronously create the BulkContactsInstance
+
+ :param items: A list of objects where each object represents a contact's details. Each object includes the following fields: `contact_id`, which must be a string representing phone number in [E.164 format](https://www.twilio.com/docs/glossary/what-e164); `correlation_id`, a unique 32-character UUID that maps the response to the original request; `country_iso_code`, a string representing the country using the ISO format (e.g., US for the United States); and `zip_code`, a string representing the postal code.
+
+ :returns: The created BulkContactsInstance
+ """
+
+ data = values.of(
+ {
+ "Items": serialize.map(items, lambda e: serialize.object(e)),
+ }
+ )
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.create_async(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return BulkContactsInstance(self._version, payload)
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
diff --git a/venv/Lib/site-packages/twilio/rest/accounts/v1/credential/__init__.py b/venv/Lib/site-packages/twilio/rest/accounts/v1/credential/__init__.py
new file mode 100644
index 00000000..e9c4653f
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/accounts/v1/credential/__init__.py
@@ -0,0 +1,65 @@
+r"""
+ This code was generated by
+ ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __
+ | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/
+ | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \
+
+ Twilio - Accounts
+ This is the public Twilio REST API.
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ https://openapi-generator.tech
+ Do not edit the class manually.
+"""
+
+from typing import Optional
+
+
+from twilio.base.list_resource import ListResource
+from twilio.base.version import Version
+
+from twilio.rest.accounts.v1.credential.aws import AwsList
+from twilio.rest.accounts.v1.credential.public_key import PublicKeyList
+
+
+class CredentialList(ListResource):
+
+ def __init__(self, version: Version):
+ """
+ Initialize the CredentialList
+
+ :param version: Version that contains the resource
+
+ """
+ super().__init__(version)
+
+ self._uri = "/Credentials"
+
+ self._aws: Optional[AwsList] = None
+ self._public_key: Optional[PublicKeyList] = None
+
+ @property
+ def aws(self) -> AwsList:
+ """
+ Access the aws
+ """
+ if self._aws is None:
+ self._aws = AwsList(self._version)
+ return self._aws
+
+ @property
+ def public_key(self) -> PublicKeyList:
+ """
+ Access the public_key
+ """
+ if self._public_key is None:
+ self._public_key = PublicKeyList(self._version)
+ return self._public_key
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
diff --git a/venv/Lib/site-packages/twilio/rest/accounts/v1/credential/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/accounts/v1/credential/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 00000000..e5474e48
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/accounts/v1/credential/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/accounts/v1/credential/__pycache__/aws.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/accounts/v1/credential/__pycache__/aws.cpython-312.pyc
new file mode 100644
index 00000000..a8c5b0fc
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/accounts/v1/credential/__pycache__/aws.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/accounts/v1/credential/__pycache__/public_key.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/accounts/v1/credential/__pycache__/public_key.cpython-312.pyc
new file mode 100644
index 00000000..b1f319c0
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/accounts/v1/credential/__pycache__/public_key.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/accounts/v1/credential/aws.py b/venv/Lib/site-packages/twilio/rest/accounts/v1/credential/aws.py
new file mode 100644
index 00000000..ba5335ac
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/accounts/v1/credential/aws.py
@@ -0,0 +1,609 @@
+r"""
+ This code was generated by
+ ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __
+ | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/
+ | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \
+
+ Twilio - Accounts
+ This is the public Twilio REST API.
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ https://openapi-generator.tech
+ Do not edit the class manually.
+"""
+
+from datetime import datetime
+from typing import Any, Dict, List, Optional, Union, Iterator, AsyncIterator
+from twilio.base import deserialize, values
+from twilio.base.instance_context import InstanceContext
+from twilio.base.instance_resource import InstanceResource
+from twilio.base.list_resource import ListResource
+from twilio.base.version import Version
+from twilio.base.page import Page
+
+
+class AwsInstance(InstanceResource):
+ """
+ :ivar sid: The unique string that we created to identify the AWS resource.
+ :ivar account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that created the AWS resource.
+ :ivar friendly_name: The string that you assigned to describe the resource.
+ :ivar date_created: The date and time in GMT when the resource was created specified in [RFC 2822](https://www.ietf.org/rfc/rfc2822.txt) format.
+ :ivar date_updated: The date and time in GMT when the resource was last updated specified in [RFC 2822](https://www.ietf.org/rfc/rfc2822.txt) format.
+ :ivar url: The URI for this resource, relative to `https://accounts.twilio.com`
+ """
+
+ def __init__(
+ self, version: Version, payload: Dict[str, Any], sid: Optional[str] = None
+ ):
+ super().__init__(version)
+
+ self.sid: Optional[str] = payload.get("sid")
+ self.account_sid: Optional[str] = payload.get("account_sid")
+ self.friendly_name: Optional[str] = payload.get("friendly_name")
+ self.date_created: Optional[datetime] = deserialize.iso8601_datetime(
+ payload.get("date_created")
+ )
+ self.date_updated: Optional[datetime] = deserialize.iso8601_datetime(
+ payload.get("date_updated")
+ )
+ self.url: Optional[str] = payload.get("url")
+
+ self._solution = {
+ "sid": sid or self.sid,
+ }
+ self._context: Optional[AwsContext] = None
+
+ @property
+ def _proxy(self) -> "AwsContext":
+ """
+ Generate an instance context for the instance, the context is capable of
+ performing various actions. All instance actions are proxied to the context
+
+ :returns: AwsContext for this AwsInstance
+ """
+ if self._context is None:
+ self._context = AwsContext(
+ self._version,
+ sid=self._solution["sid"],
+ )
+ return self._context
+
+ def delete(self) -> bool:
+ """
+ Deletes the AwsInstance
+
+
+ :returns: True if delete succeeds, False otherwise
+ """
+ return self._proxy.delete()
+
+ async def delete_async(self) -> bool:
+ """
+ Asynchronous coroutine that deletes the AwsInstance
+
+
+ :returns: True if delete succeeds, False otherwise
+ """
+ return await self._proxy.delete_async()
+
+ def fetch(self) -> "AwsInstance":
+ """
+ Fetch the AwsInstance
+
+
+ :returns: The fetched AwsInstance
+ """
+ return self._proxy.fetch()
+
+ async def fetch_async(self) -> "AwsInstance":
+ """
+ Asynchronous coroutine to fetch the AwsInstance
+
+
+ :returns: The fetched AwsInstance
+ """
+ return await self._proxy.fetch_async()
+
+ def update(self, friendly_name: Union[str, object] = values.unset) -> "AwsInstance":
+ """
+ Update the AwsInstance
+
+ :param friendly_name: A descriptive string that you create to describe the resource. It can be up to 64 characters long.
+
+ :returns: The updated AwsInstance
+ """
+ return self._proxy.update(
+ friendly_name=friendly_name,
+ )
+
+ async def update_async(
+ self, friendly_name: Union[str, object] = values.unset
+ ) -> "AwsInstance":
+ """
+ Asynchronous coroutine to update the AwsInstance
+
+ :param friendly_name: A descriptive string that you create to describe the resource. It can be up to 64 characters long.
+
+ :returns: The updated AwsInstance
+ """
+ return await self._proxy.update_async(
+ friendly_name=friendly_name,
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(context)
+
+
+class AwsContext(InstanceContext):
+
+ def __init__(self, version: Version, sid: str):
+ """
+ Initialize the AwsContext
+
+ :param version: Version that contains the resource
+ :param sid: The Twilio-provided string that uniquely identifies the AWS resource to update.
+ """
+ super().__init__(version)
+
+ # Path Solution
+ self._solution = {
+ "sid": sid,
+ }
+ self._uri = "/Credentials/AWS/{sid}".format(**self._solution)
+
+ def delete(self) -> bool:
+ """
+ Deletes the AwsInstance
+
+
+ :returns: True if delete succeeds, False otherwise
+ """
+
+ headers = values.of({})
+
+ return self._version.delete(method="DELETE", uri=self._uri, headers=headers)
+
+ async def delete_async(self) -> bool:
+ """
+ Asynchronous coroutine that deletes the AwsInstance
+
+
+ :returns: True if delete succeeds, False otherwise
+ """
+
+ headers = values.of({})
+
+ return await self._version.delete_async(
+ method="DELETE", uri=self._uri, headers=headers
+ )
+
+ def fetch(self) -> AwsInstance:
+ """
+ Fetch the AwsInstance
+
+
+ :returns: The fetched AwsInstance
+ """
+
+ headers = values.of({})
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.fetch(method="GET", uri=self._uri, headers=headers)
+
+ return AwsInstance(
+ self._version,
+ payload,
+ sid=self._solution["sid"],
+ )
+
+ async def fetch_async(self) -> AwsInstance:
+ """
+ Asynchronous coroutine to fetch the AwsInstance
+
+
+ :returns: The fetched AwsInstance
+ """
+
+ headers = values.of({})
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.fetch_async(
+ method="GET", uri=self._uri, headers=headers
+ )
+
+ return AwsInstance(
+ self._version,
+ payload,
+ sid=self._solution["sid"],
+ )
+
+ def update(self, friendly_name: Union[str, object] = values.unset) -> AwsInstance:
+ """
+ Update the AwsInstance
+
+ :param friendly_name: A descriptive string that you create to describe the resource. It can be up to 64 characters long.
+
+ :returns: The updated AwsInstance
+ """
+
+ data = values.of(
+ {
+ "FriendlyName": friendly_name,
+ }
+ )
+ headers = values.of({})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.update(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return AwsInstance(self._version, payload, sid=self._solution["sid"])
+
+ async def update_async(
+ self, friendly_name: Union[str, object] = values.unset
+ ) -> AwsInstance:
+ """
+ Asynchronous coroutine to update the AwsInstance
+
+ :param friendly_name: A descriptive string that you create to describe the resource. It can be up to 64 characters long.
+
+ :returns: The updated AwsInstance
+ """
+
+ data = values.of(
+ {
+ "FriendlyName": friendly_name,
+ }
+ )
+ headers = values.of({})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.update_async(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return AwsInstance(self._version, payload, sid=self._solution["sid"])
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(context)
+
+
+class AwsPage(Page):
+
+ def get_instance(self, payload: Dict[str, Any]) -> AwsInstance:
+ """
+ Build an instance of AwsInstance
+
+ :param payload: Payload response from the API
+ """
+ return AwsInstance(self._version, payload)
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
+
+
+class AwsList(ListResource):
+
+ def __init__(self, version: Version):
+ """
+ Initialize the AwsList
+
+ :param version: Version that contains the resource
+
+ """
+ super().__init__(version)
+
+ self._uri = "/Credentials/AWS"
+
+ def create(
+ self,
+ credentials: str,
+ friendly_name: Union[str, object] = values.unset,
+ account_sid: Union[str, object] = values.unset,
+ ) -> AwsInstance:
+ """
+ Create the AwsInstance
+
+ :param credentials: A string that contains the AWS access credentials in the format `:`. For example, `AKIAIOSFODNN7EXAMPLE:wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY`
+ :param friendly_name: A descriptive string that you create to describe the resource. It can be up to 64 characters long.
+ :param account_sid: The SID of the Subaccount that this Credential should be associated with. Must be a valid Subaccount of the account issuing the request.
+
+ :returns: The created AwsInstance
+ """
+
+ data = values.of(
+ {
+ "Credentials": credentials,
+ "FriendlyName": friendly_name,
+ "AccountSid": account_sid,
+ }
+ )
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.create(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return AwsInstance(self._version, payload)
+
+ async def create_async(
+ self,
+ credentials: str,
+ friendly_name: Union[str, object] = values.unset,
+ account_sid: Union[str, object] = values.unset,
+ ) -> AwsInstance:
+ """
+ Asynchronously create the AwsInstance
+
+ :param credentials: A string that contains the AWS access credentials in the format `:`. For example, `AKIAIOSFODNN7EXAMPLE:wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY`
+ :param friendly_name: A descriptive string that you create to describe the resource. It can be up to 64 characters long.
+ :param account_sid: The SID of the Subaccount that this Credential should be associated with. Must be a valid Subaccount of the account issuing the request.
+
+ :returns: The created AwsInstance
+ """
+
+ data = values.of(
+ {
+ "Credentials": credentials,
+ "FriendlyName": friendly_name,
+ "AccountSid": account_sid,
+ }
+ )
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.create_async(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return AwsInstance(self._version, payload)
+
+ def stream(
+ self,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> Iterator[AwsInstance]:
+ """
+ Streams AwsInstance records from the API as a generator stream.
+ This operation lazily loads records as efficiently as possible until the limit
+ is reached.
+ The results are returned as a generator, so this operation is memory efficient.
+
+ :param limit: Upper limit for the number of records to return. stream()
+ guarantees to never return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, stream() will attempt to read the
+ limit with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: Generator that will yield up to limit results
+ """
+ limits = self._version.read_limits(limit, page_size)
+ page = self.page(page_size=limits["page_size"])
+
+ return self._version.stream(page, limits["limit"])
+
+ async def stream_async(
+ self,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> AsyncIterator[AwsInstance]:
+ """
+ Asynchronously streams AwsInstance records from the API as a generator stream.
+ This operation lazily loads records as efficiently as possible until the limit
+ is reached.
+ The results are returned as a generator, so this operation is memory efficient.
+
+ :param limit: Upper limit for the number of records to return. stream()
+ guarantees to never return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, stream() will attempt to read the
+ limit with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: Generator that will yield up to limit results
+ """
+ limits = self._version.read_limits(limit, page_size)
+ page = await self.page_async(page_size=limits["page_size"])
+
+ return self._version.stream_async(page, limits["limit"])
+
+ def list(
+ self,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> List[AwsInstance]:
+ """
+ Lists AwsInstance records from the API as a list.
+ Unlike stream(), this operation is eager and will load `limit` records into
+ memory before returning.
+
+ :param limit: Upper limit for the number of records to return. list() guarantees
+ never to return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, list() will attempt to read the limit
+ with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: list that will contain up to limit results
+ """
+ return list(
+ self.stream(
+ limit=limit,
+ page_size=page_size,
+ )
+ )
+
+ async def list_async(
+ self,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> List[AwsInstance]:
+ """
+ Asynchronously lists AwsInstance records from the API as a list.
+ Unlike stream(), this operation is eager and will load `limit` records into
+ memory before returning.
+
+ :param limit: Upper limit for the number of records to return. list() guarantees
+ never to return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, list() will attempt to read the limit
+ with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: list that will contain up to limit results
+ """
+ return [
+ record
+ async for record in await self.stream_async(
+ limit=limit,
+ page_size=page_size,
+ )
+ ]
+
+ def page(
+ self,
+ page_token: Union[str, object] = values.unset,
+ page_number: Union[int, object] = values.unset,
+ page_size: Union[int, object] = values.unset,
+ ) -> AwsPage:
+ """
+ Retrieve a single page of AwsInstance records from the API.
+ Request is executed immediately
+
+ :param page_token: PageToken provided by the API
+ :param page_number: Page Number, this value is simply for client state
+ :param page_size: Number of records to return, defaults to 50
+
+ :returns: Page of AwsInstance
+ """
+ data = values.of(
+ {
+ "PageToken": page_token,
+ "Page": page_number,
+ "PageSize": page_size,
+ }
+ )
+
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ response = self._version.page(
+ method="GET", uri=self._uri, params=data, headers=headers
+ )
+ return AwsPage(self._version, response)
+
+ async def page_async(
+ self,
+ page_token: Union[str, object] = values.unset,
+ page_number: Union[int, object] = values.unset,
+ page_size: Union[int, object] = values.unset,
+ ) -> AwsPage:
+ """
+ Asynchronously retrieve a single page of AwsInstance records from the API.
+ Request is executed immediately
+
+ :param page_token: PageToken provided by the API
+ :param page_number: Page Number, this value is simply for client state
+ :param page_size: Number of records to return, defaults to 50
+
+ :returns: Page of AwsInstance
+ """
+ data = values.of(
+ {
+ "PageToken": page_token,
+ "Page": page_number,
+ "PageSize": page_size,
+ }
+ )
+
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ response = await self._version.page_async(
+ method="GET", uri=self._uri, params=data, headers=headers
+ )
+ return AwsPage(self._version, response)
+
+ def get_page(self, target_url: str) -> AwsPage:
+ """
+ Retrieve a specific page of AwsInstance records from the API.
+ Request is executed immediately
+
+ :param target_url: API-generated URL for the requested results page
+
+ :returns: Page of AwsInstance
+ """
+ response = self._version.domain.twilio.request("GET", target_url)
+ return AwsPage(self._version, response)
+
+ async def get_page_async(self, target_url: str) -> AwsPage:
+ """
+ Asynchronously retrieve a specific page of AwsInstance records from the API.
+ Request is executed immediately
+
+ :param target_url: API-generated URL for the requested results page
+
+ :returns: Page of AwsInstance
+ """
+ response = await self._version.domain.twilio.request_async("GET", target_url)
+ return AwsPage(self._version, response)
+
+ def get(self, sid: str) -> AwsContext:
+ """
+ Constructs a AwsContext
+
+ :param sid: The Twilio-provided string that uniquely identifies the AWS resource to update.
+ """
+ return AwsContext(self._version, sid=sid)
+
+ def __call__(self, sid: str) -> AwsContext:
+ """
+ Constructs a AwsContext
+
+ :param sid: The Twilio-provided string that uniquely identifies the AWS resource to update.
+ """
+ return AwsContext(self._version, sid=sid)
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
diff --git a/venv/Lib/site-packages/twilio/rest/accounts/v1/credential/public_key.py b/venv/Lib/site-packages/twilio/rest/accounts/v1/credential/public_key.py
new file mode 100644
index 00000000..c2b4f9bb
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/accounts/v1/credential/public_key.py
@@ -0,0 +1,613 @@
+r"""
+ This code was generated by
+ ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __
+ | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/
+ | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \
+
+ Twilio - Accounts
+ This is the public Twilio REST API.
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ https://openapi-generator.tech
+ Do not edit the class manually.
+"""
+
+from datetime import datetime
+from typing import Any, Dict, List, Optional, Union, Iterator, AsyncIterator
+from twilio.base import deserialize, values
+from twilio.base.instance_context import InstanceContext
+from twilio.base.instance_resource import InstanceResource
+from twilio.base.list_resource import ListResource
+from twilio.base.version import Version
+from twilio.base.page import Page
+
+
+class PublicKeyInstance(InstanceResource):
+ """
+ :ivar sid: The unique string that that we created to identify the PublicKey resource.
+ :ivar account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that created the Credential that the PublicKey resource belongs to.
+ :ivar friendly_name: The string that you assigned to describe the resource.
+ :ivar date_created: The date and time in GMT when the resource was created specified in [RFC 2822](https://www.ietf.org/rfc/rfc2822.txt) format.
+ :ivar date_updated: The date and time in GMT when the resource was last updated specified in [RFC 2822](https://www.ietf.org/rfc/rfc2822.txt) format.
+ :ivar url: The URI for this resource, relative to `https://accounts.twilio.com`
+ """
+
+ def __init__(
+ self, version: Version, payload: Dict[str, Any], sid: Optional[str] = None
+ ):
+ super().__init__(version)
+
+ self.sid: Optional[str] = payload.get("sid")
+ self.account_sid: Optional[str] = payload.get("account_sid")
+ self.friendly_name: Optional[str] = payload.get("friendly_name")
+ self.date_created: Optional[datetime] = deserialize.iso8601_datetime(
+ payload.get("date_created")
+ )
+ self.date_updated: Optional[datetime] = deserialize.iso8601_datetime(
+ payload.get("date_updated")
+ )
+ self.url: Optional[str] = payload.get("url")
+
+ self._solution = {
+ "sid": sid or self.sid,
+ }
+ self._context: Optional[PublicKeyContext] = None
+
+ @property
+ def _proxy(self) -> "PublicKeyContext":
+ """
+ Generate an instance context for the instance, the context is capable of
+ performing various actions. All instance actions are proxied to the context
+
+ :returns: PublicKeyContext for this PublicKeyInstance
+ """
+ if self._context is None:
+ self._context = PublicKeyContext(
+ self._version,
+ sid=self._solution["sid"],
+ )
+ return self._context
+
+ def delete(self) -> bool:
+ """
+ Deletes the PublicKeyInstance
+
+
+ :returns: True if delete succeeds, False otherwise
+ """
+ return self._proxy.delete()
+
+ async def delete_async(self) -> bool:
+ """
+ Asynchronous coroutine that deletes the PublicKeyInstance
+
+
+ :returns: True if delete succeeds, False otherwise
+ """
+ return await self._proxy.delete_async()
+
+ def fetch(self) -> "PublicKeyInstance":
+ """
+ Fetch the PublicKeyInstance
+
+
+ :returns: The fetched PublicKeyInstance
+ """
+ return self._proxy.fetch()
+
+ async def fetch_async(self) -> "PublicKeyInstance":
+ """
+ Asynchronous coroutine to fetch the PublicKeyInstance
+
+
+ :returns: The fetched PublicKeyInstance
+ """
+ return await self._proxy.fetch_async()
+
+ def update(
+ self, friendly_name: Union[str, object] = values.unset
+ ) -> "PublicKeyInstance":
+ """
+ Update the PublicKeyInstance
+
+ :param friendly_name: A descriptive string that you create to describe the resource. It can be up to 64 characters long.
+
+ :returns: The updated PublicKeyInstance
+ """
+ return self._proxy.update(
+ friendly_name=friendly_name,
+ )
+
+ async def update_async(
+ self, friendly_name: Union[str, object] = values.unset
+ ) -> "PublicKeyInstance":
+ """
+ Asynchronous coroutine to update the PublicKeyInstance
+
+ :param friendly_name: A descriptive string that you create to describe the resource. It can be up to 64 characters long.
+
+ :returns: The updated PublicKeyInstance
+ """
+ return await self._proxy.update_async(
+ friendly_name=friendly_name,
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(context)
+
+
+class PublicKeyContext(InstanceContext):
+
+ def __init__(self, version: Version, sid: str):
+ """
+ Initialize the PublicKeyContext
+
+ :param version: Version that contains the resource
+ :param sid: The Twilio-provided string that uniquely identifies the PublicKey resource to update.
+ """
+ super().__init__(version)
+
+ # Path Solution
+ self._solution = {
+ "sid": sid,
+ }
+ self._uri = "/Credentials/PublicKeys/{sid}".format(**self._solution)
+
+ def delete(self) -> bool:
+ """
+ Deletes the PublicKeyInstance
+
+
+ :returns: True if delete succeeds, False otherwise
+ """
+
+ headers = values.of({})
+
+ return self._version.delete(method="DELETE", uri=self._uri, headers=headers)
+
+ async def delete_async(self) -> bool:
+ """
+ Asynchronous coroutine that deletes the PublicKeyInstance
+
+
+ :returns: True if delete succeeds, False otherwise
+ """
+
+ headers = values.of({})
+
+ return await self._version.delete_async(
+ method="DELETE", uri=self._uri, headers=headers
+ )
+
+ def fetch(self) -> PublicKeyInstance:
+ """
+ Fetch the PublicKeyInstance
+
+
+ :returns: The fetched PublicKeyInstance
+ """
+
+ headers = values.of({})
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.fetch(method="GET", uri=self._uri, headers=headers)
+
+ return PublicKeyInstance(
+ self._version,
+ payload,
+ sid=self._solution["sid"],
+ )
+
+ async def fetch_async(self) -> PublicKeyInstance:
+ """
+ Asynchronous coroutine to fetch the PublicKeyInstance
+
+
+ :returns: The fetched PublicKeyInstance
+ """
+
+ headers = values.of({})
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.fetch_async(
+ method="GET", uri=self._uri, headers=headers
+ )
+
+ return PublicKeyInstance(
+ self._version,
+ payload,
+ sid=self._solution["sid"],
+ )
+
+ def update(
+ self, friendly_name: Union[str, object] = values.unset
+ ) -> PublicKeyInstance:
+ """
+ Update the PublicKeyInstance
+
+ :param friendly_name: A descriptive string that you create to describe the resource. It can be up to 64 characters long.
+
+ :returns: The updated PublicKeyInstance
+ """
+
+ data = values.of(
+ {
+ "FriendlyName": friendly_name,
+ }
+ )
+ headers = values.of({})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.update(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return PublicKeyInstance(self._version, payload, sid=self._solution["sid"])
+
+ async def update_async(
+ self, friendly_name: Union[str, object] = values.unset
+ ) -> PublicKeyInstance:
+ """
+ Asynchronous coroutine to update the PublicKeyInstance
+
+ :param friendly_name: A descriptive string that you create to describe the resource. It can be up to 64 characters long.
+
+ :returns: The updated PublicKeyInstance
+ """
+
+ data = values.of(
+ {
+ "FriendlyName": friendly_name,
+ }
+ )
+ headers = values.of({})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.update_async(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return PublicKeyInstance(self._version, payload, sid=self._solution["sid"])
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(context)
+
+
+class PublicKeyPage(Page):
+
+ def get_instance(self, payload: Dict[str, Any]) -> PublicKeyInstance:
+ """
+ Build an instance of PublicKeyInstance
+
+ :param payload: Payload response from the API
+ """
+ return PublicKeyInstance(self._version, payload)
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
+
+
+class PublicKeyList(ListResource):
+
+ def __init__(self, version: Version):
+ """
+ Initialize the PublicKeyList
+
+ :param version: Version that contains the resource
+
+ """
+ super().__init__(version)
+
+ self._uri = "/Credentials/PublicKeys"
+
+ def create(
+ self,
+ public_key: str,
+ friendly_name: Union[str, object] = values.unset,
+ account_sid: Union[str, object] = values.unset,
+ ) -> PublicKeyInstance:
+ """
+ Create the PublicKeyInstance
+
+ :param public_key: A URL encoded representation of the public key. For example, `-----BEGIN PUBLIC KEY-----MIIBIjANB.pa9xQIDAQAB-----END PUBLIC KEY-----`
+ :param friendly_name: A descriptive string that you create to describe the resource. It can be up to 64 characters long.
+ :param account_sid: The SID of the Subaccount that this Credential should be associated with. Must be a valid Subaccount of the account issuing the request
+
+ :returns: The created PublicKeyInstance
+ """
+
+ data = values.of(
+ {
+ "PublicKey": public_key,
+ "FriendlyName": friendly_name,
+ "AccountSid": account_sid,
+ }
+ )
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.create(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return PublicKeyInstance(self._version, payload)
+
+ async def create_async(
+ self,
+ public_key: str,
+ friendly_name: Union[str, object] = values.unset,
+ account_sid: Union[str, object] = values.unset,
+ ) -> PublicKeyInstance:
+ """
+ Asynchronously create the PublicKeyInstance
+
+ :param public_key: A URL encoded representation of the public key. For example, `-----BEGIN PUBLIC KEY-----MIIBIjANB.pa9xQIDAQAB-----END PUBLIC KEY-----`
+ :param friendly_name: A descriptive string that you create to describe the resource. It can be up to 64 characters long.
+ :param account_sid: The SID of the Subaccount that this Credential should be associated with. Must be a valid Subaccount of the account issuing the request
+
+ :returns: The created PublicKeyInstance
+ """
+
+ data = values.of(
+ {
+ "PublicKey": public_key,
+ "FriendlyName": friendly_name,
+ "AccountSid": account_sid,
+ }
+ )
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.create_async(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return PublicKeyInstance(self._version, payload)
+
+ def stream(
+ self,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> Iterator[PublicKeyInstance]:
+ """
+ Streams PublicKeyInstance records from the API as a generator stream.
+ This operation lazily loads records as efficiently as possible until the limit
+ is reached.
+ The results are returned as a generator, so this operation is memory efficient.
+
+ :param limit: Upper limit for the number of records to return. stream()
+ guarantees to never return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, stream() will attempt to read the
+ limit with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: Generator that will yield up to limit results
+ """
+ limits = self._version.read_limits(limit, page_size)
+ page = self.page(page_size=limits["page_size"])
+
+ return self._version.stream(page, limits["limit"])
+
+ async def stream_async(
+ self,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> AsyncIterator[PublicKeyInstance]:
+ """
+ Asynchronously streams PublicKeyInstance records from the API as a generator stream.
+ This operation lazily loads records as efficiently as possible until the limit
+ is reached.
+ The results are returned as a generator, so this operation is memory efficient.
+
+ :param limit: Upper limit for the number of records to return. stream()
+ guarantees to never return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, stream() will attempt to read the
+ limit with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: Generator that will yield up to limit results
+ """
+ limits = self._version.read_limits(limit, page_size)
+ page = await self.page_async(page_size=limits["page_size"])
+
+ return self._version.stream_async(page, limits["limit"])
+
+ def list(
+ self,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> List[PublicKeyInstance]:
+ """
+ Lists PublicKeyInstance records from the API as a list.
+ Unlike stream(), this operation is eager and will load `limit` records into
+ memory before returning.
+
+ :param limit: Upper limit for the number of records to return. list() guarantees
+ never to return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, list() will attempt to read the limit
+ with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: list that will contain up to limit results
+ """
+ return list(
+ self.stream(
+ limit=limit,
+ page_size=page_size,
+ )
+ )
+
+ async def list_async(
+ self,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> List[PublicKeyInstance]:
+ """
+ Asynchronously lists PublicKeyInstance records from the API as a list.
+ Unlike stream(), this operation is eager and will load `limit` records into
+ memory before returning.
+
+ :param limit: Upper limit for the number of records to return. list() guarantees
+ never to return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, list() will attempt to read the limit
+ with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: list that will contain up to limit results
+ """
+ return [
+ record
+ async for record in await self.stream_async(
+ limit=limit,
+ page_size=page_size,
+ )
+ ]
+
+ def page(
+ self,
+ page_token: Union[str, object] = values.unset,
+ page_number: Union[int, object] = values.unset,
+ page_size: Union[int, object] = values.unset,
+ ) -> PublicKeyPage:
+ """
+ Retrieve a single page of PublicKeyInstance records from the API.
+ Request is executed immediately
+
+ :param page_token: PageToken provided by the API
+ :param page_number: Page Number, this value is simply for client state
+ :param page_size: Number of records to return, defaults to 50
+
+ :returns: Page of PublicKeyInstance
+ """
+ data = values.of(
+ {
+ "PageToken": page_token,
+ "Page": page_number,
+ "PageSize": page_size,
+ }
+ )
+
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ response = self._version.page(
+ method="GET", uri=self._uri, params=data, headers=headers
+ )
+ return PublicKeyPage(self._version, response)
+
+ async def page_async(
+ self,
+ page_token: Union[str, object] = values.unset,
+ page_number: Union[int, object] = values.unset,
+ page_size: Union[int, object] = values.unset,
+ ) -> PublicKeyPage:
+ """
+ Asynchronously retrieve a single page of PublicKeyInstance records from the API.
+ Request is executed immediately
+
+ :param page_token: PageToken provided by the API
+ :param page_number: Page Number, this value is simply for client state
+ :param page_size: Number of records to return, defaults to 50
+
+ :returns: Page of PublicKeyInstance
+ """
+ data = values.of(
+ {
+ "PageToken": page_token,
+ "Page": page_number,
+ "PageSize": page_size,
+ }
+ )
+
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ response = await self._version.page_async(
+ method="GET", uri=self._uri, params=data, headers=headers
+ )
+ return PublicKeyPage(self._version, response)
+
+ def get_page(self, target_url: str) -> PublicKeyPage:
+ """
+ Retrieve a specific page of PublicKeyInstance records from the API.
+ Request is executed immediately
+
+ :param target_url: API-generated URL for the requested results page
+
+ :returns: Page of PublicKeyInstance
+ """
+ response = self._version.domain.twilio.request("GET", target_url)
+ return PublicKeyPage(self._version, response)
+
+ async def get_page_async(self, target_url: str) -> PublicKeyPage:
+ """
+ Asynchronously retrieve a specific page of PublicKeyInstance records from the API.
+ Request is executed immediately
+
+ :param target_url: API-generated URL for the requested results page
+
+ :returns: Page of PublicKeyInstance
+ """
+ response = await self._version.domain.twilio.request_async("GET", target_url)
+ return PublicKeyPage(self._version, response)
+
+ def get(self, sid: str) -> PublicKeyContext:
+ """
+ Constructs a PublicKeyContext
+
+ :param sid: The Twilio-provided string that uniquely identifies the PublicKey resource to update.
+ """
+ return PublicKeyContext(self._version, sid=sid)
+
+ def __call__(self, sid: str) -> PublicKeyContext:
+ """
+ Constructs a PublicKeyContext
+
+ :param sid: The Twilio-provided string that uniquely identifies the PublicKey resource to update.
+ """
+ return PublicKeyContext(self._version, sid=sid)
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
diff --git a/venv/Lib/site-packages/twilio/rest/accounts/v1/safelist.py b/venv/Lib/site-packages/twilio/rest/accounts/v1/safelist.py
new file mode 100644
index 00000000..be8fe416
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/accounts/v1/safelist.py
@@ -0,0 +1,204 @@
+r"""
+ This code was generated by
+ ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __
+ | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/
+ | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \
+
+ Twilio - Accounts
+ This is the public Twilio REST API.
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ https://openapi-generator.tech
+ Do not edit the class manually.
+"""
+
+from typing import Any, Dict, Optional, Union
+from twilio.base import values
+
+from twilio.base.instance_resource import InstanceResource
+from twilio.base.list_resource import ListResource
+from twilio.base.version import Version
+
+
+class SafelistInstance(InstanceResource):
+ """
+ :ivar sid: The unique string that we created to identify the SafeList resource.
+ :ivar phone_number: The phone number or phone number 1k prefix in SafeList.
+ """
+
+ def __init__(self, version: Version, payload: Dict[str, Any]):
+ super().__init__(version)
+
+ self.sid: Optional[str] = payload.get("sid")
+ self.phone_number: Optional[str] = payload.get("phone_number")
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+
+ return ""
+
+
+class SafelistList(ListResource):
+
+ def __init__(self, version: Version):
+ """
+ Initialize the SafelistList
+
+ :param version: Version that contains the resource
+
+ """
+ super().__init__(version)
+
+ self._uri = "/SafeList/Numbers"
+
+ def create(self, phone_number: str) -> SafelistInstance:
+ """
+ Create the SafelistInstance
+
+ :param phone_number: The phone number or phone number 1k prefix to be added in SafeList. Phone numbers must be in [E.164 format](https://www.twilio.com/docs/glossary/what-e164).
+
+ :returns: The created SafelistInstance
+ """
+
+ data = values.of(
+ {
+ "PhoneNumber": phone_number,
+ }
+ )
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.create(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return SafelistInstance(self._version, payload)
+
+ async def create_async(self, phone_number: str) -> SafelistInstance:
+ """
+ Asynchronously create the SafelistInstance
+
+ :param phone_number: The phone number or phone number 1k prefix to be added in SafeList. Phone numbers must be in [E.164 format](https://www.twilio.com/docs/glossary/what-e164).
+
+ :returns: The created SafelistInstance
+ """
+
+ data = values.of(
+ {
+ "PhoneNumber": phone_number,
+ }
+ )
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.create_async(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return SafelistInstance(self._version, payload)
+
+ def delete(self, phone_number: Union[str, object] = values.unset) -> bool:
+ """
+ Asynchronously delete the SafelistInstance
+
+ :param phone_number: The phone number or phone number 1k prefix to be removed from SafeList. Phone numbers must be in [E.164 format](https://www.twilio.com/docs/glossary/what-e164).
+ :returns: True if delete succeeds, False otherwise
+ """
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ params = values.of(
+ {
+ "PhoneNumber": phone_number,
+ }
+ )
+ return self._version.delete(
+ method="DELETE", uri=self._uri, headers=headers, params=params
+ )
+
+ async def delete_async(
+ self, phone_number: Union[str, object] = values.unset
+ ) -> bool:
+ """
+ Asynchronously delete the SafelistInstance
+
+ :param phone_number: The phone number or phone number 1k prefix to be removed from SafeList. Phone numbers must be in [E.164 format](https://www.twilio.com/docs/glossary/what-e164).
+ :returns: True if delete succeeds, False otherwise
+ """
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ params = values.of(
+ {
+ "PhoneNumber": phone_number,
+ }
+ )
+ return await self._version.delete_async(
+ method="DELETE", uri=self._uri, headers=headers, params=params
+ )
+
+ def fetch(
+ self, phone_number: Union[str, object] = values.unset
+ ) -> SafelistInstance:
+ """
+ Asynchronously fetch the SafelistInstance
+
+ :param phone_number: The phone number or phone number 1k prefix to be fetched from SafeList. Phone numbers must be in [E.164 format](https://www.twilio.com/docs/glossary/what-e164).
+ :returns: The fetched SafelistInstance
+ """
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ params = values.of(
+ {
+ "PhoneNumber": phone_number,
+ }
+ )
+
+ payload = self._version.fetch(
+ method="GET", uri=self._uri, headers=headers, params=params
+ )
+
+ return SafelistInstance(self._version, payload)
+
+ async def fetch_async(
+ self, phone_number: Union[str, object] = values.unset
+ ) -> SafelistInstance:
+ """
+ Asynchronously fetch the SafelistInstance
+
+ :param phone_number: The phone number or phone number 1k prefix to be fetched from SafeList. Phone numbers must be in [E.164 format](https://www.twilio.com/docs/glossary/what-e164).
+ :returns: The fetched SafelistInstance
+ """
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ params = values.of(
+ {
+ "PhoneNumber": phone_number,
+ }
+ )
+
+ payload = await self._version.fetch_async(
+ method="GET", uri=self._uri, headers=headers, params=params
+ )
+
+ return SafelistInstance(self._version, payload)
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
diff --git a/venv/Lib/site-packages/twilio/rest/accounts/v1/secondary_auth_token.py b/venv/Lib/site-packages/twilio/rest/accounts/v1/secondary_auth_token.py
new file mode 100644
index 00000000..f5e2b5c1
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/accounts/v1/secondary_auth_token.py
@@ -0,0 +1,215 @@
+r"""
+ This code was generated by
+ ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __
+ | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/
+ | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \
+
+ Twilio - Accounts
+ This is the public Twilio REST API.
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ https://openapi-generator.tech
+ Do not edit the class manually.
+"""
+
+from datetime import datetime
+from typing import Any, Dict, Optional
+from twilio.base import deserialize, values
+from twilio.base.instance_context import InstanceContext
+from twilio.base.instance_resource import InstanceResource
+from twilio.base.list_resource import ListResource
+from twilio.base.version import Version
+
+
+class SecondaryAuthTokenInstance(InstanceResource):
+ """
+ :ivar account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that the secondary Auth Token was created for.
+ :ivar date_created: The date and time in UTC when the resource was created specified in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format.
+ :ivar date_updated: The date and time in UTC when the resource was last updated specified in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format.
+ :ivar secondary_auth_token: The generated secondary Auth Token that can be used to authenticate future API requests.
+ :ivar url: The URI for this resource, relative to `https://accounts.twilio.com`
+ """
+
+ def __init__(self, version: Version, payload: Dict[str, Any]):
+ super().__init__(version)
+
+ self.account_sid: Optional[str] = payload.get("account_sid")
+ self.date_created: Optional[datetime] = deserialize.iso8601_datetime(
+ payload.get("date_created")
+ )
+ self.date_updated: Optional[datetime] = deserialize.iso8601_datetime(
+ payload.get("date_updated")
+ )
+ self.secondary_auth_token: Optional[str] = payload.get("secondary_auth_token")
+ self.url: Optional[str] = payload.get("url")
+
+ self._context: Optional[SecondaryAuthTokenContext] = None
+
+ @property
+ def _proxy(self) -> "SecondaryAuthTokenContext":
+ """
+ Generate an instance context for the instance, the context is capable of
+ performing various actions. All instance actions are proxied to the context
+
+ :returns: SecondaryAuthTokenContext for this SecondaryAuthTokenInstance
+ """
+ if self._context is None:
+ self._context = SecondaryAuthTokenContext(
+ self._version,
+ )
+ return self._context
+
+ def create(self) -> "SecondaryAuthTokenInstance":
+ """
+ Create the SecondaryAuthTokenInstance
+
+
+ :returns: The created SecondaryAuthTokenInstance
+ """
+ return self._proxy.create()
+
+ async def create_async(self) -> "SecondaryAuthTokenInstance":
+ """
+ Asynchronous coroutine to create the SecondaryAuthTokenInstance
+
+
+ :returns: The created SecondaryAuthTokenInstance
+ """
+ return await self._proxy.create_async()
+
+ def delete(self) -> bool:
+ """
+ Deletes the SecondaryAuthTokenInstance
+
+
+ :returns: True if delete succeeds, False otherwise
+ """
+ return self._proxy.delete()
+
+ async def delete_async(self) -> bool:
+ """
+ Asynchronous coroutine that deletes the SecondaryAuthTokenInstance
+
+
+ :returns: True if delete succeeds, False otherwise
+ """
+ return await self._proxy.delete_async()
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+
+ return ""
+
+
+class SecondaryAuthTokenContext(InstanceContext):
+
+ def __init__(self, version: Version):
+ """
+ Initialize the SecondaryAuthTokenContext
+
+ :param version: Version that contains the resource
+ """
+ super().__init__(version)
+
+ self._uri = "/AuthTokens/Secondary"
+
+ def create(self) -> SecondaryAuthTokenInstance:
+ """
+ Create the SecondaryAuthTokenInstance
+
+
+ :returns: The created SecondaryAuthTokenInstance
+ """
+ data = values.of({})
+
+ payload = self._version.create(method="POST", uri=self._uri, data=data)
+
+ return SecondaryAuthTokenInstance(self._version, payload)
+
+ async def create_async(self) -> SecondaryAuthTokenInstance:
+ """
+ Asynchronous coroutine to create the SecondaryAuthTokenInstance
+
+
+ :returns: The created SecondaryAuthTokenInstance
+ """
+ data = values.of({})
+
+ payload = await self._version.create_async(
+ method="POST", uri=self._uri, data=data
+ )
+
+ return SecondaryAuthTokenInstance(self._version, payload)
+
+ def delete(self) -> bool:
+ """
+ Deletes the SecondaryAuthTokenInstance
+
+
+ :returns: True if delete succeeds, False otherwise
+ """
+
+ headers = values.of({})
+
+ return self._version.delete(method="DELETE", uri=self._uri, headers=headers)
+
+ async def delete_async(self) -> bool:
+ """
+ Asynchronous coroutine that deletes the SecondaryAuthTokenInstance
+
+
+ :returns: True if delete succeeds, False otherwise
+ """
+
+ headers = values.of({})
+
+ return await self._version.delete_async(
+ method="DELETE", uri=self._uri, headers=headers
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+
+ return ""
+
+
+class SecondaryAuthTokenList(ListResource):
+
+ def __init__(self, version: Version):
+ """
+ Initialize the SecondaryAuthTokenList
+
+ :param version: Version that contains the resource
+
+ """
+ super().__init__(version)
+
+ def get(self) -> SecondaryAuthTokenContext:
+ """
+ Constructs a SecondaryAuthTokenContext
+
+ """
+ return SecondaryAuthTokenContext(self._version)
+
+ def __call__(self) -> SecondaryAuthTokenContext:
+ """
+ Constructs a SecondaryAuthTokenContext
+
+ """
+ return SecondaryAuthTokenContext(self._version)
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
diff --git a/venv/Lib/site-packages/twilio/rest/api/ApiBase.py b/venv/Lib/site-packages/twilio/rest/api/ApiBase.py
new file mode 100644
index 00000000..e53535ab
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/api/ApiBase.py
@@ -0,0 +1,44 @@
+r"""
+ This code was generated by
+ ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __
+ | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/
+ | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ https://openapi-generator.tech
+ Do not edit the class manually.
+"""
+
+from typing import Optional
+
+from twilio.base.domain import Domain
+from twilio.rest import Client
+from twilio.rest.api.v2010 import V2010
+
+
+class ApiBase(Domain):
+
+ def __init__(self, twilio: Client):
+ """
+ Initialize the Api Domain
+
+ :returns: Domain for Api
+ """
+ super().__init__(twilio, "https://api.twilio.com")
+ self._v2010: Optional[V2010] = None
+
+ @property
+ def v2010(self) -> V2010:
+ """
+ :returns: Versions v2010 of Api
+ """
+ if self._v2010 is None:
+ self._v2010 = V2010(self)
+ return self._v2010
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+ :returns: Machine friendly representation
+ """
+ return ""
diff --git a/venv/Lib/site-packages/twilio/rest/api/__init__.py b/venv/Lib/site-packages/twilio/rest/api/__init__.py
new file mode 100644
index 00000000..08d5885c
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/api/__init__.py
@@ -0,0 +1,258 @@
+from warnings import warn
+
+from twilio.rest.api.ApiBase import ApiBase
+from twilio.rest.api.v2010.account import AccountContext, AccountList
+from twilio.rest.api.v2010.account.address import AddressList
+from twilio.rest.api.v2010.account.application import ApplicationList
+from twilio.rest.api.v2010.account.authorized_connect_app import (
+ AuthorizedConnectAppList,
+)
+from twilio.rest.api.v2010.account.available_phone_number_country import (
+ AvailablePhoneNumberCountryList,
+)
+from twilio.rest.api.v2010.account.balance import BalanceList
+from twilio.rest.api.v2010.account.call import CallList
+from twilio.rest.api.v2010.account.conference import ConferenceList
+from twilio.rest.api.v2010.account.connect_app import ConnectAppList
+from twilio.rest.api.v2010.account.incoming_phone_number import IncomingPhoneNumberList
+from twilio.rest.api.v2010.account.key import KeyList
+from twilio.rest.api.v2010.account.message import MessageList
+from twilio.rest.api.v2010.account.new_key import NewKeyList
+from twilio.rest.api.v2010.account.new_signing_key import NewSigningKeyList
+from twilio.rest.api.v2010.account.notification import NotificationList
+from twilio.rest.api.v2010.account.outgoing_caller_id import OutgoingCallerIdList
+from twilio.rest.api.v2010.account.queue import QueueList
+from twilio.rest.api.v2010.account.recording import RecordingList
+from twilio.rest.api.v2010.account.short_code import ShortCodeList
+from twilio.rest.api.v2010.account.signing_key import SigningKeyList
+from twilio.rest.api.v2010.account.sip import SipList
+from twilio.rest.api.v2010.account.token import TokenList
+from twilio.rest.api.v2010.account.transcription import TranscriptionList
+from twilio.rest.api.v2010.account.usage import UsageList
+from twilio.rest.api.v2010.account.validation_request import ValidationRequestList
+
+
+class Api(ApiBase):
+ @property
+ def account(self) -> AccountContext:
+ return self.v2010.account
+
+ @property
+ def accounts(self) -> AccountList:
+ return self.v2010.accounts
+
+ @property
+ def addresses(self) -> AddressList:
+ warn(
+ "addresses is deprecated. Use account.addresses instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ return self.account.addresses
+
+ @property
+ def applications(self) -> ApplicationList:
+ warn(
+ "applications is deprecated. Use account.applications instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ return self.account.applications
+
+ @property
+ def authorized_connect_apps(self) -> AuthorizedConnectAppList:
+ warn(
+ "authorized_connect_apps is deprecated. Use account.authorized_connect_apps instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ return self.account.authorized_connect_apps
+
+ @property
+ def available_phone_numbers(self) -> AvailablePhoneNumberCountryList:
+ warn(
+ "available_phone_numbers is deprecated. Use account.available_phone_numbers instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ return self.account.available_phone_numbers
+
+ @property
+ def balance(self) -> BalanceList:
+ warn(
+ "balance is deprecated. Use account.balance instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ return self.account.balance
+
+ @property
+ def calls(self) -> CallList:
+ warn(
+ "calls is deprecated. Use account.calls instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ return self.account.calls
+
+ @property
+ def conferences(self) -> ConferenceList:
+ warn(
+ "conferences is deprecated. Use account.conferences instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ return self.account.conferences
+
+ @property
+ def connect_apps(self) -> ConnectAppList:
+ warn(
+ "connect_apps is deprecated. Use account.connect_apps instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ return self.account.connect_apps
+
+ @property
+ def incoming_phone_numbers(self) -> IncomingPhoneNumberList:
+ warn(
+ "incoming_phone_numbers is deprecated. Use account.incoming_phone_numbers instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ return self.account.incoming_phone_numbers
+
+ @property
+ def keys(self) -> KeyList:
+ warn(
+ "keys is deprecated. Use account.keys instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ return self.account.keys
+
+ @property
+ def messages(self) -> MessageList:
+ warn(
+ "messages is deprecated. Use account.messages instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ return self.account.messages
+
+ @property
+ def new_keys(self) -> NewKeyList:
+ warn(
+ "new_keys is deprecated. Use account.new_keys instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ return self.account.new_keys
+
+ @property
+ def new_signing_keys(self) -> NewSigningKeyList:
+ warn(
+ "new_signing_keys is deprecated. Use account.new_signing_keys instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ return self.account.new_signing_keys
+
+ @property
+ def notifications(self) -> NotificationList:
+ warn(
+ "notifications is deprecated. Use account.notifications instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ return self.account.notifications
+
+ @property
+ def outgoing_caller_ids(self) -> OutgoingCallerIdList:
+ warn(
+ "outgoing_caller_ids is deprecated. Use account.outgoing_caller_ids instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ return self.account.outgoing_caller_ids
+
+ @property
+ def queues(self) -> QueueList:
+ warn(
+ "queues is deprecated. Use account.queues instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ return self.account.queues
+
+ @property
+ def recordings(self) -> RecordingList:
+ warn(
+ "recordings is deprecated. Use account.recordings instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ return self.account.recordings
+
+ @property
+ def signing_keys(self) -> SigningKeyList:
+ warn(
+ "signing_keys is deprecated. Use account.signing_keys instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ return self.account.signing_keys
+
+ @property
+ def sip(self) -> SipList:
+ warn(
+ "sip is deprecated. Use account.sip instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ return self.account.sip
+
+ @property
+ def short_codes(self) -> ShortCodeList:
+ warn(
+ "short_codes is deprecated. Use account.short_codes instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ return self.account.short_codes
+
+ @property
+ def tokens(self) -> TokenList:
+ warn(
+ "tokens is deprecated. Use account.tokens instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ return self.account.tokens
+
+ @property
+ def transcriptions(self) -> TranscriptionList:
+ warn(
+ "transcriptions is deprecated. Use account.transcriptions instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ return self.account.transcriptions
+
+ @property
+ def usage(self) -> UsageList:
+ warn(
+ "usage is deprecated. Use account.usage instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ return self.account.usage
+
+ @property
+ def validation_requests(self) -> ValidationRequestList:
+ warn(
+ "validation_requests is deprecated. Use account.validation_requests instead.",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ return self.account.validation_requests
diff --git a/venv/Lib/site-packages/twilio/rest/api/__pycache__/ApiBase.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/api/__pycache__/ApiBase.cpython-312.pyc
new file mode 100644
index 00000000..1eff59a8
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/api/__pycache__/ApiBase.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/api/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/api/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 00000000..ec203214
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/api/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/__init__.py b/venv/Lib/site-packages/twilio/rest/api/v2010/__init__.py
new file mode 100644
index 00000000..2efb4ff3
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/api/v2010/__init__.py
@@ -0,0 +1,59 @@
+r"""
+ This code was generated by
+ ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __
+ | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/
+ | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \
+
+ Twilio - Api
+ This is the public Twilio REST API.
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ https://openapi-generator.tech
+ Do not edit the class manually.
+"""
+
+from typing import Optional
+from twilio.base.version import Version
+from twilio.base.domain import Domain
+from twilio.rest.api.v2010.account import AccountList
+from twilio.rest.api.v2010.account import AccountContext
+
+
+class V2010(Version):
+
+ def __init__(self, domain: Domain):
+ """
+ Initialize the V2010 version of Api
+
+ :param domain: The Twilio.api domain
+ """
+ super().__init__(domain, "2010-04-01")
+ self._accounts: Optional[AccountList] = None
+ self._account: Optional[AccountContext] = None
+
+ @property
+ def accounts(self) -> AccountList:
+ if self._accounts is None:
+ self._accounts = AccountList(self)
+ return self._accounts
+
+ @property
+ def account(self) -> AccountContext:
+ if self._account is None:
+ self._account = AccountContext(self, self.domain.twilio.account_sid)
+ return self._account
+
+ @account.setter
+ def account(self, value: AccountContext) -> None:
+ """
+ Setter to override account
+ :param value: value to use as account
+ """
+ self._account = value
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+ :returns: Machine friendly representation
+ """
+ return ""
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/api/v2010/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 00000000..e626f8e9
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/api/v2010/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/__init__.py b/venv/Lib/site-packages/twilio/rest/api/v2010/account/__init__.py
new file mode 100644
index 00000000..7c7e2c10
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/api/v2010/account/__init__.py
@@ -0,0 +1,1136 @@
+r"""
+ This code was generated by
+ ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __
+ | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/
+ | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \
+
+ Twilio - Api
+ This is the public Twilio REST API.
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ https://openapi-generator.tech
+ Do not edit the class manually.
+"""
+
+from datetime import datetime
+from typing import Any, Dict, List, Optional, Union, Iterator, AsyncIterator
+from twilio.base import deserialize, values
+from twilio.base.instance_context import InstanceContext
+from twilio.base.instance_resource import InstanceResource
+from twilio.base.list_resource import ListResource
+from twilio.base.version import Version
+from twilio.base.page import Page
+from twilio.rest.api.v2010.account.address import AddressList
+from twilio.rest.api.v2010.account.application import ApplicationList
+from twilio.rest.api.v2010.account.authorized_connect_app import (
+ AuthorizedConnectAppList,
+)
+from twilio.rest.api.v2010.account.available_phone_number_country import (
+ AvailablePhoneNumberCountryList,
+)
+from twilio.rest.api.v2010.account.balance import BalanceList
+from twilio.rest.api.v2010.account.call import CallList
+from twilio.rest.api.v2010.account.conference import ConferenceList
+from twilio.rest.api.v2010.account.connect_app import ConnectAppList
+from twilio.rest.api.v2010.account.incoming_phone_number import IncomingPhoneNumberList
+from twilio.rest.api.v2010.account.key import KeyList
+from twilio.rest.api.v2010.account.message import MessageList
+from twilio.rest.api.v2010.account.new_key import NewKeyList
+from twilio.rest.api.v2010.account.new_signing_key import NewSigningKeyList
+from twilio.rest.api.v2010.account.notification import NotificationList
+from twilio.rest.api.v2010.account.outgoing_caller_id import OutgoingCallerIdList
+from twilio.rest.api.v2010.account.queue import QueueList
+from twilio.rest.api.v2010.account.recording import RecordingList
+from twilio.rest.api.v2010.account.short_code import ShortCodeList
+from twilio.rest.api.v2010.account.signing_key import SigningKeyList
+from twilio.rest.api.v2010.account.sip import SipList
+from twilio.rest.api.v2010.account.token import TokenList
+from twilio.rest.api.v2010.account.transcription import TranscriptionList
+from twilio.rest.api.v2010.account.usage import UsageList
+from twilio.rest.api.v2010.account.validation_request import ValidationRequestList
+
+
+class AccountInstance(InstanceResource):
+
+ class Status(object):
+ ACTIVE = "active"
+ SUSPENDED = "suspended"
+ CLOSED = "closed"
+
+ class Type(object):
+ TRIAL = "Trial"
+ FULL = "Full"
+
+ """
+ :ivar auth_token: The authorization token for this account. This token should be kept a secret, so no sharing.
+ :ivar date_created: The date that this account was created, in GMT in RFC 2822 format
+ :ivar date_updated: The date that this account was last updated, in GMT in RFC 2822 format.
+ :ivar friendly_name: A human readable description of this account, up to 64 characters long. By default the FriendlyName is your email address.
+ :ivar owner_account_sid: The unique 34 character id that represents the parent of this account. The OwnerAccountSid of a parent account is it's own sid.
+ :ivar sid: A 34 character string that uniquely identifies this resource.
+ :ivar status:
+ :ivar subresource_uris: A Map of various subresources available for the given Account Instance
+ :ivar type:
+ :ivar uri: The URI for this resource, relative to `https://api.twilio.com`
+ """
+
+ def __init__(
+ self, version: Version, payload: Dict[str, Any], sid: Optional[str] = None
+ ):
+ super().__init__(version)
+
+ self.auth_token: Optional[str] = payload.get("auth_token")
+ self.date_created: Optional[datetime] = deserialize.rfc2822_datetime(
+ payload.get("date_created")
+ )
+ self.date_updated: Optional[datetime] = deserialize.rfc2822_datetime(
+ payload.get("date_updated")
+ )
+ self.friendly_name: Optional[str] = payload.get("friendly_name")
+ self.owner_account_sid: Optional[str] = payload.get("owner_account_sid")
+ self.sid: Optional[str] = payload.get("sid")
+ self.status: Optional["AccountInstance.Status"] = payload.get("status")
+ self.subresource_uris: Optional[Dict[str, object]] = payload.get(
+ "subresource_uris"
+ )
+ self.type: Optional["AccountInstance.Type"] = payload.get("type")
+ self.uri: Optional[str] = payload.get("uri")
+
+ self._solution = {
+ "sid": sid or self.sid,
+ }
+ self._context: Optional[AccountContext] = None
+
+ @property
+ def _proxy(self) -> "AccountContext":
+ """
+ Generate an instance context for the instance, the context is capable of
+ performing various actions. All instance actions are proxied to the context
+
+ :returns: AccountContext for this AccountInstance
+ """
+ if self._context is None:
+ self._context = AccountContext(
+ self._version,
+ sid=self._solution["sid"],
+ )
+ return self._context
+
+ def fetch(self) -> "AccountInstance":
+ """
+ Fetch the AccountInstance
+
+
+ :returns: The fetched AccountInstance
+ """
+ return self._proxy.fetch()
+
+ async def fetch_async(self) -> "AccountInstance":
+ """
+ Asynchronous coroutine to fetch the AccountInstance
+
+
+ :returns: The fetched AccountInstance
+ """
+ return await self._proxy.fetch_async()
+
+ def update(
+ self,
+ friendly_name: Union[str, object] = values.unset,
+ status: Union["AccountInstance.Status", object] = values.unset,
+ ) -> "AccountInstance":
+ """
+ Update the AccountInstance
+
+ :param friendly_name: Update the human-readable description of this Account
+ :param status:
+
+ :returns: The updated AccountInstance
+ """
+ return self._proxy.update(
+ friendly_name=friendly_name,
+ status=status,
+ )
+
+ async def update_async(
+ self,
+ friendly_name: Union[str, object] = values.unset,
+ status: Union["AccountInstance.Status", object] = values.unset,
+ ) -> "AccountInstance":
+ """
+ Asynchronous coroutine to update the AccountInstance
+
+ :param friendly_name: Update the human-readable description of this Account
+ :param status:
+
+ :returns: The updated AccountInstance
+ """
+ return await self._proxy.update_async(
+ friendly_name=friendly_name,
+ status=status,
+ )
+
+ @property
+ def addresses(self) -> AddressList:
+ """
+ Access the addresses
+ """
+ return self._proxy.addresses
+
+ @property
+ def applications(self) -> ApplicationList:
+ """
+ Access the applications
+ """
+ return self._proxy.applications
+
+ @property
+ def authorized_connect_apps(self) -> AuthorizedConnectAppList:
+ """
+ Access the authorized_connect_apps
+ """
+ return self._proxy.authorized_connect_apps
+
+ @property
+ def available_phone_numbers(self) -> AvailablePhoneNumberCountryList:
+ """
+ Access the available_phone_numbers
+ """
+ return self._proxy.available_phone_numbers
+
+ @property
+ def balance(self) -> BalanceList:
+ """
+ Access the balance
+ """
+ return self._proxy.balance
+
+ @property
+ def calls(self) -> CallList:
+ """
+ Access the calls
+ """
+ return self._proxy.calls
+
+ @property
+ def conferences(self) -> ConferenceList:
+ """
+ Access the conferences
+ """
+ return self._proxy.conferences
+
+ @property
+ def connect_apps(self) -> ConnectAppList:
+ """
+ Access the connect_apps
+ """
+ return self._proxy.connect_apps
+
+ @property
+ def incoming_phone_numbers(self) -> IncomingPhoneNumberList:
+ """
+ Access the incoming_phone_numbers
+ """
+ return self._proxy.incoming_phone_numbers
+
+ @property
+ def keys(self) -> KeyList:
+ """
+ Access the keys
+ """
+ return self._proxy.keys
+
+ @property
+ def messages(self) -> MessageList:
+ """
+ Access the messages
+ """
+ return self._proxy.messages
+
+ @property
+ def new_keys(self) -> NewKeyList:
+ """
+ Access the new_keys
+ """
+ return self._proxy.new_keys
+
+ @property
+ def new_signing_keys(self) -> NewSigningKeyList:
+ """
+ Access the new_signing_keys
+ """
+ return self._proxy.new_signing_keys
+
+ @property
+ def notifications(self) -> NotificationList:
+ """
+ Access the notifications
+ """
+ return self._proxy.notifications
+
+ @property
+ def outgoing_caller_ids(self) -> OutgoingCallerIdList:
+ """
+ Access the outgoing_caller_ids
+ """
+ return self._proxy.outgoing_caller_ids
+
+ @property
+ def queues(self) -> QueueList:
+ """
+ Access the queues
+ """
+ return self._proxy.queues
+
+ @property
+ def recordings(self) -> RecordingList:
+ """
+ Access the recordings
+ """
+ return self._proxy.recordings
+
+ @property
+ def short_codes(self) -> ShortCodeList:
+ """
+ Access the short_codes
+ """
+ return self._proxy.short_codes
+
+ @property
+ def signing_keys(self) -> SigningKeyList:
+ """
+ Access the signing_keys
+ """
+ return self._proxy.signing_keys
+
+ @property
+ def sip(self) -> SipList:
+ """
+ Access the sip
+ """
+ return self._proxy.sip
+
+ @property
+ def tokens(self) -> TokenList:
+ """
+ Access the tokens
+ """
+ return self._proxy.tokens
+
+ @property
+ def transcriptions(self) -> TranscriptionList:
+ """
+ Access the transcriptions
+ """
+ return self._proxy.transcriptions
+
+ @property
+ def usage(self) -> UsageList:
+ """
+ Access the usage
+ """
+ return self._proxy.usage
+
+ @property
+ def validation_requests(self) -> ValidationRequestList:
+ """
+ Access the validation_requests
+ """
+ return self._proxy.validation_requests
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(context)
+
+
+class AccountContext(InstanceContext):
+
+ def __init__(self, version: Version, sid: str):
+ """
+ Initialize the AccountContext
+
+ :param version: Version that contains the resource
+ :param sid: The Account Sid that uniquely identifies the account to update
+ """
+ super().__init__(version)
+
+ # Path Solution
+ self._solution = {
+ "sid": sid,
+ }
+ self._uri = "/Accounts/{sid}.json".format(**self._solution)
+
+ self._addresses: Optional[AddressList] = None
+ self._applications: Optional[ApplicationList] = None
+ self._authorized_connect_apps: Optional[AuthorizedConnectAppList] = None
+ self._available_phone_numbers: Optional[AvailablePhoneNumberCountryList] = None
+ self._balance: Optional[BalanceList] = None
+ self._calls: Optional[CallList] = None
+ self._conferences: Optional[ConferenceList] = None
+ self._connect_apps: Optional[ConnectAppList] = None
+ self._incoming_phone_numbers: Optional[IncomingPhoneNumberList] = None
+ self._keys: Optional[KeyList] = None
+ self._messages: Optional[MessageList] = None
+ self._new_keys: Optional[NewKeyList] = None
+ self._new_signing_keys: Optional[NewSigningKeyList] = None
+ self._notifications: Optional[NotificationList] = None
+ self._outgoing_caller_ids: Optional[OutgoingCallerIdList] = None
+ self._queues: Optional[QueueList] = None
+ self._recordings: Optional[RecordingList] = None
+ self._short_codes: Optional[ShortCodeList] = None
+ self._signing_keys: Optional[SigningKeyList] = None
+ self._sip: Optional[SipList] = None
+ self._tokens: Optional[TokenList] = None
+ self._transcriptions: Optional[TranscriptionList] = None
+ self._usage: Optional[UsageList] = None
+ self._validation_requests: Optional[ValidationRequestList] = None
+
+ def fetch(self) -> AccountInstance:
+ """
+ Fetch the AccountInstance
+
+
+ :returns: The fetched AccountInstance
+ """
+
+ headers = values.of({})
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.fetch(method="GET", uri=self._uri, headers=headers)
+
+ return AccountInstance(
+ self._version,
+ payload,
+ sid=self._solution["sid"],
+ )
+
+ async def fetch_async(self) -> AccountInstance:
+ """
+ Asynchronous coroutine to fetch the AccountInstance
+
+
+ :returns: The fetched AccountInstance
+ """
+
+ headers = values.of({})
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.fetch_async(
+ method="GET", uri=self._uri, headers=headers
+ )
+
+ return AccountInstance(
+ self._version,
+ payload,
+ sid=self._solution["sid"],
+ )
+
+ def update(
+ self,
+ friendly_name: Union[str, object] = values.unset,
+ status: Union["AccountInstance.Status", object] = values.unset,
+ ) -> AccountInstance:
+ """
+ Update the AccountInstance
+
+ :param friendly_name: Update the human-readable description of this Account
+ :param status:
+
+ :returns: The updated AccountInstance
+ """
+
+ data = values.of(
+ {
+ "FriendlyName": friendly_name,
+ "Status": status,
+ }
+ )
+ headers = values.of({})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.update(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return AccountInstance(self._version, payload, sid=self._solution["sid"])
+
+ async def update_async(
+ self,
+ friendly_name: Union[str, object] = values.unset,
+ status: Union["AccountInstance.Status", object] = values.unset,
+ ) -> AccountInstance:
+ """
+ Asynchronous coroutine to update the AccountInstance
+
+ :param friendly_name: Update the human-readable description of this Account
+ :param status:
+
+ :returns: The updated AccountInstance
+ """
+
+ data = values.of(
+ {
+ "FriendlyName": friendly_name,
+ "Status": status,
+ }
+ )
+ headers = values.of({})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.update_async(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return AccountInstance(self._version, payload, sid=self._solution["sid"])
+
+ @property
+ def addresses(self) -> AddressList:
+ """
+ Access the addresses
+ """
+ if self._addresses is None:
+ self._addresses = AddressList(
+ self._version,
+ self._solution["sid"],
+ )
+ return self._addresses
+
+ @property
+ def applications(self) -> ApplicationList:
+ """
+ Access the applications
+ """
+ if self._applications is None:
+ self._applications = ApplicationList(
+ self._version,
+ self._solution["sid"],
+ )
+ return self._applications
+
+ @property
+ def authorized_connect_apps(self) -> AuthorizedConnectAppList:
+ """
+ Access the authorized_connect_apps
+ """
+ if self._authorized_connect_apps is None:
+ self._authorized_connect_apps = AuthorizedConnectAppList(
+ self._version,
+ self._solution["sid"],
+ )
+ return self._authorized_connect_apps
+
+ @property
+ def available_phone_numbers(self) -> AvailablePhoneNumberCountryList:
+ """
+ Access the available_phone_numbers
+ """
+ if self._available_phone_numbers is None:
+ self._available_phone_numbers = AvailablePhoneNumberCountryList(
+ self._version,
+ self._solution["sid"],
+ )
+ return self._available_phone_numbers
+
+ @property
+ def balance(self) -> BalanceList:
+ """
+ Access the balance
+ """
+ if self._balance is None:
+ self._balance = BalanceList(
+ self._version,
+ self._solution["sid"],
+ )
+ return self._balance
+
+ @property
+ def calls(self) -> CallList:
+ """
+ Access the calls
+ """
+ if self._calls is None:
+ self._calls = CallList(
+ self._version,
+ self._solution["sid"],
+ )
+ return self._calls
+
+ @property
+ def conferences(self) -> ConferenceList:
+ """
+ Access the conferences
+ """
+ if self._conferences is None:
+ self._conferences = ConferenceList(
+ self._version,
+ self._solution["sid"],
+ )
+ return self._conferences
+
+ @property
+ def connect_apps(self) -> ConnectAppList:
+ """
+ Access the connect_apps
+ """
+ if self._connect_apps is None:
+ self._connect_apps = ConnectAppList(
+ self._version,
+ self._solution["sid"],
+ )
+ return self._connect_apps
+
+ @property
+ def incoming_phone_numbers(self) -> IncomingPhoneNumberList:
+ """
+ Access the incoming_phone_numbers
+ """
+ if self._incoming_phone_numbers is None:
+ self._incoming_phone_numbers = IncomingPhoneNumberList(
+ self._version,
+ self._solution["sid"],
+ )
+ return self._incoming_phone_numbers
+
+ @property
+ def keys(self) -> KeyList:
+ """
+ Access the keys
+ """
+ if self._keys is None:
+ self._keys = KeyList(
+ self._version,
+ self._solution["sid"],
+ )
+ return self._keys
+
+ @property
+ def messages(self) -> MessageList:
+ """
+ Access the messages
+ """
+ if self._messages is None:
+ self._messages = MessageList(
+ self._version,
+ self._solution["sid"],
+ )
+ return self._messages
+
+ @property
+ def new_keys(self) -> NewKeyList:
+ """
+ Access the new_keys
+ """
+ if self._new_keys is None:
+ self._new_keys = NewKeyList(
+ self._version,
+ self._solution["sid"],
+ )
+ return self._new_keys
+
+ @property
+ def new_signing_keys(self) -> NewSigningKeyList:
+ """
+ Access the new_signing_keys
+ """
+ if self._new_signing_keys is None:
+ self._new_signing_keys = NewSigningKeyList(
+ self._version,
+ self._solution["sid"],
+ )
+ return self._new_signing_keys
+
+ @property
+ def notifications(self) -> NotificationList:
+ """
+ Access the notifications
+ """
+ if self._notifications is None:
+ self._notifications = NotificationList(
+ self._version,
+ self._solution["sid"],
+ )
+ return self._notifications
+
+ @property
+ def outgoing_caller_ids(self) -> OutgoingCallerIdList:
+ """
+ Access the outgoing_caller_ids
+ """
+ if self._outgoing_caller_ids is None:
+ self._outgoing_caller_ids = OutgoingCallerIdList(
+ self._version,
+ self._solution["sid"],
+ )
+ return self._outgoing_caller_ids
+
+ @property
+ def queues(self) -> QueueList:
+ """
+ Access the queues
+ """
+ if self._queues is None:
+ self._queues = QueueList(
+ self._version,
+ self._solution["sid"],
+ )
+ return self._queues
+
+ @property
+ def recordings(self) -> RecordingList:
+ """
+ Access the recordings
+ """
+ if self._recordings is None:
+ self._recordings = RecordingList(
+ self._version,
+ self._solution["sid"],
+ )
+ return self._recordings
+
+ @property
+ def short_codes(self) -> ShortCodeList:
+ """
+ Access the short_codes
+ """
+ if self._short_codes is None:
+ self._short_codes = ShortCodeList(
+ self._version,
+ self._solution["sid"],
+ )
+ return self._short_codes
+
+ @property
+ def signing_keys(self) -> SigningKeyList:
+ """
+ Access the signing_keys
+ """
+ if self._signing_keys is None:
+ self._signing_keys = SigningKeyList(
+ self._version,
+ self._solution["sid"],
+ )
+ return self._signing_keys
+
+ @property
+ def sip(self) -> SipList:
+ """
+ Access the sip
+ """
+ if self._sip is None:
+ self._sip = SipList(
+ self._version,
+ self._solution["sid"],
+ )
+ return self._sip
+
+ @property
+ def tokens(self) -> TokenList:
+ """
+ Access the tokens
+ """
+ if self._tokens is None:
+ self._tokens = TokenList(
+ self._version,
+ self._solution["sid"],
+ )
+ return self._tokens
+
+ @property
+ def transcriptions(self) -> TranscriptionList:
+ """
+ Access the transcriptions
+ """
+ if self._transcriptions is None:
+ self._transcriptions = TranscriptionList(
+ self._version,
+ self._solution["sid"],
+ )
+ return self._transcriptions
+
+ @property
+ def usage(self) -> UsageList:
+ """
+ Access the usage
+ """
+ if self._usage is None:
+ self._usage = UsageList(
+ self._version,
+ self._solution["sid"],
+ )
+ return self._usage
+
+ @property
+ def validation_requests(self) -> ValidationRequestList:
+ """
+ Access the validation_requests
+ """
+ if self._validation_requests is None:
+ self._validation_requests = ValidationRequestList(
+ self._version,
+ self._solution["sid"],
+ )
+ return self._validation_requests
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(context)
+
+
+class AccountPage(Page):
+
+ def get_instance(self, payload: Dict[str, Any]) -> AccountInstance:
+ """
+ Build an instance of AccountInstance
+
+ :param payload: Payload response from the API
+ """
+ return AccountInstance(self._version, payload)
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
+
+
+class AccountList(ListResource):
+
+ def __init__(self, version: Version):
+ """
+ Initialize the AccountList
+
+ :param version: Version that contains the resource
+
+ """
+ super().__init__(version)
+
+ self._uri = "/Accounts.json"
+
+ def create(
+ self, friendly_name: Union[str, object] = values.unset
+ ) -> AccountInstance:
+ """
+ Create the AccountInstance
+
+ :param friendly_name: A human readable description of the account to create, defaults to `SubAccount Created at {YYYY-MM-DD HH:MM meridian}`
+
+ :returns: The created AccountInstance
+ """
+
+ data = values.of(
+ {
+ "FriendlyName": friendly_name,
+ }
+ )
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.create(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return AccountInstance(self._version, payload)
+
+ async def create_async(
+ self, friendly_name: Union[str, object] = values.unset
+ ) -> AccountInstance:
+ """
+ Asynchronously create the AccountInstance
+
+ :param friendly_name: A human readable description of the account to create, defaults to `SubAccount Created at {YYYY-MM-DD HH:MM meridian}`
+
+ :returns: The created AccountInstance
+ """
+
+ data = values.of(
+ {
+ "FriendlyName": friendly_name,
+ }
+ )
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.create_async(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return AccountInstance(self._version, payload)
+
+ def stream(
+ self,
+ friendly_name: Union[str, object] = values.unset,
+ status: Union["AccountInstance.Status", object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> Iterator[AccountInstance]:
+ """
+ Streams AccountInstance records from the API as a generator stream.
+ This operation lazily loads records as efficiently as possible until the limit
+ is reached.
+ The results are returned as a generator, so this operation is memory efficient.
+
+ :param str friendly_name: Only return the Account resources with friendly names that exactly match this name.
+ :param "AccountInstance.Status" status: Only return Account resources with the given status. Can be `closed`, `suspended` or `active`.
+ :param limit: Upper limit for the number of records to return. stream()
+ guarantees to never return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, stream() will attempt to read the
+ limit with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: Generator that will yield up to limit results
+ """
+ limits = self._version.read_limits(limit, page_size)
+ page = self.page(
+ friendly_name=friendly_name, status=status, page_size=limits["page_size"]
+ )
+
+ return self._version.stream(page, limits["limit"])
+
+ async def stream_async(
+ self,
+ friendly_name: Union[str, object] = values.unset,
+ status: Union["AccountInstance.Status", object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> AsyncIterator[AccountInstance]:
+ """
+ Asynchronously streams AccountInstance records from the API as a generator stream.
+ This operation lazily loads records as efficiently as possible until the limit
+ is reached.
+ The results are returned as a generator, so this operation is memory efficient.
+
+ :param str friendly_name: Only return the Account resources with friendly names that exactly match this name.
+ :param "AccountInstance.Status" status: Only return Account resources with the given status. Can be `closed`, `suspended` or `active`.
+ :param limit: Upper limit for the number of records to return. stream()
+ guarantees to never return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, stream() will attempt to read the
+ limit with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: Generator that will yield up to limit results
+ """
+ limits = self._version.read_limits(limit, page_size)
+ page = await self.page_async(
+ friendly_name=friendly_name, status=status, page_size=limits["page_size"]
+ )
+
+ return self._version.stream_async(page, limits["limit"])
+
+ def list(
+ self,
+ friendly_name: Union[str, object] = values.unset,
+ status: Union["AccountInstance.Status", object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> List[AccountInstance]:
+ """
+ Lists AccountInstance records from the API as a list.
+ Unlike stream(), this operation is eager and will load `limit` records into
+ memory before returning.
+
+ :param str friendly_name: Only return the Account resources with friendly names that exactly match this name.
+ :param "AccountInstance.Status" status: Only return Account resources with the given status. Can be `closed`, `suspended` or `active`.
+ :param limit: Upper limit for the number of records to return. list() guarantees
+ never to return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, list() will attempt to read the limit
+ with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: list that will contain up to limit results
+ """
+ return list(
+ self.stream(
+ friendly_name=friendly_name,
+ status=status,
+ limit=limit,
+ page_size=page_size,
+ )
+ )
+
+ async def list_async(
+ self,
+ friendly_name: Union[str, object] = values.unset,
+ status: Union["AccountInstance.Status", object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> List[AccountInstance]:
+ """
+ Asynchronously lists AccountInstance records from the API as a list.
+ Unlike stream(), this operation is eager and will load `limit` records into
+ memory before returning.
+
+ :param str friendly_name: Only return the Account resources with friendly names that exactly match this name.
+ :param "AccountInstance.Status" status: Only return Account resources with the given status. Can be `closed`, `suspended` or `active`.
+ :param limit: Upper limit for the number of records to return. list() guarantees
+ never to return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, list() will attempt to read the limit
+ with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: list that will contain up to limit results
+ """
+ return [
+ record
+ async for record in await self.stream_async(
+ friendly_name=friendly_name,
+ status=status,
+ limit=limit,
+ page_size=page_size,
+ )
+ ]
+
+ def page(
+ self,
+ friendly_name: Union[str, object] = values.unset,
+ status: Union["AccountInstance.Status", object] = values.unset,
+ page_token: Union[str, object] = values.unset,
+ page_number: Union[int, object] = values.unset,
+ page_size: Union[int, object] = values.unset,
+ ) -> AccountPage:
+ """
+ Retrieve a single page of AccountInstance records from the API.
+ Request is executed immediately
+
+ :param friendly_name: Only return the Account resources with friendly names that exactly match this name.
+ :param status: Only return Account resources with the given status. Can be `closed`, `suspended` or `active`.
+ :param page_token: PageToken provided by the API
+ :param page_number: Page Number, this value is simply for client state
+ :param page_size: Number of records to return, defaults to 50
+
+ :returns: Page of AccountInstance
+ """
+ data = values.of(
+ {
+ "FriendlyName": friendly_name,
+ "Status": status,
+ "PageToken": page_token,
+ "Page": page_number,
+ "PageSize": page_size,
+ }
+ )
+
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ response = self._version.page(
+ method="GET", uri=self._uri, params=data, headers=headers
+ )
+ return AccountPage(self._version, response)
+
+ async def page_async(
+ self,
+ friendly_name: Union[str, object] = values.unset,
+ status: Union["AccountInstance.Status", object] = values.unset,
+ page_token: Union[str, object] = values.unset,
+ page_number: Union[int, object] = values.unset,
+ page_size: Union[int, object] = values.unset,
+ ) -> AccountPage:
+ """
+ Asynchronously retrieve a single page of AccountInstance records from the API.
+ Request is executed immediately
+
+ :param friendly_name: Only return the Account resources with friendly names that exactly match this name.
+ :param status: Only return Account resources with the given status. Can be `closed`, `suspended` or `active`.
+ :param page_token: PageToken provided by the API
+ :param page_number: Page Number, this value is simply for client state
+ :param page_size: Number of records to return, defaults to 50
+
+ :returns: Page of AccountInstance
+ """
+ data = values.of(
+ {
+ "FriendlyName": friendly_name,
+ "Status": status,
+ "PageToken": page_token,
+ "Page": page_number,
+ "PageSize": page_size,
+ }
+ )
+
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ response = await self._version.page_async(
+ method="GET", uri=self._uri, params=data, headers=headers
+ )
+ return AccountPage(self._version, response)
+
+ def get_page(self, target_url: str) -> AccountPage:
+ """
+ Retrieve a specific page of AccountInstance records from the API.
+ Request is executed immediately
+
+ :param target_url: API-generated URL for the requested results page
+
+ :returns: Page of AccountInstance
+ """
+ response = self._version.domain.twilio.request("GET", target_url)
+ return AccountPage(self._version, response)
+
+ async def get_page_async(self, target_url: str) -> AccountPage:
+ """
+ Asynchronously retrieve a specific page of AccountInstance records from the API.
+ Request is executed immediately
+
+ :param target_url: API-generated URL for the requested results page
+
+ :returns: Page of AccountInstance
+ """
+ response = await self._version.domain.twilio.request_async("GET", target_url)
+ return AccountPage(self._version, response)
+
+ def get(self, sid: str) -> AccountContext:
+ """
+ Constructs a AccountContext
+
+ :param sid: The Account Sid that uniquely identifies the account to update
+ """
+ return AccountContext(self._version, sid=sid)
+
+ def __call__(self, sid: str) -> AccountContext:
+ """
+ Constructs a AccountContext
+
+ :param sid: The Account Sid that uniquely identifies the account to update
+ """
+ return AccountContext(self._version, sid=sid)
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 00000000..946d905b
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/application.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/application.cpython-312.pyc
new file mode 100644
index 00000000..9af4e1b8
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/application.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/authorized_connect_app.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/authorized_connect_app.cpython-312.pyc
new file mode 100644
index 00000000..745150d9
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/authorized_connect_app.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/balance.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/balance.cpython-312.pyc
new file mode 100644
index 00000000..2f3f7cd7
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/balance.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/connect_app.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/connect_app.cpython-312.pyc
new file mode 100644
index 00000000..3e91c5c4
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/connect_app.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/key.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/key.cpython-312.pyc
new file mode 100644
index 00000000..a6549714
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/key.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/new_key.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/new_key.cpython-312.pyc
new file mode 100644
index 00000000..a6bf7c8c
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/new_key.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/new_signing_key.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/new_signing_key.cpython-312.pyc
new file mode 100644
index 00000000..b5494780
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/new_signing_key.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/notification.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/notification.cpython-312.pyc
new file mode 100644
index 00000000..663846ba
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/notification.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/outgoing_caller_id.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/outgoing_caller_id.cpython-312.pyc
new file mode 100644
index 00000000..b869c18a
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/outgoing_caller_id.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/short_code.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/short_code.cpython-312.pyc
new file mode 100644
index 00000000..74b95bf6
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/short_code.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/signing_key.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/signing_key.cpython-312.pyc
new file mode 100644
index 00000000..4bae097a
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/signing_key.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/token.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/token.cpython-312.pyc
new file mode 100644
index 00000000..4782c443
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/token.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/transcription.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/transcription.cpython-312.pyc
new file mode 100644
index 00000000..d5f7846b
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/transcription.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/validation_request.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/validation_request.cpython-312.pyc
new file mode 100644
index 00000000..479d5b27
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/api/v2010/account/__pycache__/validation_request.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/address/__init__.py b/venv/Lib/site-packages/twilio/rest/api/v2010/account/address/__init__.py
new file mode 100644
index 00000000..77fc702c
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/api/v2010/account/address/__init__.py
@@ -0,0 +1,913 @@
+r"""
+ This code was generated by
+ ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __
+ | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/
+ | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \
+
+ Twilio - Api
+ This is the public Twilio REST API.
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ https://openapi-generator.tech
+ Do not edit the class manually.
+"""
+
+from datetime import datetime
+from typing import Any, Dict, List, Optional, Union, Iterator, AsyncIterator
+from twilio.base import deserialize, serialize, values
+from twilio.base.instance_context import InstanceContext
+from twilio.base.instance_resource import InstanceResource
+from twilio.base.list_resource import ListResource
+from twilio.base.version import Version
+from twilio.base.page import Page
+from twilio.rest.api.v2010.account.address.dependent_phone_number import (
+ DependentPhoneNumberList,
+)
+
+
+class AddressInstance(InstanceResource):
+ """
+ :ivar account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that is responsible for the Address resource.
+ :ivar city: The city in which the address is located.
+ :ivar customer_name: The name associated with the address.This property has a maximum length of 16 4-byte characters, or 21 3-byte characters.
+ :ivar date_created: The date and time in GMT that the resource was created specified in [RFC 2822](https://www.ietf.org/rfc/rfc2822.txt) format.
+ :ivar date_updated: The date and time in GMT that the resource was last updated specified in [RFC 2822](https://www.ietf.org/rfc/rfc2822.txt) format.
+ :ivar friendly_name: The string that you assigned to describe the resource.
+ :ivar iso_country: The ISO country code of the address.
+ :ivar postal_code: The postal code of the address.
+ :ivar region: The state or region of the address.
+ :ivar sid: The unique string that that we created to identify the Address resource.
+ :ivar street: The number and street address of the address.
+ :ivar uri: The URI of the resource, relative to `https://api.twilio.com`.
+ :ivar emergency_enabled: Whether emergency calling has been enabled on this number.
+ :ivar validated: Whether the address has been validated to comply with local regulation. In countries that require valid addresses, an invalid address will not be accepted. `true` indicates the Address has been validated. `false` indicate the country doesn't require validation or the Address is not valid.
+ :ivar verified: Whether the address has been verified to comply with regulation. In countries that require valid addresses, an invalid address will not be accepted. `true` indicates the Address has been verified. `false` indicate the country doesn't require verified or the Address is not valid.
+ :ivar street_secondary: The additional number and street address of the address.
+ """
+
+ def __init__(
+ self,
+ version: Version,
+ payload: Dict[str, Any],
+ account_sid: str,
+ sid: Optional[str] = None,
+ ):
+ super().__init__(version)
+
+ self.account_sid: Optional[str] = payload.get("account_sid")
+ self.city: Optional[str] = payload.get("city")
+ self.customer_name: Optional[str] = payload.get("customer_name")
+ self.date_created: Optional[datetime] = deserialize.rfc2822_datetime(
+ payload.get("date_created")
+ )
+ self.date_updated: Optional[datetime] = deserialize.rfc2822_datetime(
+ payload.get("date_updated")
+ )
+ self.friendly_name: Optional[str] = payload.get("friendly_name")
+ self.iso_country: Optional[str] = payload.get("iso_country")
+ self.postal_code: Optional[str] = payload.get("postal_code")
+ self.region: Optional[str] = payload.get("region")
+ self.sid: Optional[str] = payload.get("sid")
+ self.street: Optional[str] = payload.get("street")
+ self.uri: Optional[str] = payload.get("uri")
+ self.emergency_enabled: Optional[bool] = payload.get("emergency_enabled")
+ self.validated: Optional[bool] = payload.get("validated")
+ self.verified: Optional[bool] = payload.get("verified")
+ self.street_secondary: Optional[str] = payload.get("street_secondary")
+
+ self._solution = {
+ "account_sid": account_sid,
+ "sid": sid or self.sid,
+ }
+ self._context: Optional[AddressContext] = None
+
+ @property
+ def _proxy(self) -> "AddressContext":
+ """
+ Generate an instance context for the instance, the context is capable of
+ performing various actions. All instance actions are proxied to the context
+
+ :returns: AddressContext for this AddressInstance
+ """
+ if self._context is None:
+ self._context = AddressContext(
+ self._version,
+ account_sid=self._solution["account_sid"],
+ sid=self._solution["sid"],
+ )
+ return self._context
+
+ def delete(self) -> bool:
+ """
+ Deletes the AddressInstance
+
+
+ :returns: True if delete succeeds, False otherwise
+ """
+ return self._proxy.delete()
+
+ async def delete_async(self) -> bool:
+ """
+ Asynchronous coroutine that deletes the AddressInstance
+
+
+ :returns: True if delete succeeds, False otherwise
+ """
+ return await self._proxy.delete_async()
+
+ def fetch(self) -> "AddressInstance":
+ """
+ Fetch the AddressInstance
+
+
+ :returns: The fetched AddressInstance
+ """
+ return self._proxy.fetch()
+
+ async def fetch_async(self) -> "AddressInstance":
+ """
+ Asynchronous coroutine to fetch the AddressInstance
+
+
+ :returns: The fetched AddressInstance
+ """
+ return await self._proxy.fetch_async()
+
+ def update(
+ self,
+ friendly_name: Union[str, object] = values.unset,
+ customer_name: Union[str, object] = values.unset,
+ street: Union[str, object] = values.unset,
+ city: Union[str, object] = values.unset,
+ region: Union[str, object] = values.unset,
+ postal_code: Union[str, object] = values.unset,
+ emergency_enabled: Union[bool, object] = values.unset,
+ auto_correct_address: Union[bool, object] = values.unset,
+ street_secondary: Union[str, object] = values.unset,
+ ) -> "AddressInstance":
+ """
+ Update the AddressInstance
+
+ :param friendly_name: A descriptive string that you create to describe the new address. It can be up to 64 characters long for Regulatory Compliance addresses and 32 characters long for Emergency addresses.
+ :param customer_name: The name to associate with the address.
+ :param street: The number and street address of the address.
+ :param city: The city of the address.
+ :param region: The state or region of the address.
+ :param postal_code: The postal code of the address.
+ :param emergency_enabled: Whether to enable emergency calling on the address. Can be: `true` or `false`.
+ :param auto_correct_address: Whether we should automatically correct the address. Can be: `true` or `false` and the default is `true`. If empty or `true`, we will correct the address you provide if necessary. If `false`, we won't alter the address you provide.
+ :param street_secondary: The additional number and street address of the address.
+
+ :returns: The updated AddressInstance
+ """
+ return self._proxy.update(
+ friendly_name=friendly_name,
+ customer_name=customer_name,
+ street=street,
+ city=city,
+ region=region,
+ postal_code=postal_code,
+ emergency_enabled=emergency_enabled,
+ auto_correct_address=auto_correct_address,
+ street_secondary=street_secondary,
+ )
+
+ async def update_async(
+ self,
+ friendly_name: Union[str, object] = values.unset,
+ customer_name: Union[str, object] = values.unset,
+ street: Union[str, object] = values.unset,
+ city: Union[str, object] = values.unset,
+ region: Union[str, object] = values.unset,
+ postal_code: Union[str, object] = values.unset,
+ emergency_enabled: Union[bool, object] = values.unset,
+ auto_correct_address: Union[bool, object] = values.unset,
+ street_secondary: Union[str, object] = values.unset,
+ ) -> "AddressInstance":
+ """
+ Asynchronous coroutine to update the AddressInstance
+
+ :param friendly_name: A descriptive string that you create to describe the new address. It can be up to 64 characters long for Regulatory Compliance addresses and 32 characters long for Emergency addresses.
+ :param customer_name: The name to associate with the address.
+ :param street: The number and street address of the address.
+ :param city: The city of the address.
+ :param region: The state or region of the address.
+ :param postal_code: The postal code of the address.
+ :param emergency_enabled: Whether to enable emergency calling on the address. Can be: `true` or `false`.
+ :param auto_correct_address: Whether we should automatically correct the address. Can be: `true` or `false` and the default is `true`. If empty or `true`, we will correct the address you provide if necessary. If `false`, we won't alter the address you provide.
+ :param street_secondary: The additional number and street address of the address.
+
+ :returns: The updated AddressInstance
+ """
+ return await self._proxy.update_async(
+ friendly_name=friendly_name,
+ customer_name=customer_name,
+ street=street,
+ city=city,
+ region=region,
+ postal_code=postal_code,
+ emergency_enabled=emergency_enabled,
+ auto_correct_address=auto_correct_address,
+ street_secondary=street_secondary,
+ )
+
+ @property
+ def dependent_phone_numbers(self) -> DependentPhoneNumberList:
+ """
+ Access the dependent_phone_numbers
+ """
+ return self._proxy.dependent_phone_numbers
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(context)
+
+
+class AddressContext(InstanceContext):
+
+ def __init__(self, version: Version, account_sid: str, sid: str):
+ """
+ Initialize the AddressContext
+
+ :param version: Version that contains the resource
+ :param account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that is responsible for the Address resource to update.
+ :param sid: The Twilio-provided string that uniquely identifies the Address resource to update.
+ """
+ super().__init__(version)
+
+ # Path Solution
+ self._solution = {
+ "account_sid": account_sid,
+ "sid": sid,
+ }
+ self._uri = "/Accounts/{account_sid}/Addresses/{sid}.json".format(
+ **self._solution
+ )
+
+ self._dependent_phone_numbers: Optional[DependentPhoneNumberList] = None
+
+ def delete(self) -> bool:
+ """
+ Deletes the AddressInstance
+
+
+ :returns: True if delete succeeds, False otherwise
+ """
+
+ headers = values.of({})
+
+ return self._version.delete(method="DELETE", uri=self._uri, headers=headers)
+
+ async def delete_async(self) -> bool:
+ """
+ Asynchronous coroutine that deletes the AddressInstance
+
+
+ :returns: True if delete succeeds, False otherwise
+ """
+
+ headers = values.of({})
+
+ return await self._version.delete_async(
+ method="DELETE", uri=self._uri, headers=headers
+ )
+
+ def fetch(self) -> AddressInstance:
+ """
+ Fetch the AddressInstance
+
+
+ :returns: The fetched AddressInstance
+ """
+
+ headers = values.of({})
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.fetch(method="GET", uri=self._uri, headers=headers)
+
+ return AddressInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ sid=self._solution["sid"],
+ )
+
+ async def fetch_async(self) -> AddressInstance:
+ """
+ Asynchronous coroutine to fetch the AddressInstance
+
+
+ :returns: The fetched AddressInstance
+ """
+
+ headers = values.of({})
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.fetch_async(
+ method="GET", uri=self._uri, headers=headers
+ )
+
+ return AddressInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ sid=self._solution["sid"],
+ )
+
+ def update(
+ self,
+ friendly_name: Union[str, object] = values.unset,
+ customer_name: Union[str, object] = values.unset,
+ street: Union[str, object] = values.unset,
+ city: Union[str, object] = values.unset,
+ region: Union[str, object] = values.unset,
+ postal_code: Union[str, object] = values.unset,
+ emergency_enabled: Union[bool, object] = values.unset,
+ auto_correct_address: Union[bool, object] = values.unset,
+ street_secondary: Union[str, object] = values.unset,
+ ) -> AddressInstance:
+ """
+ Update the AddressInstance
+
+ :param friendly_name: A descriptive string that you create to describe the new address. It can be up to 64 characters long for Regulatory Compliance addresses and 32 characters long for Emergency addresses.
+ :param customer_name: The name to associate with the address.
+ :param street: The number and street address of the address.
+ :param city: The city of the address.
+ :param region: The state or region of the address.
+ :param postal_code: The postal code of the address.
+ :param emergency_enabled: Whether to enable emergency calling on the address. Can be: `true` or `false`.
+ :param auto_correct_address: Whether we should automatically correct the address. Can be: `true` or `false` and the default is `true`. If empty or `true`, we will correct the address you provide if necessary. If `false`, we won't alter the address you provide.
+ :param street_secondary: The additional number and street address of the address.
+
+ :returns: The updated AddressInstance
+ """
+
+ data = values.of(
+ {
+ "FriendlyName": friendly_name,
+ "CustomerName": customer_name,
+ "Street": street,
+ "City": city,
+ "Region": region,
+ "PostalCode": postal_code,
+ "EmergencyEnabled": serialize.boolean_to_string(emergency_enabled),
+ "AutoCorrectAddress": serialize.boolean_to_string(auto_correct_address),
+ "StreetSecondary": street_secondary,
+ }
+ )
+ headers = values.of({})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.update(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return AddressInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ sid=self._solution["sid"],
+ )
+
+ async def update_async(
+ self,
+ friendly_name: Union[str, object] = values.unset,
+ customer_name: Union[str, object] = values.unset,
+ street: Union[str, object] = values.unset,
+ city: Union[str, object] = values.unset,
+ region: Union[str, object] = values.unset,
+ postal_code: Union[str, object] = values.unset,
+ emergency_enabled: Union[bool, object] = values.unset,
+ auto_correct_address: Union[bool, object] = values.unset,
+ street_secondary: Union[str, object] = values.unset,
+ ) -> AddressInstance:
+ """
+ Asynchronous coroutine to update the AddressInstance
+
+ :param friendly_name: A descriptive string that you create to describe the new address. It can be up to 64 characters long for Regulatory Compliance addresses and 32 characters long for Emergency addresses.
+ :param customer_name: The name to associate with the address.
+ :param street: The number and street address of the address.
+ :param city: The city of the address.
+ :param region: The state or region of the address.
+ :param postal_code: The postal code of the address.
+ :param emergency_enabled: Whether to enable emergency calling on the address. Can be: `true` or `false`.
+ :param auto_correct_address: Whether we should automatically correct the address. Can be: `true` or `false` and the default is `true`. If empty or `true`, we will correct the address you provide if necessary. If `false`, we won't alter the address you provide.
+ :param street_secondary: The additional number and street address of the address.
+
+ :returns: The updated AddressInstance
+ """
+
+ data = values.of(
+ {
+ "FriendlyName": friendly_name,
+ "CustomerName": customer_name,
+ "Street": street,
+ "City": city,
+ "Region": region,
+ "PostalCode": postal_code,
+ "EmergencyEnabled": serialize.boolean_to_string(emergency_enabled),
+ "AutoCorrectAddress": serialize.boolean_to_string(auto_correct_address),
+ "StreetSecondary": street_secondary,
+ }
+ )
+ headers = values.of({})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.update_async(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return AddressInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ sid=self._solution["sid"],
+ )
+
+ @property
+ def dependent_phone_numbers(self) -> DependentPhoneNumberList:
+ """
+ Access the dependent_phone_numbers
+ """
+ if self._dependent_phone_numbers is None:
+ self._dependent_phone_numbers = DependentPhoneNumberList(
+ self._version,
+ self._solution["account_sid"],
+ self._solution["sid"],
+ )
+ return self._dependent_phone_numbers
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(context)
+
+
+class AddressPage(Page):
+
+ def get_instance(self, payload: Dict[str, Any]) -> AddressInstance:
+ """
+ Build an instance of AddressInstance
+
+ :param payload: Payload response from the API
+ """
+ return AddressInstance(
+ self._version, payload, account_sid=self._solution["account_sid"]
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
+
+
+class AddressList(ListResource):
+
+ def __init__(self, version: Version, account_sid: str):
+ """
+ Initialize the AddressList
+
+ :param version: Version that contains the resource
+ :param account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that is responsible for the Address resource to read.
+
+ """
+ super().__init__(version)
+
+ # Path Solution
+ self._solution = {
+ "account_sid": account_sid,
+ }
+ self._uri = "/Accounts/{account_sid}/Addresses.json".format(**self._solution)
+
+ def create(
+ self,
+ customer_name: str,
+ street: str,
+ city: str,
+ region: str,
+ postal_code: str,
+ iso_country: str,
+ friendly_name: Union[str, object] = values.unset,
+ emergency_enabled: Union[bool, object] = values.unset,
+ auto_correct_address: Union[bool, object] = values.unset,
+ street_secondary: Union[str, object] = values.unset,
+ ) -> AddressInstance:
+ """
+ Create the AddressInstance
+
+ :param customer_name: The name to associate with the new address.
+ :param street: The number and street address of the new address.
+ :param city: The city of the new address.
+ :param region: The state or region of the new address.
+ :param postal_code: The postal code of the new address.
+ :param iso_country: The ISO country code of the new address.
+ :param friendly_name: A descriptive string that you create to describe the new address. It can be up to 64 characters long.
+ :param emergency_enabled: Whether to enable emergency calling on the new address. Can be: `true` or `false`.
+ :param auto_correct_address: Whether we should automatically correct the address. Can be: `true` or `false` and the default is `true`. If empty or `true`, we will correct the address you provide if necessary. If `false`, we won't alter the address you provide.
+ :param street_secondary: The additional number and street address of the address.
+
+ :returns: The created AddressInstance
+ """
+
+ data = values.of(
+ {
+ "CustomerName": customer_name,
+ "Street": street,
+ "City": city,
+ "Region": region,
+ "PostalCode": postal_code,
+ "IsoCountry": iso_country,
+ "FriendlyName": friendly_name,
+ "EmergencyEnabled": serialize.boolean_to_string(emergency_enabled),
+ "AutoCorrectAddress": serialize.boolean_to_string(auto_correct_address),
+ "StreetSecondary": street_secondary,
+ }
+ )
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.create(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return AddressInstance(
+ self._version, payload, account_sid=self._solution["account_sid"]
+ )
+
+ async def create_async(
+ self,
+ customer_name: str,
+ street: str,
+ city: str,
+ region: str,
+ postal_code: str,
+ iso_country: str,
+ friendly_name: Union[str, object] = values.unset,
+ emergency_enabled: Union[bool, object] = values.unset,
+ auto_correct_address: Union[bool, object] = values.unset,
+ street_secondary: Union[str, object] = values.unset,
+ ) -> AddressInstance:
+ """
+ Asynchronously create the AddressInstance
+
+ :param customer_name: The name to associate with the new address.
+ :param street: The number and street address of the new address.
+ :param city: The city of the new address.
+ :param region: The state or region of the new address.
+ :param postal_code: The postal code of the new address.
+ :param iso_country: The ISO country code of the new address.
+ :param friendly_name: A descriptive string that you create to describe the new address. It can be up to 64 characters long.
+ :param emergency_enabled: Whether to enable emergency calling on the new address. Can be: `true` or `false`.
+ :param auto_correct_address: Whether we should automatically correct the address. Can be: `true` or `false` and the default is `true`. If empty or `true`, we will correct the address you provide if necessary. If `false`, we won't alter the address you provide.
+ :param street_secondary: The additional number and street address of the address.
+
+ :returns: The created AddressInstance
+ """
+
+ data = values.of(
+ {
+ "CustomerName": customer_name,
+ "Street": street,
+ "City": city,
+ "Region": region,
+ "PostalCode": postal_code,
+ "IsoCountry": iso_country,
+ "FriendlyName": friendly_name,
+ "EmergencyEnabled": serialize.boolean_to_string(emergency_enabled),
+ "AutoCorrectAddress": serialize.boolean_to_string(auto_correct_address),
+ "StreetSecondary": street_secondary,
+ }
+ )
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.create_async(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return AddressInstance(
+ self._version, payload, account_sid=self._solution["account_sid"]
+ )
+
+ def stream(
+ self,
+ customer_name: Union[str, object] = values.unset,
+ friendly_name: Union[str, object] = values.unset,
+ emergency_enabled: Union[bool, object] = values.unset,
+ iso_country: Union[str, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> Iterator[AddressInstance]:
+ """
+ Streams AddressInstance records from the API as a generator stream.
+ This operation lazily loads records as efficiently as possible until the limit
+ is reached.
+ The results are returned as a generator, so this operation is memory efficient.
+
+ :param str customer_name: The `customer_name` of the Address resources to read.
+ :param str friendly_name: The string that identifies the Address resources to read.
+ :param bool emergency_enabled: Whether the address can be associated to a number for emergency calling.
+ :param str iso_country: The ISO country code of the Address resources to read.
+ :param limit: Upper limit for the number of records to return. stream()
+ guarantees to never return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, stream() will attempt to read the
+ limit with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: Generator that will yield up to limit results
+ """
+ limits = self._version.read_limits(limit, page_size)
+ page = self.page(
+ customer_name=customer_name,
+ friendly_name=friendly_name,
+ emergency_enabled=emergency_enabled,
+ iso_country=iso_country,
+ page_size=limits["page_size"],
+ )
+
+ return self._version.stream(page, limits["limit"])
+
+ async def stream_async(
+ self,
+ customer_name: Union[str, object] = values.unset,
+ friendly_name: Union[str, object] = values.unset,
+ emergency_enabled: Union[bool, object] = values.unset,
+ iso_country: Union[str, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> AsyncIterator[AddressInstance]:
+ """
+ Asynchronously streams AddressInstance records from the API as a generator stream.
+ This operation lazily loads records as efficiently as possible until the limit
+ is reached.
+ The results are returned as a generator, so this operation is memory efficient.
+
+ :param str customer_name: The `customer_name` of the Address resources to read.
+ :param str friendly_name: The string that identifies the Address resources to read.
+ :param bool emergency_enabled: Whether the address can be associated to a number for emergency calling.
+ :param str iso_country: The ISO country code of the Address resources to read.
+ :param limit: Upper limit for the number of records to return. stream()
+ guarantees to never return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, stream() will attempt to read the
+ limit with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: Generator that will yield up to limit results
+ """
+ limits = self._version.read_limits(limit, page_size)
+ page = await self.page_async(
+ customer_name=customer_name,
+ friendly_name=friendly_name,
+ emergency_enabled=emergency_enabled,
+ iso_country=iso_country,
+ page_size=limits["page_size"],
+ )
+
+ return self._version.stream_async(page, limits["limit"])
+
+ def list(
+ self,
+ customer_name: Union[str, object] = values.unset,
+ friendly_name: Union[str, object] = values.unset,
+ emergency_enabled: Union[bool, object] = values.unset,
+ iso_country: Union[str, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> List[AddressInstance]:
+ """
+ Lists AddressInstance records from the API as a list.
+ Unlike stream(), this operation is eager and will load `limit` records into
+ memory before returning.
+
+ :param str customer_name: The `customer_name` of the Address resources to read.
+ :param str friendly_name: The string that identifies the Address resources to read.
+ :param bool emergency_enabled: Whether the address can be associated to a number for emergency calling.
+ :param str iso_country: The ISO country code of the Address resources to read.
+ :param limit: Upper limit for the number of records to return. list() guarantees
+ never to return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, list() will attempt to read the limit
+ with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: list that will contain up to limit results
+ """
+ return list(
+ self.stream(
+ customer_name=customer_name,
+ friendly_name=friendly_name,
+ emergency_enabled=emergency_enabled,
+ iso_country=iso_country,
+ limit=limit,
+ page_size=page_size,
+ )
+ )
+
+ async def list_async(
+ self,
+ customer_name: Union[str, object] = values.unset,
+ friendly_name: Union[str, object] = values.unset,
+ emergency_enabled: Union[bool, object] = values.unset,
+ iso_country: Union[str, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> List[AddressInstance]:
+ """
+ Asynchronously lists AddressInstance records from the API as a list.
+ Unlike stream(), this operation is eager and will load `limit` records into
+ memory before returning.
+
+ :param str customer_name: The `customer_name` of the Address resources to read.
+ :param str friendly_name: The string that identifies the Address resources to read.
+ :param bool emergency_enabled: Whether the address can be associated to a number for emergency calling.
+ :param str iso_country: The ISO country code of the Address resources to read.
+ :param limit: Upper limit for the number of records to return. list() guarantees
+ never to return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, list() will attempt to read the limit
+ with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: list that will contain up to limit results
+ """
+ return [
+ record
+ async for record in await self.stream_async(
+ customer_name=customer_name,
+ friendly_name=friendly_name,
+ emergency_enabled=emergency_enabled,
+ iso_country=iso_country,
+ limit=limit,
+ page_size=page_size,
+ )
+ ]
+
+ def page(
+ self,
+ customer_name: Union[str, object] = values.unset,
+ friendly_name: Union[str, object] = values.unset,
+ emergency_enabled: Union[bool, object] = values.unset,
+ iso_country: Union[str, object] = values.unset,
+ page_token: Union[str, object] = values.unset,
+ page_number: Union[int, object] = values.unset,
+ page_size: Union[int, object] = values.unset,
+ ) -> AddressPage:
+ """
+ Retrieve a single page of AddressInstance records from the API.
+ Request is executed immediately
+
+ :param customer_name: The `customer_name` of the Address resources to read.
+ :param friendly_name: The string that identifies the Address resources to read.
+ :param emergency_enabled: Whether the address can be associated to a number for emergency calling.
+ :param iso_country: The ISO country code of the Address resources to read.
+ :param page_token: PageToken provided by the API
+ :param page_number: Page Number, this value is simply for client state
+ :param page_size: Number of records to return, defaults to 50
+
+ :returns: Page of AddressInstance
+ """
+ data = values.of(
+ {
+ "CustomerName": customer_name,
+ "FriendlyName": friendly_name,
+ "EmergencyEnabled": serialize.boolean_to_string(emergency_enabled),
+ "IsoCountry": iso_country,
+ "PageToken": page_token,
+ "Page": page_number,
+ "PageSize": page_size,
+ }
+ )
+
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ response = self._version.page(
+ method="GET", uri=self._uri, params=data, headers=headers
+ )
+ return AddressPage(self._version, response, self._solution)
+
+ async def page_async(
+ self,
+ customer_name: Union[str, object] = values.unset,
+ friendly_name: Union[str, object] = values.unset,
+ emergency_enabled: Union[bool, object] = values.unset,
+ iso_country: Union[str, object] = values.unset,
+ page_token: Union[str, object] = values.unset,
+ page_number: Union[int, object] = values.unset,
+ page_size: Union[int, object] = values.unset,
+ ) -> AddressPage:
+ """
+ Asynchronously retrieve a single page of AddressInstance records from the API.
+ Request is executed immediately
+
+ :param customer_name: The `customer_name` of the Address resources to read.
+ :param friendly_name: The string that identifies the Address resources to read.
+ :param emergency_enabled: Whether the address can be associated to a number for emergency calling.
+ :param iso_country: The ISO country code of the Address resources to read.
+ :param page_token: PageToken provided by the API
+ :param page_number: Page Number, this value is simply for client state
+ :param page_size: Number of records to return, defaults to 50
+
+ :returns: Page of AddressInstance
+ """
+ data = values.of(
+ {
+ "CustomerName": customer_name,
+ "FriendlyName": friendly_name,
+ "EmergencyEnabled": serialize.boolean_to_string(emergency_enabled),
+ "IsoCountry": iso_country,
+ "PageToken": page_token,
+ "Page": page_number,
+ "PageSize": page_size,
+ }
+ )
+
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ response = await self._version.page_async(
+ method="GET", uri=self._uri, params=data, headers=headers
+ )
+ return AddressPage(self._version, response, self._solution)
+
+ def get_page(self, target_url: str) -> AddressPage:
+ """
+ Retrieve a specific page of AddressInstance records from the API.
+ Request is executed immediately
+
+ :param target_url: API-generated URL for the requested results page
+
+ :returns: Page of AddressInstance
+ """
+ response = self._version.domain.twilio.request("GET", target_url)
+ return AddressPage(self._version, response, self._solution)
+
+ async def get_page_async(self, target_url: str) -> AddressPage:
+ """
+ Asynchronously retrieve a specific page of AddressInstance records from the API.
+ Request is executed immediately
+
+ :param target_url: API-generated URL for the requested results page
+
+ :returns: Page of AddressInstance
+ """
+ response = await self._version.domain.twilio.request_async("GET", target_url)
+ return AddressPage(self._version, response, self._solution)
+
+ def get(self, sid: str) -> AddressContext:
+ """
+ Constructs a AddressContext
+
+ :param sid: The Twilio-provided string that uniquely identifies the Address resource to update.
+ """
+ return AddressContext(
+ self._version, account_sid=self._solution["account_sid"], sid=sid
+ )
+
+ def __call__(self, sid: str) -> AddressContext:
+ """
+ Constructs a AddressContext
+
+ :param sid: The Twilio-provided string that uniquely identifies the Address resource to update.
+ """
+ return AddressContext(
+ self._version, account_sid=self._solution["account_sid"], sid=sid
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/address/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/api/v2010/account/address/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 00000000..589d1646
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/api/v2010/account/address/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/address/__pycache__/dependent_phone_number.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/api/v2010/account/address/__pycache__/dependent_phone_number.cpython-312.pyc
new file mode 100644
index 00000000..2e34a8ec
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/api/v2010/account/address/__pycache__/dependent_phone_number.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/address/dependent_phone_number.py b/venv/Lib/site-packages/twilio/rest/api/v2010/account/address/dependent_phone_number.py
new file mode 100644
index 00000000..504e69bc
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/api/v2010/account/address/dependent_phone_number.py
@@ -0,0 +1,374 @@
+r"""
+ This code was generated by
+ ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __
+ | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/
+ | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \
+
+ Twilio - Api
+ This is the public Twilio REST API.
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ https://openapi-generator.tech
+ Do not edit the class manually.
+"""
+
+from datetime import datetime
+from typing import Any, Dict, List, Optional, Union, Iterator, AsyncIterator
+from twilio.base import deserialize, values
+
+from twilio.base.instance_resource import InstanceResource
+from twilio.base.list_resource import ListResource
+from twilio.base.version import Version
+from twilio.base.page import Page
+
+
+class DependentPhoneNumberInstance(InstanceResource):
+
+ class AddressRequirement(object):
+ NONE = "none"
+ ANY = "any"
+ LOCAL = "local"
+ FOREIGN = "foreign"
+
+ class EmergencyStatus(object):
+ ACTIVE = "Active"
+ INACTIVE = "Inactive"
+
+ """
+ :ivar sid: The unique string that that we created to identify the DependentPhoneNumber resource.
+ :ivar account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that created the DependentPhoneNumber resource.
+ :ivar friendly_name: The string that you assigned to describe the resource.
+ :ivar phone_number: The phone number in [E.164](https://www.twilio.com/docs/glossary/what-e164) format, which consists of a + followed by the country code and subscriber number.
+ :ivar voice_url: The URL we call when the phone number receives a call. The `voice_url` will not be used if a `voice_application_sid` or a `trunk_sid` is set.
+ :ivar voice_method: The HTTP method we use to call `voice_url`. Can be: `GET` or `POST`.
+ :ivar voice_fallback_method: The HTTP method we use to call `voice_fallback_url`. Can be: `GET` or `POST`.
+ :ivar voice_fallback_url: The URL that we call when an error occurs retrieving or executing the TwiML requested by `url`.
+ :ivar voice_caller_id_lookup: Whether we look up the caller's caller-ID name from the CNAM database. Can be: `true` or `false`. Caller ID lookups can cost $0.01 each.
+ :ivar date_created: The date and time in GMT that the resource was created specified in [RFC 2822](https://www.ietf.org/rfc/rfc2822.txt) format.
+ :ivar date_updated: The date and time in GMT that the resource was last updated specified in [RFC 2822](https://www.ietf.org/rfc/rfc2822.txt) format.
+ :ivar sms_fallback_method: The HTTP method we use to call `sms_fallback_url`. Can be: `GET` or `POST`.
+ :ivar sms_fallback_url: The URL that we call when an error occurs while retrieving or executing the TwiML from `sms_url`.
+ :ivar sms_method: The HTTP method we use to call `sms_url`. Can be: `GET` or `POST`.
+ :ivar sms_url: The URL we call when the phone number receives an incoming SMS message.
+ :ivar address_requirements:
+ :ivar capabilities: The set of Boolean properties that indicates whether a phone number can receive calls or messages. Capabilities are `Voice`, `SMS`, and `MMS` and each capability can be: `true` or `false`.
+ :ivar status_callback: The URL we call using the `status_callback_method` to send status information to your application.
+ :ivar status_callback_method: The HTTP method we use to call `status_callback`. Can be: `GET` or `POST`.
+ :ivar api_version: The API version used to start a new TwiML session.
+ :ivar sms_application_sid: The SID of the application that handles SMS messages sent to the phone number. If an `sms_application_sid` is present, we ignore all `sms_*_url` values and use those of the application.
+ :ivar voice_application_sid: The SID of the application that handles calls to the phone number. If a `voice_application_sid` is present, we ignore all of the voice urls and use those set on the application. Setting a `voice_application_sid` will automatically delete your `trunk_sid` and vice versa.
+ :ivar trunk_sid: The SID of the Trunk that handles calls to the phone number. If a `trunk_sid` is present, we ignore all of the voice urls and voice applications and use those set on the Trunk. Setting a `trunk_sid` will automatically delete your `voice_application_sid` and vice versa.
+ :ivar emergency_status:
+ :ivar emergency_address_sid: The SID of the emergency address configuration that we use for emergency calling from the phone number.
+ :ivar uri: The URI of the resource, relative to `https://api.twilio.com`.
+ """
+
+ def __init__(
+ self,
+ version: Version,
+ payload: Dict[str, Any],
+ account_sid: str,
+ address_sid: str,
+ ):
+ super().__init__(version)
+
+ self.sid: Optional[str] = payload.get("sid")
+ self.account_sid: Optional[str] = payload.get("account_sid")
+ self.friendly_name: Optional[str] = payload.get("friendly_name")
+ self.phone_number: Optional[str] = payload.get("phone_number")
+ self.voice_url: Optional[str] = payload.get("voice_url")
+ self.voice_method: Optional[str] = payload.get("voice_method")
+ self.voice_fallback_method: Optional[str] = payload.get("voice_fallback_method")
+ self.voice_fallback_url: Optional[str] = payload.get("voice_fallback_url")
+ self.voice_caller_id_lookup: Optional[bool] = payload.get(
+ "voice_caller_id_lookup"
+ )
+ self.date_created: Optional[datetime] = deserialize.rfc2822_datetime(
+ payload.get("date_created")
+ )
+ self.date_updated: Optional[datetime] = deserialize.rfc2822_datetime(
+ payload.get("date_updated")
+ )
+ self.sms_fallback_method: Optional[str] = payload.get("sms_fallback_method")
+ self.sms_fallback_url: Optional[str] = payload.get("sms_fallback_url")
+ self.sms_method: Optional[str] = payload.get("sms_method")
+ self.sms_url: Optional[str] = payload.get("sms_url")
+ self.address_requirements: Optional[
+ "DependentPhoneNumberInstance.AddressRequirement"
+ ] = payload.get("address_requirements")
+ self.capabilities: Optional[Dict[str, object]] = payload.get("capabilities")
+ self.status_callback: Optional[str] = payload.get("status_callback")
+ self.status_callback_method: Optional[str] = payload.get(
+ "status_callback_method"
+ )
+ self.api_version: Optional[str] = payload.get("api_version")
+ self.sms_application_sid: Optional[str] = payload.get("sms_application_sid")
+ self.voice_application_sid: Optional[str] = payload.get("voice_application_sid")
+ self.trunk_sid: Optional[str] = payload.get("trunk_sid")
+ self.emergency_status: Optional[
+ "DependentPhoneNumberInstance.EmergencyStatus"
+ ] = payload.get("emergency_status")
+ self.emergency_address_sid: Optional[str] = payload.get("emergency_address_sid")
+ self.uri: Optional[str] = payload.get("uri")
+
+ self._solution = {
+ "account_sid": account_sid,
+ "address_sid": address_sid,
+ }
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(context)
+
+
+class DependentPhoneNumberPage(Page):
+
+ def get_instance(self, payload: Dict[str, Any]) -> DependentPhoneNumberInstance:
+ """
+ Build an instance of DependentPhoneNumberInstance
+
+ :param payload: Payload response from the API
+ """
+ return DependentPhoneNumberInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ address_sid=self._solution["address_sid"],
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
+
+
+class DependentPhoneNumberList(ListResource):
+
+ def __init__(self, version: Version, account_sid: str, address_sid: str):
+ """
+ Initialize the DependentPhoneNumberList
+
+ :param version: Version that contains the resource
+ :param account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that created the DependentPhoneNumber resources to read.
+ :param address_sid: The SID of the Address resource associated with the phone number.
+
+ """
+ super().__init__(version)
+
+ # Path Solution
+ self._solution = {
+ "account_sid": account_sid,
+ "address_sid": address_sid,
+ }
+ self._uri = "/Accounts/{account_sid}/Addresses/{address_sid}/DependentPhoneNumbers.json".format(
+ **self._solution
+ )
+
+ def stream(
+ self,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> Iterator[DependentPhoneNumberInstance]:
+ """
+ Streams DependentPhoneNumberInstance records from the API as a generator stream.
+ This operation lazily loads records as efficiently as possible until the limit
+ is reached.
+ The results are returned as a generator, so this operation is memory efficient.
+
+ :param limit: Upper limit for the number of records to return. stream()
+ guarantees to never return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, stream() will attempt to read the
+ limit with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: Generator that will yield up to limit results
+ """
+ limits = self._version.read_limits(limit, page_size)
+ page = self.page(page_size=limits["page_size"])
+
+ return self._version.stream(page, limits["limit"])
+
+ async def stream_async(
+ self,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> AsyncIterator[DependentPhoneNumberInstance]:
+ """
+ Asynchronously streams DependentPhoneNumberInstance records from the API as a generator stream.
+ This operation lazily loads records as efficiently as possible until the limit
+ is reached.
+ The results are returned as a generator, so this operation is memory efficient.
+
+ :param limit: Upper limit for the number of records to return. stream()
+ guarantees to never return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, stream() will attempt to read the
+ limit with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: Generator that will yield up to limit results
+ """
+ limits = self._version.read_limits(limit, page_size)
+ page = await self.page_async(page_size=limits["page_size"])
+
+ return self._version.stream_async(page, limits["limit"])
+
+ def list(
+ self,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> List[DependentPhoneNumberInstance]:
+ """
+ Lists DependentPhoneNumberInstance records from the API as a list.
+ Unlike stream(), this operation is eager and will load `limit` records into
+ memory before returning.
+
+ :param limit: Upper limit for the number of records to return. list() guarantees
+ never to return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, list() will attempt to read the limit
+ with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: list that will contain up to limit results
+ """
+ return list(
+ self.stream(
+ limit=limit,
+ page_size=page_size,
+ )
+ )
+
+ async def list_async(
+ self,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> List[DependentPhoneNumberInstance]:
+ """
+ Asynchronously lists DependentPhoneNumberInstance records from the API as a list.
+ Unlike stream(), this operation is eager and will load `limit` records into
+ memory before returning.
+
+ :param limit: Upper limit for the number of records to return. list() guarantees
+ never to return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, list() will attempt to read the limit
+ with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: list that will contain up to limit results
+ """
+ return [
+ record
+ async for record in await self.stream_async(
+ limit=limit,
+ page_size=page_size,
+ )
+ ]
+
+ def page(
+ self,
+ page_token: Union[str, object] = values.unset,
+ page_number: Union[int, object] = values.unset,
+ page_size: Union[int, object] = values.unset,
+ ) -> DependentPhoneNumberPage:
+ """
+ Retrieve a single page of DependentPhoneNumberInstance records from the API.
+ Request is executed immediately
+
+ :param page_token: PageToken provided by the API
+ :param page_number: Page Number, this value is simply for client state
+ :param page_size: Number of records to return, defaults to 50
+
+ :returns: Page of DependentPhoneNumberInstance
+ """
+ data = values.of(
+ {
+ "PageToken": page_token,
+ "Page": page_number,
+ "PageSize": page_size,
+ }
+ )
+
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ response = self._version.page(
+ method="GET", uri=self._uri, params=data, headers=headers
+ )
+ return DependentPhoneNumberPage(self._version, response, self._solution)
+
+ async def page_async(
+ self,
+ page_token: Union[str, object] = values.unset,
+ page_number: Union[int, object] = values.unset,
+ page_size: Union[int, object] = values.unset,
+ ) -> DependentPhoneNumberPage:
+ """
+ Asynchronously retrieve a single page of DependentPhoneNumberInstance records from the API.
+ Request is executed immediately
+
+ :param page_token: PageToken provided by the API
+ :param page_number: Page Number, this value is simply for client state
+ :param page_size: Number of records to return, defaults to 50
+
+ :returns: Page of DependentPhoneNumberInstance
+ """
+ data = values.of(
+ {
+ "PageToken": page_token,
+ "Page": page_number,
+ "PageSize": page_size,
+ }
+ )
+
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ response = await self._version.page_async(
+ method="GET", uri=self._uri, params=data, headers=headers
+ )
+ return DependentPhoneNumberPage(self._version, response, self._solution)
+
+ def get_page(self, target_url: str) -> DependentPhoneNumberPage:
+ """
+ Retrieve a specific page of DependentPhoneNumberInstance records from the API.
+ Request is executed immediately
+
+ :param target_url: API-generated URL for the requested results page
+
+ :returns: Page of DependentPhoneNumberInstance
+ """
+ response = self._version.domain.twilio.request("GET", target_url)
+ return DependentPhoneNumberPage(self._version, response, self._solution)
+
+ async def get_page_async(self, target_url: str) -> DependentPhoneNumberPage:
+ """
+ Asynchronously retrieve a specific page of DependentPhoneNumberInstance records from the API.
+ Request is executed immediately
+
+ :param target_url: API-generated URL for the requested results page
+
+ :returns: Page of DependentPhoneNumberInstance
+ """
+ response = await self._version.domain.twilio.request_async("GET", target_url)
+ return DependentPhoneNumberPage(self._version, response, self._solution)
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/application.py b/venv/Lib/site-packages/twilio/rest/api/v2010/account/application.py
new file mode 100644
index 00000000..555ab72b
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/api/v2010/account/application.py
@@ -0,0 +1,984 @@
+r"""
+ This code was generated by
+ ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __
+ | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/
+ | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \
+
+ Twilio - Api
+ This is the public Twilio REST API.
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ https://openapi-generator.tech
+ Do not edit the class manually.
+"""
+
+from datetime import datetime
+from typing import Any, Dict, List, Optional, Union, Iterator, AsyncIterator
+from twilio.base import deserialize, serialize, values
+from twilio.base.instance_context import InstanceContext
+from twilio.base.instance_resource import InstanceResource
+from twilio.base.list_resource import ListResource
+from twilio.base.version import Version
+from twilio.base.page import Page
+
+
+class ApplicationInstance(InstanceResource):
+ """
+ :ivar account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that created the Application resource.
+ :ivar api_version: The API version used to start a new TwiML session.
+ :ivar date_created: The date and time in GMT that the resource was created specified in [RFC 2822](https://www.ietf.org/rfc/rfc2822.txt) format.
+ :ivar date_updated: The date and time in GMT that the resource was last updated specified in [RFC 2822](https://www.ietf.org/rfc/rfc2822.txt) format.
+ :ivar friendly_name: The string that you assigned to describe the resource.
+ :ivar message_status_callback: The URL we call using a POST method to send message status information to your application.
+ :ivar sid: The unique string that that we created to identify the Application resource.
+ :ivar sms_fallback_method: The HTTP method we use to call `sms_fallback_url`. Can be: `GET` or `POST`.
+ :ivar sms_fallback_url: The URL that we call when an error occurs while retrieving or executing the TwiML from `sms_url`.
+ :ivar sms_method: The HTTP method we use to call `sms_url`. Can be: `GET` or `POST`.
+ :ivar sms_status_callback: The URL we call using a POST method to send status information to your application about SMS messages that refer to the application.
+ :ivar sms_url: The URL we call when the phone number receives an incoming SMS message.
+ :ivar status_callback: The URL we call using the `status_callback_method` to send status information to your application.
+ :ivar status_callback_method: The HTTP method we use to call `status_callback`. Can be: `GET` or `POST`.
+ :ivar uri: The URI of the resource, relative to `https://api.twilio.com`.
+ :ivar voice_caller_id_lookup: Whether we look up the caller's caller-ID name from the CNAM database (additional charges apply). Can be: `true` or `false`.
+ :ivar voice_fallback_method: The HTTP method we use to call `voice_fallback_url`. Can be: `GET` or `POST`.
+ :ivar voice_fallback_url: The URL that we call when an error occurs retrieving or executing the TwiML requested by `url`.
+ :ivar voice_method: The HTTP method we use to call `voice_url`. Can be: `GET` or `POST`.
+ :ivar voice_url: The URL we call when the phone number assigned to this application receives a call.
+ :ivar public_application_connect_enabled: Whether to allow other Twilio accounts to dial this applicaton using Dial verb. Can be: `true` or `false`.
+ """
+
+ def __init__(
+ self,
+ version: Version,
+ payload: Dict[str, Any],
+ account_sid: str,
+ sid: Optional[str] = None,
+ ):
+ super().__init__(version)
+
+ self.account_sid: Optional[str] = payload.get("account_sid")
+ self.api_version: Optional[str] = payload.get("api_version")
+ self.date_created: Optional[datetime] = deserialize.rfc2822_datetime(
+ payload.get("date_created")
+ )
+ self.date_updated: Optional[datetime] = deserialize.rfc2822_datetime(
+ payload.get("date_updated")
+ )
+ self.friendly_name: Optional[str] = payload.get("friendly_name")
+ self.message_status_callback: Optional[str] = payload.get(
+ "message_status_callback"
+ )
+ self.sid: Optional[str] = payload.get("sid")
+ self.sms_fallback_method: Optional[str] = payload.get("sms_fallback_method")
+ self.sms_fallback_url: Optional[str] = payload.get("sms_fallback_url")
+ self.sms_method: Optional[str] = payload.get("sms_method")
+ self.sms_status_callback: Optional[str] = payload.get("sms_status_callback")
+ self.sms_url: Optional[str] = payload.get("sms_url")
+ self.status_callback: Optional[str] = payload.get("status_callback")
+ self.status_callback_method: Optional[str] = payload.get(
+ "status_callback_method"
+ )
+ self.uri: Optional[str] = payload.get("uri")
+ self.voice_caller_id_lookup: Optional[bool] = payload.get(
+ "voice_caller_id_lookup"
+ )
+ self.voice_fallback_method: Optional[str] = payload.get("voice_fallback_method")
+ self.voice_fallback_url: Optional[str] = payload.get("voice_fallback_url")
+ self.voice_method: Optional[str] = payload.get("voice_method")
+ self.voice_url: Optional[str] = payload.get("voice_url")
+ self.public_application_connect_enabled: Optional[bool] = payload.get(
+ "public_application_connect_enabled"
+ )
+
+ self._solution = {
+ "account_sid": account_sid,
+ "sid": sid or self.sid,
+ }
+ self._context: Optional[ApplicationContext] = None
+
+ @property
+ def _proxy(self) -> "ApplicationContext":
+ """
+ Generate an instance context for the instance, the context is capable of
+ performing various actions. All instance actions are proxied to the context
+
+ :returns: ApplicationContext for this ApplicationInstance
+ """
+ if self._context is None:
+ self._context = ApplicationContext(
+ self._version,
+ account_sid=self._solution["account_sid"],
+ sid=self._solution["sid"],
+ )
+ return self._context
+
+ def delete(self) -> bool:
+ """
+ Deletes the ApplicationInstance
+
+
+ :returns: True if delete succeeds, False otherwise
+ """
+ return self._proxy.delete()
+
+ async def delete_async(self) -> bool:
+ """
+ Asynchronous coroutine that deletes the ApplicationInstance
+
+
+ :returns: True if delete succeeds, False otherwise
+ """
+ return await self._proxy.delete_async()
+
+ def fetch(self) -> "ApplicationInstance":
+ """
+ Fetch the ApplicationInstance
+
+
+ :returns: The fetched ApplicationInstance
+ """
+ return self._proxy.fetch()
+
+ async def fetch_async(self) -> "ApplicationInstance":
+ """
+ Asynchronous coroutine to fetch the ApplicationInstance
+
+
+ :returns: The fetched ApplicationInstance
+ """
+ return await self._proxy.fetch_async()
+
+ def update(
+ self,
+ friendly_name: Union[str, object] = values.unset,
+ api_version: Union[str, object] = values.unset,
+ voice_url: Union[str, object] = values.unset,
+ voice_method: Union[str, object] = values.unset,
+ voice_fallback_url: Union[str, object] = values.unset,
+ voice_fallback_method: Union[str, object] = values.unset,
+ status_callback: Union[str, object] = values.unset,
+ status_callback_method: Union[str, object] = values.unset,
+ voice_caller_id_lookup: Union[bool, object] = values.unset,
+ sms_url: Union[str, object] = values.unset,
+ sms_method: Union[str, object] = values.unset,
+ sms_fallback_url: Union[str, object] = values.unset,
+ sms_fallback_method: Union[str, object] = values.unset,
+ sms_status_callback: Union[str, object] = values.unset,
+ message_status_callback: Union[str, object] = values.unset,
+ public_application_connect_enabled: Union[bool, object] = values.unset,
+ ) -> "ApplicationInstance":
+ """
+ Update the ApplicationInstance
+
+ :param friendly_name: A descriptive string that you create to describe the resource. It can be up to 64 characters long.
+ :param api_version: The API version to use to start a new TwiML session. Can be: `2010-04-01` or `2008-08-01`. The default value is your account's default API version.
+ :param voice_url: The URL we should call when the phone number assigned to this application receives a call.
+ :param voice_method: The HTTP method we should use to call `voice_url`. Can be: `GET` or `POST`.
+ :param voice_fallback_url: The URL that we should call when an error occurs retrieving or executing the TwiML requested by `url`.
+ :param voice_fallback_method: The HTTP method we should use to call `voice_fallback_url`. Can be: `GET` or `POST`.
+ :param status_callback: The URL we should call using the `status_callback_method` to send status information to your application.
+ :param status_callback_method: The HTTP method we should use to call `status_callback`. Can be: `GET` or `POST`.
+ :param voice_caller_id_lookup: Whether we should look up the caller's caller-ID name from the CNAM database (additional charges apply). Can be: `true` or `false`.
+ :param sms_url: The URL we should call when the phone number receives an incoming SMS message.
+ :param sms_method: The HTTP method we should use to call `sms_url`. Can be: `GET` or `POST`.
+ :param sms_fallback_url: The URL that we should call when an error occurs while retrieving or executing the TwiML from `sms_url`.
+ :param sms_fallback_method: The HTTP method we should use to call `sms_fallback_url`. Can be: `GET` or `POST`.
+ :param sms_status_callback: Same as message_status_callback: The URL we should call using a POST method to send status information about SMS messages sent by the application. Deprecated, included for backwards compatibility.
+ :param message_status_callback: The URL we should call using a POST method to send message status information to your application.
+ :param public_application_connect_enabled: Whether to allow other Twilio accounts to dial this applicaton using Dial verb. Can be: `true` or `false`.
+
+ :returns: The updated ApplicationInstance
+ """
+ return self._proxy.update(
+ friendly_name=friendly_name,
+ api_version=api_version,
+ voice_url=voice_url,
+ voice_method=voice_method,
+ voice_fallback_url=voice_fallback_url,
+ voice_fallback_method=voice_fallback_method,
+ status_callback=status_callback,
+ status_callback_method=status_callback_method,
+ voice_caller_id_lookup=voice_caller_id_lookup,
+ sms_url=sms_url,
+ sms_method=sms_method,
+ sms_fallback_url=sms_fallback_url,
+ sms_fallback_method=sms_fallback_method,
+ sms_status_callback=sms_status_callback,
+ message_status_callback=message_status_callback,
+ public_application_connect_enabled=public_application_connect_enabled,
+ )
+
+ async def update_async(
+ self,
+ friendly_name: Union[str, object] = values.unset,
+ api_version: Union[str, object] = values.unset,
+ voice_url: Union[str, object] = values.unset,
+ voice_method: Union[str, object] = values.unset,
+ voice_fallback_url: Union[str, object] = values.unset,
+ voice_fallback_method: Union[str, object] = values.unset,
+ status_callback: Union[str, object] = values.unset,
+ status_callback_method: Union[str, object] = values.unset,
+ voice_caller_id_lookup: Union[bool, object] = values.unset,
+ sms_url: Union[str, object] = values.unset,
+ sms_method: Union[str, object] = values.unset,
+ sms_fallback_url: Union[str, object] = values.unset,
+ sms_fallback_method: Union[str, object] = values.unset,
+ sms_status_callback: Union[str, object] = values.unset,
+ message_status_callback: Union[str, object] = values.unset,
+ public_application_connect_enabled: Union[bool, object] = values.unset,
+ ) -> "ApplicationInstance":
+ """
+ Asynchronous coroutine to update the ApplicationInstance
+
+ :param friendly_name: A descriptive string that you create to describe the resource. It can be up to 64 characters long.
+ :param api_version: The API version to use to start a new TwiML session. Can be: `2010-04-01` or `2008-08-01`. The default value is your account's default API version.
+ :param voice_url: The URL we should call when the phone number assigned to this application receives a call.
+ :param voice_method: The HTTP method we should use to call `voice_url`. Can be: `GET` or `POST`.
+ :param voice_fallback_url: The URL that we should call when an error occurs retrieving or executing the TwiML requested by `url`.
+ :param voice_fallback_method: The HTTP method we should use to call `voice_fallback_url`. Can be: `GET` or `POST`.
+ :param status_callback: The URL we should call using the `status_callback_method` to send status information to your application.
+ :param status_callback_method: The HTTP method we should use to call `status_callback`. Can be: `GET` or `POST`.
+ :param voice_caller_id_lookup: Whether we should look up the caller's caller-ID name from the CNAM database (additional charges apply). Can be: `true` or `false`.
+ :param sms_url: The URL we should call when the phone number receives an incoming SMS message.
+ :param sms_method: The HTTP method we should use to call `sms_url`. Can be: `GET` or `POST`.
+ :param sms_fallback_url: The URL that we should call when an error occurs while retrieving or executing the TwiML from `sms_url`.
+ :param sms_fallback_method: The HTTP method we should use to call `sms_fallback_url`. Can be: `GET` or `POST`.
+ :param sms_status_callback: Same as message_status_callback: The URL we should call using a POST method to send status information about SMS messages sent by the application. Deprecated, included for backwards compatibility.
+ :param message_status_callback: The URL we should call using a POST method to send message status information to your application.
+ :param public_application_connect_enabled: Whether to allow other Twilio accounts to dial this applicaton using Dial verb. Can be: `true` or `false`.
+
+ :returns: The updated ApplicationInstance
+ """
+ return await self._proxy.update_async(
+ friendly_name=friendly_name,
+ api_version=api_version,
+ voice_url=voice_url,
+ voice_method=voice_method,
+ voice_fallback_url=voice_fallback_url,
+ voice_fallback_method=voice_fallback_method,
+ status_callback=status_callback,
+ status_callback_method=status_callback_method,
+ voice_caller_id_lookup=voice_caller_id_lookup,
+ sms_url=sms_url,
+ sms_method=sms_method,
+ sms_fallback_url=sms_fallback_url,
+ sms_fallback_method=sms_fallback_method,
+ sms_status_callback=sms_status_callback,
+ message_status_callback=message_status_callback,
+ public_application_connect_enabled=public_application_connect_enabled,
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(context)
+
+
+class ApplicationContext(InstanceContext):
+
+ def __init__(self, version: Version, account_sid: str, sid: str):
+ """
+ Initialize the ApplicationContext
+
+ :param version: Version that contains the resource
+ :param account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that created the Application resources to update.
+ :param sid: The Twilio-provided string that uniquely identifies the Application resource to update.
+ """
+ super().__init__(version)
+
+ # Path Solution
+ self._solution = {
+ "account_sid": account_sid,
+ "sid": sid,
+ }
+ self._uri = "/Accounts/{account_sid}/Applications/{sid}.json".format(
+ **self._solution
+ )
+
+ def delete(self) -> bool:
+ """
+ Deletes the ApplicationInstance
+
+
+ :returns: True if delete succeeds, False otherwise
+ """
+
+ headers = values.of({})
+
+ return self._version.delete(method="DELETE", uri=self._uri, headers=headers)
+
+ async def delete_async(self) -> bool:
+ """
+ Asynchronous coroutine that deletes the ApplicationInstance
+
+
+ :returns: True if delete succeeds, False otherwise
+ """
+
+ headers = values.of({})
+
+ return await self._version.delete_async(
+ method="DELETE", uri=self._uri, headers=headers
+ )
+
+ def fetch(self) -> ApplicationInstance:
+ """
+ Fetch the ApplicationInstance
+
+
+ :returns: The fetched ApplicationInstance
+ """
+
+ headers = values.of({})
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.fetch(method="GET", uri=self._uri, headers=headers)
+
+ return ApplicationInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ sid=self._solution["sid"],
+ )
+
+ async def fetch_async(self) -> ApplicationInstance:
+ """
+ Asynchronous coroutine to fetch the ApplicationInstance
+
+
+ :returns: The fetched ApplicationInstance
+ """
+
+ headers = values.of({})
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.fetch_async(
+ method="GET", uri=self._uri, headers=headers
+ )
+
+ return ApplicationInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ sid=self._solution["sid"],
+ )
+
+ def update(
+ self,
+ friendly_name: Union[str, object] = values.unset,
+ api_version: Union[str, object] = values.unset,
+ voice_url: Union[str, object] = values.unset,
+ voice_method: Union[str, object] = values.unset,
+ voice_fallback_url: Union[str, object] = values.unset,
+ voice_fallback_method: Union[str, object] = values.unset,
+ status_callback: Union[str, object] = values.unset,
+ status_callback_method: Union[str, object] = values.unset,
+ voice_caller_id_lookup: Union[bool, object] = values.unset,
+ sms_url: Union[str, object] = values.unset,
+ sms_method: Union[str, object] = values.unset,
+ sms_fallback_url: Union[str, object] = values.unset,
+ sms_fallback_method: Union[str, object] = values.unset,
+ sms_status_callback: Union[str, object] = values.unset,
+ message_status_callback: Union[str, object] = values.unset,
+ public_application_connect_enabled: Union[bool, object] = values.unset,
+ ) -> ApplicationInstance:
+ """
+ Update the ApplicationInstance
+
+ :param friendly_name: A descriptive string that you create to describe the resource. It can be up to 64 characters long.
+ :param api_version: The API version to use to start a new TwiML session. Can be: `2010-04-01` or `2008-08-01`. The default value is your account's default API version.
+ :param voice_url: The URL we should call when the phone number assigned to this application receives a call.
+ :param voice_method: The HTTP method we should use to call `voice_url`. Can be: `GET` or `POST`.
+ :param voice_fallback_url: The URL that we should call when an error occurs retrieving or executing the TwiML requested by `url`.
+ :param voice_fallback_method: The HTTP method we should use to call `voice_fallback_url`. Can be: `GET` or `POST`.
+ :param status_callback: The URL we should call using the `status_callback_method` to send status information to your application.
+ :param status_callback_method: The HTTP method we should use to call `status_callback`. Can be: `GET` or `POST`.
+ :param voice_caller_id_lookup: Whether we should look up the caller's caller-ID name from the CNAM database (additional charges apply). Can be: `true` or `false`.
+ :param sms_url: The URL we should call when the phone number receives an incoming SMS message.
+ :param sms_method: The HTTP method we should use to call `sms_url`. Can be: `GET` or `POST`.
+ :param sms_fallback_url: The URL that we should call when an error occurs while retrieving or executing the TwiML from `sms_url`.
+ :param sms_fallback_method: The HTTP method we should use to call `sms_fallback_url`. Can be: `GET` or `POST`.
+ :param sms_status_callback: Same as message_status_callback: The URL we should call using a POST method to send status information about SMS messages sent by the application. Deprecated, included for backwards compatibility.
+ :param message_status_callback: The URL we should call using a POST method to send message status information to your application.
+ :param public_application_connect_enabled: Whether to allow other Twilio accounts to dial this applicaton using Dial verb. Can be: `true` or `false`.
+
+ :returns: The updated ApplicationInstance
+ """
+
+ data = values.of(
+ {
+ "FriendlyName": friendly_name,
+ "ApiVersion": api_version,
+ "VoiceUrl": voice_url,
+ "VoiceMethod": voice_method,
+ "VoiceFallbackUrl": voice_fallback_url,
+ "VoiceFallbackMethod": voice_fallback_method,
+ "StatusCallback": status_callback,
+ "StatusCallbackMethod": status_callback_method,
+ "VoiceCallerIdLookup": serialize.boolean_to_string(
+ voice_caller_id_lookup
+ ),
+ "SmsUrl": sms_url,
+ "SmsMethod": sms_method,
+ "SmsFallbackUrl": sms_fallback_url,
+ "SmsFallbackMethod": sms_fallback_method,
+ "SmsStatusCallback": sms_status_callback,
+ "MessageStatusCallback": message_status_callback,
+ "PublicApplicationConnectEnabled": serialize.boolean_to_string(
+ public_application_connect_enabled
+ ),
+ }
+ )
+ headers = values.of({})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.update(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return ApplicationInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ sid=self._solution["sid"],
+ )
+
+ async def update_async(
+ self,
+ friendly_name: Union[str, object] = values.unset,
+ api_version: Union[str, object] = values.unset,
+ voice_url: Union[str, object] = values.unset,
+ voice_method: Union[str, object] = values.unset,
+ voice_fallback_url: Union[str, object] = values.unset,
+ voice_fallback_method: Union[str, object] = values.unset,
+ status_callback: Union[str, object] = values.unset,
+ status_callback_method: Union[str, object] = values.unset,
+ voice_caller_id_lookup: Union[bool, object] = values.unset,
+ sms_url: Union[str, object] = values.unset,
+ sms_method: Union[str, object] = values.unset,
+ sms_fallback_url: Union[str, object] = values.unset,
+ sms_fallback_method: Union[str, object] = values.unset,
+ sms_status_callback: Union[str, object] = values.unset,
+ message_status_callback: Union[str, object] = values.unset,
+ public_application_connect_enabled: Union[bool, object] = values.unset,
+ ) -> ApplicationInstance:
+ """
+ Asynchronous coroutine to update the ApplicationInstance
+
+ :param friendly_name: A descriptive string that you create to describe the resource. It can be up to 64 characters long.
+ :param api_version: The API version to use to start a new TwiML session. Can be: `2010-04-01` or `2008-08-01`. The default value is your account's default API version.
+ :param voice_url: The URL we should call when the phone number assigned to this application receives a call.
+ :param voice_method: The HTTP method we should use to call `voice_url`. Can be: `GET` or `POST`.
+ :param voice_fallback_url: The URL that we should call when an error occurs retrieving or executing the TwiML requested by `url`.
+ :param voice_fallback_method: The HTTP method we should use to call `voice_fallback_url`. Can be: `GET` or `POST`.
+ :param status_callback: The URL we should call using the `status_callback_method` to send status information to your application.
+ :param status_callback_method: The HTTP method we should use to call `status_callback`. Can be: `GET` or `POST`.
+ :param voice_caller_id_lookup: Whether we should look up the caller's caller-ID name from the CNAM database (additional charges apply). Can be: `true` or `false`.
+ :param sms_url: The URL we should call when the phone number receives an incoming SMS message.
+ :param sms_method: The HTTP method we should use to call `sms_url`. Can be: `GET` or `POST`.
+ :param sms_fallback_url: The URL that we should call when an error occurs while retrieving or executing the TwiML from `sms_url`.
+ :param sms_fallback_method: The HTTP method we should use to call `sms_fallback_url`. Can be: `GET` or `POST`.
+ :param sms_status_callback: Same as message_status_callback: The URL we should call using a POST method to send status information about SMS messages sent by the application. Deprecated, included for backwards compatibility.
+ :param message_status_callback: The URL we should call using a POST method to send message status information to your application.
+ :param public_application_connect_enabled: Whether to allow other Twilio accounts to dial this applicaton using Dial verb. Can be: `true` or `false`.
+
+ :returns: The updated ApplicationInstance
+ """
+
+ data = values.of(
+ {
+ "FriendlyName": friendly_name,
+ "ApiVersion": api_version,
+ "VoiceUrl": voice_url,
+ "VoiceMethod": voice_method,
+ "VoiceFallbackUrl": voice_fallback_url,
+ "VoiceFallbackMethod": voice_fallback_method,
+ "StatusCallback": status_callback,
+ "StatusCallbackMethod": status_callback_method,
+ "VoiceCallerIdLookup": serialize.boolean_to_string(
+ voice_caller_id_lookup
+ ),
+ "SmsUrl": sms_url,
+ "SmsMethod": sms_method,
+ "SmsFallbackUrl": sms_fallback_url,
+ "SmsFallbackMethod": sms_fallback_method,
+ "SmsStatusCallback": sms_status_callback,
+ "MessageStatusCallback": message_status_callback,
+ "PublicApplicationConnectEnabled": serialize.boolean_to_string(
+ public_application_connect_enabled
+ ),
+ }
+ )
+ headers = values.of({})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.update_async(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return ApplicationInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ sid=self._solution["sid"],
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(context)
+
+
+class ApplicationPage(Page):
+
+ def get_instance(self, payload: Dict[str, Any]) -> ApplicationInstance:
+ """
+ Build an instance of ApplicationInstance
+
+ :param payload: Payload response from the API
+ """
+ return ApplicationInstance(
+ self._version, payload, account_sid=self._solution["account_sid"]
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
+
+
+class ApplicationList(ListResource):
+
+ def __init__(self, version: Version, account_sid: str):
+ """
+ Initialize the ApplicationList
+
+ :param version: Version that contains the resource
+ :param account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that created the Application resources to read.
+
+ """
+ super().__init__(version)
+
+ # Path Solution
+ self._solution = {
+ "account_sid": account_sid,
+ }
+ self._uri = "/Accounts/{account_sid}/Applications.json".format(**self._solution)
+
+ def create(
+ self,
+ api_version: Union[str, object] = values.unset,
+ voice_url: Union[str, object] = values.unset,
+ voice_method: Union[str, object] = values.unset,
+ voice_fallback_url: Union[str, object] = values.unset,
+ voice_fallback_method: Union[str, object] = values.unset,
+ status_callback: Union[str, object] = values.unset,
+ status_callback_method: Union[str, object] = values.unset,
+ voice_caller_id_lookup: Union[bool, object] = values.unset,
+ sms_url: Union[str, object] = values.unset,
+ sms_method: Union[str, object] = values.unset,
+ sms_fallback_url: Union[str, object] = values.unset,
+ sms_fallback_method: Union[str, object] = values.unset,
+ sms_status_callback: Union[str, object] = values.unset,
+ message_status_callback: Union[str, object] = values.unset,
+ friendly_name: Union[str, object] = values.unset,
+ public_application_connect_enabled: Union[bool, object] = values.unset,
+ ) -> ApplicationInstance:
+ """
+ Create the ApplicationInstance
+
+ :param api_version: The API version to use to start a new TwiML session. Can be: `2010-04-01` or `2008-08-01`. The default value is the account's default API version.
+ :param voice_url: The URL we should call when the phone number assigned to this application receives a call.
+ :param voice_method: The HTTP method we should use to call `voice_url`. Can be: `GET` or `POST`.
+ :param voice_fallback_url: The URL that we should call when an error occurs retrieving or executing the TwiML requested by `url`.
+ :param voice_fallback_method: The HTTP method we should use to call `voice_fallback_url`. Can be: `GET` or `POST`.
+ :param status_callback: The URL we should call using the `status_callback_method` to send status information to your application.
+ :param status_callback_method: The HTTP method we should use to call `status_callback`. Can be: `GET` or `POST`.
+ :param voice_caller_id_lookup: Whether we should look up the caller's caller-ID name from the CNAM database (additional charges apply). Can be: `true` or `false`.
+ :param sms_url: The URL we should call when the phone number receives an incoming SMS message.
+ :param sms_method: The HTTP method we should use to call `sms_url`. Can be: `GET` or `POST`.
+ :param sms_fallback_url: The URL that we should call when an error occurs while retrieving or executing the TwiML from `sms_url`.
+ :param sms_fallback_method: The HTTP method we should use to call `sms_fallback_url`. Can be: `GET` or `POST`.
+ :param sms_status_callback: The URL we should call using a POST method to send status information about SMS messages sent by the application.
+ :param message_status_callback: The URL we should call using a POST method to send message status information to your application.
+ :param friendly_name: A descriptive string that you create to describe the new application. It can be up to 64 characters long.
+ :param public_application_connect_enabled: Whether to allow other Twilio accounts to dial this applicaton using Dial verb. Can be: `true` or `false`.
+
+ :returns: The created ApplicationInstance
+ """
+
+ data = values.of(
+ {
+ "ApiVersion": api_version,
+ "VoiceUrl": voice_url,
+ "VoiceMethod": voice_method,
+ "VoiceFallbackUrl": voice_fallback_url,
+ "VoiceFallbackMethod": voice_fallback_method,
+ "StatusCallback": status_callback,
+ "StatusCallbackMethod": status_callback_method,
+ "VoiceCallerIdLookup": serialize.boolean_to_string(
+ voice_caller_id_lookup
+ ),
+ "SmsUrl": sms_url,
+ "SmsMethod": sms_method,
+ "SmsFallbackUrl": sms_fallback_url,
+ "SmsFallbackMethod": sms_fallback_method,
+ "SmsStatusCallback": sms_status_callback,
+ "MessageStatusCallback": message_status_callback,
+ "FriendlyName": friendly_name,
+ "PublicApplicationConnectEnabled": serialize.boolean_to_string(
+ public_application_connect_enabled
+ ),
+ }
+ )
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.create(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return ApplicationInstance(
+ self._version, payload, account_sid=self._solution["account_sid"]
+ )
+
+ async def create_async(
+ self,
+ api_version: Union[str, object] = values.unset,
+ voice_url: Union[str, object] = values.unset,
+ voice_method: Union[str, object] = values.unset,
+ voice_fallback_url: Union[str, object] = values.unset,
+ voice_fallback_method: Union[str, object] = values.unset,
+ status_callback: Union[str, object] = values.unset,
+ status_callback_method: Union[str, object] = values.unset,
+ voice_caller_id_lookup: Union[bool, object] = values.unset,
+ sms_url: Union[str, object] = values.unset,
+ sms_method: Union[str, object] = values.unset,
+ sms_fallback_url: Union[str, object] = values.unset,
+ sms_fallback_method: Union[str, object] = values.unset,
+ sms_status_callback: Union[str, object] = values.unset,
+ message_status_callback: Union[str, object] = values.unset,
+ friendly_name: Union[str, object] = values.unset,
+ public_application_connect_enabled: Union[bool, object] = values.unset,
+ ) -> ApplicationInstance:
+ """
+ Asynchronously create the ApplicationInstance
+
+ :param api_version: The API version to use to start a new TwiML session. Can be: `2010-04-01` or `2008-08-01`. The default value is the account's default API version.
+ :param voice_url: The URL we should call when the phone number assigned to this application receives a call.
+ :param voice_method: The HTTP method we should use to call `voice_url`. Can be: `GET` or `POST`.
+ :param voice_fallback_url: The URL that we should call when an error occurs retrieving or executing the TwiML requested by `url`.
+ :param voice_fallback_method: The HTTP method we should use to call `voice_fallback_url`. Can be: `GET` or `POST`.
+ :param status_callback: The URL we should call using the `status_callback_method` to send status information to your application.
+ :param status_callback_method: The HTTP method we should use to call `status_callback`. Can be: `GET` or `POST`.
+ :param voice_caller_id_lookup: Whether we should look up the caller's caller-ID name from the CNAM database (additional charges apply). Can be: `true` or `false`.
+ :param sms_url: The URL we should call when the phone number receives an incoming SMS message.
+ :param sms_method: The HTTP method we should use to call `sms_url`. Can be: `GET` or `POST`.
+ :param sms_fallback_url: The URL that we should call when an error occurs while retrieving or executing the TwiML from `sms_url`.
+ :param sms_fallback_method: The HTTP method we should use to call `sms_fallback_url`. Can be: `GET` or `POST`.
+ :param sms_status_callback: The URL we should call using a POST method to send status information about SMS messages sent by the application.
+ :param message_status_callback: The URL we should call using a POST method to send message status information to your application.
+ :param friendly_name: A descriptive string that you create to describe the new application. It can be up to 64 characters long.
+ :param public_application_connect_enabled: Whether to allow other Twilio accounts to dial this applicaton using Dial verb. Can be: `true` or `false`.
+
+ :returns: The created ApplicationInstance
+ """
+
+ data = values.of(
+ {
+ "ApiVersion": api_version,
+ "VoiceUrl": voice_url,
+ "VoiceMethod": voice_method,
+ "VoiceFallbackUrl": voice_fallback_url,
+ "VoiceFallbackMethod": voice_fallback_method,
+ "StatusCallback": status_callback,
+ "StatusCallbackMethod": status_callback_method,
+ "VoiceCallerIdLookup": serialize.boolean_to_string(
+ voice_caller_id_lookup
+ ),
+ "SmsUrl": sms_url,
+ "SmsMethod": sms_method,
+ "SmsFallbackUrl": sms_fallback_url,
+ "SmsFallbackMethod": sms_fallback_method,
+ "SmsStatusCallback": sms_status_callback,
+ "MessageStatusCallback": message_status_callback,
+ "FriendlyName": friendly_name,
+ "PublicApplicationConnectEnabled": serialize.boolean_to_string(
+ public_application_connect_enabled
+ ),
+ }
+ )
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.create_async(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return ApplicationInstance(
+ self._version, payload, account_sid=self._solution["account_sid"]
+ )
+
+ def stream(
+ self,
+ friendly_name: Union[str, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> Iterator[ApplicationInstance]:
+ """
+ Streams ApplicationInstance records from the API as a generator stream.
+ This operation lazily loads records as efficiently as possible until the limit
+ is reached.
+ The results are returned as a generator, so this operation is memory efficient.
+
+ :param str friendly_name: The string that identifies the Application resources to read.
+ :param limit: Upper limit for the number of records to return. stream()
+ guarantees to never return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, stream() will attempt to read the
+ limit with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: Generator that will yield up to limit results
+ """
+ limits = self._version.read_limits(limit, page_size)
+ page = self.page(friendly_name=friendly_name, page_size=limits["page_size"])
+
+ return self._version.stream(page, limits["limit"])
+
+ async def stream_async(
+ self,
+ friendly_name: Union[str, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> AsyncIterator[ApplicationInstance]:
+ """
+ Asynchronously streams ApplicationInstance records from the API as a generator stream.
+ This operation lazily loads records as efficiently as possible until the limit
+ is reached.
+ The results are returned as a generator, so this operation is memory efficient.
+
+ :param str friendly_name: The string that identifies the Application resources to read.
+ :param limit: Upper limit for the number of records to return. stream()
+ guarantees to never return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, stream() will attempt to read the
+ limit with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: Generator that will yield up to limit results
+ """
+ limits = self._version.read_limits(limit, page_size)
+ page = await self.page_async(
+ friendly_name=friendly_name, page_size=limits["page_size"]
+ )
+
+ return self._version.stream_async(page, limits["limit"])
+
+ def list(
+ self,
+ friendly_name: Union[str, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> List[ApplicationInstance]:
+ """
+ Lists ApplicationInstance records from the API as a list.
+ Unlike stream(), this operation is eager and will load `limit` records into
+ memory before returning.
+
+ :param str friendly_name: The string that identifies the Application resources to read.
+ :param limit: Upper limit for the number of records to return. list() guarantees
+ never to return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, list() will attempt to read the limit
+ with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: list that will contain up to limit results
+ """
+ return list(
+ self.stream(
+ friendly_name=friendly_name,
+ limit=limit,
+ page_size=page_size,
+ )
+ )
+
+ async def list_async(
+ self,
+ friendly_name: Union[str, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> List[ApplicationInstance]:
+ """
+ Asynchronously lists ApplicationInstance records from the API as a list.
+ Unlike stream(), this operation is eager and will load `limit` records into
+ memory before returning.
+
+ :param str friendly_name: The string that identifies the Application resources to read.
+ :param limit: Upper limit for the number of records to return. list() guarantees
+ never to return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, list() will attempt to read the limit
+ with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: list that will contain up to limit results
+ """
+ return [
+ record
+ async for record in await self.stream_async(
+ friendly_name=friendly_name,
+ limit=limit,
+ page_size=page_size,
+ )
+ ]
+
+ def page(
+ self,
+ friendly_name: Union[str, object] = values.unset,
+ page_token: Union[str, object] = values.unset,
+ page_number: Union[int, object] = values.unset,
+ page_size: Union[int, object] = values.unset,
+ ) -> ApplicationPage:
+ """
+ Retrieve a single page of ApplicationInstance records from the API.
+ Request is executed immediately
+
+ :param friendly_name: The string that identifies the Application resources to read.
+ :param page_token: PageToken provided by the API
+ :param page_number: Page Number, this value is simply for client state
+ :param page_size: Number of records to return, defaults to 50
+
+ :returns: Page of ApplicationInstance
+ """
+ data = values.of(
+ {
+ "FriendlyName": friendly_name,
+ "PageToken": page_token,
+ "Page": page_number,
+ "PageSize": page_size,
+ }
+ )
+
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ response = self._version.page(
+ method="GET", uri=self._uri, params=data, headers=headers
+ )
+ return ApplicationPage(self._version, response, self._solution)
+
+ async def page_async(
+ self,
+ friendly_name: Union[str, object] = values.unset,
+ page_token: Union[str, object] = values.unset,
+ page_number: Union[int, object] = values.unset,
+ page_size: Union[int, object] = values.unset,
+ ) -> ApplicationPage:
+ """
+ Asynchronously retrieve a single page of ApplicationInstance records from the API.
+ Request is executed immediately
+
+ :param friendly_name: The string that identifies the Application resources to read.
+ :param page_token: PageToken provided by the API
+ :param page_number: Page Number, this value is simply for client state
+ :param page_size: Number of records to return, defaults to 50
+
+ :returns: Page of ApplicationInstance
+ """
+ data = values.of(
+ {
+ "FriendlyName": friendly_name,
+ "PageToken": page_token,
+ "Page": page_number,
+ "PageSize": page_size,
+ }
+ )
+
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ response = await self._version.page_async(
+ method="GET", uri=self._uri, params=data, headers=headers
+ )
+ return ApplicationPage(self._version, response, self._solution)
+
+ def get_page(self, target_url: str) -> ApplicationPage:
+ """
+ Retrieve a specific page of ApplicationInstance records from the API.
+ Request is executed immediately
+
+ :param target_url: API-generated URL for the requested results page
+
+ :returns: Page of ApplicationInstance
+ """
+ response = self._version.domain.twilio.request("GET", target_url)
+ return ApplicationPage(self._version, response, self._solution)
+
+ async def get_page_async(self, target_url: str) -> ApplicationPage:
+ """
+ Asynchronously retrieve a specific page of ApplicationInstance records from the API.
+ Request is executed immediately
+
+ :param target_url: API-generated URL for the requested results page
+
+ :returns: Page of ApplicationInstance
+ """
+ response = await self._version.domain.twilio.request_async("GET", target_url)
+ return ApplicationPage(self._version, response, self._solution)
+
+ def get(self, sid: str) -> ApplicationContext:
+ """
+ Constructs a ApplicationContext
+
+ :param sid: The Twilio-provided string that uniquely identifies the Application resource to update.
+ """
+ return ApplicationContext(
+ self._version, account_sid=self._solution["account_sid"], sid=sid
+ )
+
+ def __call__(self, sid: str) -> ApplicationContext:
+ """
+ Constructs a ApplicationContext
+
+ :param sid: The Twilio-provided string that uniquely identifies the Application resource to update.
+ """
+ return ApplicationContext(
+ self._version, account_sid=self._solution["account_sid"], sid=sid
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/authorized_connect_app.py b/venv/Lib/site-packages/twilio/rest/api/v2010/account/authorized_connect_app.py
new file mode 100644
index 00000000..cceb694c
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/api/v2010/account/authorized_connect_app.py
@@ -0,0 +1,458 @@
+r"""
+ This code was generated by
+ ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __
+ | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/
+ | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \
+
+ Twilio - Api
+ This is the public Twilio REST API.
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ https://openapi-generator.tech
+ Do not edit the class manually.
+"""
+
+from typing import Any, Dict, List, Optional, Union, Iterator, AsyncIterator
+from twilio.base import values
+from twilio.base.instance_context import InstanceContext
+from twilio.base.instance_resource import InstanceResource
+from twilio.base.list_resource import ListResource
+from twilio.base.version import Version
+from twilio.base.page import Page
+
+
+class AuthorizedConnectAppInstance(InstanceResource):
+
+ class Permission(object):
+ GET_ALL = "get-all"
+ POST_ALL = "post-all"
+
+ """
+ :ivar account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that created the AuthorizedConnectApp resource.
+ :ivar connect_app_company_name: The company name set for the Connect App.
+ :ivar connect_app_description: A detailed description of the Connect App.
+ :ivar connect_app_friendly_name: The name of the Connect App.
+ :ivar connect_app_homepage_url: The public URL for the Connect App.
+ :ivar connect_app_sid: The SID that we assigned to the Connect App.
+ :ivar permissions: The set of permissions that you authorized for the Connect App. Can be: `get-all` or `post-all`.
+ :ivar uri: The URI of the resource, relative to `https://api.twilio.com`.
+ """
+
+ def __init__(
+ self,
+ version: Version,
+ payload: Dict[str, Any],
+ account_sid: str,
+ connect_app_sid: Optional[str] = None,
+ ):
+ super().__init__(version)
+
+ self.account_sid: Optional[str] = payload.get("account_sid")
+ self.connect_app_company_name: Optional[str] = payload.get(
+ "connect_app_company_name"
+ )
+ self.connect_app_description: Optional[str] = payload.get(
+ "connect_app_description"
+ )
+ self.connect_app_friendly_name: Optional[str] = payload.get(
+ "connect_app_friendly_name"
+ )
+ self.connect_app_homepage_url: Optional[str] = payload.get(
+ "connect_app_homepage_url"
+ )
+ self.connect_app_sid: Optional[str] = payload.get("connect_app_sid")
+ self.permissions: Optional[List["AuthorizedConnectAppInstance.Permission"]] = (
+ payload.get("permissions")
+ )
+ self.uri: Optional[str] = payload.get("uri")
+
+ self._solution = {
+ "account_sid": account_sid,
+ "connect_app_sid": connect_app_sid or self.connect_app_sid,
+ }
+ self._context: Optional[AuthorizedConnectAppContext] = None
+
+ @property
+ def _proxy(self) -> "AuthorizedConnectAppContext":
+ """
+ Generate an instance context for the instance, the context is capable of
+ performing various actions. All instance actions are proxied to the context
+
+ :returns: AuthorizedConnectAppContext for this AuthorizedConnectAppInstance
+ """
+ if self._context is None:
+ self._context = AuthorizedConnectAppContext(
+ self._version,
+ account_sid=self._solution["account_sid"],
+ connect_app_sid=self._solution["connect_app_sid"],
+ )
+ return self._context
+
+ def fetch(self) -> "AuthorizedConnectAppInstance":
+ """
+ Fetch the AuthorizedConnectAppInstance
+
+
+ :returns: The fetched AuthorizedConnectAppInstance
+ """
+ return self._proxy.fetch()
+
+ async def fetch_async(self) -> "AuthorizedConnectAppInstance":
+ """
+ Asynchronous coroutine to fetch the AuthorizedConnectAppInstance
+
+
+ :returns: The fetched AuthorizedConnectAppInstance
+ """
+ return await self._proxy.fetch_async()
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(context)
+
+
+class AuthorizedConnectAppContext(InstanceContext):
+
+ def __init__(self, version: Version, account_sid: str, connect_app_sid: str):
+ """
+ Initialize the AuthorizedConnectAppContext
+
+ :param version: Version that contains the resource
+ :param account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that created the AuthorizedConnectApp resource to fetch.
+ :param connect_app_sid: The SID of the Connect App to fetch.
+ """
+ super().__init__(version)
+
+ # Path Solution
+ self._solution = {
+ "account_sid": account_sid,
+ "connect_app_sid": connect_app_sid,
+ }
+ self._uri = "/Accounts/{account_sid}/AuthorizedConnectApps/{connect_app_sid}.json".format(
+ **self._solution
+ )
+
+ def fetch(self) -> AuthorizedConnectAppInstance:
+ """
+ Fetch the AuthorizedConnectAppInstance
+
+
+ :returns: The fetched AuthorizedConnectAppInstance
+ """
+
+ headers = values.of({})
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.fetch(method="GET", uri=self._uri, headers=headers)
+
+ return AuthorizedConnectAppInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ connect_app_sid=self._solution["connect_app_sid"],
+ )
+
+ async def fetch_async(self) -> AuthorizedConnectAppInstance:
+ """
+ Asynchronous coroutine to fetch the AuthorizedConnectAppInstance
+
+
+ :returns: The fetched AuthorizedConnectAppInstance
+ """
+
+ headers = values.of({})
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.fetch_async(
+ method="GET", uri=self._uri, headers=headers
+ )
+
+ return AuthorizedConnectAppInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ connect_app_sid=self._solution["connect_app_sid"],
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(context)
+
+
+class AuthorizedConnectAppPage(Page):
+
+ def get_instance(self, payload: Dict[str, Any]) -> AuthorizedConnectAppInstance:
+ """
+ Build an instance of AuthorizedConnectAppInstance
+
+ :param payload: Payload response from the API
+ """
+ return AuthorizedConnectAppInstance(
+ self._version, payload, account_sid=self._solution["account_sid"]
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
+
+
+class AuthorizedConnectAppList(ListResource):
+
+ def __init__(self, version: Version, account_sid: str):
+ """
+ Initialize the AuthorizedConnectAppList
+
+ :param version: Version that contains the resource
+ :param account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that created the AuthorizedConnectApp resources to read.
+
+ """
+ super().__init__(version)
+
+ # Path Solution
+ self._solution = {
+ "account_sid": account_sid,
+ }
+ self._uri = "/Accounts/{account_sid}/AuthorizedConnectApps.json".format(
+ **self._solution
+ )
+
+ def stream(
+ self,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> Iterator[AuthorizedConnectAppInstance]:
+ """
+ Streams AuthorizedConnectAppInstance records from the API as a generator stream.
+ This operation lazily loads records as efficiently as possible until the limit
+ is reached.
+ The results are returned as a generator, so this operation is memory efficient.
+
+ :param limit: Upper limit for the number of records to return. stream()
+ guarantees to never return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, stream() will attempt to read the
+ limit with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: Generator that will yield up to limit results
+ """
+ limits = self._version.read_limits(limit, page_size)
+ page = self.page(page_size=limits["page_size"])
+
+ return self._version.stream(page, limits["limit"])
+
+ async def stream_async(
+ self,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> AsyncIterator[AuthorizedConnectAppInstance]:
+ """
+ Asynchronously streams AuthorizedConnectAppInstance records from the API as a generator stream.
+ This operation lazily loads records as efficiently as possible until the limit
+ is reached.
+ The results are returned as a generator, so this operation is memory efficient.
+
+ :param limit: Upper limit for the number of records to return. stream()
+ guarantees to never return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, stream() will attempt to read the
+ limit with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: Generator that will yield up to limit results
+ """
+ limits = self._version.read_limits(limit, page_size)
+ page = await self.page_async(page_size=limits["page_size"])
+
+ return self._version.stream_async(page, limits["limit"])
+
+ def list(
+ self,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> List[AuthorizedConnectAppInstance]:
+ """
+ Lists AuthorizedConnectAppInstance records from the API as a list.
+ Unlike stream(), this operation is eager and will load `limit` records into
+ memory before returning.
+
+ :param limit: Upper limit for the number of records to return. list() guarantees
+ never to return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, list() will attempt to read the limit
+ with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: list that will contain up to limit results
+ """
+ return list(
+ self.stream(
+ limit=limit,
+ page_size=page_size,
+ )
+ )
+
+ async def list_async(
+ self,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> List[AuthorizedConnectAppInstance]:
+ """
+ Asynchronously lists AuthorizedConnectAppInstance records from the API as a list.
+ Unlike stream(), this operation is eager and will load `limit` records into
+ memory before returning.
+
+ :param limit: Upper limit for the number of records to return. list() guarantees
+ never to return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, list() will attempt to read the limit
+ with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: list that will contain up to limit results
+ """
+ return [
+ record
+ async for record in await self.stream_async(
+ limit=limit,
+ page_size=page_size,
+ )
+ ]
+
+ def page(
+ self,
+ page_token: Union[str, object] = values.unset,
+ page_number: Union[int, object] = values.unset,
+ page_size: Union[int, object] = values.unset,
+ ) -> AuthorizedConnectAppPage:
+ """
+ Retrieve a single page of AuthorizedConnectAppInstance records from the API.
+ Request is executed immediately
+
+ :param page_token: PageToken provided by the API
+ :param page_number: Page Number, this value is simply for client state
+ :param page_size: Number of records to return, defaults to 50
+
+ :returns: Page of AuthorizedConnectAppInstance
+ """
+ data = values.of(
+ {
+ "PageToken": page_token,
+ "Page": page_number,
+ "PageSize": page_size,
+ }
+ )
+
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ response = self._version.page(
+ method="GET", uri=self._uri, params=data, headers=headers
+ )
+ return AuthorizedConnectAppPage(self._version, response, self._solution)
+
+ async def page_async(
+ self,
+ page_token: Union[str, object] = values.unset,
+ page_number: Union[int, object] = values.unset,
+ page_size: Union[int, object] = values.unset,
+ ) -> AuthorizedConnectAppPage:
+ """
+ Asynchronously retrieve a single page of AuthorizedConnectAppInstance records from the API.
+ Request is executed immediately
+
+ :param page_token: PageToken provided by the API
+ :param page_number: Page Number, this value is simply for client state
+ :param page_size: Number of records to return, defaults to 50
+
+ :returns: Page of AuthorizedConnectAppInstance
+ """
+ data = values.of(
+ {
+ "PageToken": page_token,
+ "Page": page_number,
+ "PageSize": page_size,
+ }
+ )
+
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ response = await self._version.page_async(
+ method="GET", uri=self._uri, params=data, headers=headers
+ )
+ return AuthorizedConnectAppPage(self._version, response, self._solution)
+
+ def get_page(self, target_url: str) -> AuthorizedConnectAppPage:
+ """
+ Retrieve a specific page of AuthorizedConnectAppInstance records from the API.
+ Request is executed immediately
+
+ :param target_url: API-generated URL for the requested results page
+
+ :returns: Page of AuthorizedConnectAppInstance
+ """
+ response = self._version.domain.twilio.request("GET", target_url)
+ return AuthorizedConnectAppPage(self._version, response, self._solution)
+
+ async def get_page_async(self, target_url: str) -> AuthorizedConnectAppPage:
+ """
+ Asynchronously retrieve a specific page of AuthorizedConnectAppInstance records from the API.
+ Request is executed immediately
+
+ :param target_url: API-generated URL for the requested results page
+
+ :returns: Page of AuthorizedConnectAppInstance
+ """
+ response = await self._version.domain.twilio.request_async("GET", target_url)
+ return AuthorizedConnectAppPage(self._version, response, self._solution)
+
+ def get(self, connect_app_sid: str) -> AuthorizedConnectAppContext:
+ """
+ Constructs a AuthorizedConnectAppContext
+
+ :param connect_app_sid: The SID of the Connect App to fetch.
+ """
+ return AuthorizedConnectAppContext(
+ self._version,
+ account_sid=self._solution["account_sid"],
+ connect_app_sid=connect_app_sid,
+ )
+
+ def __call__(self, connect_app_sid: str) -> AuthorizedConnectAppContext:
+ """
+ Constructs a AuthorizedConnectAppContext
+
+ :param connect_app_sid: The SID of the Connect App to fetch.
+ """
+ return AuthorizedConnectAppContext(
+ self._version,
+ account_sid=self._solution["account_sid"],
+ connect_app_sid=connect_app_sid,
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/__init__.py b/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/__init__.py
new file mode 100644
index 00000000..fc2a6f06
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/__init__.py
@@ -0,0 +1,612 @@
+r"""
+ This code was generated by
+ ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __
+ | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/
+ | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \
+
+ Twilio - Api
+ This is the public Twilio REST API.
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ https://openapi-generator.tech
+ Do not edit the class manually.
+"""
+
+from typing import Any, Dict, List, Optional, Union, Iterator, AsyncIterator
+from twilio.base import values
+from twilio.base.instance_context import InstanceContext
+from twilio.base.instance_resource import InstanceResource
+from twilio.base.list_resource import ListResource
+from twilio.base.version import Version
+from twilio.base.page import Page
+from twilio.rest.api.v2010.account.available_phone_number_country.local import LocalList
+from twilio.rest.api.v2010.account.available_phone_number_country.machine_to_machine import (
+ MachineToMachineList,
+)
+from twilio.rest.api.v2010.account.available_phone_number_country.mobile import (
+ MobileList,
+)
+from twilio.rest.api.v2010.account.available_phone_number_country.national import (
+ NationalList,
+)
+from twilio.rest.api.v2010.account.available_phone_number_country.shared_cost import (
+ SharedCostList,
+)
+from twilio.rest.api.v2010.account.available_phone_number_country.toll_free import (
+ TollFreeList,
+)
+from twilio.rest.api.v2010.account.available_phone_number_country.voip import VoipList
+
+
+class AvailablePhoneNumberCountryInstance(InstanceResource):
+ """
+ :ivar country_code: The [ISO-3166-1](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code of the country.
+ :ivar country: The name of the country.
+ :ivar uri: The URI of the Country resource, relative to `https://api.twilio.com`.
+ :ivar beta: Whether all phone numbers available in the country are new to the Twilio platform. `true` if they are and `false` if all numbers are not in the Twilio Phone Number Beta program.
+ :ivar subresource_uris: A list of related AvailablePhoneNumber resources identified by their URIs relative to `https://api.twilio.com`.
+ """
+
+ def __init__(
+ self,
+ version: Version,
+ payload: Dict[str, Any],
+ account_sid: str,
+ country_code: Optional[str] = None,
+ ):
+ super().__init__(version)
+
+ self.country_code: Optional[str] = payload.get("country_code")
+ self.country: Optional[str] = payload.get("country")
+ self.uri: Optional[str] = payload.get("uri")
+ self.beta: Optional[bool] = payload.get("beta")
+ self.subresource_uris: Optional[Dict[str, object]] = payload.get(
+ "subresource_uris"
+ )
+
+ self._solution = {
+ "account_sid": account_sid,
+ "country_code": country_code or self.country_code,
+ }
+ self._context: Optional[AvailablePhoneNumberCountryContext] = None
+
+ @property
+ def _proxy(self) -> "AvailablePhoneNumberCountryContext":
+ """
+ Generate an instance context for the instance, the context is capable of
+ performing various actions. All instance actions are proxied to the context
+
+ :returns: AvailablePhoneNumberCountryContext for this AvailablePhoneNumberCountryInstance
+ """
+ if self._context is None:
+ self._context = AvailablePhoneNumberCountryContext(
+ self._version,
+ account_sid=self._solution["account_sid"],
+ country_code=self._solution["country_code"],
+ )
+ return self._context
+
+ def fetch(self) -> "AvailablePhoneNumberCountryInstance":
+ """
+ Fetch the AvailablePhoneNumberCountryInstance
+
+
+ :returns: The fetched AvailablePhoneNumberCountryInstance
+ """
+ return self._proxy.fetch()
+
+ async def fetch_async(self) -> "AvailablePhoneNumberCountryInstance":
+ """
+ Asynchronous coroutine to fetch the AvailablePhoneNumberCountryInstance
+
+
+ :returns: The fetched AvailablePhoneNumberCountryInstance
+ """
+ return await self._proxy.fetch_async()
+
+ @property
+ def local(self) -> LocalList:
+ """
+ Access the local
+ """
+ return self._proxy.local
+
+ @property
+ def machine_to_machine(self) -> MachineToMachineList:
+ """
+ Access the machine_to_machine
+ """
+ return self._proxy.machine_to_machine
+
+ @property
+ def mobile(self) -> MobileList:
+ """
+ Access the mobile
+ """
+ return self._proxy.mobile
+
+ @property
+ def national(self) -> NationalList:
+ """
+ Access the national
+ """
+ return self._proxy.national
+
+ @property
+ def shared_cost(self) -> SharedCostList:
+ """
+ Access the shared_cost
+ """
+ return self._proxy.shared_cost
+
+ @property
+ def toll_free(self) -> TollFreeList:
+ """
+ Access the toll_free
+ """
+ return self._proxy.toll_free
+
+ @property
+ def voip(self) -> VoipList:
+ """
+ Access the voip
+ """
+ return self._proxy.voip
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(
+ context
+ )
+
+
+class AvailablePhoneNumberCountryContext(InstanceContext):
+
+ def __init__(self, version: Version, account_sid: str, country_code: str):
+ """
+ Initialize the AvailablePhoneNumberCountryContext
+
+ :param version: Version that contains the resource
+ :param account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) requesting the available phone number Country resource.
+ :param country_code: The [ISO-3166-1](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code of the country to fetch available phone number information about.
+ """
+ super().__init__(version)
+
+ # Path Solution
+ self._solution = {
+ "account_sid": account_sid,
+ "country_code": country_code,
+ }
+ self._uri = (
+ "/Accounts/{account_sid}/AvailablePhoneNumbers/{country_code}.json".format(
+ **self._solution
+ )
+ )
+
+ self._local: Optional[LocalList] = None
+ self._machine_to_machine: Optional[MachineToMachineList] = None
+ self._mobile: Optional[MobileList] = None
+ self._national: Optional[NationalList] = None
+ self._shared_cost: Optional[SharedCostList] = None
+ self._toll_free: Optional[TollFreeList] = None
+ self._voip: Optional[VoipList] = None
+
+ def fetch(self) -> AvailablePhoneNumberCountryInstance:
+ """
+ Fetch the AvailablePhoneNumberCountryInstance
+
+
+ :returns: The fetched AvailablePhoneNumberCountryInstance
+ """
+
+ headers = values.of({})
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.fetch(method="GET", uri=self._uri, headers=headers)
+
+ return AvailablePhoneNumberCountryInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ country_code=self._solution["country_code"],
+ )
+
+ async def fetch_async(self) -> AvailablePhoneNumberCountryInstance:
+ """
+ Asynchronous coroutine to fetch the AvailablePhoneNumberCountryInstance
+
+
+ :returns: The fetched AvailablePhoneNumberCountryInstance
+ """
+
+ headers = values.of({})
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.fetch_async(
+ method="GET", uri=self._uri, headers=headers
+ )
+
+ return AvailablePhoneNumberCountryInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ country_code=self._solution["country_code"],
+ )
+
+ @property
+ def local(self) -> LocalList:
+ """
+ Access the local
+ """
+ if self._local is None:
+ self._local = LocalList(
+ self._version,
+ self._solution["account_sid"],
+ self._solution["country_code"],
+ )
+ return self._local
+
+ @property
+ def machine_to_machine(self) -> MachineToMachineList:
+ """
+ Access the machine_to_machine
+ """
+ if self._machine_to_machine is None:
+ self._machine_to_machine = MachineToMachineList(
+ self._version,
+ self._solution["account_sid"],
+ self._solution["country_code"],
+ )
+ return self._machine_to_machine
+
+ @property
+ def mobile(self) -> MobileList:
+ """
+ Access the mobile
+ """
+ if self._mobile is None:
+ self._mobile = MobileList(
+ self._version,
+ self._solution["account_sid"],
+ self._solution["country_code"],
+ )
+ return self._mobile
+
+ @property
+ def national(self) -> NationalList:
+ """
+ Access the national
+ """
+ if self._national is None:
+ self._national = NationalList(
+ self._version,
+ self._solution["account_sid"],
+ self._solution["country_code"],
+ )
+ return self._national
+
+ @property
+ def shared_cost(self) -> SharedCostList:
+ """
+ Access the shared_cost
+ """
+ if self._shared_cost is None:
+ self._shared_cost = SharedCostList(
+ self._version,
+ self._solution["account_sid"],
+ self._solution["country_code"],
+ )
+ return self._shared_cost
+
+ @property
+ def toll_free(self) -> TollFreeList:
+ """
+ Access the toll_free
+ """
+ if self._toll_free is None:
+ self._toll_free = TollFreeList(
+ self._version,
+ self._solution["account_sid"],
+ self._solution["country_code"],
+ )
+ return self._toll_free
+
+ @property
+ def voip(self) -> VoipList:
+ """
+ Access the voip
+ """
+ if self._voip is None:
+ self._voip = VoipList(
+ self._version,
+ self._solution["account_sid"],
+ self._solution["country_code"],
+ )
+ return self._voip
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(
+ context
+ )
+
+
+class AvailablePhoneNumberCountryPage(Page):
+
+ def get_instance(
+ self, payload: Dict[str, Any]
+ ) -> AvailablePhoneNumberCountryInstance:
+ """
+ Build an instance of AvailablePhoneNumberCountryInstance
+
+ :param payload: Payload response from the API
+ """
+ return AvailablePhoneNumberCountryInstance(
+ self._version, payload, account_sid=self._solution["account_sid"]
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
+
+
+class AvailablePhoneNumberCountryList(ListResource):
+
+ def __init__(self, version: Version, account_sid: str):
+ """
+ Initialize the AvailablePhoneNumberCountryList
+
+ :param version: Version that contains the resource
+ :param account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) requesting the available phone number Country resources.
+
+ """
+ super().__init__(version)
+
+ # Path Solution
+ self._solution = {
+ "account_sid": account_sid,
+ }
+ self._uri = "/Accounts/{account_sid}/AvailablePhoneNumbers.json".format(
+ **self._solution
+ )
+
+ def stream(
+ self,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> Iterator[AvailablePhoneNumberCountryInstance]:
+ """
+ Streams AvailablePhoneNumberCountryInstance records from the API as a generator stream.
+ This operation lazily loads records as efficiently as possible until the limit
+ is reached.
+ The results are returned as a generator, so this operation is memory efficient.
+
+ :param limit: Upper limit for the number of records to return. stream()
+ guarantees to never return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, stream() will attempt to read the
+ limit with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: Generator that will yield up to limit results
+ """
+ limits = self._version.read_limits(limit, page_size)
+ page = self.page(page_size=limits["page_size"])
+
+ return self._version.stream(page, limits["limit"])
+
+ async def stream_async(
+ self,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> AsyncIterator[AvailablePhoneNumberCountryInstance]:
+ """
+ Asynchronously streams AvailablePhoneNumberCountryInstance records from the API as a generator stream.
+ This operation lazily loads records as efficiently as possible until the limit
+ is reached.
+ The results are returned as a generator, so this operation is memory efficient.
+
+ :param limit: Upper limit for the number of records to return. stream()
+ guarantees to never return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, stream() will attempt to read the
+ limit with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: Generator that will yield up to limit results
+ """
+ limits = self._version.read_limits(limit, page_size)
+ page = await self.page_async(page_size=limits["page_size"])
+
+ return self._version.stream_async(page, limits["limit"])
+
+ def list(
+ self,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> List[AvailablePhoneNumberCountryInstance]:
+ """
+ Lists AvailablePhoneNumberCountryInstance records from the API as a list.
+ Unlike stream(), this operation is eager and will load `limit` records into
+ memory before returning.
+
+ :param limit: Upper limit for the number of records to return. list() guarantees
+ never to return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, list() will attempt to read the limit
+ with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: list that will contain up to limit results
+ """
+ return list(
+ self.stream(
+ limit=limit,
+ page_size=page_size,
+ )
+ )
+
+ async def list_async(
+ self,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> List[AvailablePhoneNumberCountryInstance]:
+ """
+ Asynchronously lists AvailablePhoneNumberCountryInstance records from the API as a list.
+ Unlike stream(), this operation is eager and will load `limit` records into
+ memory before returning.
+
+ :param limit: Upper limit for the number of records to return. list() guarantees
+ never to return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, list() will attempt to read the limit
+ with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: list that will contain up to limit results
+ """
+ return [
+ record
+ async for record in await self.stream_async(
+ limit=limit,
+ page_size=page_size,
+ )
+ ]
+
+ def page(
+ self,
+ page_token: Union[str, object] = values.unset,
+ page_number: Union[int, object] = values.unset,
+ page_size: Union[int, object] = values.unset,
+ ) -> AvailablePhoneNumberCountryPage:
+ """
+ Retrieve a single page of AvailablePhoneNumberCountryInstance records from the API.
+ Request is executed immediately
+
+ :param page_token: PageToken provided by the API
+ :param page_number: Page Number, this value is simply for client state
+ :param page_size: Number of records to return, defaults to 50
+
+ :returns: Page of AvailablePhoneNumberCountryInstance
+ """
+ data = values.of(
+ {
+ "PageToken": page_token,
+ "Page": page_number,
+ "PageSize": page_size,
+ }
+ )
+
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ response = self._version.page(
+ method="GET", uri=self._uri, params=data, headers=headers
+ )
+ return AvailablePhoneNumberCountryPage(self._version, response, self._solution)
+
+ async def page_async(
+ self,
+ page_token: Union[str, object] = values.unset,
+ page_number: Union[int, object] = values.unset,
+ page_size: Union[int, object] = values.unset,
+ ) -> AvailablePhoneNumberCountryPage:
+ """
+ Asynchronously retrieve a single page of AvailablePhoneNumberCountryInstance records from the API.
+ Request is executed immediately
+
+ :param page_token: PageToken provided by the API
+ :param page_number: Page Number, this value is simply for client state
+ :param page_size: Number of records to return, defaults to 50
+
+ :returns: Page of AvailablePhoneNumberCountryInstance
+ """
+ data = values.of(
+ {
+ "PageToken": page_token,
+ "Page": page_number,
+ "PageSize": page_size,
+ }
+ )
+
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ response = await self._version.page_async(
+ method="GET", uri=self._uri, params=data, headers=headers
+ )
+ return AvailablePhoneNumberCountryPage(self._version, response, self._solution)
+
+ def get_page(self, target_url: str) -> AvailablePhoneNumberCountryPage:
+ """
+ Retrieve a specific page of AvailablePhoneNumberCountryInstance records from the API.
+ Request is executed immediately
+
+ :param target_url: API-generated URL for the requested results page
+
+ :returns: Page of AvailablePhoneNumberCountryInstance
+ """
+ response = self._version.domain.twilio.request("GET", target_url)
+ return AvailablePhoneNumberCountryPage(self._version, response, self._solution)
+
+ async def get_page_async(self, target_url: str) -> AvailablePhoneNumberCountryPage:
+ """
+ Asynchronously retrieve a specific page of AvailablePhoneNumberCountryInstance records from the API.
+ Request is executed immediately
+
+ :param target_url: API-generated URL for the requested results page
+
+ :returns: Page of AvailablePhoneNumberCountryInstance
+ """
+ response = await self._version.domain.twilio.request_async("GET", target_url)
+ return AvailablePhoneNumberCountryPage(self._version, response, self._solution)
+
+ def get(self, country_code: str) -> AvailablePhoneNumberCountryContext:
+ """
+ Constructs a AvailablePhoneNumberCountryContext
+
+ :param country_code: The [ISO-3166-1](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code of the country to fetch available phone number information about.
+ """
+ return AvailablePhoneNumberCountryContext(
+ self._version,
+ account_sid=self._solution["account_sid"],
+ country_code=country_code,
+ )
+
+ def __call__(self, country_code: str) -> AvailablePhoneNumberCountryContext:
+ """
+ Constructs a AvailablePhoneNumberCountryContext
+
+ :param country_code: The [ISO-3166-1](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code of the country to fetch available phone number information about.
+ """
+ return AvailablePhoneNumberCountryContext(
+ self._version,
+ account_sid=self._solution["account_sid"],
+ country_code=country_code,
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 00000000..2760af69
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/__pycache__/local.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/__pycache__/local.cpython-312.pyc
new file mode 100644
index 00000000..f1dadf36
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/__pycache__/local.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/__pycache__/machine_to_machine.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/__pycache__/machine_to_machine.cpython-312.pyc
new file mode 100644
index 00000000..e97b523d
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/__pycache__/machine_to_machine.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/__pycache__/mobile.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/__pycache__/mobile.cpython-312.pyc
new file mode 100644
index 00000000..c8f30665
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/__pycache__/mobile.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/__pycache__/national.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/__pycache__/national.cpython-312.pyc
new file mode 100644
index 00000000..4205f515
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/__pycache__/national.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/__pycache__/shared_cost.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/__pycache__/shared_cost.cpython-312.pyc
new file mode 100644
index 00000000..cf71637e
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/__pycache__/shared_cost.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/__pycache__/toll_free.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/__pycache__/toll_free.cpython-312.pyc
new file mode 100644
index 00000000..b0b85e3f
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/__pycache__/toll_free.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/__pycache__/voip.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/__pycache__/voip.cpython-312.pyc
new file mode 100644
index 00000000..cd145b76
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/__pycache__/voip.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/local.py b/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/local.py
new file mode 100644
index 00000000..4f0b2e79
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/local.py
@@ -0,0 +1,664 @@
+r"""
+ This code was generated by
+ ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __
+ | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/
+ | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \
+
+ Twilio - Api
+ This is the public Twilio REST API.
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ https://openapi-generator.tech
+ Do not edit the class manually.
+"""
+
+from typing import Any, Dict, List, Optional, Union, Iterator, AsyncIterator
+from twilio.base import deserialize, serialize, values
+
+from twilio.base.instance_resource import InstanceResource
+from twilio.base.list_resource import ListResource
+from twilio.base.version import Version
+from twilio.base.page import Page
+
+
+class LocalInstance(InstanceResource):
+ """
+ :ivar friendly_name: A formatted version of the phone number.
+ :ivar phone_number: The phone number in [E.164](https://www.twilio.com/docs/glossary/what-e164) format, which consists of a + followed by the country code and subscriber number.
+ :ivar lata: The [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) of this phone number. Available for only phone numbers from the US and Canada.
+ :ivar locality: The locality or city of this phone number's location.
+ :ivar rate_center: The [rate center](https://en.wikipedia.org/wiki/Telephone_exchange) of this phone number. Available for only phone numbers from the US and Canada.
+ :ivar latitude: The latitude of this phone number's location. Available for only phone numbers from the US and Canada.
+ :ivar longitude: The longitude of this phone number's location. Available for only phone numbers from the US and Canada.
+ :ivar region: The two-letter state or province abbreviation of this phone number's location. Available for only phone numbers from the US and Canada.
+ :ivar postal_code: The postal or ZIP code of this phone number's location. Available for only phone numbers from the US and Canada.
+ :ivar iso_country: The [ISO country code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) of this phone number.
+ :ivar address_requirements: The type of [Address](https://www.twilio.com/docs/usage/api/address) resource the phone number requires. Can be: `none`, `any`, `local`, or `foreign`. `none` means no address is required. `any` means an address is required, but it can be anywhere in the world. `local` means an address in the phone number's country is required. `foreign` means an address outside of the phone number's country is required.
+ :ivar beta: Whether the phone number is new to the Twilio platform. Can be: `true` or `false`.
+ :ivar capabilities:
+ """
+
+ def __init__(
+ self,
+ version: Version,
+ payload: Dict[str, Any],
+ account_sid: str,
+ country_code: str,
+ ):
+ super().__init__(version)
+
+ self.friendly_name: Optional[str] = payload.get("friendly_name")
+ self.phone_number: Optional[str] = payload.get("phone_number")
+ self.lata: Optional[str] = payload.get("lata")
+ self.locality: Optional[str] = payload.get("locality")
+ self.rate_center: Optional[str] = payload.get("rate_center")
+ self.latitude: Optional[float] = deserialize.decimal(payload.get("latitude"))
+ self.longitude: Optional[float] = deserialize.decimal(payload.get("longitude"))
+ self.region: Optional[str] = payload.get("region")
+ self.postal_code: Optional[str] = payload.get("postal_code")
+ self.iso_country: Optional[str] = payload.get("iso_country")
+ self.address_requirements: Optional[str] = payload.get("address_requirements")
+ self.beta: Optional[bool] = payload.get("beta")
+ self.capabilities: Optional[str] = payload.get("capabilities")
+
+ self._solution = {
+ "account_sid": account_sid,
+ "country_code": country_code,
+ }
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(context)
+
+
+class LocalPage(Page):
+
+ def get_instance(self, payload: Dict[str, Any]) -> LocalInstance:
+ """
+ Build an instance of LocalInstance
+
+ :param payload: Payload response from the API
+ """
+ return LocalInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ country_code=self._solution["country_code"],
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
+
+
+class LocalList(ListResource):
+
+ def __init__(self, version: Version, account_sid: str, country_code: str):
+ """
+ Initialize the LocalList
+
+ :param version: Version that contains the resource
+ :param account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) requesting the AvailablePhoneNumber resources.
+ :param country_code: The [ISO-3166-1](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code of the country from which to read phone numbers.
+
+ """
+ super().__init__(version)
+
+ # Path Solution
+ self._solution = {
+ "account_sid": account_sid,
+ "country_code": country_code,
+ }
+ self._uri = "/Accounts/{account_sid}/AvailablePhoneNumbers/{country_code}/Local.json".format(
+ **self._solution
+ )
+
+ def stream(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> Iterator[LocalInstance]:
+ """
+ Streams LocalInstance records from the API as a generator stream.
+ This operation lazily loads records as efficiently as possible until the limit
+ is reached.
+ The results are returned as a generator, so this operation is memory efficient.
+
+ :param int area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param str contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumberlocal-resource?code-sample=code-find-phone-numbers-by-number-pattern) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumberlocal-resource?code-sample=code-find-phone-numbers-by-character-pattern). If specified, this value must have at least two characters.
+ :param bool sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param bool mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param bool voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param bool exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param str near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param str near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param int distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param str in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param str in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param bool fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param limit: Upper limit for the number of records to return. stream()
+ guarantees to never return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, stream() will attempt to read the
+ limit with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: Generator that will yield up to limit results
+ """
+ limits = self._version.read_limits(limit, page_size)
+ page = self.page(
+ area_code=area_code,
+ contains=contains,
+ sms_enabled=sms_enabled,
+ mms_enabled=mms_enabled,
+ voice_enabled=voice_enabled,
+ exclude_all_address_required=exclude_all_address_required,
+ exclude_local_address_required=exclude_local_address_required,
+ exclude_foreign_address_required=exclude_foreign_address_required,
+ beta=beta,
+ near_number=near_number,
+ near_lat_long=near_lat_long,
+ distance=distance,
+ in_postal_code=in_postal_code,
+ in_region=in_region,
+ in_rate_center=in_rate_center,
+ in_lata=in_lata,
+ in_locality=in_locality,
+ fax_enabled=fax_enabled,
+ page_size=limits["page_size"],
+ )
+
+ return self._version.stream(page, limits["limit"])
+
+ async def stream_async(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> AsyncIterator[LocalInstance]:
+ """
+ Asynchronously streams LocalInstance records from the API as a generator stream.
+ This operation lazily loads records as efficiently as possible until the limit
+ is reached.
+ The results are returned as a generator, so this operation is memory efficient.
+
+ :param int area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param str contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumberlocal-resource?code-sample=code-find-phone-numbers-by-number-pattern) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumberlocal-resource?code-sample=code-find-phone-numbers-by-character-pattern). If specified, this value must have at least two characters.
+ :param bool sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param bool mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param bool voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param bool exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param str near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param str near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param int distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param str in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param str in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param bool fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param limit: Upper limit for the number of records to return. stream()
+ guarantees to never return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, stream() will attempt to read the
+ limit with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: Generator that will yield up to limit results
+ """
+ limits = self._version.read_limits(limit, page_size)
+ page = await self.page_async(
+ area_code=area_code,
+ contains=contains,
+ sms_enabled=sms_enabled,
+ mms_enabled=mms_enabled,
+ voice_enabled=voice_enabled,
+ exclude_all_address_required=exclude_all_address_required,
+ exclude_local_address_required=exclude_local_address_required,
+ exclude_foreign_address_required=exclude_foreign_address_required,
+ beta=beta,
+ near_number=near_number,
+ near_lat_long=near_lat_long,
+ distance=distance,
+ in_postal_code=in_postal_code,
+ in_region=in_region,
+ in_rate_center=in_rate_center,
+ in_lata=in_lata,
+ in_locality=in_locality,
+ fax_enabled=fax_enabled,
+ page_size=limits["page_size"],
+ )
+
+ return self._version.stream_async(page, limits["limit"])
+
+ def list(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> List[LocalInstance]:
+ """
+ Lists LocalInstance records from the API as a list.
+ Unlike stream(), this operation is eager and will load `limit` records into
+ memory before returning.
+
+ :param int area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param str contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumberlocal-resource?code-sample=code-find-phone-numbers-by-number-pattern) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumberlocal-resource?code-sample=code-find-phone-numbers-by-character-pattern). If specified, this value must have at least two characters.
+ :param bool sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param bool mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param bool voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param bool exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param str near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param str near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param int distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param str in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param str in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param bool fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param limit: Upper limit for the number of records to return. list() guarantees
+ never to return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, list() will attempt to read the limit
+ with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: list that will contain up to limit results
+ """
+ return list(
+ self.stream(
+ area_code=area_code,
+ contains=contains,
+ sms_enabled=sms_enabled,
+ mms_enabled=mms_enabled,
+ voice_enabled=voice_enabled,
+ exclude_all_address_required=exclude_all_address_required,
+ exclude_local_address_required=exclude_local_address_required,
+ exclude_foreign_address_required=exclude_foreign_address_required,
+ beta=beta,
+ near_number=near_number,
+ near_lat_long=near_lat_long,
+ distance=distance,
+ in_postal_code=in_postal_code,
+ in_region=in_region,
+ in_rate_center=in_rate_center,
+ in_lata=in_lata,
+ in_locality=in_locality,
+ fax_enabled=fax_enabled,
+ limit=limit,
+ page_size=page_size,
+ )
+ )
+
+ async def list_async(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> List[LocalInstance]:
+ """
+ Asynchronously lists LocalInstance records from the API as a list.
+ Unlike stream(), this operation is eager and will load `limit` records into
+ memory before returning.
+
+ :param int area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param str contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumberlocal-resource?code-sample=code-find-phone-numbers-by-number-pattern) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumberlocal-resource?code-sample=code-find-phone-numbers-by-character-pattern). If specified, this value must have at least two characters.
+ :param bool sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param bool mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param bool voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param bool exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param str near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param str near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param int distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param str in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param str in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param bool fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param limit: Upper limit for the number of records to return. list() guarantees
+ never to return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, list() will attempt to read the limit
+ with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: list that will contain up to limit results
+ """
+ return [
+ record
+ async for record in await self.stream_async(
+ area_code=area_code,
+ contains=contains,
+ sms_enabled=sms_enabled,
+ mms_enabled=mms_enabled,
+ voice_enabled=voice_enabled,
+ exclude_all_address_required=exclude_all_address_required,
+ exclude_local_address_required=exclude_local_address_required,
+ exclude_foreign_address_required=exclude_foreign_address_required,
+ beta=beta,
+ near_number=near_number,
+ near_lat_long=near_lat_long,
+ distance=distance,
+ in_postal_code=in_postal_code,
+ in_region=in_region,
+ in_rate_center=in_rate_center,
+ in_lata=in_lata,
+ in_locality=in_locality,
+ fax_enabled=fax_enabled,
+ limit=limit,
+ page_size=page_size,
+ )
+ ]
+
+ def page(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ page_token: Union[str, object] = values.unset,
+ page_number: Union[int, object] = values.unset,
+ page_size: Union[int, object] = values.unset,
+ ) -> LocalPage:
+ """
+ Retrieve a single page of LocalInstance records from the API.
+ Request is executed immediately
+
+ :param area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumberlocal-resource?code-sample=code-find-phone-numbers-by-number-pattern) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumberlocal-resource?code-sample=code-find-phone-numbers-by-character-pattern). If specified, this value must have at least two characters.
+ :param sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param page_token: PageToken provided by the API
+ :param page_number: Page Number, this value is simply for client state
+ :param page_size: Number of records to return, defaults to 50
+
+ :returns: Page of LocalInstance
+ """
+ data = values.of(
+ {
+ "AreaCode": area_code,
+ "Contains": contains,
+ "SmsEnabled": serialize.boolean_to_string(sms_enabled),
+ "MmsEnabled": serialize.boolean_to_string(mms_enabled),
+ "VoiceEnabled": serialize.boolean_to_string(voice_enabled),
+ "ExcludeAllAddressRequired": serialize.boolean_to_string(
+ exclude_all_address_required
+ ),
+ "ExcludeLocalAddressRequired": serialize.boolean_to_string(
+ exclude_local_address_required
+ ),
+ "ExcludeForeignAddressRequired": serialize.boolean_to_string(
+ exclude_foreign_address_required
+ ),
+ "Beta": serialize.boolean_to_string(beta),
+ "NearNumber": near_number,
+ "NearLatLong": near_lat_long,
+ "Distance": distance,
+ "InPostalCode": in_postal_code,
+ "InRegion": in_region,
+ "InRateCenter": in_rate_center,
+ "InLata": in_lata,
+ "InLocality": in_locality,
+ "FaxEnabled": serialize.boolean_to_string(fax_enabled),
+ "PageToken": page_token,
+ "Page": page_number,
+ "PageSize": page_size,
+ }
+ )
+
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ response = self._version.page(
+ method="GET", uri=self._uri, params=data, headers=headers
+ )
+ return LocalPage(self._version, response, self._solution)
+
+ async def page_async(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ page_token: Union[str, object] = values.unset,
+ page_number: Union[int, object] = values.unset,
+ page_size: Union[int, object] = values.unset,
+ ) -> LocalPage:
+ """
+ Asynchronously retrieve a single page of LocalInstance records from the API.
+ Request is executed immediately
+
+ :param area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumberlocal-resource?code-sample=code-find-phone-numbers-by-number-pattern) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumberlocal-resource?code-sample=code-find-phone-numbers-by-character-pattern). If specified, this value must have at least two characters.
+ :param sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param page_token: PageToken provided by the API
+ :param page_number: Page Number, this value is simply for client state
+ :param page_size: Number of records to return, defaults to 50
+
+ :returns: Page of LocalInstance
+ """
+ data = values.of(
+ {
+ "AreaCode": area_code,
+ "Contains": contains,
+ "SmsEnabled": serialize.boolean_to_string(sms_enabled),
+ "MmsEnabled": serialize.boolean_to_string(mms_enabled),
+ "VoiceEnabled": serialize.boolean_to_string(voice_enabled),
+ "ExcludeAllAddressRequired": serialize.boolean_to_string(
+ exclude_all_address_required
+ ),
+ "ExcludeLocalAddressRequired": serialize.boolean_to_string(
+ exclude_local_address_required
+ ),
+ "ExcludeForeignAddressRequired": serialize.boolean_to_string(
+ exclude_foreign_address_required
+ ),
+ "Beta": serialize.boolean_to_string(beta),
+ "NearNumber": near_number,
+ "NearLatLong": near_lat_long,
+ "Distance": distance,
+ "InPostalCode": in_postal_code,
+ "InRegion": in_region,
+ "InRateCenter": in_rate_center,
+ "InLata": in_lata,
+ "InLocality": in_locality,
+ "FaxEnabled": serialize.boolean_to_string(fax_enabled),
+ "PageToken": page_token,
+ "Page": page_number,
+ "PageSize": page_size,
+ }
+ )
+
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ response = await self._version.page_async(
+ method="GET", uri=self._uri, params=data, headers=headers
+ )
+ return LocalPage(self._version, response, self._solution)
+
+ def get_page(self, target_url: str) -> LocalPage:
+ """
+ Retrieve a specific page of LocalInstance records from the API.
+ Request is executed immediately
+
+ :param target_url: API-generated URL for the requested results page
+
+ :returns: Page of LocalInstance
+ """
+ response = self._version.domain.twilio.request("GET", target_url)
+ return LocalPage(self._version, response, self._solution)
+
+ async def get_page_async(self, target_url: str) -> LocalPage:
+ """
+ Asynchronously retrieve a specific page of LocalInstance records from the API.
+ Request is executed immediately
+
+ :param target_url: API-generated URL for the requested results page
+
+ :returns: Page of LocalInstance
+ """
+ response = await self._version.domain.twilio.request_async("GET", target_url)
+ return LocalPage(self._version, response, self._solution)
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/machine_to_machine.py b/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/machine_to_machine.py
new file mode 100644
index 00000000..5695c917
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/machine_to_machine.py
@@ -0,0 +1,664 @@
+r"""
+ This code was generated by
+ ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __
+ | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/
+ | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \
+
+ Twilio - Api
+ This is the public Twilio REST API.
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ https://openapi-generator.tech
+ Do not edit the class manually.
+"""
+
+from typing import Any, Dict, List, Optional, Union, Iterator, AsyncIterator
+from twilio.base import deserialize, serialize, values
+
+from twilio.base.instance_resource import InstanceResource
+from twilio.base.list_resource import ListResource
+from twilio.base.version import Version
+from twilio.base.page import Page
+
+
+class MachineToMachineInstance(InstanceResource):
+ """
+ :ivar friendly_name: A formatted version of the phone number.
+ :ivar phone_number: The phone number in [E.164](https://www.twilio.com/docs/glossary/what-e164) format, which consists of a + followed by the country code and subscriber number.
+ :ivar lata: The [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) of this phone number. Available for only phone numbers from the US and Canada.
+ :ivar locality: The locality or city of this phone number's location.
+ :ivar rate_center: The [rate center](https://en.wikipedia.org/wiki/Telephone_exchange) of this phone number. Available for only phone numbers from the US and Canada.
+ :ivar latitude: The latitude of this phone number's location. Available for only phone numbers from the US and Canada.
+ :ivar longitude: The longitude of this phone number's location. Available for only phone numbers from the US and Canada.
+ :ivar region: The two-letter state or province abbreviation of this phone number's location. Available for only phone numbers from the US and Canada.
+ :ivar postal_code: The postal or ZIP code of this phone number's location. Available for only phone numbers from the US and Canada.
+ :ivar iso_country: The [ISO country code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) of this phone number.
+ :ivar address_requirements: The type of [Address](https://www.twilio.com/docs/usage/api/address) resource the phone number requires. Can be: `none`, `any`, `local`, or `foreign`. `none` means no address is required. `any` means an address is required, but it can be anywhere in the world. `local` means an address in the phone number's country is required. `foreign` means an address outside of the phone number's country is required.
+ :ivar beta: Whether the phone number is new to the Twilio platform. Can be: `true` or `false`.
+ :ivar capabilities:
+ """
+
+ def __init__(
+ self,
+ version: Version,
+ payload: Dict[str, Any],
+ account_sid: str,
+ country_code: str,
+ ):
+ super().__init__(version)
+
+ self.friendly_name: Optional[str] = payload.get("friendly_name")
+ self.phone_number: Optional[str] = payload.get("phone_number")
+ self.lata: Optional[str] = payload.get("lata")
+ self.locality: Optional[str] = payload.get("locality")
+ self.rate_center: Optional[str] = payload.get("rate_center")
+ self.latitude: Optional[float] = deserialize.decimal(payload.get("latitude"))
+ self.longitude: Optional[float] = deserialize.decimal(payload.get("longitude"))
+ self.region: Optional[str] = payload.get("region")
+ self.postal_code: Optional[str] = payload.get("postal_code")
+ self.iso_country: Optional[str] = payload.get("iso_country")
+ self.address_requirements: Optional[str] = payload.get("address_requirements")
+ self.beta: Optional[bool] = payload.get("beta")
+ self.capabilities: Optional[str] = payload.get("capabilities")
+
+ self._solution = {
+ "account_sid": account_sid,
+ "country_code": country_code,
+ }
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(context)
+
+
+class MachineToMachinePage(Page):
+
+ def get_instance(self, payload: Dict[str, Any]) -> MachineToMachineInstance:
+ """
+ Build an instance of MachineToMachineInstance
+
+ :param payload: Payload response from the API
+ """
+ return MachineToMachineInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ country_code=self._solution["country_code"],
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
+
+
+class MachineToMachineList(ListResource):
+
+ def __init__(self, version: Version, account_sid: str, country_code: str):
+ """
+ Initialize the MachineToMachineList
+
+ :param version: Version that contains the resource
+ :param account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) requesting the AvailablePhoneNumber resources.
+ :param country_code: The [ISO-3166-1](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code of the country from which to read phone numbers.
+
+ """
+ super().__init__(version)
+
+ # Path Solution
+ self._solution = {
+ "account_sid": account_sid,
+ "country_code": country_code,
+ }
+ self._uri = "/Accounts/{account_sid}/AvailablePhoneNumbers/{country_code}/MachineToMachine.json".format(
+ **self._solution
+ )
+
+ def stream(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> Iterator[MachineToMachineInstance]:
+ """
+ Streams MachineToMachineInstance records from the API as a generator stream.
+ This operation lazily loads records as efficiently as possible until the limit
+ is reached.
+ The results are returned as a generator, so this operation is memory efficient.
+
+ :param int area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param str contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-2) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-3). If specified, this value must have at least two characters.
+ :param bool sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param bool mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param bool voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param bool exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param str near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param str near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param int distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param str in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param str in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param bool fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param limit: Upper limit for the number of records to return. stream()
+ guarantees to never return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, stream() will attempt to read the
+ limit with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: Generator that will yield up to limit results
+ """
+ limits = self._version.read_limits(limit, page_size)
+ page = self.page(
+ area_code=area_code,
+ contains=contains,
+ sms_enabled=sms_enabled,
+ mms_enabled=mms_enabled,
+ voice_enabled=voice_enabled,
+ exclude_all_address_required=exclude_all_address_required,
+ exclude_local_address_required=exclude_local_address_required,
+ exclude_foreign_address_required=exclude_foreign_address_required,
+ beta=beta,
+ near_number=near_number,
+ near_lat_long=near_lat_long,
+ distance=distance,
+ in_postal_code=in_postal_code,
+ in_region=in_region,
+ in_rate_center=in_rate_center,
+ in_lata=in_lata,
+ in_locality=in_locality,
+ fax_enabled=fax_enabled,
+ page_size=limits["page_size"],
+ )
+
+ return self._version.stream(page, limits["limit"])
+
+ async def stream_async(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> AsyncIterator[MachineToMachineInstance]:
+ """
+ Asynchronously streams MachineToMachineInstance records from the API as a generator stream.
+ This operation lazily loads records as efficiently as possible until the limit
+ is reached.
+ The results are returned as a generator, so this operation is memory efficient.
+
+ :param int area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param str contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-2) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-3). If specified, this value must have at least two characters.
+ :param bool sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param bool mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param bool voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param bool exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param str near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param str near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param int distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param str in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param str in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param bool fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param limit: Upper limit for the number of records to return. stream()
+ guarantees to never return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, stream() will attempt to read the
+ limit with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: Generator that will yield up to limit results
+ """
+ limits = self._version.read_limits(limit, page_size)
+ page = await self.page_async(
+ area_code=area_code,
+ contains=contains,
+ sms_enabled=sms_enabled,
+ mms_enabled=mms_enabled,
+ voice_enabled=voice_enabled,
+ exclude_all_address_required=exclude_all_address_required,
+ exclude_local_address_required=exclude_local_address_required,
+ exclude_foreign_address_required=exclude_foreign_address_required,
+ beta=beta,
+ near_number=near_number,
+ near_lat_long=near_lat_long,
+ distance=distance,
+ in_postal_code=in_postal_code,
+ in_region=in_region,
+ in_rate_center=in_rate_center,
+ in_lata=in_lata,
+ in_locality=in_locality,
+ fax_enabled=fax_enabled,
+ page_size=limits["page_size"],
+ )
+
+ return self._version.stream_async(page, limits["limit"])
+
+ def list(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> List[MachineToMachineInstance]:
+ """
+ Lists MachineToMachineInstance records from the API as a list.
+ Unlike stream(), this operation is eager and will load `limit` records into
+ memory before returning.
+
+ :param int area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param str contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-2) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-3). If specified, this value must have at least two characters.
+ :param bool sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param bool mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param bool voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param bool exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param str near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param str near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param int distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param str in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param str in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param bool fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param limit: Upper limit for the number of records to return. list() guarantees
+ never to return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, list() will attempt to read the limit
+ with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: list that will contain up to limit results
+ """
+ return list(
+ self.stream(
+ area_code=area_code,
+ contains=contains,
+ sms_enabled=sms_enabled,
+ mms_enabled=mms_enabled,
+ voice_enabled=voice_enabled,
+ exclude_all_address_required=exclude_all_address_required,
+ exclude_local_address_required=exclude_local_address_required,
+ exclude_foreign_address_required=exclude_foreign_address_required,
+ beta=beta,
+ near_number=near_number,
+ near_lat_long=near_lat_long,
+ distance=distance,
+ in_postal_code=in_postal_code,
+ in_region=in_region,
+ in_rate_center=in_rate_center,
+ in_lata=in_lata,
+ in_locality=in_locality,
+ fax_enabled=fax_enabled,
+ limit=limit,
+ page_size=page_size,
+ )
+ )
+
+ async def list_async(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> List[MachineToMachineInstance]:
+ """
+ Asynchronously lists MachineToMachineInstance records from the API as a list.
+ Unlike stream(), this operation is eager and will load `limit` records into
+ memory before returning.
+
+ :param int area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param str contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-2) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-3). If specified, this value must have at least two characters.
+ :param bool sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param bool mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param bool voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param bool exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param str near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param str near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param int distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param str in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param str in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param bool fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param limit: Upper limit for the number of records to return. list() guarantees
+ never to return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, list() will attempt to read the limit
+ with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: list that will contain up to limit results
+ """
+ return [
+ record
+ async for record in await self.stream_async(
+ area_code=area_code,
+ contains=contains,
+ sms_enabled=sms_enabled,
+ mms_enabled=mms_enabled,
+ voice_enabled=voice_enabled,
+ exclude_all_address_required=exclude_all_address_required,
+ exclude_local_address_required=exclude_local_address_required,
+ exclude_foreign_address_required=exclude_foreign_address_required,
+ beta=beta,
+ near_number=near_number,
+ near_lat_long=near_lat_long,
+ distance=distance,
+ in_postal_code=in_postal_code,
+ in_region=in_region,
+ in_rate_center=in_rate_center,
+ in_lata=in_lata,
+ in_locality=in_locality,
+ fax_enabled=fax_enabled,
+ limit=limit,
+ page_size=page_size,
+ )
+ ]
+
+ def page(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ page_token: Union[str, object] = values.unset,
+ page_number: Union[int, object] = values.unset,
+ page_size: Union[int, object] = values.unset,
+ ) -> MachineToMachinePage:
+ """
+ Retrieve a single page of MachineToMachineInstance records from the API.
+ Request is executed immediately
+
+ :param area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-2) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-3). If specified, this value must have at least two characters.
+ :param sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param page_token: PageToken provided by the API
+ :param page_number: Page Number, this value is simply for client state
+ :param page_size: Number of records to return, defaults to 50
+
+ :returns: Page of MachineToMachineInstance
+ """
+ data = values.of(
+ {
+ "AreaCode": area_code,
+ "Contains": contains,
+ "SmsEnabled": serialize.boolean_to_string(sms_enabled),
+ "MmsEnabled": serialize.boolean_to_string(mms_enabled),
+ "VoiceEnabled": serialize.boolean_to_string(voice_enabled),
+ "ExcludeAllAddressRequired": serialize.boolean_to_string(
+ exclude_all_address_required
+ ),
+ "ExcludeLocalAddressRequired": serialize.boolean_to_string(
+ exclude_local_address_required
+ ),
+ "ExcludeForeignAddressRequired": serialize.boolean_to_string(
+ exclude_foreign_address_required
+ ),
+ "Beta": serialize.boolean_to_string(beta),
+ "NearNumber": near_number,
+ "NearLatLong": near_lat_long,
+ "Distance": distance,
+ "InPostalCode": in_postal_code,
+ "InRegion": in_region,
+ "InRateCenter": in_rate_center,
+ "InLata": in_lata,
+ "InLocality": in_locality,
+ "FaxEnabled": serialize.boolean_to_string(fax_enabled),
+ "PageToken": page_token,
+ "Page": page_number,
+ "PageSize": page_size,
+ }
+ )
+
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ response = self._version.page(
+ method="GET", uri=self._uri, params=data, headers=headers
+ )
+ return MachineToMachinePage(self._version, response, self._solution)
+
+ async def page_async(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ page_token: Union[str, object] = values.unset,
+ page_number: Union[int, object] = values.unset,
+ page_size: Union[int, object] = values.unset,
+ ) -> MachineToMachinePage:
+ """
+ Asynchronously retrieve a single page of MachineToMachineInstance records from the API.
+ Request is executed immediately
+
+ :param area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-2) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-3). If specified, this value must have at least two characters.
+ :param sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param page_token: PageToken provided by the API
+ :param page_number: Page Number, this value is simply for client state
+ :param page_size: Number of records to return, defaults to 50
+
+ :returns: Page of MachineToMachineInstance
+ """
+ data = values.of(
+ {
+ "AreaCode": area_code,
+ "Contains": contains,
+ "SmsEnabled": serialize.boolean_to_string(sms_enabled),
+ "MmsEnabled": serialize.boolean_to_string(mms_enabled),
+ "VoiceEnabled": serialize.boolean_to_string(voice_enabled),
+ "ExcludeAllAddressRequired": serialize.boolean_to_string(
+ exclude_all_address_required
+ ),
+ "ExcludeLocalAddressRequired": serialize.boolean_to_string(
+ exclude_local_address_required
+ ),
+ "ExcludeForeignAddressRequired": serialize.boolean_to_string(
+ exclude_foreign_address_required
+ ),
+ "Beta": serialize.boolean_to_string(beta),
+ "NearNumber": near_number,
+ "NearLatLong": near_lat_long,
+ "Distance": distance,
+ "InPostalCode": in_postal_code,
+ "InRegion": in_region,
+ "InRateCenter": in_rate_center,
+ "InLata": in_lata,
+ "InLocality": in_locality,
+ "FaxEnabled": serialize.boolean_to_string(fax_enabled),
+ "PageToken": page_token,
+ "Page": page_number,
+ "PageSize": page_size,
+ }
+ )
+
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ response = await self._version.page_async(
+ method="GET", uri=self._uri, params=data, headers=headers
+ )
+ return MachineToMachinePage(self._version, response, self._solution)
+
+ def get_page(self, target_url: str) -> MachineToMachinePage:
+ """
+ Retrieve a specific page of MachineToMachineInstance records from the API.
+ Request is executed immediately
+
+ :param target_url: API-generated URL for the requested results page
+
+ :returns: Page of MachineToMachineInstance
+ """
+ response = self._version.domain.twilio.request("GET", target_url)
+ return MachineToMachinePage(self._version, response, self._solution)
+
+ async def get_page_async(self, target_url: str) -> MachineToMachinePage:
+ """
+ Asynchronously retrieve a specific page of MachineToMachineInstance records from the API.
+ Request is executed immediately
+
+ :param target_url: API-generated URL for the requested results page
+
+ :returns: Page of MachineToMachineInstance
+ """
+ response = await self._version.domain.twilio.request_async("GET", target_url)
+ return MachineToMachinePage(self._version, response, self._solution)
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/mobile.py b/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/mobile.py
new file mode 100644
index 00000000..2382155e
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/mobile.py
@@ -0,0 +1,664 @@
+r"""
+ This code was generated by
+ ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __
+ | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/
+ | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \
+
+ Twilio - Api
+ This is the public Twilio REST API.
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ https://openapi-generator.tech
+ Do not edit the class manually.
+"""
+
+from typing import Any, Dict, List, Optional, Union, Iterator, AsyncIterator
+from twilio.base import deserialize, serialize, values
+
+from twilio.base.instance_resource import InstanceResource
+from twilio.base.list_resource import ListResource
+from twilio.base.version import Version
+from twilio.base.page import Page
+
+
+class MobileInstance(InstanceResource):
+ """
+ :ivar friendly_name: A formatted version of the phone number.
+ :ivar phone_number: The phone number in [E.164](https://www.twilio.com/docs/glossary/what-e164) format, which consists of a + followed by the country code and subscriber number.
+ :ivar lata: The [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) of this phone number. Available for only phone numbers from the US and Canada.
+ :ivar locality: The locality or city of this phone number's location.
+ :ivar rate_center: The [rate center](https://en.wikipedia.org/wiki/Telephone_exchange) of this phone number. Available for only phone numbers from the US and Canada.
+ :ivar latitude: The latitude of this phone number's location. Available for only phone numbers from the US and Canada.
+ :ivar longitude: The longitude of this phone number's location. Available for only phone numbers from the US and Canada.
+ :ivar region: The two-letter state or province abbreviation of this phone number's location. Available for only phone numbers from the US and Canada.
+ :ivar postal_code: The postal or ZIP code of this phone number's location. Available for only phone numbers from the US and Canada.
+ :ivar iso_country: The [ISO country code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) of this phone number.
+ :ivar address_requirements: The type of [Address](https://www.twilio.com/docs/usage/api/address) resource the phone number requires. Can be: `none`, `any`, `local`, or `foreign`. `none` means no address is required. `any` means an address is required, but it can be anywhere in the world. `local` means an address in the phone number's country is required. `foreign` means an address outside of the phone number's country is required.
+ :ivar beta: Whether the phone number is new to the Twilio platform. Can be: `true` or `false`.
+ :ivar capabilities:
+ """
+
+ def __init__(
+ self,
+ version: Version,
+ payload: Dict[str, Any],
+ account_sid: str,
+ country_code: str,
+ ):
+ super().__init__(version)
+
+ self.friendly_name: Optional[str] = payload.get("friendly_name")
+ self.phone_number: Optional[str] = payload.get("phone_number")
+ self.lata: Optional[str] = payload.get("lata")
+ self.locality: Optional[str] = payload.get("locality")
+ self.rate_center: Optional[str] = payload.get("rate_center")
+ self.latitude: Optional[float] = deserialize.decimal(payload.get("latitude"))
+ self.longitude: Optional[float] = deserialize.decimal(payload.get("longitude"))
+ self.region: Optional[str] = payload.get("region")
+ self.postal_code: Optional[str] = payload.get("postal_code")
+ self.iso_country: Optional[str] = payload.get("iso_country")
+ self.address_requirements: Optional[str] = payload.get("address_requirements")
+ self.beta: Optional[bool] = payload.get("beta")
+ self.capabilities: Optional[str] = payload.get("capabilities")
+
+ self._solution = {
+ "account_sid": account_sid,
+ "country_code": country_code,
+ }
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(context)
+
+
+class MobilePage(Page):
+
+ def get_instance(self, payload: Dict[str, Any]) -> MobileInstance:
+ """
+ Build an instance of MobileInstance
+
+ :param payload: Payload response from the API
+ """
+ return MobileInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ country_code=self._solution["country_code"],
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
+
+
+class MobileList(ListResource):
+
+ def __init__(self, version: Version, account_sid: str, country_code: str):
+ """
+ Initialize the MobileList
+
+ :param version: Version that contains the resource
+ :param account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) requesting the AvailablePhoneNumber resources.
+ :param country_code: The [ISO-3166-1](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code of the country from which to read phone numbers.
+
+ """
+ super().__init__(version)
+
+ # Path Solution
+ self._solution = {
+ "account_sid": account_sid,
+ "country_code": country_code,
+ }
+ self._uri = "/Accounts/{account_sid}/AvailablePhoneNumbers/{country_code}/Mobile.json".format(
+ **self._solution
+ )
+
+ def stream(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> Iterator[MobileInstance]:
+ """
+ Streams MobileInstance records from the API as a generator stream.
+ This operation lazily loads records as efficiently as possible until the limit
+ is reached.
+ The results are returned as a generator, so this operation is memory efficient.
+
+ :param int area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param str contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-2) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-3). If specified, this value must have at least two characters.
+ :param bool sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param bool mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param bool voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param bool exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param str near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param str near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param int distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param str in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param str in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param bool fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param limit: Upper limit for the number of records to return. stream()
+ guarantees to never return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, stream() will attempt to read the
+ limit with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: Generator that will yield up to limit results
+ """
+ limits = self._version.read_limits(limit, page_size)
+ page = self.page(
+ area_code=area_code,
+ contains=contains,
+ sms_enabled=sms_enabled,
+ mms_enabled=mms_enabled,
+ voice_enabled=voice_enabled,
+ exclude_all_address_required=exclude_all_address_required,
+ exclude_local_address_required=exclude_local_address_required,
+ exclude_foreign_address_required=exclude_foreign_address_required,
+ beta=beta,
+ near_number=near_number,
+ near_lat_long=near_lat_long,
+ distance=distance,
+ in_postal_code=in_postal_code,
+ in_region=in_region,
+ in_rate_center=in_rate_center,
+ in_lata=in_lata,
+ in_locality=in_locality,
+ fax_enabled=fax_enabled,
+ page_size=limits["page_size"],
+ )
+
+ return self._version.stream(page, limits["limit"])
+
+ async def stream_async(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> AsyncIterator[MobileInstance]:
+ """
+ Asynchronously streams MobileInstance records from the API as a generator stream.
+ This operation lazily loads records as efficiently as possible until the limit
+ is reached.
+ The results are returned as a generator, so this operation is memory efficient.
+
+ :param int area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param str contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-2) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-3). If specified, this value must have at least two characters.
+ :param bool sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param bool mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param bool voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param bool exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param str near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param str near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param int distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param str in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param str in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param bool fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param limit: Upper limit for the number of records to return. stream()
+ guarantees to never return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, stream() will attempt to read the
+ limit with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: Generator that will yield up to limit results
+ """
+ limits = self._version.read_limits(limit, page_size)
+ page = await self.page_async(
+ area_code=area_code,
+ contains=contains,
+ sms_enabled=sms_enabled,
+ mms_enabled=mms_enabled,
+ voice_enabled=voice_enabled,
+ exclude_all_address_required=exclude_all_address_required,
+ exclude_local_address_required=exclude_local_address_required,
+ exclude_foreign_address_required=exclude_foreign_address_required,
+ beta=beta,
+ near_number=near_number,
+ near_lat_long=near_lat_long,
+ distance=distance,
+ in_postal_code=in_postal_code,
+ in_region=in_region,
+ in_rate_center=in_rate_center,
+ in_lata=in_lata,
+ in_locality=in_locality,
+ fax_enabled=fax_enabled,
+ page_size=limits["page_size"],
+ )
+
+ return self._version.stream_async(page, limits["limit"])
+
+ def list(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> List[MobileInstance]:
+ """
+ Lists MobileInstance records from the API as a list.
+ Unlike stream(), this operation is eager and will load `limit` records into
+ memory before returning.
+
+ :param int area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param str contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-2) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-3). If specified, this value must have at least two characters.
+ :param bool sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param bool mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param bool voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param bool exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param str near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param str near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param int distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param str in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param str in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param bool fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param limit: Upper limit for the number of records to return. list() guarantees
+ never to return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, list() will attempt to read the limit
+ with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: list that will contain up to limit results
+ """
+ return list(
+ self.stream(
+ area_code=area_code,
+ contains=contains,
+ sms_enabled=sms_enabled,
+ mms_enabled=mms_enabled,
+ voice_enabled=voice_enabled,
+ exclude_all_address_required=exclude_all_address_required,
+ exclude_local_address_required=exclude_local_address_required,
+ exclude_foreign_address_required=exclude_foreign_address_required,
+ beta=beta,
+ near_number=near_number,
+ near_lat_long=near_lat_long,
+ distance=distance,
+ in_postal_code=in_postal_code,
+ in_region=in_region,
+ in_rate_center=in_rate_center,
+ in_lata=in_lata,
+ in_locality=in_locality,
+ fax_enabled=fax_enabled,
+ limit=limit,
+ page_size=page_size,
+ )
+ )
+
+ async def list_async(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> List[MobileInstance]:
+ """
+ Asynchronously lists MobileInstance records from the API as a list.
+ Unlike stream(), this operation is eager and will load `limit` records into
+ memory before returning.
+
+ :param int area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param str contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-2) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-3). If specified, this value must have at least two characters.
+ :param bool sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param bool mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param bool voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param bool exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param str near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param str near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param int distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param str in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param str in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param bool fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param limit: Upper limit for the number of records to return. list() guarantees
+ never to return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, list() will attempt to read the limit
+ with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: list that will contain up to limit results
+ """
+ return [
+ record
+ async for record in await self.stream_async(
+ area_code=area_code,
+ contains=contains,
+ sms_enabled=sms_enabled,
+ mms_enabled=mms_enabled,
+ voice_enabled=voice_enabled,
+ exclude_all_address_required=exclude_all_address_required,
+ exclude_local_address_required=exclude_local_address_required,
+ exclude_foreign_address_required=exclude_foreign_address_required,
+ beta=beta,
+ near_number=near_number,
+ near_lat_long=near_lat_long,
+ distance=distance,
+ in_postal_code=in_postal_code,
+ in_region=in_region,
+ in_rate_center=in_rate_center,
+ in_lata=in_lata,
+ in_locality=in_locality,
+ fax_enabled=fax_enabled,
+ limit=limit,
+ page_size=page_size,
+ )
+ ]
+
+ def page(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ page_token: Union[str, object] = values.unset,
+ page_number: Union[int, object] = values.unset,
+ page_size: Union[int, object] = values.unset,
+ ) -> MobilePage:
+ """
+ Retrieve a single page of MobileInstance records from the API.
+ Request is executed immediately
+
+ :param area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-2) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-3). If specified, this value must have at least two characters.
+ :param sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param page_token: PageToken provided by the API
+ :param page_number: Page Number, this value is simply for client state
+ :param page_size: Number of records to return, defaults to 50
+
+ :returns: Page of MobileInstance
+ """
+ data = values.of(
+ {
+ "AreaCode": area_code,
+ "Contains": contains,
+ "SmsEnabled": serialize.boolean_to_string(sms_enabled),
+ "MmsEnabled": serialize.boolean_to_string(mms_enabled),
+ "VoiceEnabled": serialize.boolean_to_string(voice_enabled),
+ "ExcludeAllAddressRequired": serialize.boolean_to_string(
+ exclude_all_address_required
+ ),
+ "ExcludeLocalAddressRequired": serialize.boolean_to_string(
+ exclude_local_address_required
+ ),
+ "ExcludeForeignAddressRequired": serialize.boolean_to_string(
+ exclude_foreign_address_required
+ ),
+ "Beta": serialize.boolean_to_string(beta),
+ "NearNumber": near_number,
+ "NearLatLong": near_lat_long,
+ "Distance": distance,
+ "InPostalCode": in_postal_code,
+ "InRegion": in_region,
+ "InRateCenter": in_rate_center,
+ "InLata": in_lata,
+ "InLocality": in_locality,
+ "FaxEnabled": serialize.boolean_to_string(fax_enabled),
+ "PageToken": page_token,
+ "Page": page_number,
+ "PageSize": page_size,
+ }
+ )
+
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ response = self._version.page(
+ method="GET", uri=self._uri, params=data, headers=headers
+ )
+ return MobilePage(self._version, response, self._solution)
+
+ async def page_async(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ page_token: Union[str, object] = values.unset,
+ page_number: Union[int, object] = values.unset,
+ page_size: Union[int, object] = values.unset,
+ ) -> MobilePage:
+ """
+ Asynchronously retrieve a single page of MobileInstance records from the API.
+ Request is executed immediately
+
+ :param area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-2) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-3). If specified, this value must have at least two characters.
+ :param sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param page_token: PageToken provided by the API
+ :param page_number: Page Number, this value is simply for client state
+ :param page_size: Number of records to return, defaults to 50
+
+ :returns: Page of MobileInstance
+ """
+ data = values.of(
+ {
+ "AreaCode": area_code,
+ "Contains": contains,
+ "SmsEnabled": serialize.boolean_to_string(sms_enabled),
+ "MmsEnabled": serialize.boolean_to_string(mms_enabled),
+ "VoiceEnabled": serialize.boolean_to_string(voice_enabled),
+ "ExcludeAllAddressRequired": serialize.boolean_to_string(
+ exclude_all_address_required
+ ),
+ "ExcludeLocalAddressRequired": serialize.boolean_to_string(
+ exclude_local_address_required
+ ),
+ "ExcludeForeignAddressRequired": serialize.boolean_to_string(
+ exclude_foreign_address_required
+ ),
+ "Beta": serialize.boolean_to_string(beta),
+ "NearNumber": near_number,
+ "NearLatLong": near_lat_long,
+ "Distance": distance,
+ "InPostalCode": in_postal_code,
+ "InRegion": in_region,
+ "InRateCenter": in_rate_center,
+ "InLata": in_lata,
+ "InLocality": in_locality,
+ "FaxEnabled": serialize.boolean_to_string(fax_enabled),
+ "PageToken": page_token,
+ "Page": page_number,
+ "PageSize": page_size,
+ }
+ )
+
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ response = await self._version.page_async(
+ method="GET", uri=self._uri, params=data, headers=headers
+ )
+ return MobilePage(self._version, response, self._solution)
+
+ def get_page(self, target_url: str) -> MobilePage:
+ """
+ Retrieve a specific page of MobileInstance records from the API.
+ Request is executed immediately
+
+ :param target_url: API-generated URL for the requested results page
+
+ :returns: Page of MobileInstance
+ """
+ response = self._version.domain.twilio.request("GET", target_url)
+ return MobilePage(self._version, response, self._solution)
+
+ async def get_page_async(self, target_url: str) -> MobilePage:
+ """
+ Asynchronously retrieve a specific page of MobileInstance records from the API.
+ Request is executed immediately
+
+ :param target_url: API-generated URL for the requested results page
+
+ :returns: Page of MobileInstance
+ """
+ response = await self._version.domain.twilio.request_async("GET", target_url)
+ return MobilePage(self._version, response, self._solution)
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/national.py b/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/national.py
new file mode 100644
index 00000000..a5e92642
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/national.py
@@ -0,0 +1,664 @@
+r"""
+ This code was generated by
+ ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __
+ | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/
+ | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \
+
+ Twilio - Api
+ This is the public Twilio REST API.
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ https://openapi-generator.tech
+ Do not edit the class manually.
+"""
+
+from typing import Any, Dict, List, Optional, Union, Iterator, AsyncIterator
+from twilio.base import deserialize, serialize, values
+
+from twilio.base.instance_resource import InstanceResource
+from twilio.base.list_resource import ListResource
+from twilio.base.version import Version
+from twilio.base.page import Page
+
+
+class NationalInstance(InstanceResource):
+ """
+ :ivar friendly_name: A formatted version of the phone number.
+ :ivar phone_number: The phone number in [E.164](https://www.twilio.com/docs/glossary/what-e164) format, which consists of a + followed by the country code and subscriber number.
+ :ivar lata: The [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) of this phone number. Available for only phone numbers from the US and Canada.
+ :ivar locality: The locality or city of this phone number's location.
+ :ivar rate_center: The [rate center](https://en.wikipedia.org/wiki/Telephone_exchange) of this phone number. Available for only phone numbers from the US and Canada.
+ :ivar latitude: The latitude of this phone number's location. Available for only phone numbers from the US and Canada.
+ :ivar longitude: The longitude of this phone number's location. Available for only phone numbers from the US and Canada.
+ :ivar region: The two-letter state or province abbreviation of this phone number's location. Available for only phone numbers from the US and Canada.
+ :ivar postal_code: The postal or ZIP code of this phone number's location. Available for only phone numbers from the US and Canada.
+ :ivar iso_country: The [ISO country code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) of this phone number.
+ :ivar address_requirements: The type of [Address](https://www.twilio.com/docs/usage/api/address) resource the phone number requires. Can be: `none`, `any`, `local`, or `foreign`. `none` means no address is required. `any` means an address is required, but it can be anywhere in the world. `local` means an address in the phone number's country is required. `foreign` means an address outside of the phone number's country is required.
+ :ivar beta: Whether the phone number is new to the Twilio platform. Can be: `true` or `false`.
+ :ivar capabilities:
+ """
+
+ def __init__(
+ self,
+ version: Version,
+ payload: Dict[str, Any],
+ account_sid: str,
+ country_code: str,
+ ):
+ super().__init__(version)
+
+ self.friendly_name: Optional[str] = payload.get("friendly_name")
+ self.phone_number: Optional[str] = payload.get("phone_number")
+ self.lata: Optional[str] = payload.get("lata")
+ self.locality: Optional[str] = payload.get("locality")
+ self.rate_center: Optional[str] = payload.get("rate_center")
+ self.latitude: Optional[float] = deserialize.decimal(payload.get("latitude"))
+ self.longitude: Optional[float] = deserialize.decimal(payload.get("longitude"))
+ self.region: Optional[str] = payload.get("region")
+ self.postal_code: Optional[str] = payload.get("postal_code")
+ self.iso_country: Optional[str] = payload.get("iso_country")
+ self.address_requirements: Optional[str] = payload.get("address_requirements")
+ self.beta: Optional[bool] = payload.get("beta")
+ self.capabilities: Optional[str] = payload.get("capabilities")
+
+ self._solution = {
+ "account_sid": account_sid,
+ "country_code": country_code,
+ }
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(context)
+
+
+class NationalPage(Page):
+
+ def get_instance(self, payload: Dict[str, Any]) -> NationalInstance:
+ """
+ Build an instance of NationalInstance
+
+ :param payload: Payload response from the API
+ """
+ return NationalInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ country_code=self._solution["country_code"],
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
+
+
+class NationalList(ListResource):
+
+ def __init__(self, version: Version, account_sid: str, country_code: str):
+ """
+ Initialize the NationalList
+
+ :param version: Version that contains the resource
+ :param account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) requesting the AvailablePhoneNumber resources.
+ :param country_code: The [ISO-3166-1](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code of the country from which to read phone numbers.
+
+ """
+ super().__init__(version)
+
+ # Path Solution
+ self._solution = {
+ "account_sid": account_sid,
+ "country_code": country_code,
+ }
+ self._uri = "/Accounts/{account_sid}/AvailablePhoneNumbers/{country_code}/National.json".format(
+ **self._solution
+ )
+
+ def stream(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> Iterator[NationalInstance]:
+ """
+ Streams NationalInstance records from the API as a generator stream.
+ This operation lazily loads records as efficiently as possible until the limit
+ is reached.
+ The results are returned as a generator, so this operation is memory efficient.
+
+ :param int area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param str contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-2) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-3). If specified, this value must have at least two characters.
+ :param bool sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param bool mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param bool voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param bool exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param str near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param str near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param int distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param str in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param str in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param bool fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param limit: Upper limit for the number of records to return. stream()
+ guarantees to never return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, stream() will attempt to read the
+ limit with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: Generator that will yield up to limit results
+ """
+ limits = self._version.read_limits(limit, page_size)
+ page = self.page(
+ area_code=area_code,
+ contains=contains,
+ sms_enabled=sms_enabled,
+ mms_enabled=mms_enabled,
+ voice_enabled=voice_enabled,
+ exclude_all_address_required=exclude_all_address_required,
+ exclude_local_address_required=exclude_local_address_required,
+ exclude_foreign_address_required=exclude_foreign_address_required,
+ beta=beta,
+ near_number=near_number,
+ near_lat_long=near_lat_long,
+ distance=distance,
+ in_postal_code=in_postal_code,
+ in_region=in_region,
+ in_rate_center=in_rate_center,
+ in_lata=in_lata,
+ in_locality=in_locality,
+ fax_enabled=fax_enabled,
+ page_size=limits["page_size"],
+ )
+
+ return self._version.stream(page, limits["limit"])
+
+ async def stream_async(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> AsyncIterator[NationalInstance]:
+ """
+ Asynchronously streams NationalInstance records from the API as a generator stream.
+ This operation lazily loads records as efficiently as possible until the limit
+ is reached.
+ The results are returned as a generator, so this operation is memory efficient.
+
+ :param int area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param str contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-2) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-3). If specified, this value must have at least two characters.
+ :param bool sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param bool mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param bool voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param bool exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param str near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param str near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param int distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param str in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param str in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param bool fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param limit: Upper limit for the number of records to return. stream()
+ guarantees to never return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, stream() will attempt to read the
+ limit with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: Generator that will yield up to limit results
+ """
+ limits = self._version.read_limits(limit, page_size)
+ page = await self.page_async(
+ area_code=area_code,
+ contains=contains,
+ sms_enabled=sms_enabled,
+ mms_enabled=mms_enabled,
+ voice_enabled=voice_enabled,
+ exclude_all_address_required=exclude_all_address_required,
+ exclude_local_address_required=exclude_local_address_required,
+ exclude_foreign_address_required=exclude_foreign_address_required,
+ beta=beta,
+ near_number=near_number,
+ near_lat_long=near_lat_long,
+ distance=distance,
+ in_postal_code=in_postal_code,
+ in_region=in_region,
+ in_rate_center=in_rate_center,
+ in_lata=in_lata,
+ in_locality=in_locality,
+ fax_enabled=fax_enabled,
+ page_size=limits["page_size"],
+ )
+
+ return self._version.stream_async(page, limits["limit"])
+
+ def list(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> List[NationalInstance]:
+ """
+ Lists NationalInstance records from the API as a list.
+ Unlike stream(), this operation is eager and will load `limit` records into
+ memory before returning.
+
+ :param int area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param str contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-2) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-3). If specified, this value must have at least two characters.
+ :param bool sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param bool mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param bool voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param bool exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param str near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param str near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param int distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param str in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param str in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param bool fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param limit: Upper limit for the number of records to return. list() guarantees
+ never to return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, list() will attempt to read the limit
+ with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: list that will contain up to limit results
+ """
+ return list(
+ self.stream(
+ area_code=area_code,
+ contains=contains,
+ sms_enabled=sms_enabled,
+ mms_enabled=mms_enabled,
+ voice_enabled=voice_enabled,
+ exclude_all_address_required=exclude_all_address_required,
+ exclude_local_address_required=exclude_local_address_required,
+ exclude_foreign_address_required=exclude_foreign_address_required,
+ beta=beta,
+ near_number=near_number,
+ near_lat_long=near_lat_long,
+ distance=distance,
+ in_postal_code=in_postal_code,
+ in_region=in_region,
+ in_rate_center=in_rate_center,
+ in_lata=in_lata,
+ in_locality=in_locality,
+ fax_enabled=fax_enabled,
+ limit=limit,
+ page_size=page_size,
+ )
+ )
+
+ async def list_async(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> List[NationalInstance]:
+ """
+ Asynchronously lists NationalInstance records from the API as a list.
+ Unlike stream(), this operation is eager and will load `limit` records into
+ memory before returning.
+
+ :param int area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param str contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-2) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-3). If specified, this value must have at least two characters.
+ :param bool sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param bool mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param bool voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param bool exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param str near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param str near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param int distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param str in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param str in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param bool fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param limit: Upper limit for the number of records to return. list() guarantees
+ never to return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, list() will attempt to read the limit
+ with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: list that will contain up to limit results
+ """
+ return [
+ record
+ async for record in await self.stream_async(
+ area_code=area_code,
+ contains=contains,
+ sms_enabled=sms_enabled,
+ mms_enabled=mms_enabled,
+ voice_enabled=voice_enabled,
+ exclude_all_address_required=exclude_all_address_required,
+ exclude_local_address_required=exclude_local_address_required,
+ exclude_foreign_address_required=exclude_foreign_address_required,
+ beta=beta,
+ near_number=near_number,
+ near_lat_long=near_lat_long,
+ distance=distance,
+ in_postal_code=in_postal_code,
+ in_region=in_region,
+ in_rate_center=in_rate_center,
+ in_lata=in_lata,
+ in_locality=in_locality,
+ fax_enabled=fax_enabled,
+ limit=limit,
+ page_size=page_size,
+ )
+ ]
+
+ def page(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ page_token: Union[str, object] = values.unset,
+ page_number: Union[int, object] = values.unset,
+ page_size: Union[int, object] = values.unset,
+ ) -> NationalPage:
+ """
+ Retrieve a single page of NationalInstance records from the API.
+ Request is executed immediately
+
+ :param area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-2) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-3). If specified, this value must have at least two characters.
+ :param sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param page_token: PageToken provided by the API
+ :param page_number: Page Number, this value is simply for client state
+ :param page_size: Number of records to return, defaults to 50
+
+ :returns: Page of NationalInstance
+ """
+ data = values.of(
+ {
+ "AreaCode": area_code,
+ "Contains": contains,
+ "SmsEnabled": serialize.boolean_to_string(sms_enabled),
+ "MmsEnabled": serialize.boolean_to_string(mms_enabled),
+ "VoiceEnabled": serialize.boolean_to_string(voice_enabled),
+ "ExcludeAllAddressRequired": serialize.boolean_to_string(
+ exclude_all_address_required
+ ),
+ "ExcludeLocalAddressRequired": serialize.boolean_to_string(
+ exclude_local_address_required
+ ),
+ "ExcludeForeignAddressRequired": serialize.boolean_to_string(
+ exclude_foreign_address_required
+ ),
+ "Beta": serialize.boolean_to_string(beta),
+ "NearNumber": near_number,
+ "NearLatLong": near_lat_long,
+ "Distance": distance,
+ "InPostalCode": in_postal_code,
+ "InRegion": in_region,
+ "InRateCenter": in_rate_center,
+ "InLata": in_lata,
+ "InLocality": in_locality,
+ "FaxEnabled": serialize.boolean_to_string(fax_enabled),
+ "PageToken": page_token,
+ "Page": page_number,
+ "PageSize": page_size,
+ }
+ )
+
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ response = self._version.page(
+ method="GET", uri=self._uri, params=data, headers=headers
+ )
+ return NationalPage(self._version, response, self._solution)
+
+ async def page_async(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ page_token: Union[str, object] = values.unset,
+ page_number: Union[int, object] = values.unset,
+ page_size: Union[int, object] = values.unset,
+ ) -> NationalPage:
+ """
+ Asynchronously retrieve a single page of NationalInstance records from the API.
+ Request is executed immediately
+
+ :param area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-2) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-3). If specified, this value must have at least two characters.
+ :param sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param page_token: PageToken provided by the API
+ :param page_number: Page Number, this value is simply for client state
+ :param page_size: Number of records to return, defaults to 50
+
+ :returns: Page of NationalInstance
+ """
+ data = values.of(
+ {
+ "AreaCode": area_code,
+ "Contains": contains,
+ "SmsEnabled": serialize.boolean_to_string(sms_enabled),
+ "MmsEnabled": serialize.boolean_to_string(mms_enabled),
+ "VoiceEnabled": serialize.boolean_to_string(voice_enabled),
+ "ExcludeAllAddressRequired": serialize.boolean_to_string(
+ exclude_all_address_required
+ ),
+ "ExcludeLocalAddressRequired": serialize.boolean_to_string(
+ exclude_local_address_required
+ ),
+ "ExcludeForeignAddressRequired": serialize.boolean_to_string(
+ exclude_foreign_address_required
+ ),
+ "Beta": serialize.boolean_to_string(beta),
+ "NearNumber": near_number,
+ "NearLatLong": near_lat_long,
+ "Distance": distance,
+ "InPostalCode": in_postal_code,
+ "InRegion": in_region,
+ "InRateCenter": in_rate_center,
+ "InLata": in_lata,
+ "InLocality": in_locality,
+ "FaxEnabled": serialize.boolean_to_string(fax_enabled),
+ "PageToken": page_token,
+ "Page": page_number,
+ "PageSize": page_size,
+ }
+ )
+
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ response = await self._version.page_async(
+ method="GET", uri=self._uri, params=data, headers=headers
+ )
+ return NationalPage(self._version, response, self._solution)
+
+ def get_page(self, target_url: str) -> NationalPage:
+ """
+ Retrieve a specific page of NationalInstance records from the API.
+ Request is executed immediately
+
+ :param target_url: API-generated URL for the requested results page
+
+ :returns: Page of NationalInstance
+ """
+ response = self._version.domain.twilio.request("GET", target_url)
+ return NationalPage(self._version, response, self._solution)
+
+ async def get_page_async(self, target_url: str) -> NationalPage:
+ """
+ Asynchronously retrieve a specific page of NationalInstance records from the API.
+ Request is executed immediately
+
+ :param target_url: API-generated URL for the requested results page
+
+ :returns: Page of NationalInstance
+ """
+ response = await self._version.domain.twilio.request_async("GET", target_url)
+ return NationalPage(self._version, response, self._solution)
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/shared_cost.py b/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/shared_cost.py
new file mode 100644
index 00000000..3a9c02ba
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/shared_cost.py
@@ -0,0 +1,664 @@
+r"""
+ This code was generated by
+ ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __
+ | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/
+ | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \
+
+ Twilio - Api
+ This is the public Twilio REST API.
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ https://openapi-generator.tech
+ Do not edit the class manually.
+"""
+
+from typing import Any, Dict, List, Optional, Union, Iterator, AsyncIterator
+from twilio.base import deserialize, serialize, values
+
+from twilio.base.instance_resource import InstanceResource
+from twilio.base.list_resource import ListResource
+from twilio.base.version import Version
+from twilio.base.page import Page
+
+
+class SharedCostInstance(InstanceResource):
+ """
+ :ivar friendly_name: A formatted version of the phone number.
+ :ivar phone_number: The phone number in [E.164](https://www.twilio.com/docs/glossary/what-e164) format, which consists of a + followed by the country code and subscriber number.
+ :ivar lata: The [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) of this phone number. Available for only phone numbers from the US and Canada.
+ :ivar locality: The locality or city of this phone number's location.
+ :ivar rate_center: The [rate center](https://en.wikipedia.org/wiki/Telephone_exchange) of this phone number. Available for only phone numbers from the US and Canada.
+ :ivar latitude: The latitude of this phone number's location. Available for only phone numbers from the US and Canada.
+ :ivar longitude: The longitude of this phone number's location. Available for only phone numbers from the US and Canada.
+ :ivar region: The two-letter state or province abbreviation of this phone number's location. Available for only phone numbers from the US and Canada.
+ :ivar postal_code: The postal or ZIP code of this phone number's location. Available for only phone numbers from the US and Canada.
+ :ivar iso_country: The [ISO country code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) of this phone number.
+ :ivar address_requirements: The type of [Address](https://www.twilio.com/docs/usage/api/address) resource the phone number requires. Can be: `none`, `any`, `local`, or `foreign`. `none` means no address is required. `any` means an address is required, but it can be anywhere in the world. `local` means an address in the phone number's country is required. `foreign` means an address outside of the phone number's country is required.
+ :ivar beta: Whether the phone number is new to the Twilio platform. Can be: `true` or `false`.
+ :ivar capabilities:
+ """
+
+ def __init__(
+ self,
+ version: Version,
+ payload: Dict[str, Any],
+ account_sid: str,
+ country_code: str,
+ ):
+ super().__init__(version)
+
+ self.friendly_name: Optional[str] = payload.get("friendly_name")
+ self.phone_number: Optional[str] = payload.get("phone_number")
+ self.lata: Optional[str] = payload.get("lata")
+ self.locality: Optional[str] = payload.get("locality")
+ self.rate_center: Optional[str] = payload.get("rate_center")
+ self.latitude: Optional[float] = deserialize.decimal(payload.get("latitude"))
+ self.longitude: Optional[float] = deserialize.decimal(payload.get("longitude"))
+ self.region: Optional[str] = payload.get("region")
+ self.postal_code: Optional[str] = payload.get("postal_code")
+ self.iso_country: Optional[str] = payload.get("iso_country")
+ self.address_requirements: Optional[str] = payload.get("address_requirements")
+ self.beta: Optional[bool] = payload.get("beta")
+ self.capabilities: Optional[str] = payload.get("capabilities")
+
+ self._solution = {
+ "account_sid": account_sid,
+ "country_code": country_code,
+ }
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(context)
+
+
+class SharedCostPage(Page):
+
+ def get_instance(self, payload: Dict[str, Any]) -> SharedCostInstance:
+ """
+ Build an instance of SharedCostInstance
+
+ :param payload: Payload response from the API
+ """
+ return SharedCostInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ country_code=self._solution["country_code"],
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
+
+
+class SharedCostList(ListResource):
+
+ def __init__(self, version: Version, account_sid: str, country_code: str):
+ """
+ Initialize the SharedCostList
+
+ :param version: Version that contains the resource
+ :param account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) requesting the AvailablePhoneNumber resources.
+ :param country_code: The [ISO-3166-1](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code of the country from which to read phone numbers.
+
+ """
+ super().__init__(version)
+
+ # Path Solution
+ self._solution = {
+ "account_sid": account_sid,
+ "country_code": country_code,
+ }
+ self._uri = "/Accounts/{account_sid}/AvailablePhoneNumbers/{country_code}/SharedCost.json".format(
+ **self._solution
+ )
+
+ def stream(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> Iterator[SharedCostInstance]:
+ """
+ Streams SharedCostInstance records from the API as a generator stream.
+ This operation lazily loads records as efficiently as possible until the limit
+ is reached.
+ The results are returned as a generator, so this operation is memory efficient.
+
+ :param int area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param str contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-2) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-3). If specified, this value must have at least two characters.
+ :param bool sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param bool mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param bool voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param bool exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param str near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param str near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param int distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param str in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param str in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param bool fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param limit: Upper limit for the number of records to return. stream()
+ guarantees to never return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, stream() will attempt to read the
+ limit with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: Generator that will yield up to limit results
+ """
+ limits = self._version.read_limits(limit, page_size)
+ page = self.page(
+ area_code=area_code,
+ contains=contains,
+ sms_enabled=sms_enabled,
+ mms_enabled=mms_enabled,
+ voice_enabled=voice_enabled,
+ exclude_all_address_required=exclude_all_address_required,
+ exclude_local_address_required=exclude_local_address_required,
+ exclude_foreign_address_required=exclude_foreign_address_required,
+ beta=beta,
+ near_number=near_number,
+ near_lat_long=near_lat_long,
+ distance=distance,
+ in_postal_code=in_postal_code,
+ in_region=in_region,
+ in_rate_center=in_rate_center,
+ in_lata=in_lata,
+ in_locality=in_locality,
+ fax_enabled=fax_enabled,
+ page_size=limits["page_size"],
+ )
+
+ return self._version.stream(page, limits["limit"])
+
+ async def stream_async(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> AsyncIterator[SharedCostInstance]:
+ """
+ Asynchronously streams SharedCostInstance records from the API as a generator stream.
+ This operation lazily loads records as efficiently as possible until the limit
+ is reached.
+ The results are returned as a generator, so this operation is memory efficient.
+
+ :param int area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param str contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-2) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-3). If specified, this value must have at least two characters.
+ :param bool sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param bool mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param bool voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param bool exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param str near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param str near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param int distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param str in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param str in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param bool fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param limit: Upper limit for the number of records to return. stream()
+ guarantees to never return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, stream() will attempt to read the
+ limit with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: Generator that will yield up to limit results
+ """
+ limits = self._version.read_limits(limit, page_size)
+ page = await self.page_async(
+ area_code=area_code,
+ contains=contains,
+ sms_enabled=sms_enabled,
+ mms_enabled=mms_enabled,
+ voice_enabled=voice_enabled,
+ exclude_all_address_required=exclude_all_address_required,
+ exclude_local_address_required=exclude_local_address_required,
+ exclude_foreign_address_required=exclude_foreign_address_required,
+ beta=beta,
+ near_number=near_number,
+ near_lat_long=near_lat_long,
+ distance=distance,
+ in_postal_code=in_postal_code,
+ in_region=in_region,
+ in_rate_center=in_rate_center,
+ in_lata=in_lata,
+ in_locality=in_locality,
+ fax_enabled=fax_enabled,
+ page_size=limits["page_size"],
+ )
+
+ return self._version.stream_async(page, limits["limit"])
+
+ def list(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> List[SharedCostInstance]:
+ """
+ Lists SharedCostInstance records from the API as a list.
+ Unlike stream(), this operation is eager and will load `limit` records into
+ memory before returning.
+
+ :param int area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param str contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-2) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-3). If specified, this value must have at least two characters.
+ :param bool sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param bool mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param bool voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param bool exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param str near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param str near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param int distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param str in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param str in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param bool fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param limit: Upper limit for the number of records to return. list() guarantees
+ never to return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, list() will attempt to read the limit
+ with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: list that will contain up to limit results
+ """
+ return list(
+ self.stream(
+ area_code=area_code,
+ contains=contains,
+ sms_enabled=sms_enabled,
+ mms_enabled=mms_enabled,
+ voice_enabled=voice_enabled,
+ exclude_all_address_required=exclude_all_address_required,
+ exclude_local_address_required=exclude_local_address_required,
+ exclude_foreign_address_required=exclude_foreign_address_required,
+ beta=beta,
+ near_number=near_number,
+ near_lat_long=near_lat_long,
+ distance=distance,
+ in_postal_code=in_postal_code,
+ in_region=in_region,
+ in_rate_center=in_rate_center,
+ in_lata=in_lata,
+ in_locality=in_locality,
+ fax_enabled=fax_enabled,
+ limit=limit,
+ page_size=page_size,
+ )
+ )
+
+ async def list_async(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> List[SharedCostInstance]:
+ """
+ Asynchronously lists SharedCostInstance records from the API as a list.
+ Unlike stream(), this operation is eager and will load `limit` records into
+ memory before returning.
+
+ :param int area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param str contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-2) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-3). If specified, this value must have at least two characters.
+ :param bool sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param bool mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param bool voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param bool exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param str near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param str near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param int distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param str in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param str in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param bool fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param limit: Upper limit for the number of records to return. list() guarantees
+ never to return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, list() will attempt to read the limit
+ with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: list that will contain up to limit results
+ """
+ return [
+ record
+ async for record in await self.stream_async(
+ area_code=area_code,
+ contains=contains,
+ sms_enabled=sms_enabled,
+ mms_enabled=mms_enabled,
+ voice_enabled=voice_enabled,
+ exclude_all_address_required=exclude_all_address_required,
+ exclude_local_address_required=exclude_local_address_required,
+ exclude_foreign_address_required=exclude_foreign_address_required,
+ beta=beta,
+ near_number=near_number,
+ near_lat_long=near_lat_long,
+ distance=distance,
+ in_postal_code=in_postal_code,
+ in_region=in_region,
+ in_rate_center=in_rate_center,
+ in_lata=in_lata,
+ in_locality=in_locality,
+ fax_enabled=fax_enabled,
+ limit=limit,
+ page_size=page_size,
+ )
+ ]
+
+ def page(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ page_token: Union[str, object] = values.unset,
+ page_number: Union[int, object] = values.unset,
+ page_size: Union[int, object] = values.unset,
+ ) -> SharedCostPage:
+ """
+ Retrieve a single page of SharedCostInstance records from the API.
+ Request is executed immediately
+
+ :param area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-2) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-3). If specified, this value must have at least two characters.
+ :param sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param page_token: PageToken provided by the API
+ :param page_number: Page Number, this value is simply for client state
+ :param page_size: Number of records to return, defaults to 50
+
+ :returns: Page of SharedCostInstance
+ """
+ data = values.of(
+ {
+ "AreaCode": area_code,
+ "Contains": contains,
+ "SmsEnabled": serialize.boolean_to_string(sms_enabled),
+ "MmsEnabled": serialize.boolean_to_string(mms_enabled),
+ "VoiceEnabled": serialize.boolean_to_string(voice_enabled),
+ "ExcludeAllAddressRequired": serialize.boolean_to_string(
+ exclude_all_address_required
+ ),
+ "ExcludeLocalAddressRequired": serialize.boolean_to_string(
+ exclude_local_address_required
+ ),
+ "ExcludeForeignAddressRequired": serialize.boolean_to_string(
+ exclude_foreign_address_required
+ ),
+ "Beta": serialize.boolean_to_string(beta),
+ "NearNumber": near_number,
+ "NearLatLong": near_lat_long,
+ "Distance": distance,
+ "InPostalCode": in_postal_code,
+ "InRegion": in_region,
+ "InRateCenter": in_rate_center,
+ "InLata": in_lata,
+ "InLocality": in_locality,
+ "FaxEnabled": serialize.boolean_to_string(fax_enabled),
+ "PageToken": page_token,
+ "Page": page_number,
+ "PageSize": page_size,
+ }
+ )
+
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ response = self._version.page(
+ method="GET", uri=self._uri, params=data, headers=headers
+ )
+ return SharedCostPage(self._version, response, self._solution)
+
+ async def page_async(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ page_token: Union[str, object] = values.unset,
+ page_number: Union[int, object] = values.unset,
+ page_size: Union[int, object] = values.unset,
+ ) -> SharedCostPage:
+ """
+ Asynchronously retrieve a single page of SharedCostInstance records from the API.
+ Request is executed immediately
+
+ :param area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-2) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-3). If specified, this value must have at least two characters.
+ :param sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param page_token: PageToken provided by the API
+ :param page_number: Page Number, this value is simply for client state
+ :param page_size: Number of records to return, defaults to 50
+
+ :returns: Page of SharedCostInstance
+ """
+ data = values.of(
+ {
+ "AreaCode": area_code,
+ "Contains": contains,
+ "SmsEnabled": serialize.boolean_to_string(sms_enabled),
+ "MmsEnabled": serialize.boolean_to_string(mms_enabled),
+ "VoiceEnabled": serialize.boolean_to_string(voice_enabled),
+ "ExcludeAllAddressRequired": serialize.boolean_to_string(
+ exclude_all_address_required
+ ),
+ "ExcludeLocalAddressRequired": serialize.boolean_to_string(
+ exclude_local_address_required
+ ),
+ "ExcludeForeignAddressRequired": serialize.boolean_to_string(
+ exclude_foreign_address_required
+ ),
+ "Beta": serialize.boolean_to_string(beta),
+ "NearNumber": near_number,
+ "NearLatLong": near_lat_long,
+ "Distance": distance,
+ "InPostalCode": in_postal_code,
+ "InRegion": in_region,
+ "InRateCenter": in_rate_center,
+ "InLata": in_lata,
+ "InLocality": in_locality,
+ "FaxEnabled": serialize.boolean_to_string(fax_enabled),
+ "PageToken": page_token,
+ "Page": page_number,
+ "PageSize": page_size,
+ }
+ )
+
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ response = await self._version.page_async(
+ method="GET", uri=self._uri, params=data, headers=headers
+ )
+ return SharedCostPage(self._version, response, self._solution)
+
+ def get_page(self, target_url: str) -> SharedCostPage:
+ """
+ Retrieve a specific page of SharedCostInstance records from the API.
+ Request is executed immediately
+
+ :param target_url: API-generated URL for the requested results page
+
+ :returns: Page of SharedCostInstance
+ """
+ response = self._version.domain.twilio.request("GET", target_url)
+ return SharedCostPage(self._version, response, self._solution)
+
+ async def get_page_async(self, target_url: str) -> SharedCostPage:
+ """
+ Asynchronously retrieve a specific page of SharedCostInstance records from the API.
+ Request is executed immediately
+
+ :param target_url: API-generated URL for the requested results page
+
+ :returns: Page of SharedCostInstance
+ """
+ response = await self._version.domain.twilio.request_async("GET", target_url)
+ return SharedCostPage(self._version, response, self._solution)
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/toll_free.py b/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/toll_free.py
new file mode 100644
index 00000000..de4a2d98
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/toll_free.py
@@ -0,0 +1,664 @@
+r"""
+ This code was generated by
+ ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __
+ | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/
+ | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \
+
+ Twilio - Api
+ This is the public Twilio REST API.
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ https://openapi-generator.tech
+ Do not edit the class manually.
+"""
+
+from typing import Any, Dict, List, Optional, Union, Iterator, AsyncIterator
+from twilio.base import deserialize, serialize, values
+
+from twilio.base.instance_resource import InstanceResource
+from twilio.base.list_resource import ListResource
+from twilio.base.version import Version
+from twilio.base.page import Page
+
+
+class TollFreeInstance(InstanceResource):
+ """
+ :ivar friendly_name: A formatted version of the phone number.
+ :ivar phone_number: The phone number in [E.164](https://www.twilio.com/docs/glossary/what-e164) format, which consists of a + followed by the country code and subscriber number.
+ :ivar lata: The [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) of this phone number. Available for only phone numbers from the US and Canada.
+ :ivar locality: The locality or city of this phone number's location.
+ :ivar rate_center: The [rate center](https://en.wikipedia.org/wiki/Telephone_exchange) of this phone number. Available for only phone numbers from the US and Canada.
+ :ivar latitude: The latitude of this phone number's location. Available for only phone numbers from the US and Canada.
+ :ivar longitude: The longitude of this phone number's location. Available for only phone numbers from the US and Canada.
+ :ivar region: The two-letter state or province abbreviation of this phone number's location. Available for only phone numbers from the US and Canada.
+ :ivar postal_code: The postal or ZIP code of this phone number's location. Available for only phone numbers from the US and Canada.
+ :ivar iso_country: The [ISO country code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) of this phone number.
+ :ivar address_requirements: The type of [Address](https://www.twilio.com/docs/usage/api/address) resource the phone number requires. Can be: `none`, `any`, `local`, or `foreign`. `none` means no address is required. `any` means an address is required, but it can be anywhere in the world. `local` means an address in the phone number's country is required. `foreign` means an address outside of the phone number's country is required.
+ :ivar beta: Whether the phone number is new to the Twilio platform. Can be: `true` or `false`.
+ :ivar capabilities:
+ """
+
+ def __init__(
+ self,
+ version: Version,
+ payload: Dict[str, Any],
+ account_sid: str,
+ country_code: str,
+ ):
+ super().__init__(version)
+
+ self.friendly_name: Optional[str] = payload.get("friendly_name")
+ self.phone_number: Optional[str] = payload.get("phone_number")
+ self.lata: Optional[str] = payload.get("lata")
+ self.locality: Optional[str] = payload.get("locality")
+ self.rate_center: Optional[str] = payload.get("rate_center")
+ self.latitude: Optional[float] = deserialize.decimal(payload.get("latitude"))
+ self.longitude: Optional[float] = deserialize.decimal(payload.get("longitude"))
+ self.region: Optional[str] = payload.get("region")
+ self.postal_code: Optional[str] = payload.get("postal_code")
+ self.iso_country: Optional[str] = payload.get("iso_country")
+ self.address_requirements: Optional[str] = payload.get("address_requirements")
+ self.beta: Optional[bool] = payload.get("beta")
+ self.capabilities: Optional[str] = payload.get("capabilities")
+
+ self._solution = {
+ "account_sid": account_sid,
+ "country_code": country_code,
+ }
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(context)
+
+
+class TollFreePage(Page):
+
+ def get_instance(self, payload: Dict[str, Any]) -> TollFreeInstance:
+ """
+ Build an instance of TollFreeInstance
+
+ :param payload: Payload response from the API
+ """
+ return TollFreeInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ country_code=self._solution["country_code"],
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
+
+
+class TollFreeList(ListResource):
+
+ def __init__(self, version: Version, account_sid: str, country_code: str):
+ """
+ Initialize the TollFreeList
+
+ :param version: Version that contains the resource
+ :param account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) requesting the AvailablePhoneNumber resources.
+ :param country_code: The [ISO-3166-1](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code of the country from which to read phone numbers.
+
+ """
+ super().__init__(version)
+
+ # Path Solution
+ self._solution = {
+ "account_sid": account_sid,
+ "country_code": country_code,
+ }
+ self._uri = "/Accounts/{account_sid}/AvailablePhoneNumbers/{country_code}/TollFree.json".format(
+ **self._solution
+ )
+
+ def stream(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> Iterator[TollFreeInstance]:
+ """
+ Streams TollFreeInstance records from the API as a generator stream.
+ This operation lazily loads records as efficiently as possible until the limit
+ is reached.
+ The results are returned as a generator, so this operation is memory efficient.
+
+ :param int area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param str contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-2) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-3). If specified, this value must have at least two characters.
+ :param bool sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param bool mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param bool voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param bool exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param str near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param str near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param int distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param str in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param str in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param bool fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param limit: Upper limit for the number of records to return. stream()
+ guarantees to never return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, stream() will attempt to read the
+ limit with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: Generator that will yield up to limit results
+ """
+ limits = self._version.read_limits(limit, page_size)
+ page = self.page(
+ area_code=area_code,
+ contains=contains,
+ sms_enabled=sms_enabled,
+ mms_enabled=mms_enabled,
+ voice_enabled=voice_enabled,
+ exclude_all_address_required=exclude_all_address_required,
+ exclude_local_address_required=exclude_local_address_required,
+ exclude_foreign_address_required=exclude_foreign_address_required,
+ beta=beta,
+ near_number=near_number,
+ near_lat_long=near_lat_long,
+ distance=distance,
+ in_postal_code=in_postal_code,
+ in_region=in_region,
+ in_rate_center=in_rate_center,
+ in_lata=in_lata,
+ in_locality=in_locality,
+ fax_enabled=fax_enabled,
+ page_size=limits["page_size"],
+ )
+
+ return self._version.stream(page, limits["limit"])
+
+ async def stream_async(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> AsyncIterator[TollFreeInstance]:
+ """
+ Asynchronously streams TollFreeInstance records from the API as a generator stream.
+ This operation lazily loads records as efficiently as possible until the limit
+ is reached.
+ The results are returned as a generator, so this operation is memory efficient.
+
+ :param int area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param str contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-2) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-3). If specified, this value must have at least two characters.
+ :param bool sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param bool mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param bool voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param bool exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param str near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param str near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param int distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param str in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param str in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param bool fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param limit: Upper limit for the number of records to return. stream()
+ guarantees to never return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, stream() will attempt to read the
+ limit with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: Generator that will yield up to limit results
+ """
+ limits = self._version.read_limits(limit, page_size)
+ page = await self.page_async(
+ area_code=area_code,
+ contains=contains,
+ sms_enabled=sms_enabled,
+ mms_enabled=mms_enabled,
+ voice_enabled=voice_enabled,
+ exclude_all_address_required=exclude_all_address_required,
+ exclude_local_address_required=exclude_local_address_required,
+ exclude_foreign_address_required=exclude_foreign_address_required,
+ beta=beta,
+ near_number=near_number,
+ near_lat_long=near_lat_long,
+ distance=distance,
+ in_postal_code=in_postal_code,
+ in_region=in_region,
+ in_rate_center=in_rate_center,
+ in_lata=in_lata,
+ in_locality=in_locality,
+ fax_enabled=fax_enabled,
+ page_size=limits["page_size"],
+ )
+
+ return self._version.stream_async(page, limits["limit"])
+
+ def list(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> List[TollFreeInstance]:
+ """
+ Lists TollFreeInstance records from the API as a list.
+ Unlike stream(), this operation is eager and will load `limit` records into
+ memory before returning.
+
+ :param int area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param str contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-2) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-3). If specified, this value must have at least two characters.
+ :param bool sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param bool mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param bool voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param bool exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param str near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param str near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param int distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param str in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param str in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param bool fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param limit: Upper limit for the number of records to return. list() guarantees
+ never to return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, list() will attempt to read the limit
+ with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: list that will contain up to limit results
+ """
+ return list(
+ self.stream(
+ area_code=area_code,
+ contains=contains,
+ sms_enabled=sms_enabled,
+ mms_enabled=mms_enabled,
+ voice_enabled=voice_enabled,
+ exclude_all_address_required=exclude_all_address_required,
+ exclude_local_address_required=exclude_local_address_required,
+ exclude_foreign_address_required=exclude_foreign_address_required,
+ beta=beta,
+ near_number=near_number,
+ near_lat_long=near_lat_long,
+ distance=distance,
+ in_postal_code=in_postal_code,
+ in_region=in_region,
+ in_rate_center=in_rate_center,
+ in_lata=in_lata,
+ in_locality=in_locality,
+ fax_enabled=fax_enabled,
+ limit=limit,
+ page_size=page_size,
+ )
+ )
+
+ async def list_async(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> List[TollFreeInstance]:
+ """
+ Asynchronously lists TollFreeInstance records from the API as a list.
+ Unlike stream(), this operation is eager and will load `limit` records into
+ memory before returning.
+
+ :param int area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param str contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-2) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-3). If specified, this value must have at least two characters.
+ :param bool sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param bool mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param bool voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param bool exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param str near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param str near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param int distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param str in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param str in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param bool fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param limit: Upper limit for the number of records to return. list() guarantees
+ never to return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, list() will attempt to read the limit
+ with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: list that will contain up to limit results
+ """
+ return [
+ record
+ async for record in await self.stream_async(
+ area_code=area_code,
+ contains=contains,
+ sms_enabled=sms_enabled,
+ mms_enabled=mms_enabled,
+ voice_enabled=voice_enabled,
+ exclude_all_address_required=exclude_all_address_required,
+ exclude_local_address_required=exclude_local_address_required,
+ exclude_foreign_address_required=exclude_foreign_address_required,
+ beta=beta,
+ near_number=near_number,
+ near_lat_long=near_lat_long,
+ distance=distance,
+ in_postal_code=in_postal_code,
+ in_region=in_region,
+ in_rate_center=in_rate_center,
+ in_lata=in_lata,
+ in_locality=in_locality,
+ fax_enabled=fax_enabled,
+ limit=limit,
+ page_size=page_size,
+ )
+ ]
+
+ def page(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ page_token: Union[str, object] = values.unset,
+ page_number: Union[int, object] = values.unset,
+ page_size: Union[int, object] = values.unset,
+ ) -> TollFreePage:
+ """
+ Retrieve a single page of TollFreeInstance records from the API.
+ Request is executed immediately
+
+ :param area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-2) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-3). If specified, this value must have at least two characters.
+ :param sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param page_token: PageToken provided by the API
+ :param page_number: Page Number, this value is simply for client state
+ :param page_size: Number of records to return, defaults to 50
+
+ :returns: Page of TollFreeInstance
+ """
+ data = values.of(
+ {
+ "AreaCode": area_code,
+ "Contains": contains,
+ "SmsEnabled": serialize.boolean_to_string(sms_enabled),
+ "MmsEnabled": serialize.boolean_to_string(mms_enabled),
+ "VoiceEnabled": serialize.boolean_to_string(voice_enabled),
+ "ExcludeAllAddressRequired": serialize.boolean_to_string(
+ exclude_all_address_required
+ ),
+ "ExcludeLocalAddressRequired": serialize.boolean_to_string(
+ exclude_local_address_required
+ ),
+ "ExcludeForeignAddressRequired": serialize.boolean_to_string(
+ exclude_foreign_address_required
+ ),
+ "Beta": serialize.boolean_to_string(beta),
+ "NearNumber": near_number,
+ "NearLatLong": near_lat_long,
+ "Distance": distance,
+ "InPostalCode": in_postal_code,
+ "InRegion": in_region,
+ "InRateCenter": in_rate_center,
+ "InLata": in_lata,
+ "InLocality": in_locality,
+ "FaxEnabled": serialize.boolean_to_string(fax_enabled),
+ "PageToken": page_token,
+ "Page": page_number,
+ "PageSize": page_size,
+ }
+ )
+
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ response = self._version.page(
+ method="GET", uri=self._uri, params=data, headers=headers
+ )
+ return TollFreePage(self._version, response, self._solution)
+
+ async def page_async(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ page_token: Union[str, object] = values.unset,
+ page_number: Union[int, object] = values.unset,
+ page_size: Union[int, object] = values.unset,
+ ) -> TollFreePage:
+ """
+ Asynchronously retrieve a single page of TollFreeInstance records from the API.
+ Request is executed immediately
+
+ :param area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-2) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-3). If specified, this value must have at least two characters.
+ :param sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param page_token: PageToken provided by the API
+ :param page_number: Page Number, this value is simply for client state
+ :param page_size: Number of records to return, defaults to 50
+
+ :returns: Page of TollFreeInstance
+ """
+ data = values.of(
+ {
+ "AreaCode": area_code,
+ "Contains": contains,
+ "SmsEnabled": serialize.boolean_to_string(sms_enabled),
+ "MmsEnabled": serialize.boolean_to_string(mms_enabled),
+ "VoiceEnabled": serialize.boolean_to_string(voice_enabled),
+ "ExcludeAllAddressRequired": serialize.boolean_to_string(
+ exclude_all_address_required
+ ),
+ "ExcludeLocalAddressRequired": serialize.boolean_to_string(
+ exclude_local_address_required
+ ),
+ "ExcludeForeignAddressRequired": serialize.boolean_to_string(
+ exclude_foreign_address_required
+ ),
+ "Beta": serialize.boolean_to_string(beta),
+ "NearNumber": near_number,
+ "NearLatLong": near_lat_long,
+ "Distance": distance,
+ "InPostalCode": in_postal_code,
+ "InRegion": in_region,
+ "InRateCenter": in_rate_center,
+ "InLata": in_lata,
+ "InLocality": in_locality,
+ "FaxEnabled": serialize.boolean_to_string(fax_enabled),
+ "PageToken": page_token,
+ "Page": page_number,
+ "PageSize": page_size,
+ }
+ )
+
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ response = await self._version.page_async(
+ method="GET", uri=self._uri, params=data, headers=headers
+ )
+ return TollFreePage(self._version, response, self._solution)
+
+ def get_page(self, target_url: str) -> TollFreePage:
+ """
+ Retrieve a specific page of TollFreeInstance records from the API.
+ Request is executed immediately
+
+ :param target_url: API-generated URL for the requested results page
+
+ :returns: Page of TollFreeInstance
+ """
+ response = self._version.domain.twilio.request("GET", target_url)
+ return TollFreePage(self._version, response, self._solution)
+
+ async def get_page_async(self, target_url: str) -> TollFreePage:
+ """
+ Asynchronously retrieve a specific page of TollFreeInstance records from the API.
+ Request is executed immediately
+
+ :param target_url: API-generated URL for the requested results page
+
+ :returns: Page of TollFreeInstance
+ """
+ response = await self._version.domain.twilio.request_async("GET", target_url)
+ return TollFreePage(self._version, response, self._solution)
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/voip.py b/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/voip.py
new file mode 100644
index 00000000..9ebfae53
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/api/v2010/account/available_phone_number_country/voip.py
@@ -0,0 +1,664 @@
+r"""
+ This code was generated by
+ ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __
+ | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/
+ | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \
+
+ Twilio - Api
+ This is the public Twilio REST API.
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ https://openapi-generator.tech
+ Do not edit the class manually.
+"""
+
+from typing import Any, Dict, List, Optional, Union, Iterator, AsyncIterator
+from twilio.base import deserialize, serialize, values
+
+from twilio.base.instance_resource import InstanceResource
+from twilio.base.list_resource import ListResource
+from twilio.base.version import Version
+from twilio.base.page import Page
+
+
+class VoipInstance(InstanceResource):
+ """
+ :ivar friendly_name: A formatted version of the phone number.
+ :ivar phone_number: The phone number in [E.164](https://www.twilio.com/docs/glossary/what-e164) format, which consists of a + followed by the country code and subscriber number.
+ :ivar lata: The [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) of this phone number. Available for only phone numbers from the US and Canada.
+ :ivar locality: The locality or city of this phone number's location.
+ :ivar rate_center: The [rate center](https://en.wikipedia.org/wiki/Telephone_exchange) of this phone number. Available for only phone numbers from the US and Canada.
+ :ivar latitude: The latitude of this phone number's location. Available for only phone numbers from the US and Canada.
+ :ivar longitude: The longitude of this phone number's location. Available for only phone numbers from the US and Canada.
+ :ivar region: The two-letter state or province abbreviation of this phone number's location. Available for only phone numbers from the US and Canada.
+ :ivar postal_code: The postal or ZIP code of this phone number's location. Available for only phone numbers from the US and Canada.
+ :ivar iso_country: The [ISO country code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) of this phone number.
+ :ivar address_requirements: The type of [Address](https://www.twilio.com/docs/usage/api/address) resource the phone number requires. Can be: `none`, `any`, `local`, or `foreign`. `none` means no address is required. `any` means an address is required, but it can be anywhere in the world. `local` means an address in the phone number's country is required. `foreign` means an address outside of the phone number's country is required.
+ :ivar beta: Whether the phone number is new to the Twilio platform. Can be: `true` or `false`.
+ :ivar capabilities:
+ """
+
+ def __init__(
+ self,
+ version: Version,
+ payload: Dict[str, Any],
+ account_sid: str,
+ country_code: str,
+ ):
+ super().__init__(version)
+
+ self.friendly_name: Optional[str] = payload.get("friendly_name")
+ self.phone_number: Optional[str] = payload.get("phone_number")
+ self.lata: Optional[str] = payload.get("lata")
+ self.locality: Optional[str] = payload.get("locality")
+ self.rate_center: Optional[str] = payload.get("rate_center")
+ self.latitude: Optional[float] = deserialize.decimal(payload.get("latitude"))
+ self.longitude: Optional[float] = deserialize.decimal(payload.get("longitude"))
+ self.region: Optional[str] = payload.get("region")
+ self.postal_code: Optional[str] = payload.get("postal_code")
+ self.iso_country: Optional[str] = payload.get("iso_country")
+ self.address_requirements: Optional[str] = payload.get("address_requirements")
+ self.beta: Optional[bool] = payload.get("beta")
+ self.capabilities: Optional[str] = payload.get("capabilities")
+
+ self._solution = {
+ "account_sid": account_sid,
+ "country_code": country_code,
+ }
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(context)
+
+
+class VoipPage(Page):
+
+ def get_instance(self, payload: Dict[str, Any]) -> VoipInstance:
+ """
+ Build an instance of VoipInstance
+
+ :param payload: Payload response from the API
+ """
+ return VoipInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ country_code=self._solution["country_code"],
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
+
+
+class VoipList(ListResource):
+
+ def __init__(self, version: Version, account_sid: str, country_code: str):
+ """
+ Initialize the VoipList
+
+ :param version: Version that contains the resource
+ :param account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) requesting the AvailablePhoneNumber resources.
+ :param country_code: The [ISO-3166-1](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code of the country from which to read phone numbers.
+
+ """
+ super().__init__(version)
+
+ # Path Solution
+ self._solution = {
+ "account_sid": account_sid,
+ "country_code": country_code,
+ }
+ self._uri = "/Accounts/{account_sid}/AvailablePhoneNumbers/{country_code}/Voip.json".format(
+ **self._solution
+ )
+
+ def stream(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> Iterator[VoipInstance]:
+ """
+ Streams VoipInstance records from the API as a generator stream.
+ This operation lazily loads records as efficiently as possible until the limit
+ is reached.
+ The results are returned as a generator, so this operation is memory efficient.
+
+ :param int area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param str contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-2) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-3). If specified, this value must have at least two characters.
+ :param bool sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param bool mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param bool voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param bool exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param str near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param str near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param int distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param str in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param str in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param bool fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param limit: Upper limit for the number of records to return. stream()
+ guarantees to never return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, stream() will attempt to read the
+ limit with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: Generator that will yield up to limit results
+ """
+ limits = self._version.read_limits(limit, page_size)
+ page = self.page(
+ area_code=area_code,
+ contains=contains,
+ sms_enabled=sms_enabled,
+ mms_enabled=mms_enabled,
+ voice_enabled=voice_enabled,
+ exclude_all_address_required=exclude_all_address_required,
+ exclude_local_address_required=exclude_local_address_required,
+ exclude_foreign_address_required=exclude_foreign_address_required,
+ beta=beta,
+ near_number=near_number,
+ near_lat_long=near_lat_long,
+ distance=distance,
+ in_postal_code=in_postal_code,
+ in_region=in_region,
+ in_rate_center=in_rate_center,
+ in_lata=in_lata,
+ in_locality=in_locality,
+ fax_enabled=fax_enabled,
+ page_size=limits["page_size"],
+ )
+
+ return self._version.stream(page, limits["limit"])
+
+ async def stream_async(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> AsyncIterator[VoipInstance]:
+ """
+ Asynchronously streams VoipInstance records from the API as a generator stream.
+ This operation lazily loads records as efficiently as possible until the limit
+ is reached.
+ The results are returned as a generator, so this operation is memory efficient.
+
+ :param int area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param str contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-2) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-3). If specified, this value must have at least two characters.
+ :param bool sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param bool mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param bool voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param bool exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param str near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param str near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param int distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param str in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param str in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param bool fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param limit: Upper limit for the number of records to return. stream()
+ guarantees to never return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, stream() will attempt to read the
+ limit with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: Generator that will yield up to limit results
+ """
+ limits = self._version.read_limits(limit, page_size)
+ page = await self.page_async(
+ area_code=area_code,
+ contains=contains,
+ sms_enabled=sms_enabled,
+ mms_enabled=mms_enabled,
+ voice_enabled=voice_enabled,
+ exclude_all_address_required=exclude_all_address_required,
+ exclude_local_address_required=exclude_local_address_required,
+ exclude_foreign_address_required=exclude_foreign_address_required,
+ beta=beta,
+ near_number=near_number,
+ near_lat_long=near_lat_long,
+ distance=distance,
+ in_postal_code=in_postal_code,
+ in_region=in_region,
+ in_rate_center=in_rate_center,
+ in_lata=in_lata,
+ in_locality=in_locality,
+ fax_enabled=fax_enabled,
+ page_size=limits["page_size"],
+ )
+
+ return self._version.stream_async(page, limits["limit"])
+
+ def list(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> List[VoipInstance]:
+ """
+ Lists VoipInstance records from the API as a list.
+ Unlike stream(), this operation is eager and will load `limit` records into
+ memory before returning.
+
+ :param int area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param str contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-2) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-3). If specified, this value must have at least two characters.
+ :param bool sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param bool mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param bool voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param bool exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param str near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param str near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param int distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param str in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param str in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param bool fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param limit: Upper limit for the number of records to return. list() guarantees
+ never to return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, list() will attempt to read the limit
+ with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: list that will contain up to limit results
+ """
+ return list(
+ self.stream(
+ area_code=area_code,
+ contains=contains,
+ sms_enabled=sms_enabled,
+ mms_enabled=mms_enabled,
+ voice_enabled=voice_enabled,
+ exclude_all_address_required=exclude_all_address_required,
+ exclude_local_address_required=exclude_local_address_required,
+ exclude_foreign_address_required=exclude_foreign_address_required,
+ beta=beta,
+ near_number=near_number,
+ near_lat_long=near_lat_long,
+ distance=distance,
+ in_postal_code=in_postal_code,
+ in_region=in_region,
+ in_rate_center=in_rate_center,
+ in_lata=in_lata,
+ in_locality=in_locality,
+ fax_enabled=fax_enabled,
+ limit=limit,
+ page_size=page_size,
+ )
+ )
+
+ async def list_async(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> List[VoipInstance]:
+ """
+ Asynchronously lists VoipInstance records from the API as a list.
+ Unlike stream(), this operation is eager and will load `limit` records into
+ memory before returning.
+
+ :param int area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param str contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-2) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-3). If specified, this value must have at least two characters.
+ :param bool sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param bool mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param bool voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param bool exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param bool beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param str near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param str near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param int distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param str in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param str in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param str in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param bool fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param limit: Upper limit for the number of records to return. list() guarantees
+ never to return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, list() will attempt to read the limit
+ with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: list that will contain up to limit results
+ """
+ return [
+ record
+ async for record in await self.stream_async(
+ area_code=area_code,
+ contains=contains,
+ sms_enabled=sms_enabled,
+ mms_enabled=mms_enabled,
+ voice_enabled=voice_enabled,
+ exclude_all_address_required=exclude_all_address_required,
+ exclude_local_address_required=exclude_local_address_required,
+ exclude_foreign_address_required=exclude_foreign_address_required,
+ beta=beta,
+ near_number=near_number,
+ near_lat_long=near_lat_long,
+ distance=distance,
+ in_postal_code=in_postal_code,
+ in_region=in_region,
+ in_rate_center=in_rate_center,
+ in_lata=in_lata,
+ in_locality=in_locality,
+ fax_enabled=fax_enabled,
+ limit=limit,
+ page_size=page_size,
+ )
+ ]
+
+ def page(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ page_token: Union[str, object] = values.unset,
+ page_number: Union[int, object] = values.unset,
+ page_size: Union[int, object] = values.unset,
+ ) -> VoipPage:
+ """
+ Retrieve a single page of VoipInstance records from the API.
+ Request is executed immediately
+
+ :param area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-2) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-3). If specified, this value must have at least two characters.
+ :param sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param page_token: PageToken provided by the API
+ :param page_number: Page Number, this value is simply for client state
+ :param page_size: Number of records to return, defaults to 50
+
+ :returns: Page of VoipInstance
+ """
+ data = values.of(
+ {
+ "AreaCode": area_code,
+ "Contains": contains,
+ "SmsEnabled": serialize.boolean_to_string(sms_enabled),
+ "MmsEnabled": serialize.boolean_to_string(mms_enabled),
+ "VoiceEnabled": serialize.boolean_to_string(voice_enabled),
+ "ExcludeAllAddressRequired": serialize.boolean_to_string(
+ exclude_all_address_required
+ ),
+ "ExcludeLocalAddressRequired": serialize.boolean_to_string(
+ exclude_local_address_required
+ ),
+ "ExcludeForeignAddressRequired": serialize.boolean_to_string(
+ exclude_foreign_address_required
+ ),
+ "Beta": serialize.boolean_to_string(beta),
+ "NearNumber": near_number,
+ "NearLatLong": near_lat_long,
+ "Distance": distance,
+ "InPostalCode": in_postal_code,
+ "InRegion": in_region,
+ "InRateCenter": in_rate_center,
+ "InLata": in_lata,
+ "InLocality": in_locality,
+ "FaxEnabled": serialize.boolean_to_string(fax_enabled),
+ "PageToken": page_token,
+ "Page": page_number,
+ "PageSize": page_size,
+ }
+ )
+
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ response = self._version.page(
+ method="GET", uri=self._uri, params=data, headers=headers
+ )
+ return VoipPage(self._version, response, self._solution)
+
+ async def page_async(
+ self,
+ area_code: Union[int, object] = values.unset,
+ contains: Union[str, object] = values.unset,
+ sms_enabled: Union[bool, object] = values.unset,
+ mms_enabled: Union[bool, object] = values.unset,
+ voice_enabled: Union[bool, object] = values.unset,
+ exclude_all_address_required: Union[bool, object] = values.unset,
+ exclude_local_address_required: Union[bool, object] = values.unset,
+ exclude_foreign_address_required: Union[bool, object] = values.unset,
+ beta: Union[bool, object] = values.unset,
+ near_number: Union[str, object] = values.unset,
+ near_lat_long: Union[str, object] = values.unset,
+ distance: Union[int, object] = values.unset,
+ in_postal_code: Union[str, object] = values.unset,
+ in_region: Union[str, object] = values.unset,
+ in_rate_center: Union[str, object] = values.unset,
+ in_lata: Union[str, object] = values.unset,
+ in_locality: Union[str, object] = values.unset,
+ fax_enabled: Union[bool, object] = values.unset,
+ page_token: Union[str, object] = values.unset,
+ page_number: Union[int, object] = values.unset,
+ page_size: Union[int, object] = values.unset,
+ ) -> VoipPage:
+ """
+ Asynchronously retrieve a single page of VoipInstance records from the API.
+ Request is executed immediately
+
+ :param area_code: The area code of the phone numbers to read. Applies to only phone numbers in the US and Canada.
+ :param contains: The pattern on which to match phone numbers. Valid characters are `*`, `0-9`, `a-z`, and `A-Z`. The `*` character matches any single digit. For examples, see [Example 2](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-2) and [Example 3](https://www.twilio.com/docs/phone-numbers/api/availablephonenumber-resource#local-get-basic-example-3). If specified, this value must have at least two characters.
+ :param sms_enabled: Whether the phone numbers can receive text messages. Can be: `true` or `false`.
+ :param mms_enabled: Whether the phone numbers can receive MMS messages. Can be: `true` or `false`.
+ :param voice_enabled: Whether the phone numbers can receive calls. Can be: `true` or `false`.
+ :param exclude_all_address_required: Whether to exclude phone numbers that require an [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param exclude_local_address_required: Whether to exclude phone numbers that require a local [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param exclude_foreign_address_required: Whether to exclude phone numbers that require a foreign [Address](https://www.twilio.com/docs/usage/api/address). Can be: `true` or `false` and the default is `false`.
+ :param beta: Whether to read phone numbers that are new to the Twilio platform. Can be: `true` or `false` and the default is `true`.
+ :param near_number: Given a phone number, find a geographically close number within `distance` miles. Distance defaults to 25 miles. Applies to only phone numbers in the US and Canada.
+ :param near_lat_long: Given a latitude/longitude pair `lat,long` find geographically close numbers within `distance` miles. Applies to only phone numbers in the US and Canada.
+ :param distance: The search radius, in miles, for a `near_` query. Can be up to `500` and the default is `25`. Applies to only phone numbers in the US and Canada.
+ :param in_postal_code: Limit results to a particular postal code. Given a phone number, search within the same postal code as that number. Applies to only phone numbers in the US and Canada.
+ :param in_region: Limit results to a particular region, state, or province. Given a phone number, search within the same region as that number. Applies to only phone numbers in the US and Canada.
+ :param in_rate_center: Limit results to a specific rate center, or given a phone number search within the same rate center as that number. Requires `in_lata` to be set as well. Applies to only phone numbers in the US and Canada.
+ :param in_lata: Limit results to a specific local access and transport area ([LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area)). Given a phone number, search within the same [LATA](https://en.wikipedia.org/wiki/Local_access_and_transport_area) as that number. Applies to only phone numbers in the US and Canada.
+ :param in_locality: Limit results to a particular locality or city. Given a phone number, search within the same Locality as that number.
+ :param fax_enabled: Whether the phone numbers can receive faxes. Can be: `true` or `false`.
+ :param page_token: PageToken provided by the API
+ :param page_number: Page Number, this value is simply for client state
+ :param page_size: Number of records to return, defaults to 50
+
+ :returns: Page of VoipInstance
+ """
+ data = values.of(
+ {
+ "AreaCode": area_code,
+ "Contains": contains,
+ "SmsEnabled": serialize.boolean_to_string(sms_enabled),
+ "MmsEnabled": serialize.boolean_to_string(mms_enabled),
+ "VoiceEnabled": serialize.boolean_to_string(voice_enabled),
+ "ExcludeAllAddressRequired": serialize.boolean_to_string(
+ exclude_all_address_required
+ ),
+ "ExcludeLocalAddressRequired": serialize.boolean_to_string(
+ exclude_local_address_required
+ ),
+ "ExcludeForeignAddressRequired": serialize.boolean_to_string(
+ exclude_foreign_address_required
+ ),
+ "Beta": serialize.boolean_to_string(beta),
+ "NearNumber": near_number,
+ "NearLatLong": near_lat_long,
+ "Distance": distance,
+ "InPostalCode": in_postal_code,
+ "InRegion": in_region,
+ "InRateCenter": in_rate_center,
+ "InLata": in_lata,
+ "InLocality": in_locality,
+ "FaxEnabled": serialize.boolean_to_string(fax_enabled),
+ "PageToken": page_token,
+ "Page": page_number,
+ "PageSize": page_size,
+ }
+ )
+
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ response = await self._version.page_async(
+ method="GET", uri=self._uri, params=data, headers=headers
+ )
+ return VoipPage(self._version, response, self._solution)
+
+ def get_page(self, target_url: str) -> VoipPage:
+ """
+ Retrieve a specific page of VoipInstance records from the API.
+ Request is executed immediately
+
+ :param target_url: API-generated URL for the requested results page
+
+ :returns: Page of VoipInstance
+ """
+ response = self._version.domain.twilio.request("GET", target_url)
+ return VoipPage(self._version, response, self._solution)
+
+ async def get_page_async(self, target_url: str) -> VoipPage:
+ """
+ Asynchronously retrieve a specific page of VoipInstance records from the API.
+ Request is executed immediately
+
+ :param target_url: API-generated URL for the requested results page
+
+ :returns: Page of VoipInstance
+ """
+ response = await self._version.domain.twilio.request_async("GET", target_url)
+ return VoipPage(self._version, response, self._solution)
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/balance.py b/venv/Lib/site-packages/twilio/rest/api/v2010/account/balance.py
new file mode 100644
index 00000000..66bb91e9
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/api/v2010/account/balance.py
@@ -0,0 +1,111 @@
+r"""
+ This code was generated by
+ ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __
+ | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/
+ | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \
+
+ Twilio - Api
+ This is the public Twilio REST API.
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ https://openapi-generator.tech
+ Do not edit the class manually.
+"""
+
+from typing import Any, Dict, Optional
+from twilio.base import values
+
+from twilio.base.instance_resource import InstanceResource
+from twilio.base.list_resource import ListResource
+from twilio.base.version import Version
+
+
+class BalanceInstance(InstanceResource):
+ """
+ :ivar account_sid: The unique SID identifier of the Account.
+ :ivar balance: The balance of the Account, in units specified by the unit parameter. Balance changes may not be reflected immediately. Child accounts do not contain balance information
+ :ivar currency: The units of currency for the account balance
+ """
+
+ def __init__(self, version: Version, payload: Dict[str, Any], account_sid: str):
+ super().__init__(version)
+
+ self.account_sid: Optional[str] = payload.get("account_sid")
+ self.balance: Optional[str] = payload.get("balance")
+ self.currency: Optional[str] = payload.get("currency")
+
+ self._solution = {
+ "account_sid": account_sid,
+ }
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(context)
+
+
+class BalanceList(ListResource):
+
+ def __init__(self, version: Version, account_sid: str):
+ """
+ Initialize the BalanceList
+
+ :param version: Version that contains the resource
+ :param account_sid: The unique SID identifier of the Account.
+
+ """
+ super().__init__(version)
+
+ # Path Solution
+ self._solution = {
+ "account_sid": account_sid,
+ }
+ self._uri = "/Accounts/{account_sid}/Balance.json".format(**self._solution)
+
+ def fetch(self) -> BalanceInstance:
+ """
+ Asynchronously fetch the BalanceInstance
+
+
+ :returns: The fetched BalanceInstance
+ """
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.fetch(method="GET", uri=self._uri, headers=headers)
+
+ return BalanceInstance(
+ self._version, payload, account_sid=self._solution["account_sid"]
+ )
+
+ async def fetch_async(self) -> BalanceInstance:
+ """
+ Asynchronously fetch the BalanceInstance
+
+
+ :returns: The fetched BalanceInstance
+ """
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.fetch_async(
+ method="GET", uri=self._uri, headers=headers
+ )
+
+ return BalanceInstance(
+ self._version, payload, account_sid=self._solution["account_sid"]
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/__init__.py b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/__init__.py
new file mode 100644
index 00000000..f7756c40
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/__init__.py
@@ -0,0 +1,1400 @@
+r"""
+ This code was generated by
+ ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __
+ | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/
+ | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \
+
+ Twilio - Api
+ This is the public Twilio REST API.
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ https://openapi-generator.tech
+ Do not edit the class manually.
+"""
+
+from datetime import datetime
+from typing import Any, Dict, List, Optional, Union, Iterator, AsyncIterator
+from twilio.base import deserialize, serialize, values
+from twilio.base.instance_context import InstanceContext
+from twilio.base.instance_resource import InstanceResource
+from twilio.base.list_resource import ListResource
+from twilio.base.version import Version
+from twilio.base.page import Page
+from twilio.rest.api.v2010.account.call.event import EventList
+from twilio.rest.api.v2010.account.call.notification import NotificationList
+from twilio.rest.api.v2010.account.call.payment import PaymentList
+from twilio.rest.api.v2010.account.call.recording import RecordingList
+from twilio.rest.api.v2010.account.call.siprec import SiprecList
+from twilio.rest.api.v2010.account.call.stream import StreamList
+from twilio.rest.api.v2010.account.call.transcription import TranscriptionList
+from twilio.rest.api.v2010.account.call.user_defined_message import (
+ UserDefinedMessageList,
+)
+from twilio.rest.api.v2010.account.call.user_defined_message_subscription import (
+ UserDefinedMessageSubscriptionList,
+)
+
+
+class CallInstance(InstanceResource):
+
+ class Status(object):
+ QUEUED = "queued"
+ RINGING = "ringing"
+ IN_PROGRESS = "in-progress"
+ COMPLETED = "completed"
+ BUSY = "busy"
+ FAILED = "failed"
+ NO_ANSWER = "no-answer"
+ CANCELED = "canceled"
+
+ class UpdateStatus(object):
+ CANCELED = "canceled"
+ COMPLETED = "completed"
+
+ """
+ :ivar sid: The unique string that we created to identify this Call resource.
+ :ivar date_created: The date and time in UTC that this resource was created specified in [RFC 2822](https://www.ietf.org/rfc/rfc2822.txt) format.
+ :ivar date_updated: The date and time in UTC that this resource was last updated, specified in [RFC 2822](https://www.ietf.org/rfc/rfc2822.txt) format.
+ :ivar parent_call_sid: The SID that identifies the call that created this leg.
+ :ivar account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that created this Call resource.
+ :ivar to: The phone number, SIP address, Client identifier or SIM SID that received this call. Phone numbers are in [E.164](https://www.twilio.com/docs/glossary/what-e164) format (e.g., +16175551212). SIP addresses are formatted as `name@company.com`. Client identifiers are formatted `client:name`. SIM SIDs are formatted as `sim:sid`.
+ :ivar to_formatted: The phone number, SIP address or Client identifier that received this call. Formatted for display. Non-North American phone numbers are in [E.164](https://www.twilio.com/docs/glossary/what-e164) format (e.g., +442071838750).
+ :ivar _from: The phone number, SIP address, Client identifier or SIM SID that made this call. Phone numbers are in [E.164](https://www.twilio.com/docs/glossary/what-e164) format (e.g., +16175551212). SIP addresses are formatted as `name@company.com`. Client identifiers are formatted `client:name`. SIM SIDs are formatted as `sim:sid`.
+ :ivar from_formatted: The calling phone number, SIP address, or Client identifier formatted for display. Non-North American phone numbers are in [E.164](https://www.twilio.com/docs/glossary/what-e164) format (e.g., +442071838750).
+ :ivar phone_number_sid: If the call was inbound, this is the SID of the IncomingPhoneNumber resource that received the call. If the call was outbound, it is the SID of the OutgoingCallerId resource from which the call was placed.
+ :ivar status:
+ :ivar start_time: The start time of the call, given as UTC in [RFC 2822](https://www.php.net/manual/en/class.datetime.php#datetime.constants.rfc2822) format. Empty if the call has not yet been dialed.
+ :ivar end_time: The time the call ended, given as UTC in [RFC 2822](https://www.php.net/manual/en/class.datetime.php#datetime.constants.rfc2822) format. Empty if the call did not complete successfully.
+ :ivar duration: The length of the call in seconds. This value is empty for busy, failed, unanswered, or ongoing calls.
+ :ivar price: The charge for this call, in the currency associated with the account. Populated after the call is completed. May not be immediately available. The price associated with a call only reflects the charge for connectivity. Charges for other call-related features such as Answering Machine Detection, Text-To-Speech, and SIP REFER are not included in this value.
+ :ivar price_unit: The currency in which `Price` is measured, in [ISO 4127](https://www.iso.org/iso/home/standards/currency_codes.htm) format (e.g., `USD`, `EUR`, `JPY`). Always capitalized for calls.
+ :ivar direction: A string describing the direction of the call. Can be: `inbound` for inbound calls, `outbound-api` for calls initiated via the REST API or `outbound-dial` for calls initiated by a `` verb. Using [Elastic SIP Trunking](https://www.twilio.com/docs/sip-trunking), the values can be [`trunking-terminating`](https://www.twilio.com/docs/sip-trunking#termination) for outgoing calls from your communications infrastructure to the PSTN or [`trunking-originating`](https://www.twilio.com/docs/sip-trunking#origination) for incoming calls to your communications infrastructure from the PSTN.
+ :ivar answered_by: Either `human` or `machine` if this call was initiated with answering machine detection. Empty otherwise.
+ :ivar api_version: The API version used to create the call.
+ :ivar forwarded_from: The forwarding phone number if this call was an incoming call forwarded from another number (depends on carrier supporting forwarding). Otherwise, empty.
+ :ivar group_sid: The Group SID associated with this call. If no Group is associated with the call, the field is empty.
+ :ivar caller_name: The caller's name if this call was an incoming call to a phone number with caller ID Lookup enabled. Otherwise, empty.
+ :ivar queue_time: The wait time in milliseconds before the call is placed.
+ :ivar trunk_sid: The unique identifier of the trunk resource that was used for this call. The field is empty if the call was not made using a SIP trunk or if the call is not terminated.
+ :ivar uri: The URI of this resource, relative to `https://api.twilio.com`.
+ :ivar subresource_uris: A list of subresources available to this call, identified by their URIs relative to `https://api.twilio.com`.
+ """
+
+ def __init__(
+ self,
+ version: Version,
+ payload: Dict[str, Any],
+ account_sid: str,
+ sid: Optional[str] = None,
+ ):
+ super().__init__(version)
+
+ self.sid: Optional[str] = payload.get("sid")
+ self.date_created: Optional[datetime] = deserialize.rfc2822_datetime(
+ payload.get("date_created")
+ )
+ self.date_updated: Optional[datetime] = deserialize.rfc2822_datetime(
+ payload.get("date_updated")
+ )
+ self.parent_call_sid: Optional[str] = payload.get("parent_call_sid")
+ self.account_sid: Optional[str] = payload.get("account_sid")
+ self.to: Optional[str] = payload.get("to")
+ self.to_formatted: Optional[str] = payload.get("to_formatted")
+ self._from: Optional[str] = payload.get("from")
+ self.from_formatted: Optional[str] = payload.get("from_formatted")
+ self.phone_number_sid: Optional[str] = payload.get("phone_number_sid")
+ self.status: Optional["CallInstance.Status"] = payload.get("status")
+ self.start_time: Optional[datetime] = deserialize.rfc2822_datetime(
+ payload.get("start_time")
+ )
+ self.end_time: Optional[datetime] = deserialize.rfc2822_datetime(
+ payload.get("end_time")
+ )
+ self.duration: Optional[str] = payload.get("duration")
+ self.price: Optional[str] = payload.get("price")
+ self.price_unit: Optional[str] = payload.get("price_unit")
+ self.direction: Optional[str] = payload.get("direction")
+ self.answered_by: Optional[str] = payload.get("answered_by")
+ self.api_version: Optional[str] = payload.get("api_version")
+ self.forwarded_from: Optional[str] = payload.get("forwarded_from")
+ self.group_sid: Optional[str] = payload.get("group_sid")
+ self.caller_name: Optional[str] = payload.get("caller_name")
+ self.queue_time: Optional[str] = payload.get("queue_time")
+ self.trunk_sid: Optional[str] = payload.get("trunk_sid")
+ self.uri: Optional[str] = payload.get("uri")
+ self.subresource_uris: Optional[Dict[str, object]] = payload.get(
+ "subresource_uris"
+ )
+
+ self._solution = {
+ "account_sid": account_sid,
+ "sid": sid or self.sid,
+ }
+ self._context: Optional[CallContext] = None
+
+ @property
+ def _proxy(self) -> "CallContext":
+ """
+ Generate an instance context for the instance, the context is capable of
+ performing various actions. All instance actions are proxied to the context
+
+ :returns: CallContext for this CallInstance
+ """
+ if self._context is None:
+ self._context = CallContext(
+ self._version,
+ account_sid=self._solution["account_sid"],
+ sid=self._solution["sid"],
+ )
+ return self._context
+
+ def delete(self) -> bool:
+ """
+ Deletes the CallInstance
+
+
+ :returns: True if delete succeeds, False otherwise
+ """
+ return self._proxy.delete()
+
+ async def delete_async(self) -> bool:
+ """
+ Asynchronous coroutine that deletes the CallInstance
+
+
+ :returns: True if delete succeeds, False otherwise
+ """
+ return await self._proxy.delete_async()
+
+ def fetch(self) -> "CallInstance":
+ """
+ Fetch the CallInstance
+
+
+ :returns: The fetched CallInstance
+ """
+ return self._proxy.fetch()
+
+ async def fetch_async(self) -> "CallInstance":
+ """
+ Asynchronous coroutine to fetch the CallInstance
+
+
+ :returns: The fetched CallInstance
+ """
+ return await self._proxy.fetch_async()
+
+ def update(
+ self,
+ url: Union[str, object] = values.unset,
+ method: Union[str, object] = values.unset,
+ status: Union["CallInstance.UpdateStatus", object] = values.unset,
+ fallback_url: Union[str, object] = values.unset,
+ fallback_method: Union[str, object] = values.unset,
+ status_callback: Union[str, object] = values.unset,
+ status_callback_method: Union[str, object] = values.unset,
+ twiml: Union[str, object] = values.unset,
+ time_limit: Union[int, object] = values.unset,
+ ) -> "CallInstance":
+ """
+ Update the CallInstance
+
+ :param url: The absolute URL that returns the TwiML instructions for the call. We will call this URL using the `method` when the call connects. For more information, see the [Url Parameter](https://www.twilio.com/docs/voice/make-calls#specify-a-url-parameter) section in [Making Calls](https://www.twilio.com/docs/voice/make-calls).
+ :param method: The HTTP method we should use when calling the `url`. Can be: `GET` or `POST` and the default is `POST`. If an `application_sid` parameter is present, this parameter is ignored.
+ :param status:
+ :param fallback_url: The URL that we call using the `fallback_method` if an error occurs when requesting or executing the TwiML at `url`. If an `application_sid` parameter is present, this parameter is ignored.
+ :param fallback_method: The HTTP method that we should use to request the `fallback_url`. Can be: `GET` or `POST` and the default is `POST`. If an `application_sid` parameter is present, this parameter is ignored.
+ :param status_callback: The URL we should call using the `status_callback_method` to send status information to your application. If no `status_callback_event` is specified, we will send the `completed` status. If an `application_sid` parameter is present, this parameter is ignored. URLs must contain a valid hostname (underscores are not permitted).
+ :param status_callback_method: The HTTP method we should use when requesting the `status_callback` URL. Can be: `GET` or `POST` and the default is `POST`. If an `application_sid` parameter is present, this parameter is ignored.
+ :param twiml: TwiML instructions for the call Twilio will use without fetching Twiml from url. Twiml and url parameters are mutually exclusive
+ :param time_limit: The maximum duration of the call in seconds. Constraints depend on account and configuration.
+
+ :returns: The updated CallInstance
+ """
+ return self._proxy.update(
+ url=url,
+ method=method,
+ status=status,
+ fallback_url=fallback_url,
+ fallback_method=fallback_method,
+ status_callback=status_callback,
+ status_callback_method=status_callback_method,
+ twiml=twiml,
+ time_limit=time_limit,
+ )
+
+ async def update_async(
+ self,
+ url: Union[str, object] = values.unset,
+ method: Union[str, object] = values.unset,
+ status: Union["CallInstance.UpdateStatus", object] = values.unset,
+ fallback_url: Union[str, object] = values.unset,
+ fallback_method: Union[str, object] = values.unset,
+ status_callback: Union[str, object] = values.unset,
+ status_callback_method: Union[str, object] = values.unset,
+ twiml: Union[str, object] = values.unset,
+ time_limit: Union[int, object] = values.unset,
+ ) -> "CallInstance":
+ """
+ Asynchronous coroutine to update the CallInstance
+
+ :param url: The absolute URL that returns the TwiML instructions for the call. We will call this URL using the `method` when the call connects. For more information, see the [Url Parameter](https://www.twilio.com/docs/voice/make-calls#specify-a-url-parameter) section in [Making Calls](https://www.twilio.com/docs/voice/make-calls).
+ :param method: The HTTP method we should use when calling the `url`. Can be: `GET` or `POST` and the default is `POST`. If an `application_sid` parameter is present, this parameter is ignored.
+ :param status:
+ :param fallback_url: The URL that we call using the `fallback_method` if an error occurs when requesting or executing the TwiML at `url`. If an `application_sid` parameter is present, this parameter is ignored.
+ :param fallback_method: The HTTP method that we should use to request the `fallback_url`. Can be: `GET` or `POST` and the default is `POST`. If an `application_sid` parameter is present, this parameter is ignored.
+ :param status_callback: The URL we should call using the `status_callback_method` to send status information to your application. If no `status_callback_event` is specified, we will send the `completed` status. If an `application_sid` parameter is present, this parameter is ignored. URLs must contain a valid hostname (underscores are not permitted).
+ :param status_callback_method: The HTTP method we should use when requesting the `status_callback` URL. Can be: `GET` or `POST` and the default is `POST`. If an `application_sid` parameter is present, this parameter is ignored.
+ :param twiml: TwiML instructions for the call Twilio will use without fetching Twiml from url. Twiml and url parameters are mutually exclusive
+ :param time_limit: The maximum duration of the call in seconds. Constraints depend on account and configuration.
+
+ :returns: The updated CallInstance
+ """
+ return await self._proxy.update_async(
+ url=url,
+ method=method,
+ status=status,
+ fallback_url=fallback_url,
+ fallback_method=fallback_method,
+ status_callback=status_callback,
+ status_callback_method=status_callback_method,
+ twiml=twiml,
+ time_limit=time_limit,
+ )
+
+ @property
+ def events(self) -> EventList:
+ """
+ Access the events
+ """
+ return self._proxy.events
+
+ @property
+ def notifications(self) -> NotificationList:
+ """
+ Access the notifications
+ """
+ return self._proxy.notifications
+
+ @property
+ def payments(self) -> PaymentList:
+ """
+ Access the payments
+ """
+ return self._proxy.payments
+
+ @property
+ def recordings(self) -> RecordingList:
+ """
+ Access the recordings
+ """
+ return self._proxy.recordings
+
+ @property
+ def siprec(self) -> SiprecList:
+ """
+ Access the siprec
+ """
+ return self._proxy.siprec
+
+ @property
+ def streams(self) -> StreamList:
+ """
+ Access the streams
+ """
+ return self._proxy.streams
+
+ @property
+ def transcriptions(self) -> TranscriptionList:
+ """
+ Access the transcriptions
+ """
+ return self._proxy.transcriptions
+
+ @property
+ def user_defined_messages(self) -> UserDefinedMessageList:
+ """
+ Access the user_defined_messages
+ """
+ return self._proxy.user_defined_messages
+
+ @property
+ def user_defined_message_subscriptions(self) -> UserDefinedMessageSubscriptionList:
+ """
+ Access the user_defined_message_subscriptions
+ """
+ return self._proxy.user_defined_message_subscriptions
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(context)
+
+
+class CallContext(InstanceContext):
+
+ def __init__(self, version: Version, account_sid: str, sid: str):
+ """
+ Initialize the CallContext
+
+ :param version: Version that contains the resource
+ :param account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that created the Call resource(s) to update.
+ :param sid: The Twilio-provided string that uniquely identifies the Call resource to update
+ """
+ super().__init__(version)
+
+ # Path Solution
+ self._solution = {
+ "account_sid": account_sid,
+ "sid": sid,
+ }
+ self._uri = "/Accounts/{account_sid}/Calls/{sid}.json".format(**self._solution)
+
+ self._events: Optional[EventList] = None
+ self._notifications: Optional[NotificationList] = None
+ self._payments: Optional[PaymentList] = None
+ self._recordings: Optional[RecordingList] = None
+ self._siprec: Optional[SiprecList] = None
+ self._streams: Optional[StreamList] = None
+ self._transcriptions: Optional[TranscriptionList] = None
+ self._user_defined_messages: Optional[UserDefinedMessageList] = None
+ self._user_defined_message_subscriptions: Optional[
+ UserDefinedMessageSubscriptionList
+ ] = None
+
+ def delete(self) -> bool:
+ """
+ Deletes the CallInstance
+
+
+ :returns: True if delete succeeds, False otherwise
+ """
+
+ headers = values.of({})
+
+ return self._version.delete(method="DELETE", uri=self._uri, headers=headers)
+
+ async def delete_async(self) -> bool:
+ """
+ Asynchronous coroutine that deletes the CallInstance
+
+
+ :returns: True if delete succeeds, False otherwise
+ """
+
+ headers = values.of({})
+
+ return await self._version.delete_async(
+ method="DELETE", uri=self._uri, headers=headers
+ )
+
+ def fetch(self) -> CallInstance:
+ """
+ Fetch the CallInstance
+
+
+ :returns: The fetched CallInstance
+ """
+
+ headers = values.of({})
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.fetch(method="GET", uri=self._uri, headers=headers)
+
+ return CallInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ sid=self._solution["sid"],
+ )
+
+ async def fetch_async(self) -> CallInstance:
+ """
+ Asynchronous coroutine to fetch the CallInstance
+
+
+ :returns: The fetched CallInstance
+ """
+
+ headers = values.of({})
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.fetch_async(
+ method="GET", uri=self._uri, headers=headers
+ )
+
+ return CallInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ sid=self._solution["sid"],
+ )
+
+ def update(
+ self,
+ url: Union[str, object] = values.unset,
+ method: Union[str, object] = values.unset,
+ status: Union["CallInstance.UpdateStatus", object] = values.unset,
+ fallback_url: Union[str, object] = values.unset,
+ fallback_method: Union[str, object] = values.unset,
+ status_callback: Union[str, object] = values.unset,
+ status_callback_method: Union[str, object] = values.unset,
+ twiml: Union[str, object] = values.unset,
+ time_limit: Union[int, object] = values.unset,
+ ) -> CallInstance:
+ """
+ Update the CallInstance
+
+ :param url: The absolute URL that returns the TwiML instructions for the call. We will call this URL using the `method` when the call connects. For more information, see the [Url Parameter](https://www.twilio.com/docs/voice/make-calls#specify-a-url-parameter) section in [Making Calls](https://www.twilio.com/docs/voice/make-calls).
+ :param method: The HTTP method we should use when calling the `url`. Can be: `GET` or `POST` and the default is `POST`. If an `application_sid` parameter is present, this parameter is ignored.
+ :param status:
+ :param fallback_url: The URL that we call using the `fallback_method` if an error occurs when requesting or executing the TwiML at `url`. If an `application_sid` parameter is present, this parameter is ignored.
+ :param fallback_method: The HTTP method that we should use to request the `fallback_url`. Can be: `GET` or `POST` and the default is `POST`. If an `application_sid` parameter is present, this parameter is ignored.
+ :param status_callback: The URL we should call using the `status_callback_method` to send status information to your application. If no `status_callback_event` is specified, we will send the `completed` status. If an `application_sid` parameter is present, this parameter is ignored. URLs must contain a valid hostname (underscores are not permitted).
+ :param status_callback_method: The HTTP method we should use when requesting the `status_callback` URL. Can be: `GET` or `POST` and the default is `POST`. If an `application_sid` parameter is present, this parameter is ignored.
+ :param twiml: TwiML instructions for the call Twilio will use without fetching Twiml from url. Twiml and url parameters are mutually exclusive
+ :param time_limit: The maximum duration of the call in seconds. Constraints depend on account and configuration.
+
+ :returns: The updated CallInstance
+ """
+
+ data = values.of(
+ {
+ "Url": url,
+ "Method": method,
+ "Status": status,
+ "FallbackUrl": fallback_url,
+ "FallbackMethod": fallback_method,
+ "StatusCallback": status_callback,
+ "StatusCallbackMethod": status_callback_method,
+ "Twiml": twiml,
+ "TimeLimit": time_limit,
+ }
+ )
+ headers = values.of({})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.update(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return CallInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ sid=self._solution["sid"],
+ )
+
+ async def update_async(
+ self,
+ url: Union[str, object] = values.unset,
+ method: Union[str, object] = values.unset,
+ status: Union["CallInstance.UpdateStatus", object] = values.unset,
+ fallback_url: Union[str, object] = values.unset,
+ fallback_method: Union[str, object] = values.unset,
+ status_callback: Union[str, object] = values.unset,
+ status_callback_method: Union[str, object] = values.unset,
+ twiml: Union[str, object] = values.unset,
+ time_limit: Union[int, object] = values.unset,
+ ) -> CallInstance:
+ """
+ Asynchronous coroutine to update the CallInstance
+
+ :param url: The absolute URL that returns the TwiML instructions for the call. We will call this URL using the `method` when the call connects. For more information, see the [Url Parameter](https://www.twilio.com/docs/voice/make-calls#specify-a-url-parameter) section in [Making Calls](https://www.twilio.com/docs/voice/make-calls).
+ :param method: The HTTP method we should use when calling the `url`. Can be: `GET` or `POST` and the default is `POST`. If an `application_sid` parameter is present, this parameter is ignored.
+ :param status:
+ :param fallback_url: The URL that we call using the `fallback_method` if an error occurs when requesting or executing the TwiML at `url`. If an `application_sid` parameter is present, this parameter is ignored.
+ :param fallback_method: The HTTP method that we should use to request the `fallback_url`. Can be: `GET` or `POST` and the default is `POST`. If an `application_sid` parameter is present, this parameter is ignored.
+ :param status_callback: The URL we should call using the `status_callback_method` to send status information to your application. If no `status_callback_event` is specified, we will send the `completed` status. If an `application_sid` parameter is present, this parameter is ignored. URLs must contain a valid hostname (underscores are not permitted).
+ :param status_callback_method: The HTTP method we should use when requesting the `status_callback` URL. Can be: `GET` or `POST` and the default is `POST`. If an `application_sid` parameter is present, this parameter is ignored.
+ :param twiml: TwiML instructions for the call Twilio will use without fetching Twiml from url. Twiml and url parameters are mutually exclusive
+ :param time_limit: The maximum duration of the call in seconds. Constraints depend on account and configuration.
+
+ :returns: The updated CallInstance
+ """
+
+ data = values.of(
+ {
+ "Url": url,
+ "Method": method,
+ "Status": status,
+ "FallbackUrl": fallback_url,
+ "FallbackMethod": fallback_method,
+ "StatusCallback": status_callback,
+ "StatusCallbackMethod": status_callback_method,
+ "Twiml": twiml,
+ "TimeLimit": time_limit,
+ }
+ )
+ headers = values.of({})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.update_async(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return CallInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ sid=self._solution["sid"],
+ )
+
+ @property
+ def events(self) -> EventList:
+ """
+ Access the events
+ """
+ if self._events is None:
+ self._events = EventList(
+ self._version,
+ self._solution["account_sid"],
+ self._solution["sid"],
+ )
+ return self._events
+
+ @property
+ def notifications(self) -> NotificationList:
+ """
+ Access the notifications
+ """
+ if self._notifications is None:
+ self._notifications = NotificationList(
+ self._version,
+ self._solution["account_sid"],
+ self._solution["sid"],
+ )
+ return self._notifications
+
+ @property
+ def payments(self) -> PaymentList:
+ """
+ Access the payments
+ """
+ if self._payments is None:
+ self._payments = PaymentList(
+ self._version,
+ self._solution["account_sid"],
+ self._solution["sid"],
+ )
+ return self._payments
+
+ @property
+ def recordings(self) -> RecordingList:
+ """
+ Access the recordings
+ """
+ if self._recordings is None:
+ self._recordings = RecordingList(
+ self._version,
+ self._solution["account_sid"],
+ self._solution["sid"],
+ )
+ return self._recordings
+
+ @property
+ def siprec(self) -> SiprecList:
+ """
+ Access the siprec
+ """
+ if self._siprec is None:
+ self._siprec = SiprecList(
+ self._version,
+ self._solution["account_sid"],
+ self._solution["sid"],
+ )
+ return self._siprec
+
+ @property
+ def streams(self) -> StreamList:
+ """
+ Access the streams
+ """
+ if self._streams is None:
+ self._streams = StreamList(
+ self._version,
+ self._solution["account_sid"],
+ self._solution["sid"],
+ )
+ return self._streams
+
+ @property
+ def transcriptions(self) -> TranscriptionList:
+ """
+ Access the transcriptions
+ """
+ if self._transcriptions is None:
+ self._transcriptions = TranscriptionList(
+ self._version,
+ self._solution["account_sid"],
+ self._solution["sid"],
+ )
+ return self._transcriptions
+
+ @property
+ def user_defined_messages(self) -> UserDefinedMessageList:
+ """
+ Access the user_defined_messages
+ """
+ if self._user_defined_messages is None:
+ self._user_defined_messages = UserDefinedMessageList(
+ self._version,
+ self._solution["account_sid"],
+ self._solution["sid"],
+ )
+ return self._user_defined_messages
+
+ @property
+ def user_defined_message_subscriptions(self) -> UserDefinedMessageSubscriptionList:
+ """
+ Access the user_defined_message_subscriptions
+ """
+ if self._user_defined_message_subscriptions is None:
+ self._user_defined_message_subscriptions = (
+ UserDefinedMessageSubscriptionList(
+ self._version,
+ self._solution["account_sid"],
+ self._solution["sid"],
+ )
+ )
+ return self._user_defined_message_subscriptions
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(context)
+
+
+class CallPage(Page):
+
+ def get_instance(self, payload: Dict[str, Any]) -> CallInstance:
+ """
+ Build an instance of CallInstance
+
+ :param payload: Payload response from the API
+ """
+ return CallInstance(
+ self._version, payload, account_sid=self._solution["account_sid"]
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
+
+
+class CallList(ListResource):
+
+ def __init__(self, version: Version, account_sid: str):
+ """
+ Initialize the CallList
+
+ :param version: Version that contains the resource
+ :param account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that created the Call resource(s) to read.
+
+ """
+ super().__init__(version)
+
+ # Path Solution
+ self._solution = {
+ "account_sid": account_sid,
+ }
+ self._uri = "/Accounts/{account_sid}/Calls.json".format(**self._solution)
+
+ def create(
+ self,
+ to: str,
+ from_: str,
+ method: Union[str, object] = values.unset,
+ fallback_url: Union[str, object] = values.unset,
+ fallback_method: Union[str, object] = values.unset,
+ status_callback: Union[str, object] = values.unset,
+ status_callback_event: Union[List[str], object] = values.unset,
+ status_callback_method: Union[str, object] = values.unset,
+ send_digits: Union[str, object] = values.unset,
+ timeout: Union[int, object] = values.unset,
+ record: Union[bool, object] = values.unset,
+ recording_channels: Union[str, object] = values.unset,
+ recording_status_callback: Union[str, object] = values.unset,
+ recording_status_callback_method: Union[str, object] = values.unset,
+ sip_auth_username: Union[str, object] = values.unset,
+ sip_auth_password: Union[str, object] = values.unset,
+ machine_detection: Union[str, object] = values.unset,
+ machine_detection_timeout: Union[int, object] = values.unset,
+ recording_status_callback_event: Union[List[str], object] = values.unset,
+ trim: Union[str, object] = values.unset,
+ caller_id: Union[str, object] = values.unset,
+ machine_detection_speech_threshold: Union[int, object] = values.unset,
+ machine_detection_speech_end_threshold: Union[int, object] = values.unset,
+ machine_detection_silence_timeout: Union[int, object] = values.unset,
+ async_amd: Union[str, object] = values.unset,
+ async_amd_status_callback: Union[str, object] = values.unset,
+ async_amd_status_callback_method: Union[str, object] = values.unset,
+ byoc: Union[str, object] = values.unset,
+ call_reason: Union[str, object] = values.unset,
+ call_token: Union[str, object] = values.unset,
+ recording_track: Union[str, object] = values.unset,
+ time_limit: Union[int, object] = values.unset,
+ url: Union[str, object] = values.unset,
+ twiml: Union[str, object] = values.unset,
+ application_sid: Union[str, object] = values.unset,
+ ) -> CallInstance:
+ """
+ Create the CallInstance
+
+ :param to: The phone number, SIP address, or client identifier to call.
+ :param from_: The phone number or client identifier to use as the caller id. If using a phone number, it must be a Twilio number or a Verified [outgoing caller id](https://www.twilio.com/docs/voice/api/outgoing-caller-ids) for your account. If the `to` parameter is a phone number, `From` must also be a phone number.
+ :param method: The HTTP method we should use when calling the `url` parameter's value. Can be: `GET` or `POST` and the default is `POST`. If an `application_sid` parameter is present, this parameter is ignored.
+ :param fallback_url: The URL that we call using the `fallback_method` if an error occurs when requesting or executing the TwiML at `url`. If an `application_sid` parameter is present, this parameter is ignored.
+ :param fallback_method: The HTTP method that we should use to request the `fallback_url`. Can be: `GET` or `POST` and the default is `POST`. If an `application_sid` parameter is present, this parameter is ignored.
+ :param status_callback: The URL we should call using the `status_callback_method` to send status information to your application. If no `status_callback_event` is specified, we will send the `completed` status. If an `application_sid` parameter is present, this parameter is ignored. URLs must contain a valid hostname (underscores are not permitted).
+ :param status_callback_event: The call progress events that we will send to the `status_callback` URL. Can be: `initiated`, `ringing`, `answered`, and `completed`. If no event is specified, we send the `completed` status. If you want to receive multiple events, specify each one in a separate `status_callback_event` parameter. See the code sample for [monitoring call progress](https://www.twilio.com/docs/voice/api/call-resource?code-sample=code-create-a-call-resource-and-specify-a-statuscallbackevent&code-sdk-version=json). If an `application_sid` is present, this parameter is ignored.
+ :param status_callback_method: The HTTP method we should use when calling the `status_callback` URL. Can be: `GET` or `POST` and the default is `POST`. If an `application_sid` parameter is present, this parameter is ignored.
+ :param send_digits: The string of keys to dial after connecting to the number, with a maximum length of 32 digits. Valid digits in the string include any digit (`0`-`9`), '`A`', '`B`', '`C`', '`D`', '`#`', and '`*`'. You can also use '`w`' to insert a half-second pause and '`W`' to insert a one-second pause. For example, to pause for one second after connecting and then dial extension 1234 followed by the # key, set this parameter to `W1234#`. Be sure to URL-encode this string because the '`#`' character has special meaning in a URL. If both `SendDigits` and `MachineDetection` parameters are provided, then `MachineDetection` will be ignored.
+ :param timeout: The integer number of seconds that we should allow the phone to ring before assuming there is no answer. The default is `60` seconds and the maximum is `600` seconds. For some call flows, we will add a 5-second buffer to the timeout value you provide. For this reason, a timeout value of 10 seconds could result in an actual timeout closer to 15 seconds. You can set this to a short time, such as `15` seconds, to hang up before reaching an answering machine or voicemail.
+ :param record: Whether to record the call. Can be `true` to record the phone call, or `false` to not. The default is `false`. The `recording_url` is sent to the `status_callback` URL.
+ :param recording_channels: The number of channels in the final recording. Can be: `mono` or `dual`. The default is `mono`. `mono` records both legs of the call in a single channel of the recording file. `dual` records each leg to a separate channel of the recording file. The first channel of a dual-channel recording contains the parent call and the second channel contains the child call.
+ :param recording_status_callback: The URL that we call when the recording is available to be accessed.
+ :param recording_status_callback_method: The HTTP method we should use when calling the `recording_status_callback` URL. Can be: `GET` or `POST` and the default is `POST`.
+ :param sip_auth_username: The username used to authenticate the caller making a SIP call.
+ :param sip_auth_password: The password required to authenticate the user account specified in `sip_auth_username`.
+ :param machine_detection: Whether to detect if a human, answering machine, or fax has picked up the call. Can be: `Enable` or `DetectMessageEnd`. Use `Enable` if you would like us to return `AnsweredBy` as soon as the called party is identified. Use `DetectMessageEnd`, if you would like to leave a message on an answering machine. If `send_digits` is provided, this parameter is ignored. For more information, see [Answering Machine Detection](https://www.twilio.com/docs/voice/answering-machine-detection).
+ :param machine_detection_timeout: The number of seconds that we should attempt to detect an answering machine before timing out and sending a voice request with `AnsweredBy` of `unknown`. The default timeout is 30 seconds.
+ :param recording_status_callback_event: The recording status events that will trigger calls to the URL specified in `recording_status_callback`. Can be: `in-progress`, `completed` and `absent`. Defaults to `completed`. Separate multiple values with a space.
+ :param trim: Whether to trim any leading and trailing silence from the recording. Can be: `trim-silence` or `do-not-trim` and the default is `trim-silence`.
+ :param caller_id: The phone number, SIP address, or Client identifier that made this call. Phone numbers are in [E.164 format](https://wwnw.twilio.com/docs/glossary/what-e164) (e.g., +16175551212). SIP addresses are formatted as `name@company.com`.
+ :param machine_detection_speech_threshold: The number of milliseconds that is used as the measuring stick for the length of the speech activity, where durations lower than this value will be interpreted as a human and longer than this value as a machine. Possible Values: 1000-6000. Default: 2400.
+ :param machine_detection_speech_end_threshold: The number of milliseconds of silence after speech activity at which point the speech activity is considered complete. Possible Values: 500-5000. Default: 1200.
+ :param machine_detection_silence_timeout: The number of milliseconds of initial silence after which an `unknown` AnsweredBy result will be returned. Possible Values: 2000-10000. Default: 5000.
+ :param async_amd: Select whether to perform answering machine detection in the background. Default, blocks the execution of the call until Answering Machine Detection is completed. Can be: `true` or `false`.
+ :param async_amd_status_callback: The URL that we should call using the `async_amd_status_callback_method` to notify customer application whether the call was answered by human, machine or fax.
+ :param async_amd_status_callback_method: The HTTP method we should use when calling the `async_amd_status_callback` URL. Can be: `GET` or `POST` and the default is `POST`.
+ :param byoc: The SID of a BYOC (Bring Your Own Carrier) trunk to route this call with. Note that `byoc` is only meaningful when `to` is a phone number; it will otherwise be ignored. (Beta)
+ :param call_reason: The Reason for the outgoing call. Use it to specify the purpose of the call that is presented on the called party's phone. (Branded Calls Beta)
+ :param call_token: A token string needed to invoke a forwarded call. A call_token is generated when an incoming call is received on a Twilio number. Pass an incoming call's call_token value to a forwarded call via the call_token parameter when creating a new call. A forwarded call should bear the same CallerID of the original incoming call.
+ :param recording_track: The audio track to record for the call. Can be: `inbound`, `outbound` or `both`. The default is `both`. `inbound` records the audio that is received by Twilio. `outbound` records the audio that is generated from Twilio. `both` records the audio that is received and generated by Twilio.
+ :param time_limit: The maximum duration of the call in seconds. Constraints depend on account and configuration.
+ :param url: The absolute URL that returns the TwiML instructions for the call. We will call this URL using the `method` when the call connects. For more information, see the [Url Parameter](https://www.twilio.com/docs/voice/make-calls#specify-a-url-parameter) section in [Making Calls](https://www.twilio.com/docs/voice/make-calls).
+ :param twiml: TwiML instructions for the call Twilio will use without fetching Twiml from url parameter. If both `twiml` and `url` are provided then `twiml` parameter will be ignored. Max 4000 characters.
+ :param application_sid: The SID of the Application resource that will handle the call, if the call will be handled by an application.
+
+ :returns: The created CallInstance
+ """
+
+ data = values.of(
+ {
+ "To": to,
+ "From": from_,
+ "Method": method,
+ "FallbackUrl": fallback_url,
+ "FallbackMethod": fallback_method,
+ "StatusCallback": status_callback,
+ "StatusCallbackEvent": serialize.map(
+ status_callback_event, lambda e: e
+ ),
+ "StatusCallbackMethod": status_callback_method,
+ "SendDigits": send_digits,
+ "Timeout": timeout,
+ "Record": serialize.boolean_to_string(record),
+ "RecordingChannels": recording_channels,
+ "RecordingStatusCallback": recording_status_callback,
+ "RecordingStatusCallbackMethod": recording_status_callback_method,
+ "SipAuthUsername": sip_auth_username,
+ "SipAuthPassword": sip_auth_password,
+ "MachineDetection": machine_detection,
+ "MachineDetectionTimeout": machine_detection_timeout,
+ "RecordingStatusCallbackEvent": serialize.map(
+ recording_status_callback_event, lambda e: e
+ ),
+ "Trim": trim,
+ "CallerId": caller_id,
+ "MachineDetectionSpeechThreshold": machine_detection_speech_threshold,
+ "MachineDetectionSpeechEndThreshold": machine_detection_speech_end_threshold,
+ "MachineDetectionSilenceTimeout": machine_detection_silence_timeout,
+ "AsyncAmd": async_amd,
+ "AsyncAmdStatusCallback": async_amd_status_callback,
+ "AsyncAmdStatusCallbackMethod": async_amd_status_callback_method,
+ "Byoc": byoc,
+ "CallReason": call_reason,
+ "CallToken": call_token,
+ "RecordingTrack": recording_track,
+ "TimeLimit": time_limit,
+ "Url": url,
+ "Twiml": twiml,
+ "ApplicationSid": application_sid,
+ }
+ )
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.create(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return CallInstance(
+ self._version, payload, account_sid=self._solution["account_sid"]
+ )
+
+ async def create_async(
+ self,
+ to: str,
+ from_: str,
+ method: Union[str, object] = values.unset,
+ fallback_url: Union[str, object] = values.unset,
+ fallback_method: Union[str, object] = values.unset,
+ status_callback: Union[str, object] = values.unset,
+ status_callback_event: Union[List[str], object] = values.unset,
+ status_callback_method: Union[str, object] = values.unset,
+ send_digits: Union[str, object] = values.unset,
+ timeout: Union[int, object] = values.unset,
+ record: Union[bool, object] = values.unset,
+ recording_channels: Union[str, object] = values.unset,
+ recording_status_callback: Union[str, object] = values.unset,
+ recording_status_callback_method: Union[str, object] = values.unset,
+ sip_auth_username: Union[str, object] = values.unset,
+ sip_auth_password: Union[str, object] = values.unset,
+ machine_detection: Union[str, object] = values.unset,
+ machine_detection_timeout: Union[int, object] = values.unset,
+ recording_status_callback_event: Union[List[str], object] = values.unset,
+ trim: Union[str, object] = values.unset,
+ caller_id: Union[str, object] = values.unset,
+ machine_detection_speech_threshold: Union[int, object] = values.unset,
+ machine_detection_speech_end_threshold: Union[int, object] = values.unset,
+ machine_detection_silence_timeout: Union[int, object] = values.unset,
+ async_amd: Union[str, object] = values.unset,
+ async_amd_status_callback: Union[str, object] = values.unset,
+ async_amd_status_callback_method: Union[str, object] = values.unset,
+ byoc: Union[str, object] = values.unset,
+ call_reason: Union[str, object] = values.unset,
+ call_token: Union[str, object] = values.unset,
+ recording_track: Union[str, object] = values.unset,
+ time_limit: Union[int, object] = values.unset,
+ url: Union[str, object] = values.unset,
+ twiml: Union[str, object] = values.unset,
+ application_sid: Union[str, object] = values.unset,
+ ) -> CallInstance:
+ """
+ Asynchronously create the CallInstance
+
+ :param to: The phone number, SIP address, or client identifier to call.
+ :param from_: The phone number or client identifier to use as the caller id. If using a phone number, it must be a Twilio number or a Verified [outgoing caller id](https://www.twilio.com/docs/voice/api/outgoing-caller-ids) for your account. If the `to` parameter is a phone number, `From` must also be a phone number.
+ :param method: The HTTP method we should use when calling the `url` parameter's value. Can be: `GET` or `POST` and the default is `POST`. If an `application_sid` parameter is present, this parameter is ignored.
+ :param fallback_url: The URL that we call using the `fallback_method` if an error occurs when requesting or executing the TwiML at `url`. If an `application_sid` parameter is present, this parameter is ignored.
+ :param fallback_method: The HTTP method that we should use to request the `fallback_url`. Can be: `GET` or `POST` and the default is `POST`. If an `application_sid` parameter is present, this parameter is ignored.
+ :param status_callback: The URL we should call using the `status_callback_method` to send status information to your application. If no `status_callback_event` is specified, we will send the `completed` status. If an `application_sid` parameter is present, this parameter is ignored. URLs must contain a valid hostname (underscores are not permitted).
+ :param status_callback_event: The call progress events that we will send to the `status_callback` URL. Can be: `initiated`, `ringing`, `answered`, and `completed`. If no event is specified, we send the `completed` status. If you want to receive multiple events, specify each one in a separate `status_callback_event` parameter. See the code sample for [monitoring call progress](https://www.twilio.com/docs/voice/api/call-resource?code-sample=code-create-a-call-resource-and-specify-a-statuscallbackevent&code-sdk-version=json). If an `application_sid` is present, this parameter is ignored.
+ :param status_callback_method: The HTTP method we should use when calling the `status_callback` URL. Can be: `GET` or `POST` and the default is `POST`. If an `application_sid` parameter is present, this parameter is ignored.
+ :param send_digits: The string of keys to dial after connecting to the number, with a maximum length of 32 digits. Valid digits in the string include any digit (`0`-`9`), '`A`', '`B`', '`C`', '`D`', '`#`', and '`*`'. You can also use '`w`' to insert a half-second pause and '`W`' to insert a one-second pause. For example, to pause for one second after connecting and then dial extension 1234 followed by the # key, set this parameter to `W1234#`. Be sure to URL-encode this string because the '`#`' character has special meaning in a URL. If both `SendDigits` and `MachineDetection` parameters are provided, then `MachineDetection` will be ignored.
+ :param timeout: The integer number of seconds that we should allow the phone to ring before assuming there is no answer. The default is `60` seconds and the maximum is `600` seconds. For some call flows, we will add a 5-second buffer to the timeout value you provide. For this reason, a timeout value of 10 seconds could result in an actual timeout closer to 15 seconds. You can set this to a short time, such as `15` seconds, to hang up before reaching an answering machine or voicemail.
+ :param record: Whether to record the call. Can be `true` to record the phone call, or `false` to not. The default is `false`. The `recording_url` is sent to the `status_callback` URL.
+ :param recording_channels: The number of channels in the final recording. Can be: `mono` or `dual`. The default is `mono`. `mono` records both legs of the call in a single channel of the recording file. `dual` records each leg to a separate channel of the recording file. The first channel of a dual-channel recording contains the parent call and the second channel contains the child call.
+ :param recording_status_callback: The URL that we call when the recording is available to be accessed.
+ :param recording_status_callback_method: The HTTP method we should use when calling the `recording_status_callback` URL. Can be: `GET` or `POST` and the default is `POST`.
+ :param sip_auth_username: The username used to authenticate the caller making a SIP call.
+ :param sip_auth_password: The password required to authenticate the user account specified in `sip_auth_username`.
+ :param machine_detection: Whether to detect if a human, answering machine, or fax has picked up the call. Can be: `Enable` or `DetectMessageEnd`. Use `Enable` if you would like us to return `AnsweredBy` as soon as the called party is identified. Use `DetectMessageEnd`, if you would like to leave a message on an answering machine. If `send_digits` is provided, this parameter is ignored. For more information, see [Answering Machine Detection](https://www.twilio.com/docs/voice/answering-machine-detection).
+ :param machine_detection_timeout: The number of seconds that we should attempt to detect an answering machine before timing out and sending a voice request with `AnsweredBy` of `unknown`. The default timeout is 30 seconds.
+ :param recording_status_callback_event: The recording status events that will trigger calls to the URL specified in `recording_status_callback`. Can be: `in-progress`, `completed` and `absent`. Defaults to `completed`. Separate multiple values with a space.
+ :param trim: Whether to trim any leading and trailing silence from the recording. Can be: `trim-silence` or `do-not-trim` and the default is `trim-silence`.
+ :param caller_id: The phone number, SIP address, or Client identifier that made this call. Phone numbers are in [E.164 format](https://wwnw.twilio.com/docs/glossary/what-e164) (e.g., +16175551212). SIP addresses are formatted as `name@company.com`.
+ :param machine_detection_speech_threshold: The number of milliseconds that is used as the measuring stick for the length of the speech activity, where durations lower than this value will be interpreted as a human and longer than this value as a machine. Possible Values: 1000-6000. Default: 2400.
+ :param machine_detection_speech_end_threshold: The number of milliseconds of silence after speech activity at which point the speech activity is considered complete. Possible Values: 500-5000. Default: 1200.
+ :param machine_detection_silence_timeout: The number of milliseconds of initial silence after which an `unknown` AnsweredBy result will be returned. Possible Values: 2000-10000. Default: 5000.
+ :param async_amd: Select whether to perform answering machine detection in the background. Default, blocks the execution of the call until Answering Machine Detection is completed. Can be: `true` or `false`.
+ :param async_amd_status_callback: The URL that we should call using the `async_amd_status_callback_method` to notify customer application whether the call was answered by human, machine or fax.
+ :param async_amd_status_callback_method: The HTTP method we should use when calling the `async_amd_status_callback` URL. Can be: `GET` or `POST` and the default is `POST`.
+ :param byoc: The SID of a BYOC (Bring Your Own Carrier) trunk to route this call with. Note that `byoc` is only meaningful when `to` is a phone number; it will otherwise be ignored. (Beta)
+ :param call_reason: The Reason for the outgoing call. Use it to specify the purpose of the call that is presented on the called party's phone. (Branded Calls Beta)
+ :param call_token: A token string needed to invoke a forwarded call. A call_token is generated when an incoming call is received on a Twilio number. Pass an incoming call's call_token value to a forwarded call via the call_token parameter when creating a new call. A forwarded call should bear the same CallerID of the original incoming call.
+ :param recording_track: The audio track to record for the call. Can be: `inbound`, `outbound` or `both`. The default is `both`. `inbound` records the audio that is received by Twilio. `outbound` records the audio that is generated from Twilio. `both` records the audio that is received and generated by Twilio.
+ :param time_limit: The maximum duration of the call in seconds. Constraints depend on account and configuration.
+ :param url: The absolute URL that returns the TwiML instructions for the call. We will call this URL using the `method` when the call connects. For more information, see the [Url Parameter](https://www.twilio.com/docs/voice/make-calls#specify-a-url-parameter) section in [Making Calls](https://www.twilio.com/docs/voice/make-calls).
+ :param twiml: TwiML instructions for the call Twilio will use without fetching Twiml from url parameter. If both `twiml` and `url` are provided then `twiml` parameter will be ignored. Max 4000 characters.
+ :param application_sid: The SID of the Application resource that will handle the call, if the call will be handled by an application.
+
+ :returns: The created CallInstance
+ """
+
+ data = values.of(
+ {
+ "To": to,
+ "From": from_,
+ "Method": method,
+ "FallbackUrl": fallback_url,
+ "FallbackMethod": fallback_method,
+ "StatusCallback": status_callback,
+ "StatusCallbackEvent": serialize.map(
+ status_callback_event, lambda e: e
+ ),
+ "StatusCallbackMethod": status_callback_method,
+ "SendDigits": send_digits,
+ "Timeout": timeout,
+ "Record": serialize.boolean_to_string(record),
+ "RecordingChannels": recording_channels,
+ "RecordingStatusCallback": recording_status_callback,
+ "RecordingStatusCallbackMethod": recording_status_callback_method,
+ "SipAuthUsername": sip_auth_username,
+ "SipAuthPassword": sip_auth_password,
+ "MachineDetection": machine_detection,
+ "MachineDetectionTimeout": machine_detection_timeout,
+ "RecordingStatusCallbackEvent": serialize.map(
+ recording_status_callback_event, lambda e: e
+ ),
+ "Trim": trim,
+ "CallerId": caller_id,
+ "MachineDetectionSpeechThreshold": machine_detection_speech_threshold,
+ "MachineDetectionSpeechEndThreshold": machine_detection_speech_end_threshold,
+ "MachineDetectionSilenceTimeout": machine_detection_silence_timeout,
+ "AsyncAmd": async_amd,
+ "AsyncAmdStatusCallback": async_amd_status_callback,
+ "AsyncAmdStatusCallbackMethod": async_amd_status_callback_method,
+ "Byoc": byoc,
+ "CallReason": call_reason,
+ "CallToken": call_token,
+ "RecordingTrack": recording_track,
+ "TimeLimit": time_limit,
+ "Url": url,
+ "Twiml": twiml,
+ "ApplicationSid": application_sid,
+ }
+ )
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.create_async(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return CallInstance(
+ self._version, payload, account_sid=self._solution["account_sid"]
+ )
+
+ def stream(
+ self,
+ to: Union[str, object] = values.unset,
+ from_: Union[str, object] = values.unset,
+ parent_call_sid: Union[str, object] = values.unset,
+ status: Union["CallInstance.Status", object] = values.unset,
+ start_time: Union[datetime, object] = values.unset,
+ start_time_before: Union[datetime, object] = values.unset,
+ start_time_after: Union[datetime, object] = values.unset,
+ end_time: Union[datetime, object] = values.unset,
+ end_time_before: Union[datetime, object] = values.unset,
+ end_time_after: Union[datetime, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> Iterator[CallInstance]:
+ """
+ Streams CallInstance records from the API as a generator stream.
+ This operation lazily loads records as efficiently as possible until the limit
+ is reached.
+ The results are returned as a generator, so this operation is memory efficient.
+
+ :param str to: Only show calls made to this phone number, SIP address, Client identifier or SIM SID.
+ :param str from_: Only include calls from this phone number, SIP address, Client identifier or SIM SID.
+ :param str parent_call_sid: Only include calls spawned by calls with this SID.
+ :param "CallInstance.Status" status: The status of the calls to include. Can be: `queued`, `ringing`, `in-progress`, `canceled`, `completed`, `failed`, `busy`, or `no-answer`.
+ :param datetime start_time: Only include calls that started on this date. Specify a date as `YYYY-MM-DD` in UTC, for example: `2009-07-06`, to read only calls that started on this date. You can also specify an inequality, such as `StartTime<=YYYY-MM-DD`, to read calls that started on or before midnight of this date, and `StartTime>=YYYY-MM-DD` to read calls that started on or after midnight of this date.
+ :param datetime start_time_before: Only include calls that started on this date. Specify a date as `YYYY-MM-DD` in UTC, for example: `2009-07-06`, to read only calls that started on this date. You can also specify an inequality, such as `StartTime<=YYYY-MM-DD`, to read calls that started on or before midnight of this date, and `StartTime>=YYYY-MM-DD` to read calls that started on or after midnight of this date.
+ :param datetime start_time_after: Only include calls that started on this date. Specify a date as `YYYY-MM-DD` in UTC, for example: `2009-07-06`, to read only calls that started on this date. You can also specify an inequality, such as `StartTime<=YYYY-MM-DD`, to read calls that started on or before midnight of this date, and `StartTime>=YYYY-MM-DD` to read calls that started on or after midnight of this date.
+ :param datetime end_time: Only include calls that ended on this date. Specify a date as `YYYY-MM-DD` in UTC, for example: `2009-07-06`, to read only calls that ended on this date. You can also specify an inequality, such as `EndTime<=YYYY-MM-DD`, to read calls that ended on or before midnight of this date, and `EndTime>=YYYY-MM-DD` to read calls that ended on or after midnight of this date.
+ :param datetime end_time_before: Only include calls that ended on this date. Specify a date as `YYYY-MM-DD` in UTC, for example: `2009-07-06`, to read only calls that ended on this date. You can also specify an inequality, such as `EndTime<=YYYY-MM-DD`, to read calls that ended on or before midnight of this date, and `EndTime>=YYYY-MM-DD` to read calls that ended on or after midnight of this date.
+ :param datetime end_time_after: Only include calls that ended on this date. Specify a date as `YYYY-MM-DD` in UTC, for example: `2009-07-06`, to read only calls that ended on this date. You can also specify an inequality, such as `EndTime<=YYYY-MM-DD`, to read calls that ended on or before midnight of this date, and `EndTime>=YYYY-MM-DD` to read calls that ended on or after midnight of this date.
+ :param limit: Upper limit for the number of records to return. stream()
+ guarantees to never return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, stream() will attempt to read the
+ limit with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: Generator that will yield up to limit results
+ """
+ limits = self._version.read_limits(limit, page_size)
+ page = self.page(
+ to=to,
+ from_=from_,
+ parent_call_sid=parent_call_sid,
+ status=status,
+ start_time=start_time,
+ start_time_before=start_time_before,
+ start_time_after=start_time_after,
+ end_time=end_time,
+ end_time_before=end_time_before,
+ end_time_after=end_time_after,
+ page_size=limits["page_size"],
+ )
+
+ return self._version.stream(page, limits["limit"])
+
+ async def stream_async(
+ self,
+ to: Union[str, object] = values.unset,
+ from_: Union[str, object] = values.unset,
+ parent_call_sid: Union[str, object] = values.unset,
+ status: Union["CallInstance.Status", object] = values.unset,
+ start_time: Union[datetime, object] = values.unset,
+ start_time_before: Union[datetime, object] = values.unset,
+ start_time_after: Union[datetime, object] = values.unset,
+ end_time: Union[datetime, object] = values.unset,
+ end_time_before: Union[datetime, object] = values.unset,
+ end_time_after: Union[datetime, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> AsyncIterator[CallInstance]:
+ """
+ Asynchronously streams CallInstance records from the API as a generator stream.
+ This operation lazily loads records as efficiently as possible until the limit
+ is reached.
+ The results are returned as a generator, so this operation is memory efficient.
+
+ :param str to: Only show calls made to this phone number, SIP address, Client identifier or SIM SID.
+ :param str from_: Only include calls from this phone number, SIP address, Client identifier or SIM SID.
+ :param str parent_call_sid: Only include calls spawned by calls with this SID.
+ :param "CallInstance.Status" status: The status of the calls to include. Can be: `queued`, `ringing`, `in-progress`, `canceled`, `completed`, `failed`, `busy`, or `no-answer`.
+ :param datetime start_time: Only include calls that started on this date. Specify a date as `YYYY-MM-DD` in UTC, for example: `2009-07-06`, to read only calls that started on this date. You can also specify an inequality, such as `StartTime<=YYYY-MM-DD`, to read calls that started on or before midnight of this date, and `StartTime>=YYYY-MM-DD` to read calls that started on or after midnight of this date.
+ :param datetime start_time_before: Only include calls that started on this date. Specify a date as `YYYY-MM-DD` in UTC, for example: `2009-07-06`, to read only calls that started on this date. You can also specify an inequality, such as `StartTime<=YYYY-MM-DD`, to read calls that started on or before midnight of this date, and `StartTime>=YYYY-MM-DD` to read calls that started on or after midnight of this date.
+ :param datetime start_time_after: Only include calls that started on this date. Specify a date as `YYYY-MM-DD` in UTC, for example: `2009-07-06`, to read only calls that started on this date. You can also specify an inequality, such as `StartTime<=YYYY-MM-DD`, to read calls that started on or before midnight of this date, and `StartTime>=YYYY-MM-DD` to read calls that started on or after midnight of this date.
+ :param datetime end_time: Only include calls that ended on this date. Specify a date as `YYYY-MM-DD` in UTC, for example: `2009-07-06`, to read only calls that ended on this date. You can also specify an inequality, such as `EndTime<=YYYY-MM-DD`, to read calls that ended on or before midnight of this date, and `EndTime>=YYYY-MM-DD` to read calls that ended on or after midnight of this date.
+ :param datetime end_time_before: Only include calls that ended on this date. Specify a date as `YYYY-MM-DD` in UTC, for example: `2009-07-06`, to read only calls that ended on this date. You can also specify an inequality, such as `EndTime<=YYYY-MM-DD`, to read calls that ended on or before midnight of this date, and `EndTime>=YYYY-MM-DD` to read calls that ended on or after midnight of this date.
+ :param datetime end_time_after: Only include calls that ended on this date. Specify a date as `YYYY-MM-DD` in UTC, for example: `2009-07-06`, to read only calls that ended on this date. You can also specify an inequality, such as `EndTime<=YYYY-MM-DD`, to read calls that ended on or before midnight of this date, and `EndTime>=YYYY-MM-DD` to read calls that ended on or after midnight of this date.
+ :param limit: Upper limit for the number of records to return. stream()
+ guarantees to never return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, stream() will attempt to read the
+ limit with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: Generator that will yield up to limit results
+ """
+ limits = self._version.read_limits(limit, page_size)
+ page = await self.page_async(
+ to=to,
+ from_=from_,
+ parent_call_sid=parent_call_sid,
+ status=status,
+ start_time=start_time,
+ start_time_before=start_time_before,
+ start_time_after=start_time_after,
+ end_time=end_time,
+ end_time_before=end_time_before,
+ end_time_after=end_time_after,
+ page_size=limits["page_size"],
+ )
+
+ return self._version.stream_async(page, limits["limit"])
+
+ def list(
+ self,
+ to: Union[str, object] = values.unset,
+ from_: Union[str, object] = values.unset,
+ parent_call_sid: Union[str, object] = values.unset,
+ status: Union["CallInstance.Status", object] = values.unset,
+ start_time: Union[datetime, object] = values.unset,
+ start_time_before: Union[datetime, object] = values.unset,
+ start_time_after: Union[datetime, object] = values.unset,
+ end_time: Union[datetime, object] = values.unset,
+ end_time_before: Union[datetime, object] = values.unset,
+ end_time_after: Union[datetime, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> List[CallInstance]:
+ """
+ Lists CallInstance records from the API as a list.
+ Unlike stream(), this operation is eager and will load `limit` records into
+ memory before returning.
+
+ :param str to: Only show calls made to this phone number, SIP address, Client identifier or SIM SID.
+ :param str from_: Only include calls from this phone number, SIP address, Client identifier or SIM SID.
+ :param str parent_call_sid: Only include calls spawned by calls with this SID.
+ :param "CallInstance.Status" status: The status of the calls to include. Can be: `queued`, `ringing`, `in-progress`, `canceled`, `completed`, `failed`, `busy`, or `no-answer`.
+ :param datetime start_time: Only include calls that started on this date. Specify a date as `YYYY-MM-DD` in UTC, for example: `2009-07-06`, to read only calls that started on this date. You can also specify an inequality, such as `StartTime<=YYYY-MM-DD`, to read calls that started on or before midnight of this date, and `StartTime>=YYYY-MM-DD` to read calls that started on or after midnight of this date.
+ :param datetime start_time_before: Only include calls that started on this date. Specify a date as `YYYY-MM-DD` in UTC, for example: `2009-07-06`, to read only calls that started on this date. You can also specify an inequality, such as `StartTime<=YYYY-MM-DD`, to read calls that started on or before midnight of this date, and `StartTime>=YYYY-MM-DD` to read calls that started on or after midnight of this date.
+ :param datetime start_time_after: Only include calls that started on this date. Specify a date as `YYYY-MM-DD` in UTC, for example: `2009-07-06`, to read only calls that started on this date. You can also specify an inequality, such as `StartTime<=YYYY-MM-DD`, to read calls that started on or before midnight of this date, and `StartTime>=YYYY-MM-DD` to read calls that started on or after midnight of this date.
+ :param datetime end_time: Only include calls that ended on this date. Specify a date as `YYYY-MM-DD` in UTC, for example: `2009-07-06`, to read only calls that ended on this date. You can also specify an inequality, such as `EndTime<=YYYY-MM-DD`, to read calls that ended on or before midnight of this date, and `EndTime>=YYYY-MM-DD` to read calls that ended on or after midnight of this date.
+ :param datetime end_time_before: Only include calls that ended on this date. Specify a date as `YYYY-MM-DD` in UTC, for example: `2009-07-06`, to read only calls that ended on this date. You can also specify an inequality, such as `EndTime<=YYYY-MM-DD`, to read calls that ended on or before midnight of this date, and `EndTime>=YYYY-MM-DD` to read calls that ended on or after midnight of this date.
+ :param datetime end_time_after: Only include calls that ended on this date. Specify a date as `YYYY-MM-DD` in UTC, for example: `2009-07-06`, to read only calls that ended on this date. You can also specify an inequality, such as `EndTime<=YYYY-MM-DD`, to read calls that ended on or before midnight of this date, and `EndTime>=YYYY-MM-DD` to read calls that ended on or after midnight of this date.
+ :param limit: Upper limit for the number of records to return. list() guarantees
+ never to return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, list() will attempt to read the limit
+ with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: list that will contain up to limit results
+ """
+ return list(
+ self.stream(
+ to=to,
+ from_=from_,
+ parent_call_sid=parent_call_sid,
+ status=status,
+ start_time=start_time,
+ start_time_before=start_time_before,
+ start_time_after=start_time_after,
+ end_time=end_time,
+ end_time_before=end_time_before,
+ end_time_after=end_time_after,
+ limit=limit,
+ page_size=page_size,
+ )
+ )
+
+ async def list_async(
+ self,
+ to: Union[str, object] = values.unset,
+ from_: Union[str, object] = values.unset,
+ parent_call_sid: Union[str, object] = values.unset,
+ status: Union["CallInstance.Status", object] = values.unset,
+ start_time: Union[datetime, object] = values.unset,
+ start_time_before: Union[datetime, object] = values.unset,
+ start_time_after: Union[datetime, object] = values.unset,
+ end_time: Union[datetime, object] = values.unset,
+ end_time_before: Union[datetime, object] = values.unset,
+ end_time_after: Union[datetime, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> List[CallInstance]:
+ """
+ Asynchronously lists CallInstance records from the API as a list.
+ Unlike stream(), this operation is eager and will load `limit` records into
+ memory before returning.
+
+ :param str to: Only show calls made to this phone number, SIP address, Client identifier or SIM SID.
+ :param str from_: Only include calls from this phone number, SIP address, Client identifier or SIM SID.
+ :param str parent_call_sid: Only include calls spawned by calls with this SID.
+ :param "CallInstance.Status" status: The status of the calls to include. Can be: `queued`, `ringing`, `in-progress`, `canceled`, `completed`, `failed`, `busy`, or `no-answer`.
+ :param datetime start_time: Only include calls that started on this date. Specify a date as `YYYY-MM-DD` in UTC, for example: `2009-07-06`, to read only calls that started on this date. You can also specify an inequality, such as `StartTime<=YYYY-MM-DD`, to read calls that started on or before midnight of this date, and `StartTime>=YYYY-MM-DD` to read calls that started on or after midnight of this date.
+ :param datetime start_time_before: Only include calls that started on this date. Specify a date as `YYYY-MM-DD` in UTC, for example: `2009-07-06`, to read only calls that started on this date. You can also specify an inequality, such as `StartTime<=YYYY-MM-DD`, to read calls that started on or before midnight of this date, and `StartTime>=YYYY-MM-DD` to read calls that started on or after midnight of this date.
+ :param datetime start_time_after: Only include calls that started on this date. Specify a date as `YYYY-MM-DD` in UTC, for example: `2009-07-06`, to read only calls that started on this date. You can also specify an inequality, such as `StartTime<=YYYY-MM-DD`, to read calls that started on or before midnight of this date, and `StartTime>=YYYY-MM-DD` to read calls that started on or after midnight of this date.
+ :param datetime end_time: Only include calls that ended on this date. Specify a date as `YYYY-MM-DD` in UTC, for example: `2009-07-06`, to read only calls that ended on this date. You can also specify an inequality, such as `EndTime<=YYYY-MM-DD`, to read calls that ended on or before midnight of this date, and `EndTime>=YYYY-MM-DD` to read calls that ended on or after midnight of this date.
+ :param datetime end_time_before: Only include calls that ended on this date. Specify a date as `YYYY-MM-DD` in UTC, for example: `2009-07-06`, to read only calls that ended on this date. You can also specify an inequality, such as `EndTime<=YYYY-MM-DD`, to read calls that ended on or before midnight of this date, and `EndTime>=YYYY-MM-DD` to read calls that ended on or after midnight of this date.
+ :param datetime end_time_after: Only include calls that ended on this date. Specify a date as `YYYY-MM-DD` in UTC, for example: `2009-07-06`, to read only calls that ended on this date. You can also specify an inequality, such as `EndTime<=YYYY-MM-DD`, to read calls that ended on or before midnight of this date, and `EndTime>=YYYY-MM-DD` to read calls that ended on or after midnight of this date.
+ :param limit: Upper limit for the number of records to return. list() guarantees
+ never to return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, list() will attempt to read the limit
+ with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: list that will contain up to limit results
+ """
+ return [
+ record
+ async for record in await self.stream_async(
+ to=to,
+ from_=from_,
+ parent_call_sid=parent_call_sid,
+ status=status,
+ start_time=start_time,
+ start_time_before=start_time_before,
+ start_time_after=start_time_after,
+ end_time=end_time,
+ end_time_before=end_time_before,
+ end_time_after=end_time_after,
+ limit=limit,
+ page_size=page_size,
+ )
+ ]
+
+ def page(
+ self,
+ to: Union[str, object] = values.unset,
+ from_: Union[str, object] = values.unset,
+ parent_call_sid: Union[str, object] = values.unset,
+ status: Union["CallInstance.Status", object] = values.unset,
+ start_time: Union[datetime, object] = values.unset,
+ start_time_before: Union[datetime, object] = values.unset,
+ start_time_after: Union[datetime, object] = values.unset,
+ end_time: Union[datetime, object] = values.unset,
+ end_time_before: Union[datetime, object] = values.unset,
+ end_time_after: Union[datetime, object] = values.unset,
+ page_token: Union[str, object] = values.unset,
+ page_number: Union[int, object] = values.unset,
+ page_size: Union[int, object] = values.unset,
+ ) -> CallPage:
+ """
+ Retrieve a single page of CallInstance records from the API.
+ Request is executed immediately
+
+ :param to: Only show calls made to this phone number, SIP address, Client identifier or SIM SID.
+ :param from_: Only include calls from this phone number, SIP address, Client identifier or SIM SID.
+ :param parent_call_sid: Only include calls spawned by calls with this SID.
+ :param status: The status of the calls to include. Can be: `queued`, `ringing`, `in-progress`, `canceled`, `completed`, `failed`, `busy`, or `no-answer`.
+ :param start_time: Only include calls that started on this date. Specify a date as `YYYY-MM-DD` in UTC, for example: `2009-07-06`, to read only calls that started on this date. You can also specify an inequality, such as `StartTime<=YYYY-MM-DD`, to read calls that started on or before midnight of this date, and `StartTime>=YYYY-MM-DD` to read calls that started on or after midnight of this date.
+ :param start_time_before: Only include calls that started on this date. Specify a date as `YYYY-MM-DD` in UTC, for example: `2009-07-06`, to read only calls that started on this date. You can also specify an inequality, such as `StartTime<=YYYY-MM-DD`, to read calls that started on or before midnight of this date, and `StartTime>=YYYY-MM-DD` to read calls that started on or after midnight of this date.
+ :param start_time_after: Only include calls that started on this date. Specify a date as `YYYY-MM-DD` in UTC, for example: `2009-07-06`, to read only calls that started on this date. You can also specify an inequality, such as `StartTime<=YYYY-MM-DD`, to read calls that started on or before midnight of this date, and `StartTime>=YYYY-MM-DD` to read calls that started on or after midnight of this date.
+ :param end_time: Only include calls that ended on this date. Specify a date as `YYYY-MM-DD` in UTC, for example: `2009-07-06`, to read only calls that ended on this date. You can also specify an inequality, such as `EndTime<=YYYY-MM-DD`, to read calls that ended on or before midnight of this date, and `EndTime>=YYYY-MM-DD` to read calls that ended on or after midnight of this date.
+ :param end_time_before: Only include calls that ended on this date. Specify a date as `YYYY-MM-DD` in UTC, for example: `2009-07-06`, to read only calls that ended on this date. You can also specify an inequality, such as `EndTime<=YYYY-MM-DD`, to read calls that ended on or before midnight of this date, and `EndTime>=YYYY-MM-DD` to read calls that ended on or after midnight of this date.
+ :param end_time_after: Only include calls that ended on this date. Specify a date as `YYYY-MM-DD` in UTC, for example: `2009-07-06`, to read only calls that ended on this date. You can also specify an inequality, such as `EndTime<=YYYY-MM-DD`, to read calls that ended on or before midnight of this date, and `EndTime>=YYYY-MM-DD` to read calls that ended on or after midnight of this date.
+ :param page_token: PageToken provided by the API
+ :param page_number: Page Number, this value is simply for client state
+ :param page_size: Number of records to return, defaults to 50
+
+ :returns: Page of CallInstance
+ """
+ data = values.of(
+ {
+ "To": to,
+ "From": from_,
+ "ParentCallSid": parent_call_sid,
+ "Status": status,
+ "StartTime": serialize.iso8601_datetime(start_time),
+ "StartTime<": serialize.iso8601_datetime(start_time_before),
+ "StartTime>": serialize.iso8601_datetime(start_time_after),
+ "EndTime": serialize.iso8601_datetime(end_time),
+ "EndTime<": serialize.iso8601_datetime(end_time_before),
+ "EndTime>": serialize.iso8601_datetime(end_time_after),
+ "PageToken": page_token,
+ "Page": page_number,
+ "PageSize": page_size,
+ }
+ )
+
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ response = self._version.page(
+ method="GET", uri=self._uri, params=data, headers=headers
+ )
+ return CallPage(self._version, response, self._solution)
+
+ async def page_async(
+ self,
+ to: Union[str, object] = values.unset,
+ from_: Union[str, object] = values.unset,
+ parent_call_sid: Union[str, object] = values.unset,
+ status: Union["CallInstance.Status", object] = values.unset,
+ start_time: Union[datetime, object] = values.unset,
+ start_time_before: Union[datetime, object] = values.unset,
+ start_time_after: Union[datetime, object] = values.unset,
+ end_time: Union[datetime, object] = values.unset,
+ end_time_before: Union[datetime, object] = values.unset,
+ end_time_after: Union[datetime, object] = values.unset,
+ page_token: Union[str, object] = values.unset,
+ page_number: Union[int, object] = values.unset,
+ page_size: Union[int, object] = values.unset,
+ ) -> CallPage:
+ """
+ Asynchronously retrieve a single page of CallInstance records from the API.
+ Request is executed immediately
+
+ :param to: Only show calls made to this phone number, SIP address, Client identifier or SIM SID.
+ :param from_: Only include calls from this phone number, SIP address, Client identifier or SIM SID.
+ :param parent_call_sid: Only include calls spawned by calls with this SID.
+ :param status: The status of the calls to include. Can be: `queued`, `ringing`, `in-progress`, `canceled`, `completed`, `failed`, `busy`, or `no-answer`.
+ :param start_time: Only include calls that started on this date. Specify a date as `YYYY-MM-DD` in UTC, for example: `2009-07-06`, to read only calls that started on this date. You can also specify an inequality, such as `StartTime<=YYYY-MM-DD`, to read calls that started on or before midnight of this date, and `StartTime>=YYYY-MM-DD` to read calls that started on or after midnight of this date.
+ :param start_time_before: Only include calls that started on this date. Specify a date as `YYYY-MM-DD` in UTC, for example: `2009-07-06`, to read only calls that started on this date. You can also specify an inequality, such as `StartTime<=YYYY-MM-DD`, to read calls that started on or before midnight of this date, and `StartTime>=YYYY-MM-DD` to read calls that started on or after midnight of this date.
+ :param start_time_after: Only include calls that started on this date. Specify a date as `YYYY-MM-DD` in UTC, for example: `2009-07-06`, to read only calls that started on this date. You can also specify an inequality, such as `StartTime<=YYYY-MM-DD`, to read calls that started on or before midnight of this date, and `StartTime>=YYYY-MM-DD` to read calls that started on or after midnight of this date.
+ :param end_time: Only include calls that ended on this date. Specify a date as `YYYY-MM-DD` in UTC, for example: `2009-07-06`, to read only calls that ended on this date. You can also specify an inequality, such as `EndTime<=YYYY-MM-DD`, to read calls that ended on or before midnight of this date, and `EndTime>=YYYY-MM-DD` to read calls that ended on or after midnight of this date.
+ :param end_time_before: Only include calls that ended on this date. Specify a date as `YYYY-MM-DD` in UTC, for example: `2009-07-06`, to read only calls that ended on this date. You can also specify an inequality, such as `EndTime<=YYYY-MM-DD`, to read calls that ended on or before midnight of this date, and `EndTime>=YYYY-MM-DD` to read calls that ended on or after midnight of this date.
+ :param end_time_after: Only include calls that ended on this date. Specify a date as `YYYY-MM-DD` in UTC, for example: `2009-07-06`, to read only calls that ended on this date. You can also specify an inequality, such as `EndTime<=YYYY-MM-DD`, to read calls that ended on or before midnight of this date, and `EndTime>=YYYY-MM-DD` to read calls that ended on or after midnight of this date.
+ :param page_token: PageToken provided by the API
+ :param page_number: Page Number, this value is simply for client state
+ :param page_size: Number of records to return, defaults to 50
+
+ :returns: Page of CallInstance
+ """
+ data = values.of(
+ {
+ "To": to,
+ "From": from_,
+ "ParentCallSid": parent_call_sid,
+ "Status": status,
+ "StartTime": serialize.iso8601_datetime(start_time),
+ "StartTime<": serialize.iso8601_datetime(start_time_before),
+ "StartTime>": serialize.iso8601_datetime(start_time_after),
+ "EndTime": serialize.iso8601_datetime(end_time),
+ "EndTime<": serialize.iso8601_datetime(end_time_before),
+ "EndTime>": serialize.iso8601_datetime(end_time_after),
+ "PageToken": page_token,
+ "Page": page_number,
+ "PageSize": page_size,
+ }
+ )
+
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ response = await self._version.page_async(
+ method="GET", uri=self._uri, params=data, headers=headers
+ )
+ return CallPage(self._version, response, self._solution)
+
+ def get_page(self, target_url: str) -> CallPage:
+ """
+ Retrieve a specific page of CallInstance records from the API.
+ Request is executed immediately
+
+ :param target_url: API-generated URL for the requested results page
+
+ :returns: Page of CallInstance
+ """
+ response = self._version.domain.twilio.request("GET", target_url)
+ return CallPage(self._version, response, self._solution)
+
+ async def get_page_async(self, target_url: str) -> CallPage:
+ """
+ Asynchronously retrieve a specific page of CallInstance records from the API.
+ Request is executed immediately
+
+ :param target_url: API-generated URL for the requested results page
+
+ :returns: Page of CallInstance
+ """
+ response = await self._version.domain.twilio.request_async("GET", target_url)
+ return CallPage(self._version, response, self._solution)
+
+ def get(self, sid: str) -> CallContext:
+ """
+ Constructs a CallContext
+
+ :param sid: The Twilio-provided string that uniquely identifies the Call resource to update
+ """
+ return CallContext(
+ self._version, account_sid=self._solution["account_sid"], sid=sid
+ )
+
+ def __call__(self, sid: str) -> CallContext:
+ """
+ Constructs a CallContext
+
+ :param sid: The Twilio-provided string that uniquely identifies the Call resource to update
+ """
+ return CallContext(
+ self._version, account_sid=self._solution["account_sid"], sid=sid
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/__pycache__/__init__.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 00000000..3efe3da2
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/__pycache__/__init__.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/__pycache__/event.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/__pycache__/event.cpython-312.pyc
new file mode 100644
index 00000000..6e119f6c
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/__pycache__/event.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/__pycache__/notification.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/__pycache__/notification.cpython-312.pyc
new file mode 100644
index 00000000..ccea5435
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/__pycache__/notification.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/__pycache__/payment.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/__pycache__/payment.cpython-312.pyc
new file mode 100644
index 00000000..9e5cacb3
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/__pycache__/payment.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/__pycache__/recording.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/__pycache__/recording.cpython-312.pyc
new file mode 100644
index 00000000..14d687fb
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/__pycache__/recording.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/__pycache__/siprec.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/__pycache__/siprec.cpython-312.pyc
new file mode 100644
index 00000000..29b58d66
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/__pycache__/siprec.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/__pycache__/stream.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/__pycache__/stream.cpython-312.pyc
new file mode 100644
index 00000000..28a88f21
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/__pycache__/stream.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/__pycache__/transcription.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/__pycache__/transcription.cpython-312.pyc
new file mode 100644
index 00000000..514066de
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/__pycache__/transcription.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/__pycache__/user_defined_message.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/__pycache__/user_defined_message.cpython-312.pyc
new file mode 100644
index 00000000..b9863eb9
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/__pycache__/user_defined_message.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/__pycache__/user_defined_message_subscription.cpython-312.pyc b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/__pycache__/user_defined_message_subscription.cpython-312.pyc
new file mode 100644
index 00000000..b02ba873
Binary files /dev/null and b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/__pycache__/user_defined_message_subscription.cpython-312.pyc differ
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/event.py b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/event.py
new file mode 100644
index 00000000..80eb8aa8
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/event.py
@@ -0,0 +1,298 @@
+r"""
+ This code was generated by
+ ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __
+ | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/
+ | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \
+
+ Twilio - Api
+ This is the public Twilio REST API.
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ https://openapi-generator.tech
+ Do not edit the class manually.
+"""
+
+from typing import Any, Dict, List, Optional, Union, Iterator, AsyncIterator
+from twilio.base import values
+
+from twilio.base.instance_resource import InstanceResource
+from twilio.base.list_resource import ListResource
+from twilio.base.version import Version
+from twilio.base.page import Page
+
+
+class EventInstance(InstanceResource):
+ """
+ :ivar request: Contains a dictionary representing the request of the call.
+ :ivar response: Contains a dictionary representing the call response, including a list of the call events.
+ """
+
+ def __init__(
+ self, version: Version, payload: Dict[str, Any], account_sid: str, call_sid: str
+ ):
+ super().__init__(version)
+
+ self.request: Optional[Dict[str, object]] = payload.get("request")
+ self.response: Optional[Dict[str, object]] = payload.get("response")
+
+ self._solution = {
+ "account_sid": account_sid,
+ "call_sid": call_sid,
+ }
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(context)
+
+
+class EventPage(Page):
+
+ def get_instance(self, payload: Dict[str, Any]) -> EventInstance:
+ """
+ Build an instance of EventInstance
+
+ :param payload: Payload response from the API
+ """
+ return EventInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
+
+
+class EventList(ListResource):
+
+ def __init__(self, version: Version, account_sid: str, call_sid: str):
+ """
+ Initialize the EventList
+
+ :param version: Version that contains the resource
+ :param account_sid: The unique SID identifier of the Account.
+ :param call_sid: The unique SID identifier of the Call.
+
+ """
+ super().__init__(version)
+
+ # Path Solution
+ self._solution = {
+ "account_sid": account_sid,
+ "call_sid": call_sid,
+ }
+ self._uri = "/Accounts/{account_sid}/Calls/{call_sid}/Events.json".format(
+ **self._solution
+ )
+
+ def stream(
+ self,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> Iterator[EventInstance]:
+ """
+ Streams EventInstance records from the API as a generator stream.
+ This operation lazily loads records as efficiently as possible until the limit
+ is reached.
+ The results are returned as a generator, so this operation is memory efficient.
+
+ :param limit: Upper limit for the number of records to return. stream()
+ guarantees to never return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, stream() will attempt to read the
+ limit with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: Generator that will yield up to limit results
+ """
+ limits = self._version.read_limits(limit, page_size)
+ page = self.page(page_size=limits["page_size"])
+
+ return self._version.stream(page, limits["limit"])
+
+ async def stream_async(
+ self,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> AsyncIterator[EventInstance]:
+ """
+ Asynchronously streams EventInstance records from the API as a generator stream.
+ This operation lazily loads records as efficiently as possible until the limit
+ is reached.
+ The results are returned as a generator, so this operation is memory efficient.
+
+ :param limit: Upper limit for the number of records to return. stream()
+ guarantees to never return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, stream() will attempt to read the
+ limit with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: Generator that will yield up to limit results
+ """
+ limits = self._version.read_limits(limit, page_size)
+ page = await self.page_async(page_size=limits["page_size"])
+
+ return self._version.stream_async(page, limits["limit"])
+
+ def list(
+ self,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> List[EventInstance]:
+ """
+ Lists EventInstance records from the API as a list.
+ Unlike stream(), this operation is eager and will load `limit` records into
+ memory before returning.
+
+ :param limit: Upper limit for the number of records to return. list() guarantees
+ never to return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, list() will attempt to read the limit
+ with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: list that will contain up to limit results
+ """
+ return list(
+ self.stream(
+ limit=limit,
+ page_size=page_size,
+ )
+ )
+
+ async def list_async(
+ self,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> List[EventInstance]:
+ """
+ Asynchronously lists EventInstance records from the API as a list.
+ Unlike stream(), this operation is eager and will load `limit` records into
+ memory before returning.
+
+ :param limit: Upper limit for the number of records to return. list() guarantees
+ never to return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, list() will attempt to read the limit
+ with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: list that will contain up to limit results
+ """
+ return [
+ record
+ async for record in await self.stream_async(
+ limit=limit,
+ page_size=page_size,
+ )
+ ]
+
+ def page(
+ self,
+ page_token: Union[str, object] = values.unset,
+ page_number: Union[int, object] = values.unset,
+ page_size: Union[int, object] = values.unset,
+ ) -> EventPage:
+ """
+ Retrieve a single page of EventInstance records from the API.
+ Request is executed immediately
+
+ :param page_token: PageToken provided by the API
+ :param page_number: Page Number, this value is simply for client state
+ :param page_size: Number of records to return, defaults to 50
+
+ :returns: Page of EventInstance
+ """
+ data = values.of(
+ {
+ "PageToken": page_token,
+ "Page": page_number,
+ "PageSize": page_size,
+ }
+ )
+
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ response = self._version.page(
+ method="GET", uri=self._uri, params=data, headers=headers
+ )
+ return EventPage(self._version, response, self._solution)
+
+ async def page_async(
+ self,
+ page_token: Union[str, object] = values.unset,
+ page_number: Union[int, object] = values.unset,
+ page_size: Union[int, object] = values.unset,
+ ) -> EventPage:
+ """
+ Asynchronously retrieve a single page of EventInstance records from the API.
+ Request is executed immediately
+
+ :param page_token: PageToken provided by the API
+ :param page_number: Page Number, this value is simply for client state
+ :param page_size: Number of records to return, defaults to 50
+
+ :returns: Page of EventInstance
+ """
+ data = values.of(
+ {
+ "PageToken": page_token,
+ "Page": page_number,
+ "PageSize": page_size,
+ }
+ )
+
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ response = await self._version.page_async(
+ method="GET", uri=self._uri, params=data, headers=headers
+ )
+ return EventPage(self._version, response, self._solution)
+
+ def get_page(self, target_url: str) -> EventPage:
+ """
+ Retrieve a specific page of EventInstance records from the API.
+ Request is executed immediately
+
+ :param target_url: API-generated URL for the requested results page
+
+ :returns: Page of EventInstance
+ """
+ response = self._version.domain.twilio.request("GET", target_url)
+ return EventPage(self._version, response, self._solution)
+
+ async def get_page_async(self, target_url: str) -> EventPage:
+ """
+ Asynchronously retrieve a specific page of EventInstance records from the API.
+ Request is executed immediately
+
+ :param target_url: API-generated URL for the requested results page
+
+ :returns: Page of EventInstance
+ """
+ response = await self._version.domain.twilio.request_async("GET", target_url)
+ return EventPage(self._version, response, self._solution)
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/notification.py b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/notification.py
new file mode 100644
index 00000000..fd9e8c0d
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/notification.py
@@ -0,0 +1,562 @@
+r"""
+ This code was generated by
+ ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __
+ | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/
+ | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \
+
+ Twilio - Api
+ This is the public Twilio REST API.
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ https://openapi-generator.tech
+ Do not edit the class manually.
+"""
+
+from datetime import date, datetime
+from typing import Any, Dict, List, Optional, Union, Iterator, AsyncIterator
+from twilio.base import deserialize, serialize, values
+from twilio.base.instance_context import InstanceContext
+from twilio.base.instance_resource import InstanceResource
+from twilio.base.list_resource import ListResource
+from twilio.base.version import Version
+from twilio.base.page import Page
+
+
+class NotificationInstance(InstanceResource):
+ """
+ :ivar account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that created the Call Notification resource.
+ :ivar api_version: The API version used to create the Call Notification resource.
+ :ivar call_sid: The SID of the [Call](https://www.twilio.com/docs/voice/api/call-resource) the Call Notification resource is associated with.
+ :ivar date_created: The date and time in GMT that the resource was created specified in [RFC 2822](https://www.ietf.org/rfc/rfc2822.txt) format.
+ :ivar date_updated: The date and time in GMT that the resource was last updated specified in [RFC 2822](https://www.ietf.org/rfc/rfc2822.txt) format.
+ :ivar error_code: A unique error code for the error condition that is described in our [Error Dictionary](https://www.twilio.com/docs/api/errors).
+ :ivar log: An integer log level that corresponds to the type of notification: `0` is ERROR, `1` is WARNING.
+ :ivar message_date: The date the notification was actually generated in [RFC 2822](https://www.ietf.org/rfc/rfc2822.txt) format. Message buffering can cause this value to differ from `date_created`.
+ :ivar message_text: The text of the notification.
+ :ivar more_info: The URL for more information about the error condition. This value is a page in our [Error Dictionary](https://www.twilio.com/docs/api/errors).
+ :ivar request_method: The HTTP method used to generate the notification. If the notification was generated during a phone call, this is the HTTP Method used to request the resource on your server. If the notification was generated by your use of our REST API, this is the HTTP method used to call the resource on our servers.
+ :ivar request_url: The URL of the resource that generated the notification. If the notification was generated during a phone call, this is the URL of the resource on your server that caused the notification. If the notification was generated by your use of our REST API, this is the URL of the resource you called.
+ :ivar request_variables: The HTTP GET or POST variables we sent to your server. However, if the notification was generated by our REST API, this contains the HTTP POST or PUT variables you sent to our API.
+ :ivar response_body: The HTTP body returned by your server.
+ :ivar response_headers: The HTTP headers returned by your server.
+ :ivar sid: The unique string that that we created to identify the Call Notification resource.
+ :ivar uri: The URI of the resource, relative to `https://api.twilio.com`.
+ """
+
+ def __init__(
+ self,
+ version: Version,
+ payload: Dict[str, Any],
+ account_sid: str,
+ call_sid: str,
+ sid: Optional[str] = None,
+ ):
+ super().__init__(version)
+
+ self.account_sid: Optional[str] = payload.get("account_sid")
+ self.api_version: Optional[str] = payload.get("api_version")
+ self.call_sid: Optional[str] = payload.get("call_sid")
+ self.date_created: Optional[datetime] = deserialize.rfc2822_datetime(
+ payload.get("date_created")
+ )
+ self.date_updated: Optional[datetime] = deserialize.rfc2822_datetime(
+ payload.get("date_updated")
+ )
+ self.error_code: Optional[str] = payload.get("error_code")
+ self.log: Optional[str] = payload.get("log")
+ self.message_date: Optional[datetime] = deserialize.rfc2822_datetime(
+ payload.get("message_date")
+ )
+ self.message_text: Optional[str] = payload.get("message_text")
+ self.more_info: Optional[str] = payload.get("more_info")
+ self.request_method: Optional[str] = payload.get("request_method")
+ self.request_url: Optional[str] = payload.get("request_url")
+ self.request_variables: Optional[str] = payload.get("request_variables")
+ self.response_body: Optional[str] = payload.get("response_body")
+ self.response_headers: Optional[str] = payload.get("response_headers")
+ self.sid: Optional[str] = payload.get("sid")
+ self.uri: Optional[str] = payload.get("uri")
+
+ self._solution = {
+ "account_sid": account_sid,
+ "call_sid": call_sid,
+ "sid": sid or self.sid,
+ }
+ self._context: Optional[NotificationContext] = None
+
+ @property
+ def _proxy(self) -> "NotificationContext":
+ """
+ Generate an instance context for the instance, the context is capable of
+ performing various actions. All instance actions are proxied to the context
+
+ :returns: NotificationContext for this NotificationInstance
+ """
+ if self._context is None:
+ self._context = NotificationContext(
+ self._version,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ sid=self._solution["sid"],
+ )
+ return self._context
+
+ def fetch(self) -> "NotificationInstance":
+ """
+ Fetch the NotificationInstance
+
+
+ :returns: The fetched NotificationInstance
+ """
+ return self._proxy.fetch()
+
+ async def fetch_async(self) -> "NotificationInstance":
+ """
+ Asynchronous coroutine to fetch the NotificationInstance
+
+
+ :returns: The fetched NotificationInstance
+ """
+ return await self._proxy.fetch_async()
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(context)
+
+
+class NotificationContext(InstanceContext):
+
+ def __init__(self, version: Version, account_sid: str, call_sid: str, sid: str):
+ """
+ Initialize the NotificationContext
+
+ :param version: Version that contains the resource
+ :param account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that created the Call Notification resource to fetch.
+ :param call_sid: The [Call](https://www.twilio.com/docs/voice/api/call-resource) SID of the Call Notification resource to fetch.
+ :param sid: The Twilio-provided string that uniquely identifies the Call Notification resource to fetch.
+ """
+ super().__init__(version)
+
+ # Path Solution
+ self._solution = {
+ "account_sid": account_sid,
+ "call_sid": call_sid,
+ "sid": sid,
+ }
+ self._uri = (
+ "/Accounts/{account_sid}/Calls/{call_sid}/Notifications/{sid}.json".format(
+ **self._solution
+ )
+ )
+
+ def fetch(self) -> NotificationInstance:
+ """
+ Fetch the NotificationInstance
+
+
+ :returns: The fetched NotificationInstance
+ """
+
+ headers = values.of({})
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.fetch(method="GET", uri=self._uri, headers=headers)
+
+ return NotificationInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ sid=self._solution["sid"],
+ )
+
+ async def fetch_async(self) -> NotificationInstance:
+ """
+ Asynchronous coroutine to fetch the NotificationInstance
+
+
+ :returns: The fetched NotificationInstance
+ """
+
+ headers = values.of({})
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.fetch_async(
+ method="GET", uri=self._uri, headers=headers
+ )
+
+ return NotificationInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ sid=self._solution["sid"],
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(context)
+
+
+class NotificationPage(Page):
+
+ def get_instance(self, payload: Dict[str, Any]) -> NotificationInstance:
+ """
+ Build an instance of NotificationInstance
+
+ :param payload: Payload response from the API
+ """
+ return NotificationInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
+
+
+class NotificationList(ListResource):
+
+ def __init__(self, version: Version, account_sid: str, call_sid: str):
+ """
+ Initialize the NotificationList
+
+ :param version: Version that contains the resource
+ :param account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that created the Call Notification resources to read.
+ :param call_sid: The [Call](https://www.twilio.com/docs/voice/api/call-resource) SID of the Call Notification resources to read.
+
+ """
+ super().__init__(version)
+
+ # Path Solution
+ self._solution = {
+ "account_sid": account_sid,
+ "call_sid": call_sid,
+ }
+ self._uri = (
+ "/Accounts/{account_sid}/Calls/{call_sid}/Notifications.json".format(
+ **self._solution
+ )
+ )
+
+ def stream(
+ self,
+ log: Union[int, object] = values.unset,
+ message_date: Union[date, object] = values.unset,
+ message_date_before: Union[date, object] = values.unset,
+ message_date_after: Union[date, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> Iterator[NotificationInstance]:
+ """
+ Streams NotificationInstance records from the API as a generator stream.
+ This operation lazily loads records as efficiently as possible until the limit
+ is reached.
+ The results are returned as a generator, so this operation is memory efficient.
+
+ :param int log: Only read notifications of the specified log level. Can be: `0` to read only ERROR notifications or `1` to read only WARNING notifications. By default, all notifications are read.
+ :param date message_date: Only show notifications for the specified date, formatted as `YYYY-MM-DD`. You can also specify an inequality, such as `<=YYYY-MM-DD` for messages logged at or before midnight on a date, or `>=YYYY-MM-DD` for messages logged at or after midnight on a date.
+ :param date message_date_before: Only show notifications for the specified date, formatted as `YYYY-MM-DD`. You can also specify an inequality, such as `<=YYYY-MM-DD` for messages logged at or before midnight on a date, or `>=YYYY-MM-DD` for messages logged at or after midnight on a date.
+ :param date message_date_after: Only show notifications for the specified date, formatted as `YYYY-MM-DD`. You can also specify an inequality, such as `<=YYYY-MM-DD` for messages logged at or before midnight on a date, or `>=YYYY-MM-DD` for messages logged at or after midnight on a date.
+ :param limit: Upper limit for the number of records to return. stream()
+ guarantees to never return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, stream() will attempt to read the
+ limit with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: Generator that will yield up to limit results
+ """
+ limits = self._version.read_limits(limit, page_size)
+ page = self.page(
+ log=log,
+ message_date=message_date,
+ message_date_before=message_date_before,
+ message_date_after=message_date_after,
+ page_size=limits["page_size"],
+ )
+
+ return self._version.stream(page, limits["limit"])
+
+ async def stream_async(
+ self,
+ log: Union[int, object] = values.unset,
+ message_date: Union[date, object] = values.unset,
+ message_date_before: Union[date, object] = values.unset,
+ message_date_after: Union[date, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> AsyncIterator[NotificationInstance]:
+ """
+ Asynchronously streams NotificationInstance records from the API as a generator stream.
+ This operation lazily loads records as efficiently as possible until the limit
+ is reached.
+ The results are returned as a generator, so this operation is memory efficient.
+
+ :param int log: Only read notifications of the specified log level. Can be: `0` to read only ERROR notifications or `1` to read only WARNING notifications. By default, all notifications are read.
+ :param date message_date: Only show notifications for the specified date, formatted as `YYYY-MM-DD`. You can also specify an inequality, such as `<=YYYY-MM-DD` for messages logged at or before midnight on a date, or `>=YYYY-MM-DD` for messages logged at or after midnight on a date.
+ :param date message_date_before: Only show notifications for the specified date, formatted as `YYYY-MM-DD`. You can also specify an inequality, such as `<=YYYY-MM-DD` for messages logged at or before midnight on a date, or `>=YYYY-MM-DD` for messages logged at or after midnight on a date.
+ :param date message_date_after: Only show notifications for the specified date, formatted as `YYYY-MM-DD`. You can also specify an inequality, such as `<=YYYY-MM-DD` for messages logged at or before midnight on a date, or `>=YYYY-MM-DD` for messages logged at or after midnight on a date.
+ :param limit: Upper limit for the number of records to return. stream()
+ guarantees to never return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, stream() will attempt to read the
+ limit with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: Generator that will yield up to limit results
+ """
+ limits = self._version.read_limits(limit, page_size)
+ page = await self.page_async(
+ log=log,
+ message_date=message_date,
+ message_date_before=message_date_before,
+ message_date_after=message_date_after,
+ page_size=limits["page_size"],
+ )
+
+ return self._version.stream_async(page, limits["limit"])
+
+ def list(
+ self,
+ log: Union[int, object] = values.unset,
+ message_date: Union[date, object] = values.unset,
+ message_date_before: Union[date, object] = values.unset,
+ message_date_after: Union[date, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> List[NotificationInstance]:
+ """
+ Lists NotificationInstance records from the API as a list.
+ Unlike stream(), this operation is eager and will load `limit` records into
+ memory before returning.
+
+ :param int log: Only read notifications of the specified log level. Can be: `0` to read only ERROR notifications or `1` to read only WARNING notifications. By default, all notifications are read.
+ :param date message_date: Only show notifications for the specified date, formatted as `YYYY-MM-DD`. You can also specify an inequality, such as `<=YYYY-MM-DD` for messages logged at or before midnight on a date, or `>=YYYY-MM-DD` for messages logged at or after midnight on a date.
+ :param date message_date_before: Only show notifications for the specified date, formatted as `YYYY-MM-DD`. You can also specify an inequality, such as `<=YYYY-MM-DD` for messages logged at or before midnight on a date, or `>=YYYY-MM-DD` for messages logged at or after midnight on a date.
+ :param date message_date_after: Only show notifications for the specified date, formatted as `YYYY-MM-DD`. You can also specify an inequality, such as `<=YYYY-MM-DD` for messages logged at or before midnight on a date, or `>=YYYY-MM-DD` for messages logged at or after midnight on a date.
+ :param limit: Upper limit for the number of records to return. list() guarantees
+ never to return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, list() will attempt to read the limit
+ with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: list that will contain up to limit results
+ """
+ return list(
+ self.stream(
+ log=log,
+ message_date=message_date,
+ message_date_before=message_date_before,
+ message_date_after=message_date_after,
+ limit=limit,
+ page_size=page_size,
+ )
+ )
+
+ async def list_async(
+ self,
+ log: Union[int, object] = values.unset,
+ message_date: Union[date, object] = values.unset,
+ message_date_before: Union[date, object] = values.unset,
+ message_date_after: Union[date, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> List[NotificationInstance]:
+ """
+ Asynchronously lists NotificationInstance records from the API as a list.
+ Unlike stream(), this operation is eager and will load `limit` records into
+ memory before returning.
+
+ :param int log: Only read notifications of the specified log level. Can be: `0` to read only ERROR notifications or `1` to read only WARNING notifications. By default, all notifications are read.
+ :param date message_date: Only show notifications for the specified date, formatted as `YYYY-MM-DD`. You can also specify an inequality, such as `<=YYYY-MM-DD` for messages logged at or before midnight on a date, or `>=YYYY-MM-DD` for messages logged at or after midnight on a date.
+ :param date message_date_before: Only show notifications for the specified date, formatted as `YYYY-MM-DD`. You can also specify an inequality, such as `<=YYYY-MM-DD` for messages logged at or before midnight on a date, or `>=YYYY-MM-DD` for messages logged at or after midnight on a date.
+ :param date message_date_after: Only show notifications for the specified date, formatted as `YYYY-MM-DD`. You can also specify an inequality, such as `<=YYYY-MM-DD` for messages logged at or before midnight on a date, or `>=YYYY-MM-DD` for messages logged at or after midnight on a date.
+ :param limit: Upper limit for the number of records to return. list() guarantees
+ never to return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, list() will attempt to read the limit
+ with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: list that will contain up to limit results
+ """
+ return [
+ record
+ async for record in await self.stream_async(
+ log=log,
+ message_date=message_date,
+ message_date_before=message_date_before,
+ message_date_after=message_date_after,
+ limit=limit,
+ page_size=page_size,
+ )
+ ]
+
+ def page(
+ self,
+ log: Union[int, object] = values.unset,
+ message_date: Union[date, object] = values.unset,
+ message_date_before: Union[date, object] = values.unset,
+ message_date_after: Union[date, object] = values.unset,
+ page_token: Union[str, object] = values.unset,
+ page_number: Union[int, object] = values.unset,
+ page_size: Union[int, object] = values.unset,
+ ) -> NotificationPage:
+ """
+ Retrieve a single page of NotificationInstance records from the API.
+ Request is executed immediately
+
+ :param log: Only read notifications of the specified log level. Can be: `0` to read only ERROR notifications or `1` to read only WARNING notifications. By default, all notifications are read.
+ :param message_date: Only show notifications for the specified date, formatted as `YYYY-MM-DD`. You can also specify an inequality, such as `<=YYYY-MM-DD` for messages logged at or before midnight on a date, or `>=YYYY-MM-DD` for messages logged at or after midnight on a date.
+ :param message_date_before: Only show notifications for the specified date, formatted as `YYYY-MM-DD`. You can also specify an inequality, such as `<=YYYY-MM-DD` for messages logged at or before midnight on a date, or `>=YYYY-MM-DD` for messages logged at or after midnight on a date.
+ :param message_date_after: Only show notifications for the specified date, formatted as `YYYY-MM-DD`. You can also specify an inequality, such as `<=YYYY-MM-DD` for messages logged at or before midnight on a date, or `>=YYYY-MM-DD` for messages logged at or after midnight on a date.
+ :param page_token: PageToken provided by the API
+ :param page_number: Page Number, this value is simply for client state
+ :param page_size: Number of records to return, defaults to 50
+
+ :returns: Page of NotificationInstance
+ """
+ data = values.of(
+ {
+ "Log": log,
+ "MessageDate": serialize.iso8601_date(message_date),
+ "MessageDate<": serialize.iso8601_date(message_date_before),
+ "MessageDate>": serialize.iso8601_date(message_date_after),
+ "PageToken": page_token,
+ "Page": page_number,
+ "PageSize": page_size,
+ }
+ )
+
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ response = self._version.page(
+ method="GET", uri=self._uri, params=data, headers=headers
+ )
+ return NotificationPage(self._version, response, self._solution)
+
+ async def page_async(
+ self,
+ log: Union[int, object] = values.unset,
+ message_date: Union[date, object] = values.unset,
+ message_date_before: Union[date, object] = values.unset,
+ message_date_after: Union[date, object] = values.unset,
+ page_token: Union[str, object] = values.unset,
+ page_number: Union[int, object] = values.unset,
+ page_size: Union[int, object] = values.unset,
+ ) -> NotificationPage:
+ """
+ Asynchronously retrieve a single page of NotificationInstance records from the API.
+ Request is executed immediately
+
+ :param log: Only read notifications of the specified log level. Can be: `0` to read only ERROR notifications or `1` to read only WARNING notifications. By default, all notifications are read.
+ :param message_date: Only show notifications for the specified date, formatted as `YYYY-MM-DD`. You can also specify an inequality, such as `<=YYYY-MM-DD` for messages logged at or before midnight on a date, or `>=YYYY-MM-DD` for messages logged at or after midnight on a date.
+ :param message_date_before: Only show notifications for the specified date, formatted as `YYYY-MM-DD`. You can also specify an inequality, such as `<=YYYY-MM-DD` for messages logged at or before midnight on a date, or `>=YYYY-MM-DD` for messages logged at or after midnight on a date.
+ :param message_date_after: Only show notifications for the specified date, formatted as `YYYY-MM-DD`. You can also specify an inequality, such as `<=YYYY-MM-DD` for messages logged at or before midnight on a date, or `>=YYYY-MM-DD` for messages logged at or after midnight on a date.
+ :param page_token: PageToken provided by the API
+ :param page_number: Page Number, this value is simply for client state
+ :param page_size: Number of records to return, defaults to 50
+
+ :returns: Page of NotificationInstance
+ """
+ data = values.of(
+ {
+ "Log": log,
+ "MessageDate": serialize.iso8601_date(message_date),
+ "MessageDate<": serialize.iso8601_date(message_date_before),
+ "MessageDate>": serialize.iso8601_date(message_date_after),
+ "PageToken": page_token,
+ "Page": page_number,
+ "PageSize": page_size,
+ }
+ )
+
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ response = await self._version.page_async(
+ method="GET", uri=self._uri, params=data, headers=headers
+ )
+ return NotificationPage(self._version, response, self._solution)
+
+ def get_page(self, target_url: str) -> NotificationPage:
+ """
+ Retrieve a specific page of NotificationInstance records from the API.
+ Request is executed immediately
+
+ :param target_url: API-generated URL for the requested results page
+
+ :returns: Page of NotificationInstance
+ """
+ response = self._version.domain.twilio.request("GET", target_url)
+ return NotificationPage(self._version, response, self._solution)
+
+ async def get_page_async(self, target_url: str) -> NotificationPage:
+ """
+ Asynchronously retrieve a specific page of NotificationInstance records from the API.
+ Request is executed immediately
+
+ :param target_url: API-generated URL for the requested results page
+
+ :returns: Page of NotificationInstance
+ """
+ response = await self._version.domain.twilio.request_async("GET", target_url)
+ return NotificationPage(self._version, response, self._solution)
+
+ def get(self, sid: str) -> NotificationContext:
+ """
+ Constructs a NotificationContext
+
+ :param sid: The Twilio-provided string that uniquely identifies the Call Notification resource to fetch.
+ """
+ return NotificationContext(
+ self._version,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ sid=sid,
+ )
+
+ def __call__(self, sid: str) -> NotificationContext:
+ """
+ Constructs a NotificationContext
+
+ :param sid: The Twilio-provided string that uniquely identifies the Call Notification resource to fetch.
+ """
+ return NotificationContext(
+ self._version,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ sid=sid,
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/payment.py b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/payment.py
new file mode 100644
index 00000000..0f918609
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/payment.py
@@ -0,0 +1,503 @@
+r"""
+ This code was generated by
+ ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __
+ | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/
+ | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \
+
+ Twilio - Api
+ This is the public Twilio REST API.
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ https://openapi-generator.tech
+ Do not edit the class manually.
+"""
+
+from datetime import datetime
+from typing import Any, Dict, Optional, Union
+from twilio.base import deserialize, serialize, values
+from twilio.base.instance_context import InstanceContext
+from twilio.base.instance_resource import InstanceResource
+from twilio.base.list_resource import ListResource
+from twilio.base.version import Version
+
+
+class PaymentInstance(InstanceResource):
+
+ class BankAccountType(object):
+ CONSUMER_CHECKING = "consumer-checking"
+ CONSUMER_SAVINGS = "consumer-savings"
+ COMMERCIAL_CHECKING = "commercial-checking"
+
+ class Capture(object):
+ PAYMENT_CARD_NUMBER = "payment-card-number"
+ EXPIRATION_DATE = "expiration-date"
+ SECURITY_CODE = "security-code"
+ POSTAL_CODE = "postal-code"
+ BANK_ROUTING_NUMBER = "bank-routing-number"
+ BANK_ACCOUNT_NUMBER = "bank-account-number"
+
+ class PaymentMethod(object):
+ CREDIT_CARD = "credit-card"
+ ACH_DEBIT = "ach-debit"
+
+ class Status(object):
+ COMPLETE = "complete"
+ CANCEL = "cancel"
+
+ class TokenType(object):
+ ONE_TIME = "one-time"
+ REUSABLE = "reusable"
+ PAYMENT_METHOD = "payment-method"
+
+ """
+ :ivar account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that created the Payments resource.
+ :ivar call_sid: The SID of the [Call](https://www.twilio.com/docs/voice/api/call-resource) the Payments resource is associated with. This will refer to the call sid that is producing the payment card (credit/ACH) information thru DTMF.
+ :ivar sid: The SID of the Payments resource.
+ :ivar date_created: The date and time in GMT that the resource was created specified in [RFC 2822](https://www.ietf.org/rfc/rfc2822.txt) format.
+ :ivar date_updated: The date and time in GMT that the resource was last updated specified in [RFC 2822](https://www.ietf.org/rfc/rfc2822.txt) format.
+ :ivar uri: The URI of the resource, relative to `https://api.twilio.com`.
+ """
+
+ def __init__(
+ self,
+ version: Version,
+ payload: Dict[str, Any],
+ account_sid: str,
+ call_sid: str,
+ sid: Optional[str] = None,
+ ):
+ super().__init__(version)
+
+ self.account_sid: Optional[str] = payload.get("account_sid")
+ self.call_sid: Optional[str] = payload.get("call_sid")
+ self.sid: Optional[str] = payload.get("sid")
+ self.date_created: Optional[datetime] = deserialize.rfc2822_datetime(
+ payload.get("date_created")
+ )
+ self.date_updated: Optional[datetime] = deserialize.rfc2822_datetime(
+ payload.get("date_updated")
+ )
+ self.uri: Optional[str] = payload.get("uri")
+
+ self._solution = {
+ "account_sid": account_sid,
+ "call_sid": call_sid,
+ "sid": sid or self.sid,
+ }
+ self._context: Optional[PaymentContext] = None
+
+ @property
+ def _proxy(self) -> "PaymentContext":
+ """
+ Generate an instance context for the instance, the context is capable of
+ performing various actions. All instance actions are proxied to the context
+
+ :returns: PaymentContext for this PaymentInstance
+ """
+ if self._context is None:
+ self._context = PaymentContext(
+ self._version,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ sid=self._solution["sid"],
+ )
+ return self._context
+
+ def update(
+ self,
+ idempotency_key: str,
+ status_callback: str,
+ capture: Union["PaymentInstance.Capture", object] = values.unset,
+ status: Union["PaymentInstance.Status", object] = values.unset,
+ ) -> "PaymentInstance":
+ """
+ Update the PaymentInstance
+
+ :param idempotency_key: A unique token that will be used to ensure that multiple API calls with the same information do not result in multiple transactions. This should be a unique string value per API call and can be a randomly generated.
+ :param status_callback: Provide an absolute or relative URL to receive status updates regarding your Pay session. Read more about the [Update](https://www.twilio.com/docs/voice/api/payment-resource#statuscallback-update) and [Complete/Cancel](https://www.twilio.com/docs/voice/api/payment-resource#statuscallback-cancelcomplete) POST requests.
+ :param capture:
+ :param status:
+
+ :returns: The updated PaymentInstance
+ """
+ return self._proxy.update(
+ idempotency_key=idempotency_key,
+ status_callback=status_callback,
+ capture=capture,
+ status=status,
+ )
+
+ async def update_async(
+ self,
+ idempotency_key: str,
+ status_callback: str,
+ capture: Union["PaymentInstance.Capture", object] = values.unset,
+ status: Union["PaymentInstance.Status", object] = values.unset,
+ ) -> "PaymentInstance":
+ """
+ Asynchronous coroutine to update the PaymentInstance
+
+ :param idempotency_key: A unique token that will be used to ensure that multiple API calls with the same information do not result in multiple transactions. This should be a unique string value per API call and can be a randomly generated.
+ :param status_callback: Provide an absolute or relative URL to receive status updates regarding your Pay session. Read more about the [Update](https://www.twilio.com/docs/voice/api/payment-resource#statuscallback-update) and [Complete/Cancel](https://www.twilio.com/docs/voice/api/payment-resource#statuscallback-cancelcomplete) POST requests.
+ :param capture:
+ :param status:
+
+ :returns: The updated PaymentInstance
+ """
+ return await self._proxy.update_async(
+ idempotency_key=idempotency_key,
+ status_callback=status_callback,
+ capture=capture,
+ status=status,
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(context)
+
+
+class PaymentContext(InstanceContext):
+
+ def __init__(self, version: Version, account_sid: str, call_sid: str, sid: str):
+ """
+ Initialize the PaymentContext
+
+ :param version: Version that contains the resource
+ :param account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that will update the resource.
+ :param call_sid: The SID of the call that will update the resource. This should be the same call sid that was used to create payments resource.
+ :param sid: The SID of Payments session that needs to be updated.
+ """
+ super().__init__(version)
+
+ # Path Solution
+ self._solution = {
+ "account_sid": account_sid,
+ "call_sid": call_sid,
+ "sid": sid,
+ }
+ self._uri = (
+ "/Accounts/{account_sid}/Calls/{call_sid}/Payments/{sid}.json".format(
+ **self._solution
+ )
+ )
+
+ def update(
+ self,
+ idempotency_key: str,
+ status_callback: str,
+ capture: Union["PaymentInstance.Capture", object] = values.unset,
+ status: Union["PaymentInstance.Status", object] = values.unset,
+ ) -> PaymentInstance:
+ """
+ Update the PaymentInstance
+
+ :param idempotency_key: A unique token that will be used to ensure that multiple API calls with the same information do not result in multiple transactions. This should be a unique string value per API call and can be a randomly generated.
+ :param status_callback: Provide an absolute or relative URL to receive status updates regarding your Pay session. Read more about the [Update](https://www.twilio.com/docs/voice/api/payment-resource#statuscallback-update) and [Complete/Cancel](https://www.twilio.com/docs/voice/api/payment-resource#statuscallback-cancelcomplete) POST requests.
+ :param capture:
+ :param status:
+
+ :returns: The updated PaymentInstance
+ """
+
+ data = values.of(
+ {
+ "IdempotencyKey": idempotency_key,
+ "StatusCallback": status_callback,
+ "Capture": capture,
+ "Status": status,
+ }
+ )
+ headers = values.of({})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.update(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return PaymentInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ sid=self._solution["sid"],
+ )
+
+ async def update_async(
+ self,
+ idempotency_key: str,
+ status_callback: str,
+ capture: Union["PaymentInstance.Capture", object] = values.unset,
+ status: Union["PaymentInstance.Status", object] = values.unset,
+ ) -> PaymentInstance:
+ """
+ Asynchronous coroutine to update the PaymentInstance
+
+ :param idempotency_key: A unique token that will be used to ensure that multiple API calls with the same information do not result in multiple transactions. This should be a unique string value per API call and can be a randomly generated.
+ :param status_callback: Provide an absolute or relative URL to receive status updates regarding your Pay session. Read more about the [Update](https://www.twilio.com/docs/voice/api/payment-resource#statuscallback-update) and [Complete/Cancel](https://www.twilio.com/docs/voice/api/payment-resource#statuscallback-cancelcomplete) POST requests.
+ :param capture:
+ :param status:
+
+ :returns: The updated PaymentInstance
+ """
+
+ data = values.of(
+ {
+ "IdempotencyKey": idempotency_key,
+ "StatusCallback": status_callback,
+ "Capture": capture,
+ "Status": status,
+ }
+ )
+ headers = values.of({})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.update_async(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return PaymentInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ sid=self._solution["sid"],
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(context)
+
+
+class PaymentList(ListResource):
+
+ def __init__(self, version: Version, account_sid: str, call_sid: str):
+ """
+ Initialize the PaymentList
+
+ :param version: Version that contains the resource
+ :param account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that will create the resource.
+ :param call_sid: The SID of the call that will create the resource. Call leg associated with this sid is expected to provide payment information thru DTMF.
+
+ """
+ super().__init__(version)
+
+ # Path Solution
+ self._solution = {
+ "account_sid": account_sid,
+ "call_sid": call_sid,
+ }
+ self._uri = "/Accounts/{account_sid}/Calls/{call_sid}/Payments.json".format(
+ **self._solution
+ )
+
+ def create(
+ self,
+ idempotency_key: str,
+ status_callback: str,
+ bank_account_type: Union[
+ "PaymentInstance.BankAccountType", object
+ ] = values.unset,
+ charge_amount: Union[float, object] = values.unset,
+ currency: Union[str, object] = values.unset,
+ description: Union[str, object] = values.unset,
+ input: Union[str, object] = values.unset,
+ min_postal_code_length: Union[int, object] = values.unset,
+ parameter: Union[object, object] = values.unset,
+ payment_connector: Union[str, object] = values.unset,
+ payment_method: Union["PaymentInstance.PaymentMethod", object] = values.unset,
+ postal_code: Union[bool, object] = values.unset,
+ security_code: Union[bool, object] = values.unset,
+ timeout: Union[int, object] = values.unset,
+ token_type: Union["PaymentInstance.TokenType", object] = values.unset,
+ valid_card_types: Union[str, object] = values.unset,
+ ) -> PaymentInstance:
+ """
+ Create the PaymentInstance
+
+ :param idempotency_key: A unique token that will be used to ensure that multiple API calls with the same information do not result in multiple transactions. This should be a unique string value per API call and can be a randomly generated.
+ :param status_callback: Provide an absolute or relative URL to receive status updates regarding your Pay session. Read more about the [expected StatusCallback values](https://www.twilio.com/docs/voice/api/payment-resource#statuscallback)
+ :param bank_account_type:
+ :param charge_amount: A positive decimal value less than 1,000,000 to charge against the credit card or bank account. Default currency can be overwritten with `currency` field. Leave blank or set to 0 to tokenize.
+ :param currency: The currency of the `charge_amount`, formatted as [ISO 4127](http://www.iso.org/iso/home/standards/currency_codes.htm) format. The default value is `USD` and all values allowed from the Pay Connector are accepted.
+ :param description: The description can be used to provide more details regarding the transaction. This information is submitted along with the payment details to the Payment Connector which are then posted on the transactions.
+ :param input: A list of inputs that should be accepted. Currently only `dtmf` is supported. All digits captured during a pay session are redacted from the logs.
+ :param min_postal_code_length: A positive integer that is used to validate the length of the `PostalCode` inputted by the user. User must enter this many digits.
+ :param parameter: A single-level JSON object used to pass custom parameters to payment processors. (Required for ACH payments). The information that has to be included here depends on the Connector. [Read more](https://www.twilio.com/console/voice/pay-connectors).
+ :param payment_connector: This is the unique name corresponding to the Pay Connector installed in the Twilio Add-ons. Learn more about [ Connectors](https://www.twilio.com/console/voice/pay-connectors). The default value is `Default`.
+ :param payment_method:
+ :param postal_code: Indicates whether the credit card postal code (zip code) is a required piece of payment information that must be provided by the caller. The default is `true`.
+ :param security_code: Indicates whether the credit card security code is a required piece of payment information that must be provided by the caller. The default is `true`.
+ :param timeout: The number of seconds that should wait for the caller to press a digit between each subsequent digit, after the first one, before moving on to validate the digits captured. The default is `5`, maximum is `600`.
+ :param token_type:
+ :param valid_card_types: Credit card types separated by space that Pay should accept. The default value is `visa mastercard amex`
+
+ :returns: The created PaymentInstance
+ """
+
+ data = values.of(
+ {
+ "IdempotencyKey": idempotency_key,
+ "StatusCallback": status_callback,
+ "BankAccountType": bank_account_type,
+ "ChargeAmount": charge_amount,
+ "Currency": currency,
+ "Description": description,
+ "Input": input,
+ "MinPostalCodeLength": min_postal_code_length,
+ "Parameter": serialize.object(parameter),
+ "PaymentConnector": payment_connector,
+ "PaymentMethod": payment_method,
+ "PostalCode": serialize.boolean_to_string(postal_code),
+ "SecurityCode": serialize.boolean_to_string(security_code),
+ "Timeout": timeout,
+ "TokenType": token_type,
+ "ValidCardTypes": valid_card_types,
+ }
+ )
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.create(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return PaymentInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ )
+
+ async def create_async(
+ self,
+ idempotency_key: str,
+ status_callback: str,
+ bank_account_type: Union[
+ "PaymentInstance.BankAccountType", object
+ ] = values.unset,
+ charge_amount: Union[float, object] = values.unset,
+ currency: Union[str, object] = values.unset,
+ description: Union[str, object] = values.unset,
+ input: Union[str, object] = values.unset,
+ min_postal_code_length: Union[int, object] = values.unset,
+ parameter: Union[object, object] = values.unset,
+ payment_connector: Union[str, object] = values.unset,
+ payment_method: Union["PaymentInstance.PaymentMethod", object] = values.unset,
+ postal_code: Union[bool, object] = values.unset,
+ security_code: Union[bool, object] = values.unset,
+ timeout: Union[int, object] = values.unset,
+ token_type: Union["PaymentInstance.TokenType", object] = values.unset,
+ valid_card_types: Union[str, object] = values.unset,
+ ) -> PaymentInstance:
+ """
+ Asynchronously create the PaymentInstance
+
+ :param idempotency_key: A unique token that will be used to ensure that multiple API calls with the same information do not result in multiple transactions. This should be a unique string value per API call and can be a randomly generated.
+ :param status_callback: Provide an absolute or relative URL to receive status updates regarding your Pay session. Read more about the [expected StatusCallback values](https://www.twilio.com/docs/voice/api/payment-resource#statuscallback)
+ :param bank_account_type:
+ :param charge_amount: A positive decimal value less than 1,000,000 to charge against the credit card or bank account. Default currency can be overwritten with `currency` field. Leave blank or set to 0 to tokenize.
+ :param currency: The currency of the `charge_amount`, formatted as [ISO 4127](http://www.iso.org/iso/home/standards/currency_codes.htm) format. The default value is `USD` and all values allowed from the Pay Connector are accepted.
+ :param description: The description can be used to provide more details regarding the transaction. This information is submitted along with the payment details to the Payment Connector which are then posted on the transactions.
+ :param input: A list of inputs that should be accepted. Currently only `dtmf` is supported. All digits captured during a pay session are redacted from the logs.
+ :param min_postal_code_length: A positive integer that is used to validate the length of the `PostalCode` inputted by the user. User must enter this many digits.
+ :param parameter: A single-level JSON object used to pass custom parameters to payment processors. (Required for ACH payments). The information that has to be included here depends on the Connector. [Read more](https://www.twilio.com/console/voice/pay-connectors).
+ :param payment_connector: This is the unique name corresponding to the Pay Connector installed in the Twilio Add-ons. Learn more about [ Connectors](https://www.twilio.com/console/voice/pay-connectors). The default value is `Default`.
+ :param payment_method:
+ :param postal_code: Indicates whether the credit card postal code (zip code) is a required piece of payment information that must be provided by the caller. The default is `true`.
+ :param security_code: Indicates whether the credit card security code is a required piece of payment information that must be provided by the caller. The default is `true`.
+ :param timeout: The number of seconds that should wait for the caller to press a digit between each subsequent digit, after the first one, before moving on to validate the digits captured. The default is `5`, maximum is `600`.
+ :param token_type:
+ :param valid_card_types: Credit card types separated by space that Pay should accept. The default value is `visa mastercard amex`
+
+ :returns: The created PaymentInstance
+ """
+
+ data = values.of(
+ {
+ "IdempotencyKey": idempotency_key,
+ "StatusCallback": status_callback,
+ "BankAccountType": bank_account_type,
+ "ChargeAmount": charge_amount,
+ "Currency": currency,
+ "Description": description,
+ "Input": input,
+ "MinPostalCodeLength": min_postal_code_length,
+ "Parameter": serialize.object(parameter),
+ "PaymentConnector": payment_connector,
+ "PaymentMethod": payment_method,
+ "PostalCode": serialize.boolean_to_string(postal_code),
+ "SecurityCode": serialize.boolean_to_string(security_code),
+ "Timeout": timeout,
+ "TokenType": token_type,
+ "ValidCardTypes": valid_card_types,
+ }
+ )
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.create_async(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return PaymentInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ )
+
+ def get(self, sid: str) -> PaymentContext:
+ """
+ Constructs a PaymentContext
+
+ :param sid: The SID of Payments session that needs to be updated.
+ """
+ return PaymentContext(
+ self._version,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ sid=sid,
+ )
+
+ def __call__(self, sid: str) -> PaymentContext:
+ """
+ Constructs a PaymentContext
+
+ :param sid: The SID of Payments session that needs to be updated.
+ """
+ return PaymentContext(
+ self._version,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ sid=sid,
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/recording.py b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/recording.py
new file mode 100644
index 00000000..5b93ec6c
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/recording.py
@@ -0,0 +1,822 @@
+r"""
+ This code was generated by
+ ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __
+ | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/
+ | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \
+
+ Twilio - Api
+ This is the public Twilio REST API.
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ https://openapi-generator.tech
+ Do not edit the class manually.
+"""
+
+from datetime import date, datetime
+from typing import Any, Dict, List, Optional, Union, Iterator, AsyncIterator
+from twilio.base import deserialize, serialize, values
+from twilio.base.instance_context import InstanceContext
+from twilio.base.instance_resource import InstanceResource
+from twilio.base.list_resource import ListResource
+from twilio.base.version import Version
+from twilio.base.page import Page
+
+
+class RecordingInstance(InstanceResource):
+
+ class Source(object):
+ DIALVERB = "DialVerb"
+ CONFERENCE = "Conference"
+ OUTBOUNDAPI = "OutboundAPI"
+ TRUNKING = "Trunking"
+ RECORDVERB = "RecordVerb"
+ STARTCALLRECORDINGAPI = "StartCallRecordingAPI"
+ STARTCONFERENCERECORDINGAPI = "StartConferenceRecordingAPI"
+
+ class Status(object):
+ IN_PROGRESS = "in-progress"
+ PAUSED = "paused"
+ STOPPED = "stopped"
+ PROCESSING = "processing"
+ COMPLETED = "completed"
+ ABSENT = "absent"
+
+ """
+ :ivar account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that created the Recording resource.
+ :ivar api_version: The API version used to make the recording.
+ :ivar call_sid: The SID of the [Call](https://www.twilio.com/docs/voice/api/call-resource) the Recording resource is associated with.
+ :ivar conference_sid: The Conference SID that identifies the conference associated with the recording, if a conference recording.
+ :ivar date_created: The date and time in GMT that the resource was created specified in [RFC 2822](https://www.ietf.org/rfc/rfc2822.txt) format.
+ :ivar date_updated: The date and time in GMT that the resource was last updated, specified in [RFC 2822](https://www.ietf.org/rfc/rfc2822.txt) format.
+ :ivar start_time: The start time of the recording in GMT and in [RFC 2822](https://www.php.net/manual/en/class.datetime.php#datetime.constants.rfc2822) format.
+ :ivar duration: The length of the recording in seconds.
+ :ivar sid: The unique string that that we created to identify the Recording resource.
+ :ivar price: The one-time cost of creating the recording in the `price_unit` currency.
+ :ivar uri: The URI of the resource, relative to `https://api.twilio.com`.
+ :ivar encryption_details: How to decrypt the recording if it was encrypted using [Call Recording Encryption](https://www.twilio.com/docs/voice/tutorials/voice-recording-encryption) feature.
+ :ivar price_unit: The currency used in the `price` property. Example: `USD`.
+ :ivar status:
+ :ivar channels: The number of channels in the final recording file. Can be: `1`, or `2`. Separating a two leg call into two separate channels of the recording file is supported in [Dial](https://www.twilio.com/docs/voice/twiml/dial#attributes-record) and [Outbound Rest API](https://www.twilio.com/docs/voice/make-calls) record options.
+ :ivar source:
+ :ivar error_code: The error code that describes why the recording is `absent`. The error code is described in our [Error Dictionary](https://www.twilio.com/docs/api/errors). This value is null if the recording `status` is not `absent`.
+ :ivar track: The recorded track. Can be: `inbound`, `outbound`, or `both`.
+ """
+
+ def __init__(
+ self,
+ version: Version,
+ payload: Dict[str, Any],
+ account_sid: str,
+ call_sid: str,
+ sid: Optional[str] = None,
+ ):
+ super().__init__(version)
+
+ self.account_sid: Optional[str] = payload.get("account_sid")
+ self.api_version: Optional[str] = payload.get("api_version")
+ self.call_sid: Optional[str] = payload.get("call_sid")
+ self.conference_sid: Optional[str] = payload.get("conference_sid")
+ self.date_created: Optional[datetime] = deserialize.rfc2822_datetime(
+ payload.get("date_created")
+ )
+ self.date_updated: Optional[datetime] = deserialize.rfc2822_datetime(
+ payload.get("date_updated")
+ )
+ self.start_time: Optional[datetime] = deserialize.rfc2822_datetime(
+ payload.get("start_time")
+ )
+ self.duration: Optional[str] = payload.get("duration")
+ self.sid: Optional[str] = payload.get("sid")
+ self.price: Optional[float] = deserialize.decimal(payload.get("price"))
+ self.uri: Optional[str] = payload.get("uri")
+ self.encryption_details: Optional[Dict[str, object]] = payload.get(
+ "encryption_details"
+ )
+ self.price_unit: Optional[str] = payload.get("price_unit")
+ self.status: Optional["RecordingInstance.Status"] = payload.get("status")
+ self.channels: Optional[int] = deserialize.integer(payload.get("channels"))
+ self.source: Optional["RecordingInstance.Source"] = payload.get("source")
+ self.error_code: Optional[int] = deserialize.integer(payload.get("error_code"))
+ self.track: Optional[str] = payload.get("track")
+
+ self._solution = {
+ "account_sid": account_sid,
+ "call_sid": call_sid,
+ "sid": sid or self.sid,
+ }
+ self._context: Optional[RecordingContext] = None
+
+ @property
+ def _proxy(self) -> "RecordingContext":
+ """
+ Generate an instance context for the instance, the context is capable of
+ performing various actions. All instance actions are proxied to the context
+
+ :returns: RecordingContext for this RecordingInstance
+ """
+ if self._context is None:
+ self._context = RecordingContext(
+ self._version,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ sid=self._solution["sid"],
+ )
+ return self._context
+
+ def delete(self) -> bool:
+ """
+ Deletes the RecordingInstance
+
+
+ :returns: True if delete succeeds, False otherwise
+ """
+ return self._proxy.delete()
+
+ async def delete_async(self) -> bool:
+ """
+ Asynchronous coroutine that deletes the RecordingInstance
+
+
+ :returns: True if delete succeeds, False otherwise
+ """
+ return await self._proxy.delete_async()
+
+ def fetch(self) -> "RecordingInstance":
+ """
+ Fetch the RecordingInstance
+
+
+ :returns: The fetched RecordingInstance
+ """
+ return self._proxy.fetch()
+
+ async def fetch_async(self) -> "RecordingInstance":
+ """
+ Asynchronous coroutine to fetch the RecordingInstance
+
+
+ :returns: The fetched RecordingInstance
+ """
+ return await self._proxy.fetch_async()
+
+ def update(
+ self,
+ status: "RecordingInstance.Status",
+ pause_behavior: Union[str, object] = values.unset,
+ ) -> "RecordingInstance":
+ """
+ Update the RecordingInstance
+
+ :param status:
+ :param pause_behavior: Whether to record during a pause. Can be: `skip` or `silence` and the default is `silence`. `skip` does not record during the pause period, while `silence` will replace the actual audio of the call with silence during the pause period. This parameter only applies when setting `status` is set to `paused`.
+
+ :returns: The updated RecordingInstance
+ """
+ return self._proxy.update(
+ status=status,
+ pause_behavior=pause_behavior,
+ )
+
+ async def update_async(
+ self,
+ status: "RecordingInstance.Status",
+ pause_behavior: Union[str, object] = values.unset,
+ ) -> "RecordingInstance":
+ """
+ Asynchronous coroutine to update the RecordingInstance
+
+ :param status:
+ :param pause_behavior: Whether to record during a pause. Can be: `skip` or `silence` and the default is `silence`. `skip` does not record during the pause period, while `silence` will replace the actual audio of the call with silence during the pause period. This parameter only applies when setting `status` is set to `paused`.
+
+ :returns: The updated RecordingInstance
+ """
+ return await self._proxy.update_async(
+ status=status,
+ pause_behavior=pause_behavior,
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(context)
+
+
+class RecordingContext(InstanceContext):
+
+ def __init__(self, version: Version, account_sid: str, call_sid: str, sid: str):
+ """
+ Initialize the RecordingContext
+
+ :param version: Version that contains the resource
+ :param account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that created the Recording resource to update.
+ :param call_sid: The [Call](https://www.twilio.com/docs/voice/api/call-resource) SID of the resource to update.
+ :param sid: The Twilio-provided string that uniquely identifies the Recording resource to update.
+ """
+ super().__init__(version)
+
+ # Path Solution
+ self._solution = {
+ "account_sid": account_sid,
+ "call_sid": call_sid,
+ "sid": sid,
+ }
+ self._uri = (
+ "/Accounts/{account_sid}/Calls/{call_sid}/Recordings/{sid}.json".format(
+ **self._solution
+ )
+ )
+
+ def delete(self) -> bool:
+ """
+ Deletes the RecordingInstance
+
+
+ :returns: True if delete succeeds, False otherwise
+ """
+
+ headers = values.of({})
+
+ return self._version.delete(method="DELETE", uri=self._uri, headers=headers)
+
+ async def delete_async(self) -> bool:
+ """
+ Asynchronous coroutine that deletes the RecordingInstance
+
+
+ :returns: True if delete succeeds, False otherwise
+ """
+
+ headers = values.of({})
+
+ return await self._version.delete_async(
+ method="DELETE", uri=self._uri, headers=headers
+ )
+
+ def fetch(self) -> RecordingInstance:
+ """
+ Fetch the RecordingInstance
+
+
+ :returns: The fetched RecordingInstance
+ """
+
+ headers = values.of({})
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.fetch(method="GET", uri=self._uri, headers=headers)
+
+ return RecordingInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ sid=self._solution["sid"],
+ )
+
+ async def fetch_async(self) -> RecordingInstance:
+ """
+ Asynchronous coroutine to fetch the RecordingInstance
+
+
+ :returns: The fetched RecordingInstance
+ """
+
+ headers = values.of({})
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.fetch_async(
+ method="GET", uri=self._uri, headers=headers
+ )
+
+ return RecordingInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ sid=self._solution["sid"],
+ )
+
+ def update(
+ self,
+ status: "RecordingInstance.Status",
+ pause_behavior: Union[str, object] = values.unset,
+ ) -> RecordingInstance:
+ """
+ Update the RecordingInstance
+
+ :param status:
+ :param pause_behavior: Whether to record during a pause. Can be: `skip` or `silence` and the default is `silence`. `skip` does not record during the pause period, while `silence` will replace the actual audio of the call with silence during the pause period. This parameter only applies when setting `status` is set to `paused`.
+
+ :returns: The updated RecordingInstance
+ """
+
+ data = values.of(
+ {
+ "Status": status,
+ "PauseBehavior": pause_behavior,
+ }
+ )
+ headers = values.of({})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.update(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return RecordingInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ sid=self._solution["sid"],
+ )
+
+ async def update_async(
+ self,
+ status: "RecordingInstance.Status",
+ pause_behavior: Union[str, object] = values.unset,
+ ) -> RecordingInstance:
+ """
+ Asynchronous coroutine to update the RecordingInstance
+
+ :param status:
+ :param pause_behavior: Whether to record during a pause. Can be: `skip` or `silence` and the default is `silence`. `skip` does not record during the pause period, while `silence` will replace the actual audio of the call with silence during the pause period. This parameter only applies when setting `status` is set to `paused`.
+
+ :returns: The updated RecordingInstance
+ """
+
+ data = values.of(
+ {
+ "Status": status,
+ "PauseBehavior": pause_behavior,
+ }
+ )
+ headers = values.of({})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.update_async(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return RecordingInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ sid=self._solution["sid"],
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(context)
+
+
+class RecordingPage(Page):
+
+ def get_instance(self, payload: Dict[str, Any]) -> RecordingInstance:
+ """
+ Build an instance of RecordingInstance
+
+ :param payload: Payload response from the API
+ """
+ return RecordingInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
+
+
+class RecordingList(ListResource):
+
+ def __init__(self, version: Version, account_sid: str, call_sid: str):
+ """
+ Initialize the RecordingList
+
+ :param version: Version that contains the resource
+ :param account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that created the Recording resources to read.
+ :param call_sid: The [Call](https://www.twilio.com/docs/voice/api/call-resource) SID of the resources to read.
+
+ """
+ super().__init__(version)
+
+ # Path Solution
+ self._solution = {
+ "account_sid": account_sid,
+ "call_sid": call_sid,
+ }
+ self._uri = "/Accounts/{account_sid}/Calls/{call_sid}/Recordings.json".format(
+ **self._solution
+ )
+
+ def create(
+ self,
+ recording_status_callback_event: Union[List[str], object] = values.unset,
+ recording_status_callback: Union[str, object] = values.unset,
+ recording_status_callback_method: Union[str, object] = values.unset,
+ trim: Union[str, object] = values.unset,
+ recording_channels: Union[str, object] = values.unset,
+ recording_track: Union[str, object] = values.unset,
+ ) -> RecordingInstance:
+ """
+ Create the RecordingInstance
+
+ :param recording_status_callback_event: The recording status events on which we should call the `recording_status_callback` URL. Can be: `in-progress`, `completed` and `absent` and the default is `completed`. Separate multiple event values with a space.
+ :param recording_status_callback: The URL we should call using the `recording_status_callback_method` on each recording event specified in `recording_status_callback_event`. For more information, see [RecordingStatusCallback parameters](https://www.twilio.com/docs/voice/api/recording#recordingstatuscallback).
+ :param recording_status_callback_method: The HTTP method we should use to call `recording_status_callback`. Can be: `GET` or `POST` and the default is `POST`.
+ :param trim: Whether to trim any leading and trailing silence in the recording. Can be: `trim-silence` or `do-not-trim` and the default is `do-not-trim`. `trim-silence` trims the silence from the beginning and end of the recording and `do-not-trim` does not.
+ :param recording_channels: The number of channels used in the recording. Can be: `mono` or `dual` and the default is `mono`. `mono` records all parties of the call into one channel. `dual` records each party of a 2-party call into separate channels.
+ :param recording_track: The audio track to record for the call. Can be: `inbound`, `outbound` or `both`. The default is `both`. `inbound` records the audio that is received by Twilio. `outbound` records the audio that is generated from Twilio. `both` records the audio that is received and generated by Twilio.
+
+ :returns: The created RecordingInstance
+ """
+
+ data = values.of(
+ {
+ "RecordingStatusCallbackEvent": serialize.map(
+ recording_status_callback_event, lambda e: e
+ ),
+ "RecordingStatusCallback": recording_status_callback,
+ "RecordingStatusCallbackMethod": recording_status_callback_method,
+ "Trim": trim,
+ "RecordingChannels": recording_channels,
+ "RecordingTrack": recording_track,
+ }
+ )
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.create(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return RecordingInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ )
+
+ async def create_async(
+ self,
+ recording_status_callback_event: Union[List[str], object] = values.unset,
+ recording_status_callback: Union[str, object] = values.unset,
+ recording_status_callback_method: Union[str, object] = values.unset,
+ trim: Union[str, object] = values.unset,
+ recording_channels: Union[str, object] = values.unset,
+ recording_track: Union[str, object] = values.unset,
+ ) -> RecordingInstance:
+ """
+ Asynchronously create the RecordingInstance
+
+ :param recording_status_callback_event: The recording status events on which we should call the `recording_status_callback` URL. Can be: `in-progress`, `completed` and `absent` and the default is `completed`. Separate multiple event values with a space.
+ :param recording_status_callback: The URL we should call using the `recording_status_callback_method` on each recording event specified in `recording_status_callback_event`. For more information, see [RecordingStatusCallback parameters](https://www.twilio.com/docs/voice/api/recording#recordingstatuscallback).
+ :param recording_status_callback_method: The HTTP method we should use to call `recording_status_callback`. Can be: `GET` or `POST` and the default is `POST`.
+ :param trim: Whether to trim any leading and trailing silence in the recording. Can be: `trim-silence` or `do-not-trim` and the default is `do-not-trim`. `trim-silence` trims the silence from the beginning and end of the recording and `do-not-trim` does not.
+ :param recording_channels: The number of channels used in the recording. Can be: `mono` or `dual` and the default is `mono`. `mono` records all parties of the call into one channel. `dual` records each party of a 2-party call into separate channels.
+ :param recording_track: The audio track to record for the call. Can be: `inbound`, `outbound` or `both`. The default is `both`. `inbound` records the audio that is received by Twilio. `outbound` records the audio that is generated from Twilio. `both` records the audio that is received and generated by Twilio.
+
+ :returns: The created RecordingInstance
+ """
+
+ data = values.of(
+ {
+ "RecordingStatusCallbackEvent": serialize.map(
+ recording_status_callback_event, lambda e: e
+ ),
+ "RecordingStatusCallback": recording_status_callback,
+ "RecordingStatusCallbackMethod": recording_status_callback_method,
+ "Trim": trim,
+ "RecordingChannels": recording_channels,
+ "RecordingTrack": recording_track,
+ }
+ )
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.create_async(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return RecordingInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ )
+
+ def stream(
+ self,
+ date_created: Union[date, object] = values.unset,
+ date_created_before: Union[date, object] = values.unset,
+ date_created_after: Union[date, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> Iterator[RecordingInstance]:
+ """
+ Streams RecordingInstance records from the API as a generator stream.
+ This operation lazily loads records as efficiently as possible until the limit
+ is reached.
+ The results are returned as a generator, so this operation is memory efficient.
+
+ :param date date_created: The `date_created` value, specified as `YYYY-MM-DD`, of the resources to read. You can also specify inequality: `DateCreated<=YYYY-MM-DD` will return recordings generated at or before midnight on a given date, and `DateCreated>=YYYY-MM-DD` returns recordings generated at or after midnight on a date.
+ :param date date_created_before: The `date_created` value, specified as `YYYY-MM-DD`, of the resources to read. You can also specify inequality: `DateCreated<=YYYY-MM-DD` will return recordings generated at or before midnight on a given date, and `DateCreated>=YYYY-MM-DD` returns recordings generated at or after midnight on a date.
+ :param date date_created_after: The `date_created` value, specified as `YYYY-MM-DD`, of the resources to read. You can also specify inequality: `DateCreated<=YYYY-MM-DD` will return recordings generated at or before midnight on a given date, and `DateCreated>=YYYY-MM-DD` returns recordings generated at or after midnight on a date.
+ :param limit: Upper limit for the number of records to return. stream()
+ guarantees to never return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, stream() will attempt to read the
+ limit with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: Generator that will yield up to limit results
+ """
+ limits = self._version.read_limits(limit, page_size)
+ page = self.page(
+ date_created=date_created,
+ date_created_before=date_created_before,
+ date_created_after=date_created_after,
+ page_size=limits["page_size"],
+ )
+
+ return self._version.stream(page, limits["limit"])
+
+ async def stream_async(
+ self,
+ date_created: Union[date, object] = values.unset,
+ date_created_before: Union[date, object] = values.unset,
+ date_created_after: Union[date, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> AsyncIterator[RecordingInstance]:
+ """
+ Asynchronously streams RecordingInstance records from the API as a generator stream.
+ This operation lazily loads records as efficiently as possible until the limit
+ is reached.
+ The results are returned as a generator, so this operation is memory efficient.
+
+ :param date date_created: The `date_created` value, specified as `YYYY-MM-DD`, of the resources to read. You can also specify inequality: `DateCreated<=YYYY-MM-DD` will return recordings generated at or before midnight on a given date, and `DateCreated>=YYYY-MM-DD` returns recordings generated at or after midnight on a date.
+ :param date date_created_before: The `date_created` value, specified as `YYYY-MM-DD`, of the resources to read. You can also specify inequality: `DateCreated<=YYYY-MM-DD` will return recordings generated at or before midnight on a given date, and `DateCreated>=YYYY-MM-DD` returns recordings generated at or after midnight on a date.
+ :param date date_created_after: The `date_created` value, specified as `YYYY-MM-DD`, of the resources to read. You can also specify inequality: `DateCreated<=YYYY-MM-DD` will return recordings generated at or before midnight on a given date, and `DateCreated>=YYYY-MM-DD` returns recordings generated at or after midnight on a date.
+ :param limit: Upper limit for the number of records to return. stream()
+ guarantees to never return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, stream() will attempt to read the
+ limit with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: Generator that will yield up to limit results
+ """
+ limits = self._version.read_limits(limit, page_size)
+ page = await self.page_async(
+ date_created=date_created,
+ date_created_before=date_created_before,
+ date_created_after=date_created_after,
+ page_size=limits["page_size"],
+ )
+
+ return self._version.stream_async(page, limits["limit"])
+
+ def list(
+ self,
+ date_created: Union[date, object] = values.unset,
+ date_created_before: Union[date, object] = values.unset,
+ date_created_after: Union[date, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> List[RecordingInstance]:
+ """
+ Lists RecordingInstance records from the API as a list.
+ Unlike stream(), this operation is eager and will load `limit` records into
+ memory before returning.
+
+ :param date date_created: The `date_created` value, specified as `YYYY-MM-DD`, of the resources to read. You can also specify inequality: `DateCreated<=YYYY-MM-DD` will return recordings generated at or before midnight on a given date, and `DateCreated>=YYYY-MM-DD` returns recordings generated at or after midnight on a date.
+ :param date date_created_before: The `date_created` value, specified as `YYYY-MM-DD`, of the resources to read. You can also specify inequality: `DateCreated<=YYYY-MM-DD` will return recordings generated at or before midnight on a given date, and `DateCreated>=YYYY-MM-DD` returns recordings generated at or after midnight on a date.
+ :param date date_created_after: The `date_created` value, specified as `YYYY-MM-DD`, of the resources to read. You can also specify inequality: `DateCreated<=YYYY-MM-DD` will return recordings generated at or before midnight on a given date, and `DateCreated>=YYYY-MM-DD` returns recordings generated at or after midnight on a date.
+ :param limit: Upper limit for the number of records to return. list() guarantees
+ never to return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, list() will attempt to read the limit
+ with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: list that will contain up to limit results
+ """
+ return list(
+ self.stream(
+ date_created=date_created,
+ date_created_before=date_created_before,
+ date_created_after=date_created_after,
+ limit=limit,
+ page_size=page_size,
+ )
+ )
+
+ async def list_async(
+ self,
+ date_created: Union[date, object] = values.unset,
+ date_created_before: Union[date, object] = values.unset,
+ date_created_after: Union[date, object] = values.unset,
+ limit: Optional[int] = None,
+ page_size: Optional[int] = None,
+ ) -> List[RecordingInstance]:
+ """
+ Asynchronously lists RecordingInstance records from the API as a list.
+ Unlike stream(), this operation is eager and will load `limit` records into
+ memory before returning.
+
+ :param date date_created: The `date_created` value, specified as `YYYY-MM-DD`, of the resources to read. You can also specify inequality: `DateCreated<=YYYY-MM-DD` will return recordings generated at or before midnight on a given date, and `DateCreated>=YYYY-MM-DD` returns recordings generated at or after midnight on a date.
+ :param date date_created_before: The `date_created` value, specified as `YYYY-MM-DD`, of the resources to read. You can also specify inequality: `DateCreated<=YYYY-MM-DD` will return recordings generated at or before midnight on a given date, and `DateCreated>=YYYY-MM-DD` returns recordings generated at or after midnight on a date.
+ :param date date_created_after: The `date_created` value, specified as `YYYY-MM-DD`, of the resources to read. You can also specify inequality: `DateCreated<=YYYY-MM-DD` will return recordings generated at or before midnight on a given date, and `DateCreated>=YYYY-MM-DD` returns recordings generated at or after midnight on a date.
+ :param limit: Upper limit for the number of records to return. list() guarantees
+ never to return more than limit. Default is no limit
+ :param page_size: Number of records to fetch per request, when not set will use
+ the default value of 50 records. If no page_size is defined
+ but a limit is defined, list() will attempt to read the limit
+ with the most efficient page size, i.e. min(limit, 1000)
+
+ :returns: list that will contain up to limit results
+ """
+ return [
+ record
+ async for record in await self.stream_async(
+ date_created=date_created,
+ date_created_before=date_created_before,
+ date_created_after=date_created_after,
+ limit=limit,
+ page_size=page_size,
+ )
+ ]
+
+ def page(
+ self,
+ date_created: Union[date, object] = values.unset,
+ date_created_before: Union[date, object] = values.unset,
+ date_created_after: Union[date, object] = values.unset,
+ page_token: Union[str, object] = values.unset,
+ page_number: Union[int, object] = values.unset,
+ page_size: Union[int, object] = values.unset,
+ ) -> RecordingPage:
+ """
+ Retrieve a single page of RecordingInstance records from the API.
+ Request is executed immediately
+
+ :param date_created: The `date_created` value, specified as `YYYY-MM-DD`, of the resources to read. You can also specify inequality: `DateCreated<=YYYY-MM-DD` will return recordings generated at or before midnight on a given date, and `DateCreated>=YYYY-MM-DD` returns recordings generated at or after midnight on a date.
+ :param date_created_before: The `date_created` value, specified as `YYYY-MM-DD`, of the resources to read. You can also specify inequality: `DateCreated<=YYYY-MM-DD` will return recordings generated at or before midnight on a given date, and `DateCreated>=YYYY-MM-DD` returns recordings generated at or after midnight on a date.
+ :param date_created_after: The `date_created` value, specified as `YYYY-MM-DD`, of the resources to read. You can also specify inequality: `DateCreated<=YYYY-MM-DD` will return recordings generated at or before midnight on a given date, and `DateCreated>=YYYY-MM-DD` returns recordings generated at or after midnight on a date.
+ :param page_token: PageToken provided by the API
+ :param page_number: Page Number, this value is simply for client state
+ :param page_size: Number of records to return, defaults to 50
+
+ :returns: Page of RecordingInstance
+ """
+ data = values.of(
+ {
+ "DateCreated": serialize.iso8601_date(date_created),
+ "DateCreated<": serialize.iso8601_date(date_created_before),
+ "DateCreated>": serialize.iso8601_date(date_created_after),
+ "PageToken": page_token,
+ "Page": page_number,
+ "PageSize": page_size,
+ }
+ )
+
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ response = self._version.page(
+ method="GET", uri=self._uri, params=data, headers=headers
+ )
+ return RecordingPage(self._version, response, self._solution)
+
+ async def page_async(
+ self,
+ date_created: Union[date, object] = values.unset,
+ date_created_before: Union[date, object] = values.unset,
+ date_created_after: Union[date, object] = values.unset,
+ page_token: Union[str, object] = values.unset,
+ page_number: Union[int, object] = values.unset,
+ page_size: Union[int, object] = values.unset,
+ ) -> RecordingPage:
+ """
+ Asynchronously retrieve a single page of RecordingInstance records from the API.
+ Request is executed immediately
+
+ :param date_created: The `date_created` value, specified as `YYYY-MM-DD`, of the resources to read. You can also specify inequality: `DateCreated<=YYYY-MM-DD` will return recordings generated at or before midnight on a given date, and `DateCreated>=YYYY-MM-DD` returns recordings generated at or after midnight on a date.
+ :param date_created_before: The `date_created` value, specified as `YYYY-MM-DD`, of the resources to read. You can also specify inequality: `DateCreated<=YYYY-MM-DD` will return recordings generated at or before midnight on a given date, and `DateCreated>=YYYY-MM-DD` returns recordings generated at or after midnight on a date.
+ :param date_created_after: The `date_created` value, specified as `YYYY-MM-DD`, of the resources to read. You can also specify inequality: `DateCreated<=YYYY-MM-DD` will return recordings generated at or before midnight on a given date, and `DateCreated>=YYYY-MM-DD` returns recordings generated at or after midnight on a date.
+ :param page_token: PageToken provided by the API
+ :param page_number: Page Number, this value is simply for client state
+ :param page_size: Number of records to return, defaults to 50
+
+ :returns: Page of RecordingInstance
+ """
+ data = values.of(
+ {
+ "DateCreated": serialize.iso8601_date(date_created),
+ "DateCreated<": serialize.iso8601_date(date_created_before),
+ "DateCreated>": serialize.iso8601_date(date_created_after),
+ "PageToken": page_token,
+ "Page": page_number,
+ "PageSize": page_size,
+ }
+ )
+
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Accept"] = "application/json"
+
+ response = await self._version.page_async(
+ method="GET", uri=self._uri, params=data, headers=headers
+ )
+ return RecordingPage(self._version, response, self._solution)
+
+ def get_page(self, target_url: str) -> RecordingPage:
+ """
+ Retrieve a specific page of RecordingInstance records from the API.
+ Request is executed immediately
+
+ :param target_url: API-generated URL for the requested results page
+
+ :returns: Page of RecordingInstance
+ """
+ response = self._version.domain.twilio.request("GET", target_url)
+ return RecordingPage(self._version, response, self._solution)
+
+ async def get_page_async(self, target_url: str) -> RecordingPage:
+ """
+ Asynchronously retrieve a specific page of RecordingInstance records from the API.
+ Request is executed immediately
+
+ :param target_url: API-generated URL for the requested results page
+
+ :returns: Page of RecordingInstance
+ """
+ response = await self._version.domain.twilio.request_async("GET", target_url)
+ return RecordingPage(self._version, response, self._solution)
+
+ def get(self, sid: str) -> RecordingContext:
+ """
+ Constructs a RecordingContext
+
+ :param sid: The Twilio-provided string that uniquely identifies the Recording resource to update.
+ """
+ return RecordingContext(
+ self._version,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ sid=sid,
+ )
+
+ def __call__(self, sid: str) -> RecordingContext:
+ """
+ Constructs a RecordingContext
+
+ :param sid: The Twilio-provided string that uniquely identifies the Recording resource to update.
+ """
+ return RecordingContext(
+ self._version,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ sid=sid,
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/siprec.py b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/siprec.py
new file mode 100644
index 00000000..d808331c
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/siprec.py
@@ -0,0 +1,1561 @@
+r"""
+ This code was generated by
+ ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __
+ | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/
+ | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \
+
+ Twilio - Api
+ This is the public Twilio REST API.
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ https://openapi-generator.tech
+ Do not edit the class manually.
+"""
+
+from datetime import datetime
+from typing import Any, Dict, Optional, Union
+from twilio.base import deserialize, values
+from twilio.base.instance_context import InstanceContext
+from twilio.base.instance_resource import InstanceResource
+from twilio.base.list_resource import ListResource
+from twilio.base.version import Version
+
+
+class SiprecInstance(InstanceResource):
+
+ class Status(object):
+ IN_PROGRESS = "in-progress"
+ STOPPED = "stopped"
+
+ class Track(object):
+ INBOUND_TRACK = "inbound_track"
+ OUTBOUND_TRACK = "outbound_track"
+ BOTH_TRACKS = "both_tracks"
+
+ class UpdateStatus(object):
+ STOPPED = "stopped"
+
+ """
+ :ivar sid: The SID of the Siprec resource.
+ :ivar account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that created this Siprec resource.
+ :ivar call_sid: The SID of the [Call](https://www.twilio.com/docs/voice/api/call-resource) the Siprec resource is associated with.
+ :ivar name: The user-specified name of this Siprec, if one was given when the Siprec was created. This may be used to stop the Siprec.
+ :ivar status:
+ :ivar date_updated: The date and time in GMT that this resource was last updated, specified in [RFC 2822](https://www.ietf.org/rfc/rfc2822.txt) format.
+ :ivar uri: The URI of the resource, relative to `https://api.twilio.com`.
+ """
+
+ def __init__(
+ self,
+ version: Version,
+ payload: Dict[str, Any],
+ account_sid: str,
+ call_sid: str,
+ sid: Optional[str] = None,
+ ):
+ super().__init__(version)
+
+ self.sid: Optional[str] = payload.get("sid")
+ self.account_sid: Optional[str] = payload.get("account_sid")
+ self.call_sid: Optional[str] = payload.get("call_sid")
+ self.name: Optional[str] = payload.get("name")
+ self.status: Optional["SiprecInstance.Status"] = payload.get("status")
+ self.date_updated: Optional[datetime] = deserialize.rfc2822_datetime(
+ payload.get("date_updated")
+ )
+ self.uri: Optional[str] = payload.get("uri")
+
+ self._solution = {
+ "account_sid": account_sid,
+ "call_sid": call_sid,
+ "sid": sid or self.sid,
+ }
+ self._context: Optional[SiprecContext] = None
+
+ @property
+ def _proxy(self) -> "SiprecContext":
+ """
+ Generate an instance context for the instance, the context is capable of
+ performing various actions. All instance actions are proxied to the context
+
+ :returns: SiprecContext for this SiprecInstance
+ """
+ if self._context is None:
+ self._context = SiprecContext(
+ self._version,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ sid=self._solution["sid"],
+ )
+ return self._context
+
+ def update(self, status: "SiprecInstance.UpdateStatus") -> "SiprecInstance":
+ """
+ Update the SiprecInstance
+
+ :param status:
+
+ :returns: The updated SiprecInstance
+ """
+ return self._proxy.update(
+ status=status,
+ )
+
+ async def update_async(
+ self, status: "SiprecInstance.UpdateStatus"
+ ) -> "SiprecInstance":
+ """
+ Asynchronous coroutine to update the SiprecInstance
+
+ :param status:
+
+ :returns: The updated SiprecInstance
+ """
+ return await self._proxy.update_async(
+ status=status,
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(context)
+
+
+class SiprecContext(InstanceContext):
+
+ def __init__(self, version: Version, account_sid: str, call_sid: str, sid: str):
+ """
+ Initialize the SiprecContext
+
+ :param version: Version that contains the resource
+ :param account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that created this Siprec resource.
+ :param call_sid: The SID of the [Call](https://www.twilio.com/docs/voice/api/call-resource) the Siprec resource is associated with.
+ :param sid: The SID of the Siprec resource, or the `name` used when creating the resource
+ """
+ super().__init__(version)
+
+ # Path Solution
+ self._solution = {
+ "account_sid": account_sid,
+ "call_sid": call_sid,
+ "sid": sid,
+ }
+ self._uri = "/Accounts/{account_sid}/Calls/{call_sid}/Siprec/{sid}.json".format(
+ **self._solution
+ )
+
+ def update(self, status: "SiprecInstance.UpdateStatus") -> SiprecInstance:
+ """
+ Update the SiprecInstance
+
+ :param status:
+
+ :returns: The updated SiprecInstance
+ """
+
+ data = values.of(
+ {
+ "Status": status,
+ }
+ )
+ headers = values.of({})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.update(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return SiprecInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ sid=self._solution["sid"],
+ )
+
+ async def update_async(
+ self, status: "SiprecInstance.UpdateStatus"
+ ) -> SiprecInstance:
+ """
+ Asynchronous coroutine to update the SiprecInstance
+
+ :param status:
+
+ :returns: The updated SiprecInstance
+ """
+
+ data = values.of(
+ {
+ "Status": status,
+ }
+ )
+ headers = values.of({})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.update_async(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return SiprecInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ sid=self._solution["sid"],
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(context)
+
+
+class SiprecList(ListResource):
+
+ def __init__(self, version: Version, account_sid: str, call_sid: str):
+ """
+ Initialize the SiprecList
+
+ :param version: Version that contains the resource
+ :param account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that created this Siprec resource.
+ :param call_sid: The SID of the [Call](https://www.twilio.com/docs/voice/api/call-resource) the Siprec resource is associated with.
+
+ """
+ super().__init__(version)
+
+ # Path Solution
+ self._solution = {
+ "account_sid": account_sid,
+ "call_sid": call_sid,
+ }
+ self._uri = "/Accounts/{account_sid}/Calls/{call_sid}/Siprec.json".format(
+ **self._solution
+ )
+
+ def create(
+ self,
+ name: Union[str, object] = values.unset,
+ connector_name: Union[str, object] = values.unset,
+ track: Union["SiprecInstance.Track", object] = values.unset,
+ status_callback: Union[str, object] = values.unset,
+ status_callback_method: Union[str, object] = values.unset,
+ parameter1_name: Union[str, object] = values.unset,
+ parameter1_value: Union[str, object] = values.unset,
+ parameter2_name: Union[str, object] = values.unset,
+ parameter2_value: Union[str, object] = values.unset,
+ parameter3_name: Union[str, object] = values.unset,
+ parameter3_value: Union[str, object] = values.unset,
+ parameter4_name: Union[str, object] = values.unset,
+ parameter4_value: Union[str, object] = values.unset,
+ parameter5_name: Union[str, object] = values.unset,
+ parameter5_value: Union[str, object] = values.unset,
+ parameter6_name: Union[str, object] = values.unset,
+ parameter6_value: Union[str, object] = values.unset,
+ parameter7_name: Union[str, object] = values.unset,
+ parameter7_value: Union[str, object] = values.unset,
+ parameter8_name: Union[str, object] = values.unset,
+ parameter8_value: Union[str, object] = values.unset,
+ parameter9_name: Union[str, object] = values.unset,
+ parameter9_value: Union[str, object] = values.unset,
+ parameter10_name: Union[str, object] = values.unset,
+ parameter10_value: Union[str, object] = values.unset,
+ parameter11_name: Union[str, object] = values.unset,
+ parameter11_value: Union[str, object] = values.unset,
+ parameter12_name: Union[str, object] = values.unset,
+ parameter12_value: Union[str, object] = values.unset,
+ parameter13_name: Union[str, object] = values.unset,
+ parameter13_value: Union[str, object] = values.unset,
+ parameter14_name: Union[str, object] = values.unset,
+ parameter14_value: Union[str, object] = values.unset,
+ parameter15_name: Union[str, object] = values.unset,
+ parameter15_value: Union[str, object] = values.unset,
+ parameter16_name: Union[str, object] = values.unset,
+ parameter16_value: Union[str, object] = values.unset,
+ parameter17_name: Union[str, object] = values.unset,
+ parameter17_value: Union[str, object] = values.unset,
+ parameter18_name: Union[str, object] = values.unset,
+ parameter18_value: Union[str, object] = values.unset,
+ parameter19_name: Union[str, object] = values.unset,
+ parameter19_value: Union[str, object] = values.unset,
+ parameter20_name: Union[str, object] = values.unset,
+ parameter20_value: Union[str, object] = values.unset,
+ parameter21_name: Union[str, object] = values.unset,
+ parameter21_value: Union[str, object] = values.unset,
+ parameter22_name: Union[str, object] = values.unset,
+ parameter22_value: Union[str, object] = values.unset,
+ parameter23_name: Union[str, object] = values.unset,
+ parameter23_value: Union[str, object] = values.unset,
+ parameter24_name: Union[str, object] = values.unset,
+ parameter24_value: Union[str, object] = values.unset,
+ parameter25_name: Union[str, object] = values.unset,
+ parameter25_value: Union[str, object] = values.unset,
+ parameter26_name: Union[str, object] = values.unset,
+ parameter26_value: Union[str, object] = values.unset,
+ parameter27_name: Union[str, object] = values.unset,
+ parameter27_value: Union[str, object] = values.unset,
+ parameter28_name: Union[str, object] = values.unset,
+ parameter28_value: Union[str, object] = values.unset,
+ parameter29_name: Union[str, object] = values.unset,
+ parameter29_value: Union[str, object] = values.unset,
+ parameter30_name: Union[str, object] = values.unset,
+ parameter30_value: Union[str, object] = values.unset,
+ parameter31_name: Union[str, object] = values.unset,
+ parameter31_value: Union[str, object] = values.unset,
+ parameter32_name: Union[str, object] = values.unset,
+ parameter32_value: Union[str, object] = values.unset,
+ parameter33_name: Union[str, object] = values.unset,
+ parameter33_value: Union[str, object] = values.unset,
+ parameter34_name: Union[str, object] = values.unset,
+ parameter34_value: Union[str, object] = values.unset,
+ parameter35_name: Union[str, object] = values.unset,
+ parameter35_value: Union[str, object] = values.unset,
+ parameter36_name: Union[str, object] = values.unset,
+ parameter36_value: Union[str, object] = values.unset,
+ parameter37_name: Union[str, object] = values.unset,
+ parameter37_value: Union[str, object] = values.unset,
+ parameter38_name: Union[str, object] = values.unset,
+ parameter38_value: Union[str, object] = values.unset,
+ parameter39_name: Union[str, object] = values.unset,
+ parameter39_value: Union[str, object] = values.unset,
+ parameter40_name: Union[str, object] = values.unset,
+ parameter40_value: Union[str, object] = values.unset,
+ parameter41_name: Union[str, object] = values.unset,
+ parameter41_value: Union[str, object] = values.unset,
+ parameter42_name: Union[str, object] = values.unset,
+ parameter42_value: Union[str, object] = values.unset,
+ parameter43_name: Union[str, object] = values.unset,
+ parameter43_value: Union[str, object] = values.unset,
+ parameter44_name: Union[str, object] = values.unset,
+ parameter44_value: Union[str, object] = values.unset,
+ parameter45_name: Union[str, object] = values.unset,
+ parameter45_value: Union[str, object] = values.unset,
+ parameter46_name: Union[str, object] = values.unset,
+ parameter46_value: Union[str, object] = values.unset,
+ parameter47_name: Union[str, object] = values.unset,
+ parameter47_value: Union[str, object] = values.unset,
+ parameter48_name: Union[str, object] = values.unset,
+ parameter48_value: Union[str, object] = values.unset,
+ parameter49_name: Union[str, object] = values.unset,
+ parameter49_value: Union[str, object] = values.unset,
+ parameter50_name: Union[str, object] = values.unset,
+ parameter50_value: Union[str, object] = values.unset,
+ parameter51_name: Union[str, object] = values.unset,
+ parameter51_value: Union[str, object] = values.unset,
+ parameter52_name: Union[str, object] = values.unset,
+ parameter52_value: Union[str, object] = values.unset,
+ parameter53_name: Union[str, object] = values.unset,
+ parameter53_value: Union[str, object] = values.unset,
+ parameter54_name: Union[str, object] = values.unset,
+ parameter54_value: Union[str, object] = values.unset,
+ parameter55_name: Union[str, object] = values.unset,
+ parameter55_value: Union[str, object] = values.unset,
+ parameter56_name: Union[str, object] = values.unset,
+ parameter56_value: Union[str, object] = values.unset,
+ parameter57_name: Union[str, object] = values.unset,
+ parameter57_value: Union[str, object] = values.unset,
+ parameter58_name: Union[str, object] = values.unset,
+ parameter58_value: Union[str, object] = values.unset,
+ parameter59_name: Union[str, object] = values.unset,
+ parameter59_value: Union[str, object] = values.unset,
+ parameter60_name: Union[str, object] = values.unset,
+ parameter60_value: Union[str, object] = values.unset,
+ parameter61_name: Union[str, object] = values.unset,
+ parameter61_value: Union[str, object] = values.unset,
+ parameter62_name: Union[str, object] = values.unset,
+ parameter62_value: Union[str, object] = values.unset,
+ parameter63_name: Union[str, object] = values.unset,
+ parameter63_value: Union[str, object] = values.unset,
+ parameter64_name: Union[str, object] = values.unset,
+ parameter64_value: Union[str, object] = values.unset,
+ parameter65_name: Union[str, object] = values.unset,
+ parameter65_value: Union[str, object] = values.unset,
+ parameter66_name: Union[str, object] = values.unset,
+ parameter66_value: Union[str, object] = values.unset,
+ parameter67_name: Union[str, object] = values.unset,
+ parameter67_value: Union[str, object] = values.unset,
+ parameter68_name: Union[str, object] = values.unset,
+ parameter68_value: Union[str, object] = values.unset,
+ parameter69_name: Union[str, object] = values.unset,
+ parameter69_value: Union[str, object] = values.unset,
+ parameter70_name: Union[str, object] = values.unset,
+ parameter70_value: Union[str, object] = values.unset,
+ parameter71_name: Union[str, object] = values.unset,
+ parameter71_value: Union[str, object] = values.unset,
+ parameter72_name: Union[str, object] = values.unset,
+ parameter72_value: Union[str, object] = values.unset,
+ parameter73_name: Union[str, object] = values.unset,
+ parameter73_value: Union[str, object] = values.unset,
+ parameter74_name: Union[str, object] = values.unset,
+ parameter74_value: Union[str, object] = values.unset,
+ parameter75_name: Union[str, object] = values.unset,
+ parameter75_value: Union[str, object] = values.unset,
+ parameter76_name: Union[str, object] = values.unset,
+ parameter76_value: Union[str, object] = values.unset,
+ parameter77_name: Union[str, object] = values.unset,
+ parameter77_value: Union[str, object] = values.unset,
+ parameter78_name: Union[str, object] = values.unset,
+ parameter78_value: Union[str, object] = values.unset,
+ parameter79_name: Union[str, object] = values.unset,
+ parameter79_value: Union[str, object] = values.unset,
+ parameter80_name: Union[str, object] = values.unset,
+ parameter80_value: Union[str, object] = values.unset,
+ parameter81_name: Union[str, object] = values.unset,
+ parameter81_value: Union[str, object] = values.unset,
+ parameter82_name: Union[str, object] = values.unset,
+ parameter82_value: Union[str, object] = values.unset,
+ parameter83_name: Union[str, object] = values.unset,
+ parameter83_value: Union[str, object] = values.unset,
+ parameter84_name: Union[str, object] = values.unset,
+ parameter84_value: Union[str, object] = values.unset,
+ parameter85_name: Union[str, object] = values.unset,
+ parameter85_value: Union[str, object] = values.unset,
+ parameter86_name: Union[str, object] = values.unset,
+ parameter86_value: Union[str, object] = values.unset,
+ parameter87_name: Union[str, object] = values.unset,
+ parameter87_value: Union[str, object] = values.unset,
+ parameter88_name: Union[str, object] = values.unset,
+ parameter88_value: Union[str, object] = values.unset,
+ parameter89_name: Union[str, object] = values.unset,
+ parameter89_value: Union[str, object] = values.unset,
+ parameter90_name: Union[str, object] = values.unset,
+ parameter90_value: Union[str, object] = values.unset,
+ parameter91_name: Union[str, object] = values.unset,
+ parameter91_value: Union[str, object] = values.unset,
+ parameter92_name: Union[str, object] = values.unset,
+ parameter92_value: Union[str, object] = values.unset,
+ parameter93_name: Union[str, object] = values.unset,
+ parameter93_value: Union[str, object] = values.unset,
+ parameter94_name: Union[str, object] = values.unset,
+ parameter94_value: Union[str, object] = values.unset,
+ parameter95_name: Union[str, object] = values.unset,
+ parameter95_value: Union[str, object] = values.unset,
+ parameter96_name: Union[str, object] = values.unset,
+ parameter96_value: Union[str, object] = values.unset,
+ parameter97_name: Union[str, object] = values.unset,
+ parameter97_value: Union[str, object] = values.unset,
+ parameter98_name: Union[str, object] = values.unset,
+ parameter98_value: Union[str, object] = values.unset,
+ parameter99_name: Union[str, object] = values.unset,
+ parameter99_value: Union[str, object] = values.unset,
+ ) -> SiprecInstance:
+ """
+ Create the SiprecInstance
+
+ :param name: The user-specified name of this Siprec, if one was given when the Siprec was created. This may be used to stop the Siprec.
+ :param connector_name: Unique name used when configuring the connector via Marketplace Add-on.
+ :param track:
+ :param status_callback: Absolute URL of the status callback.
+ :param status_callback_method: The http method for the status_callback (one of GET, POST).
+ :param parameter1_name: Parameter name
+ :param parameter1_value: Parameter value
+ :param parameter2_name: Parameter name
+ :param parameter2_value: Parameter value
+ :param parameter3_name: Parameter name
+ :param parameter3_value: Parameter value
+ :param parameter4_name: Parameter name
+ :param parameter4_value: Parameter value
+ :param parameter5_name: Parameter name
+ :param parameter5_value: Parameter value
+ :param parameter6_name: Parameter name
+ :param parameter6_value: Parameter value
+ :param parameter7_name: Parameter name
+ :param parameter7_value: Parameter value
+ :param parameter8_name: Parameter name
+ :param parameter8_value: Parameter value
+ :param parameter9_name: Parameter name
+ :param parameter9_value: Parameter value
+ :param parameter10_name: Parameter name
+ :param parameter10_value: Parameter value
+ :param parameter11_name: Parameter name
+ :param parameter11_value: Parameter value
+ :param parameter12_name: Parameter name
+ :param parameter12_value: Parameter value
+ :param parameter13_name: Parameter name
+ :param parameter13_value: Parameter value
+ :param parameter14_name: Parameter name
+ :param parameter14_value: Parameter value
+ :param parameter15_name: Parameter name
+ :param parameter15_value: Parameter value
+ :param parameter16_name: Parameter name
+ :param parameter16_value: Parameter value
+ :param parameter17_name: Parameter name
+ :param parameter17_value: Parameter value
+ :param parameter18_name: Parameter name
+ :param parameter18_value: Parameter value
+ :param parameter19_name: Parameter name
+ :param parameter19_value: Parameter value
+ :param parameter20_name: Parameter name
+ :param parameter20_value: Parameter value
+ :param parameter21_name: Parameter name
+ :param parameter21_value: Parameter value
+ :param parameter22_name: Parameter name
+ :param parameter22_value: Parameter value
+ :param parameter23_name: Parameter name
+ :param parameter23_value: Parameter value
+ :param parameter24_name: Parameter name
+ :param parameter24_value: Parameter value
+ :param parameter25_name: Parameter name
+ :param parameter25_value: Parameter value
+ :param parameter26_name: Parameter name
+ :param parameter26_value: Parameter value
+ :param parameter27_name: Parameter name
+ :param parameter27_value: Parameter value
+ :param parameter28_name: Parameter name
+ :param parameter28_value: Parameter value
+ :param parameter29_name: Parameter name
+ :param parameter29_value: Parameter value
+ :param parameter30_name: Parameter name
+ :param parameter30_value: Parameter value
+ :param parameter31_name: Parameter name
+ :param parameter31_value: Parameter value
+ :param parameter32_name: Parameter name
+ :param parameter32_value: Parameter value
+ :param parameter33_name: Parameter name
+ :param parameter33_value: Parameter value
+ :param parameter34_name: Parameter name
+ :param parameter34_value: Parameter value
+ :param parameter35_name: Parameter name
+ :param parameter35_value: Parameter value
+ :param parameter36_name: Parameter name
+ :param parameter36_value: Parameter value
+ :param parameter37_name: Parameter name
+ :param parameter37_value: Parameter value
+ :param parameter38_name: Parameter name
+ :param parameter38_value: Parameter value
+ :param parameter39_name: Parameter name
+ :param parameter39_value: Parameter value
+ :param parameter40_name: Parameter name
+ :param parameter40_value: Parameter value
+ :param parameter41_name: Parameter name
+ :param parameter41_value: Parameter value
+ :param parameter42_name: Parameter name
+ :param parameter42_value: Parameter value
+ :param parameter43_name: Parameter name
+ :param parameter43_value: Parameter value
+ :param parameter44_name: Parameter name
+ :param parameter44_value: Parameter value
+ :param parameter45_name: Parameter name
+ :param parameter45_value: Parameter value
+ :param parameter46_name: Parameter name
+ :param parameter46_value: Parameter value
+ :param parameter47_name: Parameter name
+ :param parameter47_value: Parameter value
+ :param parameter48_name: Parameter name
+ :param parameter48_value: Parameter value
+ :param parameter49_name: Parameter name
+ :param parameter49_value: Parameter value
+ :param parameter50_name: Parameter name
+ :param parameter50_value: Parameter value
+ :param parameter51_name: Parameter name
+ :param parameter51_value: Parameter value
+ :param parameter52_name: Parameter name
+ :param parameter52_value: Parameter value
+ :param parameter53_name: Parameter name
+ :param parameter53_value: Parameter value
+ :param parameter54_name: Parameter name
+ :param parameter54_value: Parameter value
+ :param parameter55_name: Parameter name
+ :param parameter55_value: Parameter value
+ :param parameter56_name: Parameter name
+ :param parameter56_value: Parameter value
+ :param parameter57_name: Parameter name
+ :param parameter57_value: Parameter value
+ :param parameter58_name: Parameter name
+ :param parameter58_value: Parameter value
+ :param parameter59_name: Parameter name
+ :param parameter59_value: Parameter value
+ :param parameter60_name: Parameter name
+ :param parameter60_value: Parameter value
+ :param parameter61_name: Parameter name
+ :param parameter61_value: Parameter value
+ :param parameter62_name: Parameter name
+ :param parameter62_value: Parameter value
+ :param parameter63_name: Parameter name
+ :param parameter63_value: Parameter value
+ :param parameter64_name: Parameter name
+ :param parameter64_value: Parameter value
+ :param parameter65_name: Parameter name
+ :param parameter65_value: Parameter value
+ :param parameter66_name: Parameter name
+ :param parameter66_value: Parameter value
+ :param parameter67_name: Parameter name
+ :param parameter67_value: Parameter value
+ :param parameter68_name: Parameter name
+ :param parameter68_value: Parameter value
+ :param parameter69_name: Parameter name
+ :param parameter69_value: Parameter value
+ :param parameter70_name: Parameter name
+ :param parameter70_value: Parameter value
+ :param parameter71_name: Parameter name
+ :param parameter71_value: Parameter value
+ :param parameter72_name: Parameter name
+ :param parameter72_value: Parameter value
+ :param parameter73_name: Parameter name
+ :param parameter73_value: Parameter value
+ :param parameter74_name: Parameter name
+ :param parameter74_value: Parameter value
+ :param parameter75_name: Parameter name
+ :param parameter75_value: Parameter value
+ :param parameter76_name: Parameter name
+ :param parameter76_value: Parameter value
+ :param parameter77_name: Parameter name
+ :param parameter77_value: Parameter value
+ :param parameter78_name: Parameter name
+ :param parameter78_value: Parameter value
+ :param parameter79_name: Parameter name
+ :param parameter79_value: Parameter value
+ :param parameter80_name: Parameter name
+ :param parameter80_value: Parameter value
+ :param parameter81_name: Parameter name
+ :param parameter81_value: Parameter value
+ :param parameter82_name: Parameter name
+ :param parameter82_value: Parameter value
+ :param parameter83_name: Parameter name
+ :param parameter83_value: Parameter value
+ :param parameter84_name: Parameter name
+ :param parameter84_value: Parameter value
+ :param parameter85_name: Parameter name
+ :param parameter85_value: Parameter value
+ :param parameter86_name: Parameter name
+ :param parameter86_value: Parameter value
+ :param parameter87_name: Parameter name
+ :param parameter87_value: Parameter value
+ :param parameter88_name: Parameter name
+ :param parameter88_value: Parameter value
+ :param parameter89_name: Parameter name
+ :param parameter89_value: Parameter value
+ :param parameter90_name: Parameter name
+ :param parameter90_value: Parameter value
+ :param parameter91_name: Parameter name
+ :param parameter91_value: Parameter value
+ :param parameter92_name: Parameter name
+ :param parameter92_value: Parameter value
+ :param parameter93_name: Parameter name
+ :param parameter93_value: Parameter value
+ :param parameter94_name: Parameter name
+ :param parameter94_value: Parameter value
+ :param parameter95_name: Parameter name
+ :param parameter95_value: Parameter value
+ :param parameter96_name: Parameter name
+ :param parameter96_value: Parameter value
+ :param parameter97_name: Parameter name
+ :param parameter97_value: Parameter value
+ :param parameter98_name: Parameter name
+ :param parameter98_value: Parameter value
+ :param parameter99_name: Parameter name
+ :param parameter99_value: Parameter value
+
+ :returns: The created SiprecInstance
+ """
+
+ data = values.of(
+ {
+ "Name": name,
+ "ConnectorName": connector_name,
+ "Track": track,
+ "StatusCallback": status_callback,
+ "StatusCallbackMethod": status_callback_method,
+ "Parameter1.Name": parameter1_name,
+ "Parameter1.Value": parameter1_value,
+ "Parameter2.Name": parameter2_name,
+ "Parameter2.Value": parameter2_value,
+ "Parameter3.Name": parameter3_name,
+ "Parameter3.Value": parameter3_value,
+ "Parameter4.Name": parameter4_name,
+ "Parameter4.Value": parameter4_value,
+ "Parameter5.Name": parameter5_name,
+ "Parameter5.Value": parameter5_value,
+ "Parameter6.Name": parameter6_name,
+ "Parameter6.Value": parameter6_value,
+ "Parameter7.Name": parameter7_name,
+ "Parameter7.Value": parameter7_value,
+ "Parameter8.Name": parameter8_name,
+ "Parameter8.Value": parameter8_value,
+ "Parameter9.Name": parameter9_name,
+ "Parameter9.Value": parameter9_value,
+ "Parameter10.Name": parameter10_name,
+ "Parameter10.Value": parameter10_value,
+ "Parameter11.Name": parameter11_name,
+ "Parameter11.Value": parameter11_value,
+ "Parameter12.Name": parameter12_name,
+ "Parameter12.Value": parameter12_value,
+ "Parameter13.Name": parameter13_name,
+ "Parameter13.Value": parameter13_value,
+ "Parameter14.Name": parameter14_name,
+ "Parameter14.Value": parameter14_value,
+ "Parameter15.Name": parameter15_name,
+ "Parameter15.Value": parameter15_value,
+ "Parameter16.Name": parameter16_name,
+ "Parameter16.Value": parameter16_value,
+ "Parameter17.Name": parameter17_name,
+ "Parameter17.Value": parameter17_value,
+ "Parameter18.Name": parameter18_name,
+ "Parameter18.Value": parameter18_value,
+ "Parameter19.Name": parameter19_name,
+ "Parameter19.Value": parameter19_value,
+ "Parameter20.Name": parameter20_name,
+ "Parameter20.Value": parameter20_value,
+ "Parameter21.Name": parameter21_name,
+ "Parameter21.Value": parameter21_value,
+ "Parameter22.Name": parameter22_name,
+ "Parameter22.Value": parameter22_value,
+ "Parameter23.Name": parameter23_name,
+ "Parameter23.Value": parameter23_value,
+ "Parameter24.Name": parameter24_name,
+ "Parameter24.Value": parameter24_value,
+ "Parameter25.Name": parameter25_name,
+ "Parameter25.Value": parameter25_value,
+ "Parameter26.Name": parameter26_name,
+ "Parameter26.Value": parameter26_value,
+ "Parameter27.Name": parameter27_name,
+ "Parameter27.Value": parameter27_value,
+ "Parameter28.Name": parameter28_name,
+ "Parameter28.Value": parameter28_value,
+ "Parameter29.Name": parameter29_name,
+ "Parameter29.Value": parameter29_value,
+ "Parameter30.Name": parameter30_name,
+ "Parameter30.Value": parameter30_value,
+ "Parameter31.Name": parameter31_name,
+ "Parameter31.Value": parameter31_value,
+ "Parameter32.Name": parameter32_name,
+ "Parameter32.Value": parameter32_value,
+ "Parameter33.Name": parameter33_name,
+ "Parameter33.Value": parameter33_value,
+ "Parameter34.Name": parameter34_name,
+ "Parameter34.Value": parameter34_value,
+ "Parameter35.Name": parameter35_name,
+ "Parameter35.Value": parameter35_value,
+ "Parameter36.Name": parameter36_name,
+ "Parameter36.Value": parameter36_value,
+ "Parameter37.Name": parameter37_name,
+ "Parameter37.Value": parameter37_value,
+ "Parameter38.Name": parameter38_name,
+ "Parameter38.Value": parameter38_value,
+ "Parameter39.Name": parameter39_name,
+ "Parameter39.Value": parameter39_value,
+ "Parameter40.Name": parameter40_name,
+ "Parameter40.Value": parameter40_value,
+ "Parameter41.Name": parameter41_name,
+ "Parameter41.Value": parameter41_value,
+ "Parameter42.Name": parameter42_name,
+ "Parameter42.Value": parameter42_value,
+ "Parameter43.Name": parameter43_name,
+ "Parameter43.Value": parameter43_value,
+ "Parameter44.Name": parameter44_name,
+ "Parameter44.Value": parameter44_value,
+ "Parameter45.Name": parameter45_name,
+ "Parameter45.Value": parameter45_value,
+ "Parameter46.Name": parameter46_name,
+ "Parameter46.Value": parameter46_value,
+ "Parameter47.Name": parameter47_name,
+ "Parameter47.Value": parameter47_value,
+ "Parameter48.Name": parameter48_name,
+ "Parameter48.Value": parameter48_value,
+ "Parameter49.Name": parameter49_name,
+ "Parameter49.Value": parameter49_value,
+ "Parameter50.Name": parameter50_name,
+ "Parameter50.Value": parameter50_value,
+ "Parameter51.Name": parameter51_name,
+ "Parameter51.Value": parameter51_value,
+ "Parameter52.Name": parameter52_name,
+ "Parameter52.Value": parameter52_value,
+ "Parameter53.Name": parameter53_name,
+ "Parameter53.Value": parameter53_value,
+ "Parameter54.Name": parameter54_name,
+ "Parameter54.Value": parameter54_value,
+ "Parameter55.Name": parameter55_name,
+ "Parameter55.Value": parameter55_value,
+ "Parameter56.Name": parameter56_name,
+ "Parameter56.Value": parameter56_value,
+ "Parameter57.Name": parameter57_name,
+ "Parameter57.Value": parameter57_value,
+ "Parameter58.Name": parameter58_name,
+ "Parameter58.Value": parameter58_value,
+ "Parameter59.Name": parameter59_name,
+ "Parameter59.Value": parameter59_value,
+ "Parameter60.Name": parameter60_name,
+ "Parameter60.Value": parameter60_value,
+ "Parameter61.Name": parameter61_name,
+ "Parameter61.Value": parameter61_value,
+ "Parameter62.Name": parameter62_name,
+ "Parameter62.Value": parameter62_value,
+ "Parameter63.Name": parameter63_name,
+ "Parameter63.Value": parameter63_value,
+ "Parameter64.Name": parameter64_name,
+ "Parameter64.Value": parameter64_value,
+ "Parameter65.Name": parameter65_name,
+ "Parameter65.Value": parameter65_value,
+ "Parameter66.Name": parameter66_name,
+ "Parameter66.Value": parameter66_value,
+ "Parameter67.Name": parameter67_name,
+ "Parameter67.Value": parameter67_value,
+ "Parameter68.Name": parameter68_name,
+ "Parameter68.Value": parameter68_value,
+ "Parameter69.Name": parameter69_name,
+ "Parameter69.Value": parameter69_value,
+ "Parameter70.Name": parameter70_name,
+ "Parameter70.Value": parameter70_value,
+ "Parameter71.Name": parameter71_name,
+ "Parameter71.Value": parameter71_value,
+ "Parameter72.Name": parameter72_name,
+ "Parameter72.Value": parameter72_value,
+ "Parameter73.Name": parameter73_name,
+ "Parameter73.Value": parameter73_value,
+ "Parameter74.Name": parameter74_name,
+ "Parameter74.Value": parameter74_value,
+ "Parameter75.Name": parameter75_name,
+ "Parameter75.Value": parameter75_value,
+ "Parameter76.Name": parameter76_name,
+ "Parameter76.Value": parameter76_value,
+ "Parameter77.Name": parameter77_name,
+ "Parameter77.Value": parameter77_value,
+ "Parameter78.Name": parameter78_name,
+ "Parameter78.Value": parameter78_value,
+ "Parameter79.Name": parameter79_name,
+ "Parameter79.Value": parameter79_value,
+ "Parameter80.Name": parameter80_name,
+ "Parameter80.Value": parameter80_value,
+ "Parameter81.Name": parameter81_name,
+ "Parameter81.Value": parameter81_value,
+ "Parameter82.Name": parameter82_name,
+ "Parameter82.Value": parameter82_value,
+ "Parameter83.Name": parameter83_name,
+ "Parameter83.Value": parameter83_value,
+ "Parameter84.Name": parameter84_name,
+ "Parameter84.Value": parameter84_value,
+ "Parameter85.Name": parameter85_name,
+ "Parameter85.Value": parameter85_value,
+ "Parameter86.Name": parameter86_name,
+ "Parameter86.Value": parameter86_value,
+ "Parameter87.Name": parameter87_name,
+ "Parameter87.Value": parameter87_value,
+ "Parameter88.Name": parameter88_name,
+ "Parameter88.Value": parameter88_value,
+ "Parameter89.Name": parameter89_name,
+ "Parameter89.Value": parameter89_value,
+ "Parameter90.Name": parameter90_name,
+ "Parameter90.Value": parameter90_value,
+ "Parameter91.Name": parameter91_name,
+ "Parameter91.Value": parameter91_value,
+ "Parameter92.Name": parameter92_name,
+ "Parameter92.Value": parameter92_value,
+ "Parameter93.Name": parameter93_name,
+ "Parameter93.Value": parameter93_value,
+ "Parameter94.Name": parameter94_name,
+ "Parameter94.Value": parameter94_value,
+ "Parameter95.Name": parameter95_name,
+ "Parameter95.Value": parameter95_value,
+ "Parameter96.Name": parameter96_name,
+ "Parameter96.Value": parameter96_value,
+ "Parameter97.Name": parameter97_name,
+ "Parameter97.Value": parameter97_value,
+ "Parameter98.Name": parameter98_name,
+ "Parameter98.Value": parameter98_value,
+ "Parameter99.Name": parameter99_name,
+ "Parameter99.Value": parameter99_value,
+ }
+ )
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.create(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return SiprecInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ )
+
+ async def create_async(
+ self,
+ name: Union[str, object] = values.unset,
+ connector_name: Union[str, object] = values.unset,
+ track: Union["SiprecInstance.Track", object] = values.unset,
+ status_callback: Union[str, object] = values.unset,
+ status_callback_method: Union[str, object] = values.unset,
+ parameter1_name: Union[str, object] = values.unset,
+ parameter1_value: Union[str, object] = values.unset,
+ parameter2_name: Union[str, object] = values.unset,
+ parameter2_value: Union[str, object] = values.unset,
+ parameter3_name: Union[str, object] = values.unset,
+ parameter3_value: Union[str, object] = values.unset,
+ parameter4_name: Union[str, object] = values.unset,
+ parameter4_value: Union[str, object] = values.unset,
+ parameter5_name: Union[str, object] = values.unset,
+ parameter5_value: Union[str, object] = values.unset,
+ parameter6_name: Union[str, object] = values.unset,
+ parameter6_value: Union[str, object] = values.unset,
+ parameter7_name: Union[str, object] = values.unset,
+ parameter7_value: Union[str, object] = values.unset,
+ parameter8_name: Union[str, object] = values.unset,
+ parameter8_value: Union[str, object] = values.unset,
+ parameter9_name: Union[str, object] = values.unset,
+ parameter9_value: Union[str, object] = values.unset,
+ parameter10_name: Union[str, object] = values.unset,
+ parameter10_value: Union[str, object] = values.unset,
+ parameter11_name: Union[str, object] = values.unset,
+ parameter11_value: Union[str, object] = values.unset,
+ parameter12_name: Union[str, object] = values.unset,
+ parameter12_value: Union[str, object] = values.unset,
+ parameter13_name: Union[str, object] = values.unset,
+ parameter13_value: Union[str, object] = values.unset,
+ parameter14_name: Union[str, object] = values.unset,
+ parameter14_value: Union[str, object] = values.unset,
+ parameter15_name: Union[str, object] = values.unset,
+ parameter15_value: Union[str, object] = values.unset,
+ parameter16_name: Union[str, object] = values.unset,
+ parameter16_value: Union[str, object] = values.unset,
+ parameter17_name: Union[str, object] = values.unset,
+ parameter17_value: Union[str, object] = values.unset,
+ parameter18_name: Union[str, object] = values.unset,
+ parameter18_value: Union[str, object] = values.unset,
+ parameter19_name: Union[str, object] = values.unset,
+ parameter19_value: Union[str, object] = values.unset,
+ parameter20_name: Union[str, object] = values.unset,
+ parameter20_value: Union[str, object] = values.unset,
+ parameter21_name: Union[str, object] = values.unset,
+ parameter21_value: Union[str, object] = values.unset,
+ parameter22_name: Union[str, object] = values.unset,
+ parameter22_value: Union[str, object] = values.unset,
+ parameter23_name: Union[str, object] = values.unset,
+ parameter23_value: Union[str, object] = values.unset,
+ parameter24_name: Union[str, object] = values.unset,
+ parameter24_value: Union[str, object] = values.unset,
+ parameter25_name: Union[str, object] = values.unset,
+ parameter25_value: Union[str, object] = values.unset,
+ parameter26_name: Union[str, object] = values.unset,
+ parameter26_value: Union[str, object] = values.unset,
+ parameter27_name: Union[str, object] = values.unset,
+ parameter27_value: Union[str, object] = values.unset,
+ parameter28_name: Union[str, object] = values.unset,
+ parameter28_value: Union[str, object] = values.unset,
+ parameter29_name: Union[str, object] = values.unset,
+ parameter29_value: Union[str, object] = values.unset,
+ parameter30_name: Union[str, object] = values.unset,
+ parameter30_value: Union[str, object] = values.unset,
+ parameter31_name: Union[str, object] = values.unset,
+ parameter31_value: Union[str, object] = values.unset,
+ parameter32_name: Union[str, object] = values.unset,
+ parameter32_value: Union[str, object] = values.unset,
+ parameter33_name: Union[str, object] = values.unset,
+ parameter33_value: Union[str, object] = values.unset,
+ parameter34_name: Union[str, object] = values.unset,
+ parameter34_value: Union[str, object] = values.unset,
+ parameter35_name: Union[str, object] = values.unset,
+ parameter35_value: Union[str, object] = values.unset,
+ parameter36_name: Union[str, object] = values.unset,
+ parameter36_value: Union[str, object] = values.unset,
+ parameter37_name: Union[str, object] = values.unset,
+ parameter37_value: Union[str, object] = values.unset,
+ parameter38_name: Union[str, object] = values.unset,
+ parameter38_value: Union[str, object] = values.unset,
+ parameter39_name: Union[str, object] = values.unset,
+ parameter39_value: Union[str, object] = values.unset,
+ parameter40_name: Union[str, object] = values.unset,
+ parameter40_value: Union[str, object] = values.unset,
+ parameter41_name: Union[str, object] = values.unset,
+ parameter41_value: Union[str, object] = values.unset,
+ parameter42_name: Union[str, object] = values.unset,
+ parameter42_value: Union[str, object] = values.unset,
+ parameter43_name: Union[str, object] = values.unset,
+ parameter43_value: Union[str, object] = values.unset,
+ parameter44_name: Union[str, object] = values.unset,
+ parameter44_value: Union[str, object] = values.unset,
+ parameter45_name: Union[str, object] = values.unset,
+ parameter45_value: Union[str, object] = values.unset,
+ parameter46_name: Union[str, object] = values.unset,
+ parameter46_value: Union[str, object] = values.unset,
+ parameter47_name: Union[str, object] = values.unset,
+ parameter47_value: Union[str, object] = values.unset,
+ parameter48_name: Union[str, object] = values.unset,
+ parameter48_value: Union[str, object] = values.unset,
+ parameter49_name: Union[str, object] = values.unset,
+ parameter49_value: Union[str, object] = values.unset,
+ parameter50_name: Union[str, object] = values.unset,
+ parameter50_value: Union[str, object] = values.unset,
+ parameter51_name: Union[str, object] = values.unset,
+ parameter51_value: Union[str, object] = values.unset,
+ parameter52_name: Union[str, object] = values.unset,
+ parameter52_value: Union[str, object] = values.unset,
+ parameter53_name: Union[str, object] = values.unset,
+ parameter53_value: Union[str, object] = values.unset,
+ parameter54_name: Union[str, object] = values.unset,
+ parameter54_value: Union[str, object] = values.unset,
+ parameter55_name: Union[str, object] = values.unset,
+ parameter55_value: Union[str, object] = values.unset,
+ parameter56_name: Union[str, object] = values.unset,
+ parameter56_value: Union[str, object] = values.unset,
+ parameter57_name: Union[str, object] = values.unset,
+ parameter57_value: Union[str, object] = values.unset,
+ parameter58_name: Union[str, object] = values.unset,
+ parameter58_value: Union[str, object] = values.unset,
+ parameter59_name: Union[str, object] = values.unset,
+ parameter59_value: Union[str, object] = values.unset,
+ parameter60_name: Union[str, object] = values.unset,
+ parameter60_value: Union[str, object] = values.unset,
+ parameter61_name: Union[str, object] = values.unset,
+ parameter61_value: Union[str, object] = values.unset,
+ parameter62_name: Union[str, object] = values.unset,
+ parameter62_value: Union[str, object] = values.unset,
+ parameter63_name: Union[str, object] = values.unset,
+ parameter63_value: Union[str, object] = values.unset,
+ parameter64_name: Union[str, object] = values.unset,
+ parameter64_value: Union[str, object] = values.unset,
+ parameter65_name: Union[str, object] = values.unset,
+ parameter65_value: Union[str, object] = values.unset,
+ parameter66_name: Union[str, object] = values.unset,
+ parameter66_value: Union[str, object] = values.unset,
+ parameter67_name: Union[str, object] = values.unset,
+ parameter67_value: Union[str, object] = values.unset,
+ parameter68_name: Union[str, object] = values.unset,
+ parameter68_value: Union[str, object] = values.unset,
+ parameter69_name: Union[str, object] = values.unset,
+ parameter69_value: Union[str, object] = values.unset,
+ parameter70_name: Union[str, object] = values.unset,
+ parameter70_value: Union[str, object] = values.unset,
+ parameter71_name: Union[str, object] = values.unset,
+ parameter71_value: Union[str, object] = values.unset,
+ parameter72_name: Union[str, object] = values.unset,
+ parameter72_value: Union[str, object] = values.unset,
+ parameter73_name: Union[str, object] = values.unset,
+ parameter73_value: Union[str, object] = values.unset,
+ parameter74_name: Union[str, object] = values.unset,
+ parameter74_value: Union[str, object] = values.unset,
+ parameter75_name: Union[str, object] = values.unset,
+ parameter75_value: Union[str, object] = values.unset,
+ parameter76_name: Union[str, object] = values.unset,
+ parameter76_value: Union[str, object] = values.unset,
+ parameter77_name: Union[str, object] = values.unset,
+ parameter77_value: Union[str, object] = values.unset,
+ parameter78_name: Union[str, object] = values.unset,
+ parameter78_value: Union[str, object] = values.unset,
+ parameter79_name: Union[str, object] = values.unset,
+ parameter79_value: Union[str, object] = values.unset,
+ parameter80_name: Union[str, object] = values.unset,
+ parameter80_value: Union[str, object] = values.unset,
+ parameter81_name: Union[str, object] = values.unset,
+ parameter81_value: Union[str, object] = values.unset,
+ parameter82_name: Union[str, object] = values.unset,
+ parameter82_value: Union[str, object] = values.unset,
+ parameter83_name: Union[str, object] = values.unset,
+ parameter83_value: Union[str, object] = values.unset,
+ parameter84_name: Union[str, object] = values.unset,
+ parameter84_value: Union[str, object] = values.unset,
+ parameter85_name: Union[str, object] = values.unset,
+ parameter85_value: Union[str, object] = values.unset,
+ parameter86_name: Union[str, object] = values.unset,
+ parameter86_value: Union[str, object] = values.unset,
+ parameter87_name: Union[str, object] = values.unset,
+ parameter87_value: Union[str, object] = values.unset,
+ parameter88_name: Union[str, object] = values.unset,
+ parameter88_value: Union[str, object] = values.unset,
+ parameter89_name: Union[str, object] = values.unset,
+ parameter89_value: Union[str, object] = values.unset,
+ parameter90_name: Union[str, object] = values.unset,
+ parameter90_value: Union[str, object] = values.unset,
+ parameter91_name: Union[str, object] = values.unset,
+ parameter91_value: Union[str, object] = values.unset,
+ parameter92_name: Union[str, object] = values.unset,
+ parameter92_value: Union[str, object] = values.unset,
+ parameter93_name: Union[str, object] = values.unset,
+ parameter93_value: Union[str, object] = values.unset,
+ parameter94_name: Union[str, object] = values.unset,
+ parameter94_value: Union[str, object] = values.unset,
+ parameter95_name: Union[str, object] = values.unset,
+ parameter95_value: Union[str, object] = values.unset,
+ parameter96_name: Union[str, object] = values.unset,
+ parameter96_value: Union[str, object] = values.unset,
+ parameter97_name: Union[str, object] = values.unset,
+ parameter97_value: Union[str, object] = values.unset,
+ parameter98_name: Union[str, object] = values.unset,
+ parameter98_value: Union[str, object] = values.unset,
+ parameter99_name: Union[str, object] = values.unset,
+ parameter99_value: Union[str, object] = values.unset,
+ ) -> SiprecInstance:
+ """
+ Asynchronously create the SiprecInstance
+
+ :param name: The user-specified name of this Siprec, if one was given when the Siprec was created. This may be used to stop the Siprec.
+ :param connector_name: Unique name used when configuring the connector via Marketplace Add-on.
+ :param track:
+ :param status_callback: Absolute URL of the status callback.
+ :param status_callback_method: The http method for the status_callback (one of GET, POST).
+ :param parameter1_name: Parameter name
+ :param parameter1_value: Parameter value
+ :param parameter2_name: Parameter name
+ :param parameter2_value: Parameter value
+ :param parameter3_name: Parameter name
+ :param parameter3_value: Parameter value
+ :param parameter4_name: Parameter name
+ :param parameter4_value: Parameter value
+ :param parameter5_name: Parameter name
+ :param parameter5_value: Parameter value
+ :param parameter6_name: Parameter name
+ :param parameter6_value: Parameter value
+ :param parameter7_name: Parameter name
+ :param parameter7_value: Parameter value
+ :param parameter8_name: Parameter name
+ :param parameter8_value: Parameter value
+ :param parameter9_name: Parameter name
+ :param parameter9_value: Parameter value
+ :param parameter10_name: Parameter name
+ :param parameter10_value: Parameter value
+ :param parameter11_name: Parameter name
+ :param parameter11_value: Parameter value
+ :param parameter12_name: Parameter name
+ :param parameter12_value: Parameter value
+ :param parameter13_name: Parameter name
+ :param parameter13_value: Parameter value
+ :param parameter14_name: Parameter name
+ :param parameter14_value: Parameter value
+ :param parameter15_name: Parameter name
+ :param parameter15_value: Parameter value
+ :param parameter16_name: Parameter name
+ :param parameter16_value: Parameter value
+ :param parameter17_name: Parameter name
+ :param parameter17_value: Parameter value
+ :param parameter18_name: Parameter name
+ :param parameter18_value: Parameter value
+ :param parameter19_name: Parameter name
+ :param parameter19_value: Parameter value
+ :param parameter20_name: Parameter name
+ :param parameter20_value: Parameter value
+ :param parameter21_name: Parameter name
+ :param parameter21_value: Parameter value
+ :param parameter22_name: Parameter name
+ :param parameter22_value: Parameter value
+ :param parameter23_name: Parameter name
+ :param parameter23_value: Parameter value
+ :param parameter24_name: Parameter name
+ :param parameter24_value: Parameter value
+ :param parameter25_name: Parameter name
+ :param parameter25_value: Parameter value
+ :param parameter26_name: Parameter name
+ :param parameter26_value: Parameter value
+ :param parameter27_name: Parameter name
+ :param parameter27_value: Parameter value
+ :param parameter28_name: Parameter name
+ :param parameter28_value: Parameter value
+ :param parameter29_name: Parameter name
+ :param parameter29_value: Parameter value
+ :param parameter30_name: Parameter name
+ :param parameter30_value: Parameter value
+ :param parameter31_name: Parameter name
+ :param parameter31_value: Parameter value
+ :param parameter32_name: Parameter name
+ :param parameter32_value: Parameter value
+ :param parameter33_name: Parameter name
+ :param parameter33_value: Parameter value
+ :param parameter34_name: Parameter name
+ :param parameter34_value: Parameter value
+ :param parameter35_name: Parameter name
+ :param parameter35_value: Parameter value
+ :param parameter36_name: Parameter name
+ :param parameter36_value: Parameter value
+ :param parameter37_name: Parameter name
+ :param parameter37_value: Parameter value
+ :param parameter38_name: Parameter name
+ :param parameter38_value: Parameter value
+ :param parameter39_name: Parameter name
+ :param parameter39_value: Parameter value
+ :param parameter40_name: Parameter name
+ :param parameter40_value: Parameter value
+ :param parameter41_name: Parameter name
+ :param parameter41_value: Parameter value
+ :param parameter42_name: Parameter name
+ :param parameter42_value: Parameter value
+ :param parameter43_name: Parameter name
+ :param parameter43_value: Parameter value
+ :param parameter44_name: Parameter name
+ :param parameter44_value: Parameter value
+ :param parameter45_name: Parameter name
+ :param parameter45_value: Parameter value
+ :param parameter46_name: Parameter name
+ :param parameter46_value: Parameter value
+ :param parameter47_name: Parameter name
+ :param parameter47_value: Parameter value
+ :param parameter48_name: Parameter name
+ :param parameter48_value: Parameter value
+ :param parameter49_name: Parameter name
+ :param parameter49_value: Parameter value
+ :param parameter50_name: Parameter name
+ :param parameter50_value: Parameter value
+ :param parameter51_name: Parameter name
+ :param parameter51_value: Parameter value
+ :param parameter52_name: Parameter name
+ :param parameter52_value: Parameter value
+ :param parameter53_name: Parameter name
+ :param parameter53_value: Parameter value
+ :param parameter54_name: Parameter name
+ :param parameter54_value: Parameter value
+ :param parameter55_name: Parameter name
+ :param parameter55_value: Parameter value
+ :param parameter56_name: Parameter name
+ :param parameter56_value: Parameter value
+ :param parameter57_name: Parameter name
+ :param parameter57_value: Parameter value
+ :param parameter58_name: Parameter name
+ :param parameter58_value: Parameter value
+ :param parameter59_name: Parameter name
+ :param parameter59_value: Parameter value
+ :param parameter60_name: Parameter name
+ :param parameter60_value: Parameter value
+ :param parameter61_name: Parameter name
+ :param parameter61_value: Parameter value
+ :param parameter62_name: Parameter name
+ :param parameter62_value: Parameter value
+ :param parameter63_name: Parameter name
+ :param parameter63_value: Parameter value
+ :param parameter64_name: Parameter name
+ :param parameter64_value: Parameter value
+ :param parameter65_name: Parameter name
+ :param parameter65_value: Parameter value
+ :param parameter66_name: Parameter name
+ :param parameter66_value: Parameter value
+ :param parameter67_name: Parameter name
+ :param parameter67_value: Parameter value
+ :param parameter68_name: Parameter name
+ :param parameter68_value: Parameter value
+ :param parameter69_name: Parameter name
+ :param parameter69_value: Parameter value
+ :param parameter70_name: Parameter name
+ :param parameter70_value: Parameter value
+ :param parameter71_name: Parameter name
+ :param parameter71_value: Parameter value
+ :param parameter72_name: Parameter name
+ :param parameter72_value: Parameter value
+ :param parameter73_name: Parameter name
+ :param parameter73_value: Parameter value
+ :param parameter74_name: Parameter name
+ :param parameter74_value: Parameter value
+ :param parameter75_name: Parameter name
+ :param parameter75_value: Parameter value
+ :param parameter76_name: Parameter name
+ :param parameter76_value: Parameter value
+ :param parameter77_name: Parameter name
+ :param parameter77_value: Parameter value
+ :param parameter78_name: Parameter name
+ :param parameter78_value: Parameter value
+ :param parameter79_name: Parameter name
+ :param parameter79_value: Parameter value
+ :param parameter80_name: Parameter name
+ :param parameter80_value: Parameter value
+ :param parameter81_name: Parameter name
+ :param parameter81_value: Parameter value
+ :param parameter82_name: Parameter name
+ :param parameter82_value: Parameter value
+ :param parameter83_name: Parameter name
+ :param parameter83_value: Parameter value
+ :param parameter84_name: Parameter name
+ :param parameter84_value: Parameter value
+ :param parameter85_name: Parameter name
+ :param parameter85_value: Parameter value
+ :param parameter86_name: Parameter name
+ :param parameter86_value: Parameter value
+ :param parameter87_name: Parameter name
+ :param parameter87_value: Parameter value
+ :param parameter88_name: Parameter name
+ :param parameter88_value: Parameter value
+ :param parameter89_name: Parameter name
+ :param parameter89_value: Parameter value
+ :param parameter90_name: Parameter name
+ :param parameter90_value: Parameter value
+ :param parameter91_name: Parameter name
+ :param parameter91_value: Parameter value
+ :param parameter92_name: Parameter name
+ :param parameter92_value: Parameter value
+ :param parameter93_name: Parameter name
+ :param parameter93_value: Parameter value
+ :param parameter94_name: Parameter name
+ :param parameter94_value: Parameter value
+ :param parameter95_name: Parameter name
+ :param parameter95_value: Parameter value
+ :param parameter96_name: Parameter name
+ :param parameter96_value: Parameter value
+ :param parameter97_name: Parameter name
+ :param parameter97_value: Parameter value
+ :param parameter98_name: Parameter name
+ :param parameter98_value: Parameter value
+ :param parameter99_name: Parameter name
+ :param parameter99_value: Parameter value
+
+ :returns: The created SiprecInstance
+ """
+
+ data = values.of(
+ {
+ "Name": name,
+ "ConnectorName": connector_name,
+ "Track": track,
+ "StatusCallback": status_callback,
+ "StatusCallbackMethod": status_callback_method,
+ "Parameter1.Name": parameter1_name,
+ "Parameter1.Value": parameter1_value,
+ "Parameter2.Name": parameter2_name,
+ "Parameter2.Value": parameter2_value,
+ "Parameter3.Name": parameter3_name,
+ "Parameter3.Value": parameter3_value,
+ "Parameter4.Name": parameter4_name,
+ "Parameter4.Value": parameter4_value,
+ "Parameter5.Name": parameter5_name,
+ "Parameter5.Value": parameter5_value,
+ "Parameter6.Name": parameter6_name,
+ "Parameter6.Value": parameter6_value,
+ "Parameter7.Name": parameter7_name,
+ "Parameter7.Value": parameter7_value,
+ "Parameter8.Name": parameter8_name,
+ "Parameter8.Value": parameter8_value,
+ "Parameter9.Name": parameter9_name,
+ "Parameter9.Value": parameter9_value,
+ "Parameter10.Name": parameter10_name,
+ "Parameter10.Value": parameter10_value,
+ "Parameter11.Name": parameter11_name,
+ "Parameter11.Value": parameter11_value,
+ "Parameter12.Name": parameter12_name,
+ "Parameter12.Value": parameter12_value,
+ "Parameter13.Name": parameter13_name,
+ "Parameter13.Value": parameter13_value,
+ "Parameter14.Name": parameter14_name,
+ "Parameter14.Value": parameter14_value,
+ "Parameter15.Name": parameter15_name,
+ "Parameter15.Value": parameter15_value,
+ "Parameter16.Name": parameter16_name,
+ "Parameter16.Value": parameter16_value,
+ "Parameter17.Name": parameter17_name,
+ "Parameter17.Value": parameter17_value,
+ "Parameter18.Name": parameter18_name,
+ "Parameter18.Value": parameter18_value,
+ "Parameter19.Name": parameter19_name,
+ "Parameter19.Value": parameter19_value,
+ "Parameter20.Name": parameter20_name,
+ "Parameter20.Value": parameter20_value,
+ "Parameter21.Name": parameter21_name,
+ "Parameter21.Value": parameter21_value,
+ "Parameter22.Name": parameter22_name,
+ "Parameter22.Value": parameter22_value,
+ "Parameter23.Name": parameter23_name,
+ "Parameter23.Value": parameter23_value,
+ "Parameter24.Name": parameter24_name,
+ "Parameter24.Value": parameter24_value,
+ "Parameter25.Name": parameter25_name,
+ "Parameter25.Value": parameter25_value,
+ "Parameter26.Name": parameter26_name,
+ "Parameter26.Value": parameter26_value,
+ "Parameter27.Name": parameter27_name,
+ "Parameter27.Value": parameter27_value,
+ "Parameter28.Name": parameter28_name,
+ "Parameter28.Value": parameter28_value,
+ "Parameter29.Name": parameter29_name,
+ "Parameter29.Value": parameter29_value,
+ "Parameter30.Name": parameter30_name,
+ "Parameter30.Value": parameter30_value,
+ "Parameter31.Name": parameter31_name,
+ "Parameter31.Value": parameter31_value,
+ "Parameter32.Name": parameter32_name,
+ "Parameter32.Value": parameter32_value,
+ "Parameter33.Name": parameter33_name,
+ "Parameter33.Value": parameter33_value,
+ "Parameter34.Name": parameter34_name,
+ "Parameter34.Value": parameter34_value,
+ "Parameter35.Name": parameter35_name,
+ "Parameter35.Value": parameter35_value,
+ "Parameter36.Name": parameter36_name,
+ "Parameter36.Value": parameter36_value,
+ "Parameter37.Name": parameter37_name,
+ "Parameter37.Value": parameter37_value,
+ "Parameter38.Name": parameter38_name,
+ "Parameter38.Value": parameter38_value,
+ "Parameter39.Name": parameter39_name,
+ "Parameter39.Value": parameter39_value,
+ "Parameter40.Name": parameter40_name,
+ "Parameter40.Value": parameter40_value,
+ "Parameter41.Name": parameter41_name,
+ "Parameter41.Value": parameter41_value,
+ "Parameter42.Name": parameter42_name,
+ "Parameter42.Value": parameter42_value,
+ "Parameter43.Name": parameter43_name,
+ "Parameter43.Value": parameter43_value,
+ "Parameter44.Name": parameter44_name,
+ "Parameter44.Value": parameter44_value,
+ "Parameter45.Name": parameter45_name,
+ "Parameter45.Value": parameter45_value,
+ "Parameter46.Name": parameter46_name,
+ "Parameter46.Value": parameter46_value,
+ "Parameter47.Name": parameter47_name,
+ "Parameter47.Value": parameter47_value,
+ "Parameter48.Name": parameter48_name,
+ "Parameter48.Value": parameter48_value,
+ "Parameter49.Name": parameter49_name,
+ "Parameter49.Value": parameter49_value,
+ "Parameter50.Name": parameter50_name,
+ "Parameter50.Value": parameter50_value,
+ "Parameter51.Name": parameter51_name,
+ "Parameter51.Value": parameter51_value,
+ "Parameter52.Name": parameter52_name,
+ "Parameter52.Value": parameter52_value,
+ "Parameter53.Name": parameter53_name,
+ "Parameter53.Value": parameter53_value,
+ "Parameter54.Name": parameter54_name,
+ "Parameter54.Value": parameter54_value,
+ "Parameter55.Name": parameter55_name,
+ "Parameter55.Value": parameter55_value,
+ "Parameter56.Name": parameter56_name,
+ "Parameter56.Value": parameter56_value,
+ "Parameter57.Name": parameter57_name,
+ "Parameter57.Value": parameter57_value,
+ "Parameter58.Name": parameter58_name,
+ "Parameter58.Value": parameter58_value,
+ "Parameter59.Name": parameter59_name,
+ "Parameter59.Value": parameter59_value,
+ "Parameter60.Name": parameter60_name,
+ "Parameter60.Value": parameter60_value,
+ "Parameter61.Name": parameter61_name,
+ "Parameter61.Value": parameter61_value,
+ "Parameter62.Name": parameter62_name,
+ "Parameter62.Value": parameter62_value,
+ "Parameter63.Name": parameter63_name,
+ "Parameter63.Value": parameter63_value,
+ "Parameter64.Name": parameter64_name,
+ "Parameter64.Value": parameter64_value,
+ "Parameter65.Name": parameter65_name,
+ "Parameter65.Value": parameter65_value,
+ "Parameter66.Name": parameter66_name,
+ "Parameter66.Value": parameter66_value,
+ "Parameter67.Name": parameter67_name,
+ "Parameter67.Value": parameter67_value,
+ "Parameter68.Name": parameter68_name,
+ "Parameter68.Value": parameter68_value,
+ "Parameter69.Name": parameter69_name,
+ "Parameter69.Value": parameter69_value,
+ "Parameter70.Name": parameter70_name,
+ "Parameter70.Value": parameter70_value,
+ "Parameter71.Name": parameter71_name,
+ "Parameter71.Value": parameter71_value,
+ "Parameter72.Name": parameter72_name,
+ "Parameter72.Value": parameter72_value,
+ "Parameter73.Name": parameter73_name,
+ "Parameter73.Value": parameter73_value,
+ "Parameter74.Name": parameter74_name,
+ "Parameter74.Value": parameter74_value,
+ "Parameter75.Name": parameter75_name,
+ "Parameter75.Value": parameter75_value,
+ "Parameter76.Name": parameter76_name,
+ "Parameter76.Value": parameter76_value,
+ "Parameter77.Name": parameter77_name,
+ "Parameter77.Value": parameter77_value,
+ "Parameter78.Name": parameter78_name,
+ "Parameter78.Value": parameter78_value,
+ "Parameter79.Name": parameter79_name,
+ "Parameter79.Value": parameter79_value,
+ "Parameter80.Name": parameter80_name,
+ "Parameter80.Value": parameter80_value,
+ "Parameter81.Name": parameter81_name,
+ "Parameter81.Value": parameter81_value,
+ "Parameter82.Name": parameter82_name,
+ "Parameter82.Value": parameter82_value,
+ "Parameter83.Name": parameter83_name,
+ "Parameter83.Value": parameter83_value,
+ "Parameter84.Name": parameter84_name,
+ "Parameter84.Value": parameter84_value,
+ "Parameter85.Name": parameter85_name,
+ "Parameter85.Value": parameter85_value,
+ "Parameter86.Name": parameter86_name,
+ "Parameter86.Value": parameter86_value,
+ "Parameter87.Name": parameter87_name,
+ "Parameter87.Value": parameter87_value,
+ "Parameter88.Name": parameter88_name,
+ "Parameter88.Value": parameter88_value,
+ "Parameter89.Name": parameter89_name,
+ "Parameter89.Value": parameter89_value,
+ "Parameter90.Name": parameter90_name,
+ "Parameter90.Value": parameter90_value,
+ "Parameter91.Name": parameter91_name,
+ "Parameter91.Value": parameter91_value,
+ "Parameter92.Name": parameter92_name,
+ "Parameter92.Value": parameter92_value,
+ "Parameter93.Name": parameter93_name,
+ "Parameter93.Value": parameter93_value,
+ "Parameter94.Name": parameter94_name,
+ "Parameter94.Value": parameter94_value,
+ "Parameter95.Name": parameter95_name,
+ "Parameter95.Value": parameter95_value,
+ "Parameter96.Name": parameter96_name,
+ "Parameter96.Value": parameter96_value,
+ "Parameter97.Name": parameter97_name,
+ "Parameter97.Value": parameter97_value,
+ "Parameter98.Name": parameter98_name,
+ "Parameter98.Value": parameter98_value,
+ "Parameter99.Name": parameter99_name,
+ "Parameter99.Value": parameter99_value,
+ }
+ )
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.create_async(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return SiprecInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ )
+
+ def get(self, sid: str) -> SiprecContext:
+ """
+ Constructs a SiprecContext
+
+ :param sid: The SID of the Siprec resource, or the `name` used when creating the resource
+ """
+ return SiprecContext(
+ self._version,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ sid=sid,
+ )
+
+ def __call__(self, sid: str) -> SiprecContext:
+ """
+ Constructs a SiprecContext
+
+ :param sid: The SID of the Siprec resource, or the `name` used when creating the resource
+ """
+ return SiprecContext(
+ self._version,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ sid=sid,
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/stream.py b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/stream.py
new file mode 100644
index 00000000..1a506e66
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/stream.py
@@ -0,0 +1,1563 @@
+r"""
+ This code was generated by
+ ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __
+ | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/
+ | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \
+
+ Twilio - Api
+ This is the public Twilio REST API.
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ https://openapi-generator.tech
+ Do not edit the class manually.
+"""
+
+from datetime import datetime
+from typing import Any, Dict, Optional, Union
+from twilio.base import deserialize, values
+from twilio.base.instance_context import InstanceContext
+from twilio.base.instance_resource import InstanceResource
+from twilio.base.list_resource import ListResource
+from twilio.base.version import Version
+
+
+class StreamInstance(InstanceResource):
+
+ class Status(object):
+ IN_PROGRESS = "in-progress"
+ STOPPED = "stopped"
+
+ class Track(object):
+ INBOUND_TRACK = "inbound_track"
+ OUTBOUND_TRACK = "outbound_track"
+ BOTH_TRACKS = "both_tracks"
+
+ class UpdateStatus(object):
+ STOPPED = "stopped"
+
+ """
+ :ivar sid: The SID of the Stream resource.
+ :ivar account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that created this Stream resource.
+ :ivar call_sid: The SID of the [Call](https://www.twilio.com/docs/voice/api/call-resource) the Stream resource is associated with.
+ :ivar name: The user-specified name of this Stream, if one was given when the Stream was created. This can be used to stop the Stream.
+ :ivar status:
+ :ivar date_updated: The date and time in GMT that this resource was last updated, specified in [RFC 2822](https://www.ietf.org/rfc/rfc2822.txt) format.
+ :ivar uri: The URI of the resource, relative to `https://api.twilio.com`.
+ """
+
+ def __init__(
+ self,
+ version: Version,
+ payload: Dict[str, Any],
+ account_sid: str,
+ call_sid: str,
+ sid: Optional[str] = None,
+ ):
+ super().__init__(version)
+
+ self.sid: Optional[str] = payload.get("sid")
+ self.account_sid: Optional[str] = payload.get("account_sid")
+ self.call_sid: Optional[str] = payload.get("call_sid")
+ self.name: Optional[str] = payload.get("name")
+ self.status: Optional["StreamInstance.Status"] = payload.get("status")
+ self.date_updated: Optional[datetime] = deserialize.rfc2822_datetime(
+ payload.get("date_updated")
+ )
+ self.uri: Optional[str] = payload.get("uri")
+
+ self._solution = {
+ "account_sid": account_sid,
+ "call_sid": call_sid,
+ "sid": sid or self.sid,
+ }
+ self._context: Optional[StreamContext] = None
+
+ @property
+ def _proxy(self) -> "StreamContext":
+ """
+ Generate an instance context for the instance, the context is capable of
+ performing various actions. All instance actions are proxied to the context
+
+ :returns: StreamContext for this StreamInstance
+ """
+ if self._context is None:
+ self._context = StreamContext(
+ self._version,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ sid=self._solution["sid"],
+ )
+ return self._context
+
+ def update(self, status: "StreamInstance.UpdateStatus") -> "StreamInstance":
+ """
+ Update the StreamInstance
+
+ :param status:
+
+ :returns: The updated StreamInstance
+ """
+ return self._proxy.update(
+ status=status,
+ )
+
+ async def update_async(
+ self, status: "StreamInstance.UpdateStatus"
+ ) -> "StreamInstance":
+ """
+ Asynchronous coroutine to update the StreamInstance
+
+ :param status:
+
+ :returns: The updated StreamInstance
+ """
+ return await self._proxy.update_async(
+ status=status,
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(context)
+
+
+class StreamContext(InstanceContext):
+
+ def __init__(self, version: Version, account_sid: str, call_sid: str, sid: str):
+ """
+ Initialize the StreamContext
+
+ :param version: Version that contains the resource
+ :param account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that created this Stream resource.
+ :param call_sid: The SID of the [Call](https://www.twilio.com/docs/voice/api/call-resource) the Stream resource is associated with.
+ :param sid: The SID or the `name` of the Stream resource to be stopped
+ """
+ super().__init__(version)
+
+ # Path Solution
+ self._solution = {
+ "account_sid": account_sid,
+ "call_sid": call_sid,
+ "sid": sid,
+ }
+ self._uri = (
+ "/Accounts/{account_sid}/Calls/{call_sid}/Streams/{sid}.json".format(
+ **self._solution
+ )
+ )
+
+ def update(self, status: "StreamInstance.UpdateStatus") -> StreamInstance:
+ """
+ Update the StreamInstance
+
+ :param status:
+
+ :returns: The updated StreamInstance
+ """
+
+ data = values.of(
+ {
+ "Status": status,
+ }
+ )
+ headers = values.of({})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.update(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return StreamInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ sid=self._solution["sid"],
+ )
+
+ async def update_async(
+ self, status: "StreamInstance.UpdateStatus"
+ ) -> StreamInstance:
+ """
+ Asynchronous coroutine to update the StreamInstance
+
+ :param status:
+
+ :returns: The updated StreamInstance
+ """
+
+ data = values.of(
+ {
+ "Status": status,
+ }
+ )
+ headers = values.of({})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.update_async(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return StreamInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ sid=self._solution["sid"],
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(context)
+
+
+class StreamList(ListResource):
+
+ def __init__(self, version: Version, account_sid: str, call_sid: str):
+ """
+ Initialize the StreamList
+
+ :param version: Version that contains the resource
+ :param account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that created this Stream resource.
+ :param call_sid: The SID of the [Call](https://www.twilio.com/docs/voice/api/call-resource) the Stream resource is associated with.
+
+ """
+ super().__init__(version)
+
+ # Path Solution
+ self._solution = {
+ "account_sid": account_sid,
+ "call_sid": call_sid,
+ }
+ self._uri = "/Accounts/{account_sid}/Calls/{call_sid}/Streams.json".format(
+ **self._solution
+ )
+
+ def create(
+ self,
+ url: str,
+ name: Union[str, object] = values.unset,
+ track: Union["StreamInstance.Track", object] = values.unset,
+ status_callback: Union[str, object] = values.unset,
+ status_callback_method: Union[str, object] = values.unset,
+ parameter1_name: Union[str, object] = values.unset,
+ parameter1_value: Union[str, object] = values.unset,
+ parameter2_name: Union[str, object] = values.unset,
+ parameter2_value: Union[str, object] = values.unset,
+ parameter3_name: Union[str, object] = values.unset,
+ parameter3_value: Union[str, object] = values.unset,
+ parameter4_name: Union[str, object] = values.unset,
+ parameter4_value: Union[str, object] = values.unset,
+ parameter5_name: Union[str, object] = values.unset,
+ parameter5_value: Union[str, object] = values.unset,
+ parameter6_name: Union[str, object] = values.unset,
+ parameter6_value: Union[str, object] = values.unset,
+ parameter7_name: Union[str, object] = values.unset,
+ parameter7_value: Union[str, object] = values.unset,
+ parameter8_name: Union[str, object] = values.unset,
+ parameter8_value: Union[str, object] = values.unset,
+ parameter9_name: Union[str, object] = values.unset,
+ parameter9_value: Union[str, object] = values.unset,
+ parameter10_name: Union[str, object] = values.unset,
+ parameter10_value: Union[str, object] = values.unset,
+ parameter11_name: Union[str, object] = values.unset,
+ parameter11_value: Union[str, object] = values.unset,
+ parameter12_name: Union[str, object] = values.unset,
+ parameter12_value: Union[str, object] = values.unset,
+ parameter13_name: Union[str, object] = values.unset,
+ parameter13_value: Union[str, object] = values.unset,
+ parameter14_name: Union[str, object] = values.unset,
+ parameter14_value: Union[str, object] = values.unset,
+ parameter15_name: Union[str, object] = values.unset,
+ parameter15_value: Union[str, object] = values.unset,
+ parameter16_name: Union[str, object] = values.unset,
+ parameter16_value: Union[str, object] = values.unset,
+ parameter17_name: Union[str, object] = values.unset,
+ parameter17_value: Union[str, object] = values.unset,
+ parameter18_name: Union[str, object] = values.unset,
+ parameter18_value: Union[str, object] = values.unset,
+ parameter19_name: Union[str, object] = values.unset,
+ parameter19_value: Union[str, object] = values.unset,
+ parameter20_name: Union[str, object] = values.unset,
+ parameter20_value: Union[str, object] = values.unset,
+ parameter21_name: Union[str, object] = values.unset,
+ parameter21_value: Union[str, object] = values.unset,
+ parameter22_name: Union[str, object] = values.unset,
+ parameter22_value: Union[str, object] = values.unset,
+ parameter23_name: Union[str, object] = values.unset,
+ parameter23_value: Union[str, object] = values.unset,
+ parameter24_name: Union[str, object] = values.unset,
+ parameter24_value: Union[str, object] = values.unset,
+ parameter25_name: Union[str, object] = values.unset,
+ parameter25_value: Union[str, object] = values.unset,
+ parameter26_name: Union[str, object] = values.unset,
+ parameter26_value: Union[str, object] = values.unset,
+ parameter27_name: Union[str, object] = values.unset,
+ parameter27_value: Union[str, object] = values.unset,
+ parameter28_name: Union[str, object] = values.unset,
+ parameter28_value: Union[str, object] = values.unset,
+ parameter29_name: Union[str, object] = values.unset,
+ parameter29_value: Union[str, object] = values.unset,
+ parameter30_name: Union[str, object] = values.unset,
+ parameter30_value: Union[str, object] = values.unset,
+ parameter31_name: Union[str, object] = values.unset,
+ parameter31_value: Union[str, object] = values.unset,
+ parameter32_name: Union[str, object] = values.unset,
+ parameter32_value: Union[str, object] = values.unset,
+ parameter33_name: Union[str, object] = values.unset,
+ parameter33_value: Union[str, object] = values.unset,
+ parameter34_name: Union[str, object] = values.unset,
+ parameter34_value: Union[str, object] = values.unset,
+ parameter35_name: Union[str, object] = values.unset,
+ parameter35_value: Union[str, object] = values.unset,
+ parameter36_name: Union[str, object] = values.unset,
+ parameter36_value: Union[str, object] = values.unset,
+ parameter37_name: Union[str, object] = values.unset,
+ parameter37_value: Union[str, object] = values.unset,
+ parameter38_name: Union[str, object] = values.unset,
+ parameter38_value: Union[str, object] = values.unset,
+ parameter39_name: Union[str, object] = values.unset,
+ parameter39_value: Union[str, object] = values.unset,
+ parameter40_name: Union[str, object] = values.unset,
+ parameter40_value: Union[str, object] = values.unset,
+ parameter41_name: Union[str, object] = values.unset,
+ parameter41_value: Union[str, object] = values.unset,
+ parameter42_name: Union[str, object] = values.unset,
+ parameter42_value: Union[str, object] = values.unset,
+ parameter43_name: Union[str, object] = values.unset,
+ parameter43_value: Union[str, object] = values.unset,
+ parameter44_name: Union[str, object] = values.unset,
+ parameter44_value: Union[str, object] = values.unset,
+ parameter45_name: Union[str, object] = values.unset,
+ parameter45_value: Union[str, object] = values.unset,
+ parameter46_name: Union[str, object] = values.unset,
+ parameter46_value: Union[str, object] = values.unset,
+ parameter47_name: Union[str, object] = values.unset,
+ parameter47_value: Union[str, object] = values.unset,
+ parameter48_name: Union[str, object] = values.unset,
+ parameter48_value: Union[str, object] = values.unset,
+ parameter49_name: Union[str, object] = values.unset,
+ parameter49_value: Union[str, object] = values.unset,
+ parameter50_name: Union[str, object] = values.unset,
+ parameter50_value: Union[str, object] = values.unset,
+ parameter51_name: Union[str, object] = values.unset,
+ parameter51_value: Union[str, object] = values.unset,
+ parameter52_name: Union[str, object] = values.unset,
+ parameter52_value: Union[str, object] = values.unset,
+ parameter53_name: Union[str, object] = values.unset,
+ parameter53_value: Union[str, object] = values.unset,
+ parameter54_name: Union[str, object] = values.unset,
+ parameter54_value: Union[str, object] = values.unset,
+ parameter55_name: Union[str, object] = values.unset,
+ parameter55_value: Union[str, object] = values.unset,
+ parameter56_name: Union[str, object] = values.unset,
+ parameter56_value: Union[str, object] = values.unset,
+ parameter57_name: Union[str, object] = values.unset,
+ parameter57_value: Union[str, object] = values.unset,
+ parameter58_name: Union[str, object] = values.unset,
+ parameter58_value: Union[str, object] = values.unset,
+ parameter59_name: Union[str, object] = values.unset,
+ parameter59_value: Union[str, object] = values.unset,
+ parameter60_name: Union[str, object] = values.unset,
+ parameter60_value: Union[str, object] = values.unset,
+ parameter61_name: Union[str, object] = values.unset,
+ parameter61_value: Union[str, object] = values.unset,
+ parameter62_name: Union[str, object] = values.unset,
+ parameter62_value: Union[str, object] = values.unset,
+ parameter63_name: Union[str, object] = values.unset,
+ parameter63_value: Union[str, object] = values.unset,
+ parameter64_name: Union[str, object] = values.unset,
+ parameter64_value: Union[str, object] = values.unset,
+ parameter65_name: Union[str, object] = values.unset,
+ parameter65_value: Union[str, object] = values.unset,
+ parameter66_name: Union[str, object] = values.unset,
+ parameter66_value: Union[str, object] = values.unset,
+ parameter67_name: Union[str, object] = values.unset,
+ parameter67_value: Union[str, object] = values.unset,
+ parameter68_name: Union[str, object] = values.unset,
+ parameter68_value: Union[str, object] = values.unset,
+ parameter69_name: Union[str, object] = values.unset,
+ parameter69_value: Union[str, object] = values.unset,
+ parameter70_name: Union[str, object] = values.unset,
+ parameter70_value: Union[str, object] = values.unset,
+ parameter71_name: Union[str, object] = values.unset,
+ parameter71_value: Union[str, object] = values.unset,
+ parameter72_name: Union[str, object] = values.unset,
+ parameter72_value: Union[str, object] = values.unset,
+ parameter73_name: Union[str, object] = values.unset,
+ parameter73_value: Union[str, object] = values.unset,
+ parameter74_name: Union[str, object] = values.unset,
+ parameter74_value: Union[str, object] = values.unset,
+ parameter75_name: Union[str, object] = values.unset,
+ parameter75_value: Union[str, object] = values.unset,
+ parameter76_name: Union[str, object] = values.unset,
+ parameter76_value: Union[str, object] = values.unset,
+ parameter77_name: Union[str, object] = values.unset,
+ parameter77_value: Union[str, object] = values.unset,
+ parameter78_name: Union[str, object] = values.unset,
+ parameter78_value: Union[str, object] = values.unset,
+ parameter79_name: Union[str, object] = values.unset,
+ parameter79_value: Union[str, object] = values.unset,
+ parameter80_name: Union[str, object] = values.unset,
+ parameter80_value: Union[str, object] = values.unset,
+ parameter81_name: Union[str, object] = values.unset,
+ parameter81_value: Union[str, object] = values.unset,
+ parameter82_name: Union[str, object] = values.unset,
+ parameter82_value: Union[str, object] = values.unset,
+ parameter83_name: Union[str, object] = values.unset,
+ parameter83_value: Union[str, object] = values.unset,
+ parameter84_name: Union[str, object] = values.unset,
+ parameter84_value: Union[str, object] = values.unset,
+ parameter85_name: Union[str, object] = values.unset,
+ parameter85_value: Union[str, object] = values.unset,
+ parameter86_name: Union[str, object] = values.unset,
+ parameter86_value: Union[str, object] = values.unset,
+ parameter87_name: Union[str, object] = values.unset,
+ parameter87_value: Union[str, object] = values.unset,
+ parameter88_name: Union[str, object] = values.unset,
+ parameter88_value: Union[str, object] = values.unset,
+ parameter89_name: Union[str, object] = values.unset,
+ parameter89_value: Union[str, object] = values.unset,
+ parameter90_name: Union[str, object] = values.unset,
+ parameter90_value: Union[str, object] = values.unset,
+ parameter91_name: Union[str, object] = values.unset,
+ parameter91_value: Union[str, object] = values.unset,
+ parameter92_name: Union[str, object] = values.unset,
+ parameter92_value: Union[str, object] = values.unset,
+ parameter93_name: Union[str, object] = values.unset,
+ parameter93_value: Union[str, object] = values.unset,
+ parameter94_name: Union[str, object] = values.unset,
+ parameter94_value: Union[str, object] = values.unset,
+ parameter95_name: Union[str, object] = values.unset,
+ parameter95_value: Union[str, object] = values.unset,
+ parameter96_name: Union[str, object] = values.unset,
+ parameter96_value: Union[str, object] = values.unset,
+ parameter97_name: Union[str, object] = values.unset,
+ parameter97_value: Union[str, object] = values.unset,
+ parameter98_name: Union[str, object] = values.unset,
+ parameter98_value: Union[str, object] = values.unset,
+ parameter99_name: Union[str, object] = values.unset,
+ parameter99_value: Union[str, object] = values.unset,
+ ) -> StreamInstance:
+ """
+ Create the StreamInstance
+
+ :param url: Relative or absolute URL where WebSocket connection will be established.
+ :param name: The user-specified name of this Stream, if one was given when the Stream was created. This can be used to stop the Stream.
+ :param track:
+ :param status_callback: Absolute URL to which Twilio sends status callback HTTP requests.
+ :param status_callback_method: The HTTP method Twilio uses when sending `status_callback` requests. Possible values are `GET` and `POST`. Default is `POST`.
+ :param parameter1_name: Parameter name
+ :param parameter1_value: Parameter value
+ :param parameter2_name: Parameter name
+ :param parameter2_value: Parameter value
+ :param parameter3_name: Parameter name
+ :param parameter3_value: Parameter value
+ :param parameter4_name: Parameter name
+ :param parameter4_value: Parameter value
+ :param parameter5_name: Parameter name
+ :param parameter5_value: Parameter value
+ :param parameter6_name: Parameter name
+ :param parameter6_value: Parameter value
+ :param parameter7_name: Parameter name
+ :param parameter7_value: Parameter value
+ :param parameter8_name: Parameter name
+ :param parameter8_value: Parameter value
+ :param parameter9_name: Parameter name
+ :param parameter9_value: Parameter value
+ :param parameter10_name: Parameter name
+ :param parameter10_value: Parameter value
+ :param parameter11_name: Parameter name
+ :param parameter11_value: Parameter value
+ :param parameter12_name: Parameter name
+ :param parameter12_value: Parameter value
+ :param parameter13_name: Parameter name
+ :param parameter13_value: Parameter value
+ :param parameter14_name: Parameter name
+ :param parameter14_value: Parameter value
+ :param parameter15_name: Parameter name
+ :param parameter15_value: Parameter value
+ :param parameter16_name: Parameter name
+ :param parameter16_value: Parameter value
+ :param parameter17_name: Parameter name
+ :param parameter17_value: Parameter value
+ :param parameter18_name: Parameter name
+ :param parameter18_value: Parameter value
+ :param parameter19_name: Parameter name
+ :param parameter19_value: Parameter value
+ :param parameter20_name: Parameter name
+ :param parameter20_value: Parameter value
+ :param parameter21_name: Parameter name
+ :param parameter21_value: Parameter value
+ :param parameter22_name: Parameter name
+ :param parameter22_value: Parameter value
+ :param parameter23_name: Parameter name
+ :param parameter23_value: Parameter value
+ :param parameter24_name: Parameter name
+ :param parameter24_value: Parameter value
+ :param parameter25_name: Parameter name
+ :param parameter25_value: Parameter value
+ :param parameter26_name: Parameter name
+ :param parameter26_value: Parameter value
+ :param parameter27_name: Parameter name
+ :param parameter27_value: Parameter value
+ :param parameter28_name: Parameter name
+ :param parameter28_value: Parameter value
+ :param parameter29_name: Parameter name
+ :param parameter29_value: Parameter value
+ :param parameter30_name: Parameter name
+ :param parameter30_value: Parameter value
+ :param parameter31_name: Parameter name
+ :param parameter31_value: Parameter value
+ :param parameter32_name: Parameter name
+ :param parameter32_value: Parameter value
+ :param parameter33_name: Parameter name
+ :param parameter33_value: Parameter value
+ :param parameter34_name: Parameter name
+ :param parameter34_value: Parameter value
+ :param parameter35_name: Parameter name
+ :param parameter35_value: Parameter value
+ :param parameter36_name: Parameter name
+ :param parameter36_value: Parameter value
+ :param parameter37_name: Parameter name
+ :param parameter37_value: Parameter value
+ :param parameter38_name: Parameter name
+ :param parameter38_value: Parameter value
+ :param parameter39_name: Parameter name
+ :param parameter39_value: Parameter value
+ :param parameter40_name: Parameter name
+ :param parameter40_value: Parameter value
+ :param parameter41_name: Parameter name
+ :param parameter41_value: Parameter value
+ :param parameter42_name: Parameter name
+ :param parameter42_value: Parameter value
+ :param parameter43_name: Parameter name
+ :param parameter43_value: Parameter value
+ :param parameter44_name: Parameter name
+ :param parameter44_value: Parameter value
+ :param parameter45_name: Parameter name
+ :param parameter45_value: Parameter value
+ :param parameter46_name: Parameter name
+ :param parameter46_value: Parameter value
+ :param parameter47_name: Parameter name
+ :param parameter47_value: Parameter value
+ :param parameter48_name: Parameter name
+ :param parameter48_value: Parameter value
+ :param parameter49_name: Parameter name
+ :param parameter49_value: Parameter value
+ :param parameter50_name: Parameter name
+ :param parameter50_value: Parameter value
+ :param parameter51_name: Parameter name
+ :param parameter51_value: Parameter value
+ :param parameter52_name: Parameter name
+ :param parameter52_value: Parameter value
+ :param parameter53_name: Parameter name
+ :param parameter53_value: Parameter value
+ :param parameter54_name: Parameter name
+ :param parameter54_value: Parameter value
+ :param parameter55_name: Parameter name
+ :param parameter55_value: Parameter value
+ :param parameter56_name: Parameter name
+ :param parameter56_value: Parameter value
+ :param parameter57_name: Parameter name
+ :param parameter57_value: Parameter value
+ :param parameter58_name: Parameter name
+ :param parameter58_value: Parameter value
+ :param parameter59_name: Parameter name
+ :param parameter59_value: Parameter value
+ :param parameter60_name: Parameter name
+ :param parameter60_value: Parameter value
+ :param parameter61_name: Parameter name
+ :param parameter61_value: Parameter value
+ :param parameter62_name: Parameter name
+ :param parameter62_value: Parameter value
+ :param parameter63_name: Parameter name
+ :param parameter63_value: Parameter value
+ :param parameter64_name: Parameter name
+ :param parameter64_value: Parameter value
+ :param parameter65_name: Parameter name
+ :param parameter65_value: Parameter value
+ :param parameter66_name: Parameter name
+ :param parameter66_value: Parameter value
+ :param parameter67_name: Parameter name
+ :param parameter67_value: Parameter value
+ :param parameter68_name: Parameter name
+ :param parameter68_value: Parameter value
+ :param parameter69_name: Parameter name
+ :param parameter69_value: Parameter value
+ :param parameter70_name: Parameter name
+ :param parameter70_value: Parameter value
+ :param parameter71_name: Parameter name
+ :param parameter71_value: Parameter value
+ :param parameter72_name: Parameter name
+ :param parameter72_value: Parameter value
+ :param parameter73_name: Parameter name
+ :param parameter73_value: Parameter value
+ :param parameter74_name: Parameter name
+ :param parameter74_value: Parameter value
+ :param parameter75_name: Parameter name
+ :param parameter75_value: Parameter value
+ :param parameter76_name: Parameter name
+ :param parameter76_value: Parameter value
+ :param parameter77_name: Parameter name
+ :param parameter77_value: Parameter value
+ :param parameter78_name: Parameter name
+ :param parameter78_value: Parameter value
+ :param parameter79_name: Parameter name
+ :param parameter79_value: Parameter value
+ :param parameter80_name: Parameter name
+ :param parameter80_value: Parameter value
+ :param parameter81_name: Parameter name
+ :param parameter81_value: Parameter value
+ :param parameter82_name: Parameter name
+ :param parameter82_value: Parameter value
+ :param parameter83_name: Parameter name
+ :param parameter83_value: Parameter value
+ :param parameter84_name: Parameter name
+ :param parameter84_value: Parameter value
+ :param parameter85_name: Parameter name
+ :param parameter85_value: Parameter value
+ :param parameter86_name: Parameter name
+ :param parameter86_value: Parameter value
+ :param parameter87_name: Parameter name
+ :param parameter87_value: Parameter value
+ :param parameter88_name: Parameter name
+ :param parameter88_value: Parameter value
+ :param parameter89_name: Parameter name
+ :param parameter89_value: Parameter value
+ :param parameter90_name: Parameter name
+ :param parameter90_value: Parameter value
+ :param parameter91_name: Parameter name
+ :param parameter91_value: Parameter value
+ :param parameter92_name: Parameter name
+ :param parameter92_value: Parameter value
+ :param parameter93_name: Parameter name
+ :param parameter93_value: Parameter value
+ :param parameter94_name: Parameter name
+ :param parameter94_value: Parameter value
+ :param parameter95_name: Parameter name
+ :param parameter95_value: Parameter value
+ :param parameter96_name: Parameter name
+ :param parameter96_value: Parameter value
+ :param parameter97_name: Parameter name
+ :param parameter97_value: Parameter value
+ :param parameter98_name: Parameter name
+ :param parameter98_value: Parameter value
+ :param parameter99_name: Parameter name
+ :param parameter99_value: Parameter value
+
+ :returns: The created StreamInstance
+ """
+
+ data = values.of(
+ {
+ "Url": url,
+ "Name": name,
+ "Track": track,
+ "StatusCallback": status_callback,
+ "StatusCallbackMethod": status_callback_method,
+ "Parameter1.Name": parameter1_name,
+ "Parameter1.Value": parameter1_value,
+ "Parameter2.Name": parameter2_name,
+ "Parameter2.Value": parameter2_value,
+ "Parameter3.Name": parameter3_name,
+ "Parameter3.Value": parameter3_value,
+ "Parameter4.Name": parameter4_name,
+ "Parameter4.Value": parameter4_value,
+ "Parameter5.Name": parameter5_name,
+ "Parameter5.Value": parameter5_value,
+ "Parameter6.Name": parameter6_name,
+ "Parameter6.Value": parameter6_value,
+ "Parameter7.Name": parameter7_name,
+ "Parameter7.Value": parameter7_value,
+ "Parameter8.Name": parameter8_name,
+ "Parameter8.Value": parameter8_value,
+ "Parameter9.Name": parameter9_name,
+ "Parameter9.Value": parameter9_value,
+ "Parameter10.Name": parameter10_name,
+ "Parameter10.Value": parameter10_value,
+ "Parameter11.Name": parameter11_name,
+ "Parameter11.Value": parameter11_value,
+ "Parameter12.Name": parameter12_name,
+ "Parameter12.Value": parameter12_value,
+ "Parameter13.Name": parameter13_name,
+ "Parameter13.Value": parameter13_value,
+ "Parameter14.Name": parameter14_name,
+ "Parameter14.Value": parameter14_value,
+ "Parameter15.Name": parameter15_name,
+ "Parameter15.Value": parameter15_value,
+ "Parameter16.Name": parameter16_name,
+ "Parameter16.Value": parameter16_value,
+ "Parameter17.Name": parameter17_name,
+ "Parameter17.Value": parameter17_value,
+ "Parameter18.Name": parameter18_name,
+ "Parameter18.Value": parameter18_value,
+ "Parameter19.Name": parameter19_name,
+ "Parameter19.Value": parameter19_value,
+ "Parameter20.Name": parameter20_name,
+ "Parameter20.Value": parameter20_value,
+ "Parameter21.Name": parameter21_name,
+ "Parameter21.Value": parameter21_value,
+ "Parameter22.Name": parameter22_name,
+ "Parameter22.Value": parameter22_value,
+ "Parameter23.Name": parameter23_name,
+ "Parameter23.Value": parameter23_value,
+ "Parameter24.Name": parameter24_name,
+ "Parameter24.Value": parameter24_value,
+ "Parameter25.Name": parameter25_name,
+ "Parameter25.Value": parameter25_value,
+ "Parameter26.Name": parameter26_name,
+ "Parameter26.Value": parameter26_value,
+ "Parameter27.Name": parameter27_name,
+ "Parameter27.Value": parameter27_value,
+ "Parameter28.Name": parameter28_name,
+ "Parameter28.Value": parameter28_value,
+ "Parameter29.Name": parameter29_name,
+ "Parameter29.Value": parameter29_value,
+ "Parameter30.Name": parameter30_name,
+ "Parameter30.Value": parameter30_value,
+ "Parameter31.Name": parameter31_name,
+ "Parameter31.Value": parameter31_value,
+ "Parameter32.Name": parameter32_name,
+ "Parameter32.Value": parameter32_value,
+ "Parameter33.Name": parameter33_name,
+ "Parameter33.Value": parameter33_value,
+ "Parameter34.Name": parameter34_name,
+ "Parameter34.Value": parameter34_value,
+ "Parameter35.Name": parameter35_name,
+ "Parameter35.Value": parameter35_value,
+ "Parameter36.Name": parameter36_name,
+ "Parameter36.Value": parameter36_value,
+ "Parameter37.Name": parameter37_name,
+ "Parameter37.Value": parameter37_value,
+ "Parameter38.Name": parameter38_name,
+ "Parameter38.Value": parameter38_value,
+ "Parameter39.Name": parameter39_name,
+ "Parameter39.Value": parameter39_value,
+ "Parameter40.Name": parameter40_name,
+ "Parameter40.Value": parameter40_value,
+ "Parameter41.Name": parameter41_name,
+ "Parameter41.Value": parameter41_value,
+ "Parameter42.Name": parameter42_name,
+ "Parameter42.Value": parameter42_value,
+ "Parameter43.Name": parameter43_name,
+ "Parameter43.Value": parameter43_value,
+ "Parameter44.Name": parameter44_name,
+ "Parameter44.Value": parameter44_value,
+ "Parameter45.Name": parameter45_name,
+ "Parameter45.Value": parameter45_value,
+ "Parameter46.Name": parameter46_name,
+ "Parameter46.Value": parameter46_value,
+ "Parameter47.Name": parameter47_name,
+ "Parameter47.Value": parameter47_value,
+ "Parameter48.Name": parameter48_name,
+ "Parameter48.Value": parameter48_value,
+ "Parameter49.Name": parameter49_name,
+ "Parameter49.Value": parameter49_value,
+ "Parameter50.Name": parameter50_name,
+ "Parameter50.Value": parameter50_value,
+ "Parameter51.Name": parameter51_name,
+ "Parameter51.Value": parameter51_value,
+ "Parameter52.Name": parameter52_name,
+ "Parameter52.Value": parameter52_value,
+ "Parameter53.Name": parameter53_name,
+ "Parameter53.Value": parameter53_value,
+ "Parameter54.Name": parameter54_name,
+ "Parameter54.Value": parameter54_value,
+ "Parameter55.Name": parameter55_name,
+ "Parameter55.Value": parameter55_value,
+ "Parameter56.Name": parameter56_name,
+ "Parameter56.Value": parameter56_value,
+ "Parameter57.Name": parameter57_name,
+ "Parameter57.Value": parameter57_value,
+ "Parameter58.Name": parameter58_name,
+ "Parameter58.Value": parameter58_value,
+ "Parameter59.Name": parameter59_name,
+ "Parameter59.Value": parameter59_value,
+ "Parameter60.Name": parameter60_name,
+ "Parameter60.Value": parameter60_value,
+ "Parameter61.Name": parameter61_name,
+ "Parameter61.Value": parameter61_value,
+ "Parameter62.Name": parameter62_name,
+ "Parameter62.Value": parameter62_value,
+ "Parameter63.Name": parameter63_name,
+ "Parameter63.Value": parameter63_value,
+ "Parameter64.Name": parameter64_name,
+ "Parameter64.Value": parameter64_value,
+ "Parameter65.Name": parameter65_name,
+ "Parameter65.Value": parameter65_value,
+ "Parameter66.Name": parameter66_name,
+ "Parameter66.Value": parameter66_value,
+ "Parameter67.Name": parameter67_name,
+ "Parameter67.Value": parameter67_value,
+ "Parameter68.Name": parameter68_name,
+ "Parameter68.Value": parameter68_value,
+ "Parameter69.Name": parameter69_name,
+ "Parameter69.Value": parameter69_value,
+ "Parameter70.Name": parameter70_name,
+ "Parameter70.Value": parameter70_value,
+ "Parameter71.Name": parameter71_name,
+ "Parameter71.Value": parameter71_value,
+ "Parameter72.Name": parameter72_name,
+ "Parameter72.Value": parameter72_value,
+ "Parameter73.Name": parameter73_name,
+ "Parameter73.Value": parameter73_value,
+ "Parameter74.Name": parameter74_name,
+ "Parameter74.Value": parameter74_value,
+ "Parameter75.Name": parameter75_name,
+ "Parameter75.Value": parameter75_value,
+ "Parameter76.Name": parameter76_name,
+ "Parameter76.Value": parameter76_value,
+ "Parameter77.Name": parameter77_name,
+ "Parameter77.Value": parameter77_value,
+ "Parameter78.Name": parameter78_name,
+ "Parameter78.Value": parameter78_value,
+ "Parameter79.Name": parameter79_name,
+ "Parameter79.Value": parameter79_value,
+ "Parameter80.Name": parameter80_name,
+ "Parameter80.Value": parameter80_value,
+ "Parameter81.Name": parameter81_name,
+ "Parameter81.Value": parameter81_value,
+ "Parameter82.Name": parameter82_name,
+ "Parameter82.Value": parameter82_value,
+ "Parameter83.Name": parameter83_name,
+ "Parameter83.Value": parameter83_value,
+ "Parameter84.Name": parameter84_name,
+ "Parameter84.Value": parameter84_value,
+ "Parameter85.Name": parameter85_name,
+ "Parameter85.Value": parameter85_value,
+ "Parameter86.Name": parameter86_name,
+ "Parameter86.Value": parameter86_value,
+ "Parameter87.Name": parameter87_name,
+ "Parameter87.Value": parameter87_value,
+ "Parameter88.Name": parameter88_name,
+ "Parameter88.Value": parameter88_value,
+ "Parameter89.Name": parameter89_name,
+ "Parameter89.Value": parameter89_value,
+ "Parameter90.Name": parameter90_name,
+ "Parameter90.Value": parameter90_value,
+ "Parameter91.Name": parameter91_name,
+ "Parameter91.Value": parameter91_value,
+ "Parameter92.Name": parameter92_name,
+ "Parameter92.Value": parameter92_value,
+ "Parameter93.Name": parameter93_name,
+ "Parameter93.Value": parameter93_value,
+ "Parameter94.Name": parameter94_name,
+ "Parameter94.Value": parameter94_value,
+ "Parameter95.Name": parameter95_name,
+ "Parameter95.Value": parameter95_value,
+ "Parameter96.Name": parameter96_name,
+ "Parameter96.Value": parameter96_value,
+ "Parameter97.Name": parameter97_name,
+ "Parameter97.Value": parameter97_value,
+ "Parameter98.Name": parameter98_name,
+ "Parameter98.Value": parameter98_value,
+ "Parameter99.Name": parameter99_name,
+ "Parameter99.Value": parameter99_value,
+ }
+ )
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.create(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return StreamInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ )
+
+ async def create_async(
+ self,
+ url: str,
+ name: Union[str, object] = values.unset,
+ track: Union["StreamInstance.Track", object] = values.unset,
+ status_callback: Union[str, object] = values.unset,
+ status_callback_method: Union[str, object] = values.unset,
+ parameter1_name: Union[str, object] = values.unset,
+ parameter1_value: Union[str, object] = values.unset,
+ parameter2_name: Union[str, object] = values.unset,
+ parameter2_value: Union[str, object] = values.unset,
+ parameter3_name: Union[str, object] = values.unset,
+ parameter3_value: Union[str, object] = values.unset,
+ parameter4_name: Union[str, object] = values.unset,
+ parameter4_value: Union[str, object] = values.unset,
+ parameter5_name: Union[str, object] = values.unset,
+ parameter5_value: Union[str, object] = values.unset,
+ parameter6_name: Union[str, object] = values.unset,
+ parameter6_value: Union[str, object] = values.unset,
+ parameter7_name: Union[str, object] = values.unset,
+ parameter7_value: Union[str, object] = values.unset,
+ parameter8_name: Union[str, object] = values.unset,
+ parameter8_value: Union[str, object] = values.unset,
+ parameter9_name: Union[str, object] = values.unset,
+ parameter9_value: Union[str, object] = values.unset,
+ parameter10_name: Union[str, object] = values.unset,
+ parameter10_value: Union[str, object] = values.unset,
+ parameter11_name: Union[str, object] = values.unset,
+ parameter11_value: Union[str, object] = values.unset,
+ parameter12_name: Union[str, object] = values.unset,
+ parameter12_value: Union[str, object] = values.unset,
+ parameter13_name: Union[str, object] = values.unset,
+ parameter13_value: Union[str, object] = values.unset,
+ parameter14_name: Union[str, object] = values.unset,
+ parameter14_value: Union[str, object] = values.unset,
+ parameter15_name: Union[str, object] = values.unset,
+ parameter15_value: Union[str, object] = values.unset,
+ parameter16_name: Union[str, object] = values.unset,
+ parameter16_value: Union[str, object] = values.unset,
+ parameter17_name: Union[str, object] = values.unset,
+ parameter17_value: Union[str, object] = values.unset,
+ parameter18_name: Union[str, object] = values.unset,
+ parameter18_value: Union[str, object] = values.unset,
+ parameter19_name: Union[str, object] = values.unset,
+ parameter19_value: Union[str, object] = values.unset,
+ parameter20_name: Union[str, object] = values.unset,
+ parameter20_value: Union[str, object] = values.unset,
+ parameter21_name: Union[str, object] = values.unset,
+ parameter21_value: Union[str, object] = values.unset,
+ parameter22_name: Union[str, object] = values.unset,
+ parameter22_value: Union[str, object] = values.unset,
+ parameter23_name: Union[str, object] = values.unset,
+ parameter23_value: Union[str, object] = values.unset,
+ parameter24_name: Union[str, object] = values.unset,
+ parameter24_value: Union[str, object] = values.unset,
+ parameter25_name: Union[str, object] = values.unset,
+ parameter25_value: Union[str, object] = values.unset,
+ parameter26_name: Union[str, object] = values.unset,
+ parameter26_value: Union[str, object] = values.unset,
+ parameter27_name: Union[str, object] = values.unset,
+ parameter27_value: Union[str, object] = values.unset,
+ parameter28_name: Union[str, object] = values.unset,
+ parameter28_value: Union[str, object] = values.unset,
+ parameter29_name: Union[str, object] = values.unset,
+ parameter29_value: Union[str, object] = values.unset,
+ parameter30_name: Union[str, object] = values.unset,
+ parameter30_value: Union[str, object] = values.unset,
+ parameter31_name: Union[str, object] = values.unset,
+ parameter31_value: Union[str, object] = values.unset,
+ parameter32_name: Union[str, object] = values.unset,
+ parameter32_value: Union[str, object] = values.unset,
+ parameter33_name: Union[str, object] = values.unset,
+ parameter33_value: Union[str, object] = values.unset,
+ parameter34_name: Union[str, object] = values.unset,
+ parameter34_value: Union[str, object] = values.unset,
+ parameter35_name: Union[str, object] = values.unset,
+ parameter35_value: Union[str, object] = values.unset,
+ parameter36_name: Union[str, object] = values.unset,
+ parameter36_value: Union[str, object] = values.unset,
+ parameter37_name: Union[str, object] = values.unset,
+ parameter37_value: Union[str, object] = values.unset,
+ parameter38_name: Union[str, object] = values.unset,
+ parameter38_value: Union[str, object] = values.unset,
+ parameter39_name: Union[str, object] = values.unset,
+ parameter39_value: Union[str, object] = values.unset,
+ parameter40_name: Union[str, object] = values.unset,
+ parameter40_value: Union[str, object] = values.unset,
+ parameter41_name: Union[str, object] = values.unset,
+ parameter41_value: Union[str, object] = values.unset,
+ parameter42_name: Union[str, object] = values.unset,
+ parameter42_value: Union[str, object] = values.unset,
+ parameter43_name: Union[str, object] = values.unset,
+ parameter43_value: Union[str, object] = values.unset,
+ parameter44_name: Union[str, object] = values.unset,
+ parameter44_value: Union[str, object] = values.unset,
+ parameter45_name: Union[str, object] = values.unset,
+ parameter45_value: Union[str, object] = values.unset,
+ parameter46_name: Union[str, object] = values.unset,
+ parameter46_value: Union[str, object] = values.unset,
+ parameter47_name: Union[str, object] = values.unset,
+ parameter47_value: Union[str, object] = values.unset,
+ parameter48_name: Union[str, object] = values.unset,
+ parameter48_value: Union[str, object] = values.unset,
+ parameter49_name: Union[str, object] = values.unset,
+ parameter49_value: Union[str, object] = values.unset,
+ parameter50_name: Union[str, object] = values.unset,
+ parameter50_value: Union[str, object] = values.unset,
+ parameter51_name: Union[str, object] = values.unset,
+ parameter51_value: Union[str, object] = values.unset,
+ parameter52_name: Union[str, object] = values.unset,
+ parameter52_value: Union[str, object] = values.unset,
+ parameter53_name: Union[str, object] = values.unset,
+ parameter53_value: Union[str, object] = values.unset,
+ parameter54_name: Union[str, object] = values.unset,
+ parameter54_value: Union[str, object] = values.unset,
+ parameter55_name: Union[str, object] = values.unset,
+ parameter55_value: Union[str, object] = values.unset,
+ parameter56_name: Union[str, object] = values.unset,
+ parameter56_value: Union[str, object] = values.unset,
+ parameter57_name: Union[str, object] = values.unset,
+ parameter57_value: Union[str, object] = values.unset,
+ parameter58_name: Union[str, object] = values.unset,
+ parameter58_value: Union[str, object] = values.unset,
+ parameter59_name: Union[str, object] = values.unset,
+ parameter59_value: Union[str, object] = values.unset,
+ parameter60_name: Union[str, object] = values.unset,
+ parameter60_value: Union[str, object] = values.unset,
+ parameter61_name: Union[str, object] = values.unset,
+ parameter61_value: Union[str, object] = values.unset,
+ parameter62_name: Union[str, object] = values.unset,
+ parameter62_value: Union[str, object] = values.unset,
+ parameter63_name: Union[str, object] = values.unset,
+ parameter63_value: Union[str, object] = values.unset,
+ parameter64_name: Union[str, object] = values.unset,
+ parameter64_value: Union[str, object] = values.unset,
+ parameter65_name: Union[str, object] = values.unset,
+ parameter65_value: Union[str, object] = values.unset,
+ parameter66_name: Union[str, object] = values.unset,
+ parameter66_value: Union[str, object] = values.unset,
+ parameter67_name: Union[str, object] = values.unset,
+ parameter67_value: Union[str, object] = values.unset,
+ parameter68_name: Union[str, object] = values.unset,
+ parameter68_value: Union[str, object] = values.unset,
+ parameter69_name: Union[str, object] = values.unset,
+ parameter69_value: Union[str, object] = values.unset,
+ parameter70_name: Union[str, object] = values.unset,
+ parameter70_value: Union[str, object] = values.unset,
+ parameter71_name: Union[str, object] = values.unset,
+ parameter71_value: Union[str, object] = values.unset,
+ parameter72_name: Union[str, object] = values.unset,
+ parameter72_value: Union[str, object] = values.unset,
+ parameter73_name: Union[str, object] = values.unset,
+ parameter73_value: Union[str, object] = values.unset,
+ parameter74_name: Union[str, object] = values.unset,
+ parameter74_value: Union[str, object] = values.unset,
+ parameter75_name: Union[str, object] = values.unset,
+ parameter75_value: Union[str, object] = values.unset,
+ parameter76_name: Union[str, object] = values.unset,
+ parameter76_value: Union[str, object] = values.unset,
+ parameter77_name: Union[str, object] = values.unset,
+ parameter77_value: Union[str, object] = values.unset,
+ parameter78_name: Union[str, object] = values.unset,
+ parameter78_value: Union[str, object] = values.unset,
+ parameter79_name: Union[str, object] = values.unset,
+ parameter79_value: Union[str, object] = values.unset,
+ parameter80_name: Union[str, object] = values.unset,
+ parameter80_value: Union[str, object] = values.unset,
+ parameter81_name: Union[str, object] = values.unset,
+ parameter81_value: Union[str, object] = values.unset,
+ parameter82_name: Union[str, object] = values.unset,
+ parameter82_value: Union[str, object] = values.unset,
+ parameter83_name: Union[str, object] = values.unset,
+ parameter83_value: Union[str, object] = values.unset,
+ parameter84_name: Union[str, object] = values.unset,
+ parameter84_value: Union[str, object] = values.unset,
+ parameter85_name: Union[str, object] = values.unset,
+ parameter85_value: Union[str, object] = values.unset,
+ parameter86_name: Union[str, object] = values.unset,
+ parameter86_value: Union[str, object] = values.unset,
+ parameter87_name: Union[str, object] = values.unset,
+ parameter87_value: Union[str, object] = values.unset,
+ parameter88_name: Union[str, object] = values.unset,
+ parameter88_value: Union[str, object] = values.unset,
+ parameter89_name: Union[str, object] = values.unset,
+ parameter89_value: Union[str, object] = values.unset,
+ parameter90_name: Union[str, object] = values.unset,
+ parameter90_value: Union[str, object] = values.unset,
+ parameter91_name: Union[str, object] = values.unset,
+ parameter91_value: Union[str, object] = values.unset,
+ parameter92_name: Union[str, object] = values.unset,
+ parameter92_value: Union[str, object] = values.unset,
+ parameter93_name: Union[str, object] = values.unset,
+ parameter93_value: Union[str, object] = values.unset,
+ parameter94_name: Union[str, object] = values.unset,
+ parameter94_value: Union[str, object] = values.unset,
+ parameter95_name: Union[str, object] = values.unset,
+ parameter95_value: Union[str, object] = values.unset,
+ parameter96_name: Union[str, object] = values.unset,
+ parameter96_value: Union[str, object] = values.unset,
+ parameter97_name: Union[str, object] = values.unset,
+ parameter97_value: Union[str, object] = values.unset,
+ parameter98_name: Union[str, object] = values.unset,
+ parameter98_value: Union[str, object] = values.unset,
+ parameter99_name: Union[str, object] = values.unset,
+ parameter99_value: Union[str, object] = values.unset,
+ ) -> StreamInstance:
+ """
+ Asynchronously create the StreamInstance
+
+ :param url: Relative or absolute URL where WebSocket connection will be established.
+ :param name: The user-specified name of this Stream, if one was given when the Stream was created. This can be used to stop the Stream.
+ :param track:
+ :param status_callback: Absolute URL to which Twilio sends status callback HTTP requests.
+ :param status_callback_method: The HTTP method Twilio uses when sending `status_callback` requests. Possible values are `GET` and `POST`. Default is `POST`.
+ :param parameter1_name: Parameter name
+ :param parameter1_value: Parameter value
+ :param parameter2_name: Parameter name
+ :param parameter2_value: Parameter value
+ :param parameter3_name: Parameter name
+ :param parameter3_value: Parameter value
+ :param parameter4_name: Parameter name
+ :param parameter4_value: Parameter value
+ :param parameter5_name: Parameter name
+ :param parameter5_value: Parameter value
+ :param parameter6_name: Parameter name
+ :param parameter6_value: Parameter value
+ :param parameter7_name: Parameter name
+ :param parameter7_value: Parameter value
+ :param parameter8_name: Parameter name
+ :param parameter8_value: Parameter value
+ :param parameter9_name: Parameter name
+ :param parameter9_value: Parameter value
+ :param parameter10_name: Parameter name
+ :param parameter10_value: Parameter value
+ :param parameter11_name: Parameter name
+ :param parameter11_value: Parameter value
+ :param parameter12_name: Parameter name
+ :param parameter12_value: Parameter value
+ :param parameter13_name: Parameter name
+ :param parameter13_value: Parameter value
+ :param parameter14_name: Parameter name
+ :param parameter14_value: Parameter value
+ :param parameter15_name: Parameter name
+ :param parameter15_value: Parameter value
+ :param parameter16_name: Parameter name
+ :param parameter16_value: Parameter value
+ :param parameter17_name: Parameter name
+ :param parameter17_value: Parameter value
+ :param parameter18_name: Parameter name
+ :param parameter18_value: Parameter value
+ :param parameter19_name: Parameter name
+ :param parameter19_value: Parameter value
+ :param parameter20_name: Parameter name
+ :param parameter20_value: Parameter value
+ :param parameter21_name: Parameter name
+ :param parameter21_value: Parameter value
+ :param parameter22_name: Parameter name
+ :param parameter22_value: Parameter value
+ :param parameter23_name: Parameter name
+ :param parameter23_value: Parameter value
+ :param parameter24_name: Parameter name
+ :param parameter24_value: Parameter value
+ :param parameter25_name: Parameter name
+ :param parameter25_value: Parameter value
+ :param parameter26_name: Parameter name
+ :param parameter26_value: Parameter value
+ :param parameter27_name: Parameter name
+ :param parameter27_value: Parameter value
+ :param parameter28_name: Parameter name
+ :param parameter28_value: Parameter value
+ :param parameter29_name: Parameter name
+ :param parameter29_value: Parameter value
+ :param parameter30_name: Parameter name
+ :param parameter30_value: Parameter value
+ :param parameter31_name: Parameter name
+ :param parameter31_value: Parameter value
+ :param parameter32_name: Parameter name
+ :param parameter32_value: Parameter value
+ :param parameter33_name: Parameter name
+ :param parameter33_value: Parameter value
+ :param parameter34_name: Parameter name
+ :param parameter34_value: Parameter value
+ :param parameter35_name: Parameter name
+ :param parameter35_value: Parameter value
+ :param parameter36_name: Parameter name
+ :param parameter36_value: Parameter value
+ :param parameter37_name: Parameter name
+ :param parameter37_value: Parameter value
+ :param parameter38_name: Parameter name
+ :param parameter38_value: Parameter value
+ :param parameter39_name: Parameter name
+ :param parameter39_value: Parameter value
+ :param parameter40_name: Parameter name
+ :param parameter40_value: Parameter value
+ :param parameter41_name: Parameter name
+ :param parameter41_value: Parameter value
+ :param parameter42_name: Parameter name
+ :param parameter42_value: Parameter value
+ :param parameter43_name: Parameter name
+ :param parameter43_value: Parameter value
+ :param parameter44_name: Parameter name
+ :param parameter44_value: Parameter value
+ :param parameter45_name: Parameter name
+ :param parameter45_value: Parameter value
+ :param parameter46_name: Parameter name
+ :param parameter46_value: Parameter value
+ :param parameter47_name: Parameter name
+ :param parameter47_value: Parameter value
+ :param parameter48_name: Parameter name
+ :param parameter48_value: Parameter value
+ :param parameter49_name: Parameter name
+ :param parameter49_value: Parameter value
+ :param parameter50_name: Parameter name
+ :param parameter50_value: Parameter value
+ :param parameter51_name: Parameter name
+ :param parameter51_value: Parameter value
+ :param parameter52_name: Parameter name
+ :param parameter52_value: Parameter value
+ :param parameter53_name: Parameter name
+ :param parameter53_value: Parameter value
+ :param parameter54_name: Parameter name
+ :param parameter54_value: Parameter value
+ :param parameter55_name: Parameter name
+ :param parameter55_value: Parameter value
+ :param parameter56_name: Parameter name
+ :param parameter56_value: Parameter value
+ :param parameter57_name: Parameter name
+ :param parameter57_value: Parameter value
+ :param parameter58_name: Parameter name
+ :param parameter58_value: Parameter value
+ :param parameter59_name: Parameter name
+ :param parameter59_value: Parameter value
+ :param parameter60_name: Parameter name
+ :param parameter60_value: Parameter value
+ :param parameter61_name: Parameter name
+ :param parameter61_value: Parameter value
+ :param parameter62_name: Parameter name
+ :param parameter62_value: Parameter value
+ :param parameter63_name: Parameter name
+ :param parameter63_value: Parameter value
+ :param parameter64_name: Parameter name
+ :param parameter64_value: Parameter value
+ :param parameter65_name: Parameter name
+ :param parameter65_value: Parameter value
+ :param parameter66_name: Parameter name
+ :param parameter66_value: Parameter value
+ :param parameter67_name: Parameter name
+ :param parameter67_value: Parameter value
+ :param parameter68_name: Parameter name
+ :param parameter68_value: Parameter value
+ :param parameter69_name: Parameter name
+ :param parameter69_value: Parameter value
+ :param parameter70_name: Parameter name
+ :param parameter70_value: Parameter value
+ :param parameter71_name: Parameter name
+ :param parameter71_value: Parameter value
+ :param parameter72_name: Parameter name
+ :param parameter72_value: Parameter value
+ :param parameter73_name: Parameter name
+ :param parameter73_value: Parameter value
+ :param parameter74_name: Parameter name
+ :param parameter74_value: Parameter value
+ :param parameter75_name: Parameter name
+ :param parameter75_value: Parameter value
+ :param parameter76_name: Parameter name
+ :param parameter76_value: Parameter value
+ :param parameter77_name: Parameter name
+ :param parameter77_value: Parameter value
+ :param parameter78_name: Parameter name
+ :param parameter78_value: Parameter value
+ :param parameter79_name: Parameter name
+ :param parameter79_value: Parameter value
+ :param parameter80_name: Parameter name
+ :param parameter80_value: Parameter value
+ :param parameter81_name: Parameter name
+ :param parameter81_value: Parameter value
+ :param parameter82_name: Parameter name
+ :param parameter82_value: Parameter value
+ :param parameter83_name: Parameter name
+ :param parameter83_value: Parameter value
+ :param parameter84_name: Parameter name
+ :param parameter84_value: Parameter value
+ :param parameter85_name: Parameter name
+ :param parameter85_value: Parameter value
+ :param parameter86_name: Parameter name
+ :param parameter86_value: Parameter value
+ :param parameter87_name: Parameter name
+ :param parameter87_value: Parameter value
+ :param parameter88_name: Parameter name
+ :param parameter88_value: Parameter value
+ :param parameter89_name: Parameter name
+ :param parameter89_value: Parameter value
+ :param parameter90_name: Parameter name
+ :param parameter90_value: Parameter value
+ :param parameter91_name: Parameter name
+ :param parameter91_value: Parameter value
+ :param parameter92_name: Parameter name
+ :param parameter92_value: Parameter value
+ :param parameter93_name: Parameter name
+ :param parameter93_value: Parameter value
+ :param parameter94_name: Parameter name
+ :param parameter94_value: Parameter value
+ :param parameter95_name: Parameter name
+ :param parameter95_value: Parameter value
+ :param parameter96_name: Parameter name
+ :param parameter96_value: Parameter value
+ :param parameter97_name: Parameter name
+ :param parameter97_value: Parameter value
+ :param parameter98_name: Parameter name
+ :param parameter98_value: Parameter value
+ :param parameter99_name: Parameter name
+ :param parameter99_value: Parameter value
+
+ :returns: The created StreamInstance
+ """
+
+ data = values.of(
+ {
+ "Url": url,
+ "Name": name,
+ "Track": track,
+ "StatusCallback": status_callback,
+ "StatusCallbackMethod": status_callback_method,
+ "Parameter1.Name": parameter1_name,
+ "Parameter1.Value": parameter1_value,
+ "Parameter2.Name": parameter2_name,
+ "Parameter2.Value": parameter2_value,
+ "Parameter3.Name": parameter3_name,
+ "Parameter3.Value": parameter3_value,
+ "Parameter4.Name": parameter4_name,
+ "Parameter4.Value": parameter4_value,
+ "Parameter5.Name": parameter5_name,
+ "Parameter5.Value": parameter5_value,
+ "Parameter6.Name": parameter6_name,
+ "Parameter6.Value": parameter6_value,
+ "Parameter7.Name": parameter7_name,
+ "Parameter7.Value": parameter7_value,
+ "Parameter8.Name": parameter8_name,
+ "Parameter8.Value": parameter8_value,
+ "Parameter9.Name": parameter9_name,
+ "Parameter9.Value": parameter9_value,
+ "Parameter10.Name": parameter10_name,
+ "Parameter10.Value": parameter10_value,
+ "Parameter11.Name": parameter11_name,
+ "Parameter11.Value": parameter11_value,
+ "Parameter12.Name": parameter12_name,
+ "Parameter12.Value": parameter12_value,
+ "Parameter13.Name": parameter13_name,
+ "Parameter13.Value": parameter13_value,
+ "Parameter14.Name": parameter14_name,
+ "Parameter14.Value": parameter14_value,
+ "Parameter15.Name": parameter15_name,
+ "Parameter15.Value": parameter15_value,
+ "Parameter16.Name": parameter16_name,
+ "Parameter16.Value": parameter16_value,
+ "Parameter17.Name": parameter17_name,
+ "Parameter17.Value": parameter17_value,
+ "Parameter18.Name": parameter18_name,
+ "Parameter18.Value": parameter18_value,
+ "Parameter19.Name": parameter19_name,
+ "Parameter19.Value": parameter19_value,
+ "Parameter20.Name": parameter20_name,
+ "Parameter20.Value": parameter20_value,
+ "Parameter21.Name": parameter21_name,
+ "Parameter21.Value": parameter21_value,
+ "Parameter22.Name": parameter22_name,
+ "Parameter22.Value": parameter22_value,
+ "Parameter23.Name": parameter23_name,
+ "Parameter23.Value": parameter23_value,
+ "Parameter24.Name": parameter24_name,
+ "Parameter24.Value": parameter24_value,
+ "Parameter25.Name": parameter25_name,
+ "Parameter25.Value": parameter25_value,
+ "Parameter26.Name": parameter26_name,
+ "Parameter26.Value": parameter26_value,
+ "Parameter27.Name": parameter27_name,
+ "Parameter27.Value": parameter27_value,
+ "Parameter28.Name": parameter28_name,
+ "Parameter28.Value": parameter28_value,
+ "Parameter29.Name": parameter29_name,
+ "Parameter29.Value": parameter29_value,
+ "Parameter30.Name": parameter30_name,
+ "Parameter30.Value": parameter30_value,
+ "Parameter31.Name": parameter31_name,
+ "Parameter31.Value": parameter31_value,
+ "Parameter32.Name": parameter32_name,
+ "Parameter32.Value": parameter32_value,
+ "Parameter33.Name": parameter33_name,
+ "Parameter33.Value": parameter33_value,
+ "Parameter34.Name": parameter34_name,
+ "Parameter34.Value": parameter34_value,
+ "Parameter35.Name": parameter35_name,
+ "Parameter35.Value": parameter35_value,
+ "Parameter36.Name": parameter36_name,
+ "Parameter36.Value": parameter36_value,
+ "Parameter37.Name": parameter37_name,
+ "Parameter37.Value": parameter37_value,
+ "Parameter38.Name": parameter38_name,
+ "Parameter38.Value": parameter38_value,
+ "Parameter39.Name": parameter39_name,
+ "Parameter39.Value": parameter39_value,
+ "Parameter40.Name": parameter40_name,
+ "Parameter40.Value": parameter40_value,
+ "Parameter41.Name": parameter41_name,
+ "Parameter41.Value": parameter41_value,
+ "Parameter42.Name": parameter42_name,
+ "Parameter42.Value": parameter42_value,
+ "Parameter43.Name": parameter43_name,
+ "Parameter43.Value": parameter43_value,
+ "Parameter44.Name": parameter44_name,
+ "Parameter44.Value": parameter44_value,
+ "Parameter45.Name": parameter45_name,
+ "Parameter45.Value": parameter45_value,
+ "Parameter46.Name": parameter46_name,
+ "Parameter46.Value": parameter46_value,
+ "Parameter47.Name": parameter47_name,
+ "Parameter47.Value": parameter47_value,
+ "Parameter48.Name": parameter48_name,
+ "Parameter48.Value": parameter48_value,
+ "Parameter49.Name": parameter49_name,
+ "Parameter49.Value": parameter49_value,
+ "Parameter50.Name": parameter50_name,
+ "Parameter50.Value": parameter50_value,
+ "Parameter51.Name": parameter51_name,
+ "Parameter51.Value": parameter51_value,
+ "Parameter52.Name": parameter52_name,
+ "Parameter52.Value": parameter52_value,
+ "Parameter53.Name": parameter53_name,
+ "Parameter53.Value": parameter53_value,
+ "Parameter54.Name": parameter54_name,
+ "Parameter54.Value": parameter54_value,
+ "Parameter55.Name": parameter55_name,
+ "Parameter55.Value": parameter55_value,
+ "Parameter56.Name": parameter56_name,
+ "Parameter56.Value": parameter56_value,
+ "Parameter57.Name": parameter57_name,
+ "Parameter57.Value": parameter57_value,
+ "Parameter58.Name": parameter58_name,
+ "Parameter58.Value": parameter58_value,
+ "Parameter59.Name": parameter59_name,
+ "Parameter59.Value": parameter59_value,
+ "Parameter60.Name": parameter60_name,
+ "Parameter60.Value": parameter60_value,
+ "Parameter61.Name": parameter61_name,
+ "Parameter61.Value": parameter61_value,
+ "Parameter62.Name": parameter62_name,
+ "Parameter62.Value": parameter62_value,
+ "Parameter63.Name": parameter63_name,
+ "Parameter63.Value": parameter63_value,
+ "Parameter64.Name": parameter64_name,
+ "Parameter64.Value": parameter64_value,
+ "Parameter65.Name": parameter65_name,
+ "Parameter65.Value": parameter65_value,
+ "Parameter66.Name": parameter66_name,
+ "Parameter66.Value": parameter66_value,
+ "Parameter67.Name": parameter67_name,
+ "Parameter67.Value": parameter67_value,
+ "Parameter68.Name": parameter68_name,
+ "Parameter68.Value": parameter68_value,
+ "Parameter69.Name": parameter69_name,
+ "Parameter69.Value": parameter69_value,
+ "Parameter70.Name": parameter70_name,
+ "Parameter70.Value": parameter70_value,
+ "Parameter71.Name": parameter71_name,
+ "Parameter71.Value": parameter71_value,
+ "Parameter72.Name": parameter72_name,
+ "Parameter72.Value": parameter72_value,
+ "Parameter73.Name": parameter73_name,
+ "Parameter73.Value": parameter73_value,
+ "Parameter74.Name": parameter74_name,
+ "Parameter74.Value": parameter74_value,
+ "Parameter75.Name": parameter75_name,
+ "Parameter75.Value": parameter75_value,
+ "Parameter76.Name": parameter76_name,
+ "Parameter76.Value": parameter76_value,
+ "Parameter77.Name": parameter77_name,
+ "Parameter77.Value": parameter77_value,
+ "Parameter78.Name": parameter78_name,
+ "Parameter78.Value": parameter78_value,
+ "Parameter79.Name": parameter79_name,
+ "Parameter79.Value": parameter79_value,
+ "Parameter80.Name": parameter80_name,
+ "Parameter80.Value": parameter80_value,
+ "Parameter81.Name": parameter81_name,
+ "Parameter81.Value": parameter81_value,
+ "Parameter82.Name": parameter82_name,
+ "Parameter82.Value": parameter82_value,
+ "Parameter83.Name": parameter83_name,
+ "Parameter83.Value": parameter83_value,
+ "Parameter84.Name": parameter84_name,
+ "Parameter84.Value": parameter84_value,
+ "Parameter85.Name": parameter85_name,
+ "Parameter85.Value": parameter85_value,
+ "Parameter86.Name": parameter86_name,
+ "Parameter86.Value": parameter86_value,
+ "Parameter87.Name": parameter87_name,
+ "Parameter87.Value": parameter87_value,
+ "Parameter88.Name": parameter88_name,
+ "Parameter88.Value": parameter88_value,
+ "Parameter89.Name": parameter89_name,
+ "Parameter89.Value": parameter89_value,
+ "Parameter90.Name": parameter90_name,
+ "Parameter90.Value": parameter90_value,
+ "Parameter91.Name": parameter91_name,
+ "Parameter91.Value": parameter91_value,
+ "Parameter92.Name": parameter92_name,
+ "Parameter92.Value": parameter92_value,
+ "Parameter93.Name": parameter93_name,
+ "Parameter93.Value": parameter93_value,
+ "Parameter94.Name": parameter94_name,
+ "Parameter94.Value": parameter94_value,
+ "Parameter95.Name": parameter95_name,
+ "Parameter95.Value": parameter95_value,
+ "Parameter96.Name": parameter96_name,
+ "Parameter96.Value": parameter96_value,
+ "Parameter97.Name": parameter97_name,
+ "Parameter97.Value": parameter97_value,
+ "Parameter98.Name": parameter98_name,
+ "Parameter98.Value": parameter98_value,
+ "Parameter99.Name": parameter99_name,
+ "Parameter99.Value": parameter99_value,
+ }
+ )
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.create_async(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return StreamInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ )
+
+ def get(self, sid: str) -> StreamContext:
+ """
+ Constructs a StreamContext
+
+ :param sid: The SID or the `name` of the Stream resource to be stopped
+ """
+ return StreamContext(
+ self._version,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ sid=sid,
+ )
+
+ def __call__(self, sid: str) -> StreamContext:
+ """
+ Constructs a StreamContext
+
+ :param sid: The SID or the `name` of the Stream resource to be stopped
+ """
+ return StreamContext(
+ self._version,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ sid=sid,
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/transcription.py b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/transcription.py
new file mode 100644
index 00000000..4f8f9125
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/transcription.py
@@ -0,0 +1,439 @@
+r"""
+ This code was generated by
+ ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __
+ | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/
+ | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \
+
+ Twilio - Api
+ This is the public Twilio REST API.
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ https://openapi-generator.tech
+ Do not edit the class manually.
+"""
+
+from datetime import datetime
+from typing import Any, Dict, Optional, Union
+from twilio.base import deserialize, serialize, values
+from twilio.base.instance_context import InstanceContext
+from twilio.base.instance_resource import InstanceResource
+from twilio.base.list_resource import ListResource
+from twilio.base.version import Version
+
+
+class TranscriptionInstance(InstanceResource):
+
+ class Status(object):
+ IN_PROGRESS = "in-progress"
+ STOPPED = "stopped"
+
+ class Track(object):
+ INBOUND_TRACK = "inbound_track"
+ OUTBOUND_TRACK = "outbound_track"
+ BOTH_TRACKS = "both_tracks"
+
+ class UpdateStatus(object):
+ STOPPED = "stopped"
+
+ """
+ :ivar sid: The SID of the Transcription resource.
+ :ivar account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that created this Transcription resource.
+ :ivar call_sid: The SID of the [Call](https://www.twilio.com/docs/voice/api/call-resource) the Transcription resource is associated with.
+ :ivar name: The user-specified name of this Transcription, if one was given when the Transcription was created. This may be used to stop the Transcription.
+ :ivar status:
+ :ivar date_updated: The date and time in GMT that this resource was last updated, specified in [RFC 2822](https://www.ietf.org/rfc/rfc2822.txt) format.
+ :ivar uri:
+ """
+
+ def __init__(
+ self,
+ version: Version,
+ payload: Dict[str, Any],
+ account_sid: str,
+ call_sid: str,
+ sid: Optional[str] = None,
+ ):
+ super().__init__(version)
+
+ self.sid: Optional[str] = payload.get("sid")
+ self.account_sid: Optional[str] = payload.get("account_sid")
+ self.call_sid: Optional[str] = payload.get("call_sid")
+ self.name: Optional[str] = payload.get("name")
+ self.status: Optional["TranscriptionInstance.Status"] = payload.get("status")
+ self.date_updated: Optional[datetime] = deserialize.rfc2822_datetime(
+ payload.get("date_updated")
+ )
+ self.uri: Optional[str] = payload.get("uri")
+
+ self._solution = {
+ "account_sid": account_sid,
+ "call_sid": call_sid,
+ "sid": sid or self.sid,
+ }
+ self._context: Optional[TranscriptionContext] = None
+
+ @property
+ def _proxy(self) -> "TranscriptionContext":
+ """
+ Generate an instance context for the instance, the context is capable of
+ performing various actions. All instance actions are proxied to the context
+
+ :returns: TranscriptionContext for this TranscriptionInstance
+ """
+ if self._context is None:
+ self._context = TranscriptionContext(
+ self._version,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ sid=self._solution["sid"],
+ )
+ return self._context
+
+ def update(
+ self, status: "TranscriptionInstance.UpdateStatus"
+ ) -> "TranscriptionInstance":
+ """
+ Update the TranscriptionInstance
+
+ :param status:
+
+ :returns: The updated TranscriptionInstance
+ """
+ return self._proxy.update(
+ status=status,
+ )
+
+ async def update_async(
+ self, status: "TranscriptionInstance.UpdateStatus"
+ ) -> "TranscriptionInstance":
+ """
+ Asynchronous coroutine to update the TranscriptionInstance
+
+ :param status:
+
+ :returns: The updated TranscriptionInstance
+ """
+ return await self._proxy.update_async(
+ status=status,
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(context)
+
+
+class TranscriptionContext(InstanceContext):
+
+ def __init__(self, version: Version, account_sid: str, call_sid: str, sid: str):
+ """
+ Initialize the TranscriptionContext
+
+ :param version: Version that contains the resource
+ :param account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that created this Transcription resource.
+ :param call_sid: The SID of the [Call](https://www.twilio.com/docs/voice/api/call-resource) the Transcription resource is associated with.
+ :param sid: The SID of the Transcription resource, or the `name` used when creating the resource
+ """
+ super().__init__(version)
+
+ # Path Solution
+ self._solution = {
+ "account_sid": account_sid,
+ "call_sid": call_sid,
+ "sid": sid,
+ }
+ self._uri = (
+ "/Accounts/{account_sid}/Calls/{call_sid}/Transcriptions/{sid}.json".format(
+ **self._solution
+ )
+ )
+
+ def update(
+ self, status: "TranscriptionInstance.UpdateStatus"
+ ) -> TranscriptionInstance:
+ """
+ Update the TranscriptionInstance
+
+ :param status:
+
+ :returns: The updated TranscriptionInstance
+ """
+
+ data = values.of(
+ {
+ "Status": status,
+ }
+ )
+ headers = values.of({})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.update(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return TranscriptionInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ sid=self._solution["sid"],
+ )
+
+ async def update_async(
+ self, status: "TranscriptionInstance.UpdateStatus"
+ ) -> TranscriptionInstance:
+ """
+ Asynchronous coroutine to update the TranscriptionInstance
+
+ :param status:
+
+ :returns: The updated TranscriptionInstance
+ """
+
+ data = values.of(
+ {
+ "Status": status,
+ }
+ )
+ headers = values.of({})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.update_async(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return TranscriptionInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ sid=self._solution["sid"],
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(context)
+
+
+class TranscriptionList(ListResource):
+
+ def __init__(self, version: Version, account_sid: str, call_sid: str):
+ """
+ Initialize the TranscriptionList
+
+ :param version: Version that contains the resource
+ :param account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that created this Transcription resource.
+ :param call_sid: The SID of the [Call](https://www.twilio.com/docs/voice/api/call-resource) the Transcription resource is associated with.
+
+ """
+ super().__init__(version)
+
+ # Path Solution
+ self._solution = {
+ "account_sid": account_sid,
+ "call_sid": call_sid,
+ }
+ self._uri = (
+ "/Accounts/{account_sid}/Calls/{call_sid}/Transcriptions.json".format(
+ **self._solution
+ )
+ )
+
+ def create(
+ self,
+ name: Union[str, object] = values.unset,
+ track: Union["TranscriptionInstance.Track", object] = values.unset,
+ status_callback_url: Union[str, object] = values.unset,
+ status_callback_method: Union[str, object] = values.unset,
+ inbound_track_label: Union[str, object] = values.unset,
+ outbound_track_label: Union[str, object] = values.unset,
+ partial_results: Union[bool, object] = values.unset,
+ language_code: Union[str, object] = values.unset,
+ transcription_engine: Union[str, object] = values.unset,
+ profanity_filter: Union[bool, object] = values.unset,
+ speech_model: Union[str, object] = values.unset,
+ hints: Union[str, object] = values.unset,
+ enable_automatic_punctuation: Union[bool, object] = values.unset,
+ intelligence_service: Union[str, object] = values.unset,
+ ) -> TranscriptionInstance:
+ """
+ Create the TranscriptionInstance
+
+ :param name: The user-specified name of this Transcription, if one was given when the Transcription was created. This may be used to stop the Transcription.
+ :param track:
+ :param status_callback_url: Absolute URL of the status callback.
+ :param status_callback_method: The http method for the status_callback (one of GET, POST).
+ :param inbound_track_label: Friendly name given to the Inbound Track
+ :param outbound_track_label: Friendly name given to the Outbound Track
+ :param partial_results: Indicates if partial results are going to be sent to the customer
+ :param language_code: Language code used by the transcription engine, specified in [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) format
+ :param transcription_engine: Definition of the transcription engine to be used, among those supported by Twilio
+ :param profanity_filter: indicates if the server will attempt to filter out profanities, replacing all but the initial character in each filtered word with asterisks
+ :param speech_model: Recognition model used by the transcription engine, among those supported by the provider
+ :param hints: A Phrase contains words and phrase \\\"hints\\\" so that the speech recognition engine is more likely to recognize them.
+ :param enable_automatic_punctuation: The provider will add punctuation to recognition result
+ :param intelligence_service: The SID or unique name of the [Intelligence Service](https://www.twilio.com/docs/conversational-intelligence/api/service-resource) for persisting transcripts and running post-call Language Operators .
+
+ :returns: The created TranscriptionInstance
+ """
+
+ data = values.of(
+ {
+ "Name": name,
+ "Track": track,
+ "StatusCallbackUrl": status_callback_url,
+ "StatusCallbackMethod": status_callback_method,
+ "InboundTrackLabel": inbound_track_label,
+ "OutboundTrackLabel": outbound_track_label,
+ "PartialResults": serialize.boolean_to_string(partial_results),
+ "LanguageCode": language_code,
+ "TranscriptionEngine": transcription_engine,
+ "ProfanityFilter": serialize.boolean_to_string(profanity_filter),
+ "SpeechModel": speech_model,
+ "Hints": hints,
+ "EnableAutomaticPunctuation": serialize.boolean_to_string(
+ enable_automatic_punctuation
+ ),
+ "IntelligenceService": intelligence_service,
+ }
+ )
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.create(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return TranscriptionInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ )
+
+ async def create_async(
+ self,
+ name: Union[str, object] = values.unset,
+ track: Union["TranscriptionInstance.Track", object] = values.unset,
+ status_callback_url: Union[str, object] = values.unset,
+ status_callback_method: Union[str, object] = values.unset,
+ inbound_track_label: Union[str, object] = values.unset,
+ outbound_track_label: Union[str, object] = values.unset,
+ partial_results: Union[bool, object] = values.unset,
+ language_code: Union[str, object] = values.unset,
+ transcription_engine: Union[str, object] = values.unset,
+ profanity_filter: Union[bool, object] = values.unset,
+ speech_model: Union[str, object] = values.unset,
+ hints: Union[str, object] = values.unset,
+ enable_automatic_punctuation: Union[bool, object] = values.unset,
+ intelligence_service: Union[str, object] = values.unset,
+ ) -> TranscriptionInstance:
+ """
+ Asynchronously create the TranscriptionInstance
+
+ :param name: The user-specified name of this Transcription, if one was given when the Transcription was created. This may be used to stop the Transcription.
+ :param track:
+ :param status_callback_url: Absolute URL of the status callback.
+ :param status_callback_method: The http method for the status_callback (one of GET, POST).
+ :param inbound_track_label: Friendly name given to the Inbound Track
+ :param outbound_track_label: Friendly name given to the Outbound Track
+ :param partial_results: Indicates if partial results are going to be sent to the customer
+ :param language_code: Language code used by the transcription engine, specified in [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) format
+ :param transcription_engine: Definition of the transcription engine to be used, among those supported by Twilio
+ :param profanity_filter: indicates if the server will attempt to filter out profanities, replacing all but the initial character in each filtered word with asterisks
+ :param speech_model: Recognition model used by the transcription engine, among those supported by the provider
+ :param hints: A Phrase contains words and phrase \\\"hints\\\" so that the speech recognition engine is more likely to recognize them.
+ :param enable_automatic_punctuation: The provider will add punctuation to recognition result
+ :param intelligence_service: The SID or unique name of the [Intelligence Service](https://www.twilio.com/docs/conversational-intelligence/api/service-resource) for persisting transcripts and running post-call Language Operators .
+
+ :returns: The created TranscriptionInstance
+ """
+
+ data = values.of(
+ {
+ "Name": name,
+ "Track": track,
+ "StatusCallbackUrl": status_callback_url,
+ "StatusCallbackMethod": status_callback_method,
+ "InboundTrackLabel": inbound_track_label,
+ "OutboundTrackLabel": outbound_track_label,
+ "PartialResults": serialize.boolean_to_string(partial_results),
+ "LanguageCode": language_code,
+ "TranscriptionEngine": transcription_engine,
+ "ProfanityFilter": serialize.boolean_to_string(profanity_filter),
+ "SpeechModel": speech_model,
+ "Hints": hints,
+ "EnableAutomaticPunctuation": serialize.boolean_to_string(
+ enable_automatic_punctuation
+ ),
+ "IntelligenceService": intelligence_service,
+ }
+ )
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.create_async(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return TranscriptionInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ )
+
+ def get(self, sid: str) -> TranscriptionContext:
+ """
+ Constructs a TranscriptionContext
+
+ :param sid: The SID of the Transcription resource, or the `name` used when creating the resource
+ """
+ return TranscriptionContext(
+ self._version,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ sid=sid,
+ )
+
+ def __call__(self, sid: str) -> TranscriptionContext:
+ """
+ Constructs a TranscriptionContext
+
+ :param sid: The SID of the Transcription resource, or the `name` used when creating the resource
+ """
+ return TranscriptionContext(
+ self._version,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ sid=sid,
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/user_defined_message.py b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/user_defined_message.py
new file mode 100644
index 00000000..bc66f8b8
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/user_defined_message.py
@@ -0,0 +1,159 @@
+r"""
+ This code was generated by
+ ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __
+ | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/
+ | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \
+
+ Twilio - Api
+ This is the public Twilio REST API.
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ https://openapi-generator.tech
+ Do not edit the class manually.
+"""
+
+from datetime import datetime
+from typing import Any, Dict, Optional, Union
+from twilio.base import deserialize, values
+
+from twilio.base.instance_resource import InstanceResource
+from twilio.base.list_resource import ListResource
+from twilio.base.version import Version
+
+
+class UserDefinedMessageInstance(InstanceResource):
+ """
+ :ivar account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that created User Defined Message.
+ :ivar call_sid: The SID of the [Call](https://www.twilio.com/docs/voice/api/call-resource) the User Defined Message is associated with.
+ :ivar sid: The SID that uniquely identifies this User Defined Message.
+ :ivar date_created: The date that this User Defined Message was created, given in RFC 2822 format.
+ """
+
+ def __init__(
+ self, version: Version, payload: Dict[str, Any], account_sid: str, call_sid: str
+ ):
+ super().__init__(version)
+
+ self.account_sid: Optional[str] = payload.get("account_sid")
+ self.call_sid: Optional[str] = payload.get("call_sid")
+ self.sid: Optional[str] = payload.get("sid")
+ self.date_created: Optional[datetime] = deserialize.rfc2822_datetime(
+ payload.get("date_created")
+ )
+
+ self._solution = {
+ "account_sid": account_sid,
+ "call_sid": call_sid,
+ }
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(context)
+
+
+class UserDefinedMessageList(ListResource):
+
+ def __init__(self, version: Version, account_sid: str, call_sid: str):
+ """
+ Initialize the UserDefinedMessageList
+
+ :param version: Version that contains the resource
+ :param account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that created User Defined Message.
+ :param call_sid: The SID of the [Call](https://www.twilio.com/docs/voice/api/call-resource) the User Defined Message is associated with.
+
+ """
+ super().__init__(version)
+
+ # Path Solution
+ self._solution = {
+ "account_sid": account_sid,
+ "call_sid": call_sid,
+ }
+ self._uri = (
+ "/Accounts/{account_sid}/Calls/{call_sid}/UserDefinedMessages.json".format(
+ **self._solution
+ )
+ )
+
+ def create(
+ self, content: str, idempotency_key: Union[str, object] = values.unset
+ ) -> UserDefinedMessageInstance:
+ """
+ Create the UserDefinedMessageInstance
+
+ :param content: The User Defined Message in the form of URL-encoded JSON string.
+ :param idempotency_key: A unique string value to identify API call. This should be a unique string value per API call and can be a randomly generated.
+
+ :returns: The created UserDefinedMessageInstance
+ """
+
+ data = values.of(
+ {
+ "Content": content,
+ "IdempotencyKey": idempotency_key,
+ }
+ )
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.create(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return UserDefinedMessageInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ )
+
+ async def create_async(
+ self, content: str, idempotency_key: Union[str, object] = values.unset
+ ) -> UserDefinedMessageInstance:
+ """
+ Asynchronously create the UserDefinedMessageInstance
+
+ :param content: The User Defined Message in the form of URL-encoded JSON string.
+ :param idempotency_key: A unique string value to identify API call. This should be a unique string value per API call and can be a randomly generated.
+
+ :returns: The created UserDefinedMessageInstance
+ """
+
+ data = values.of(
+ {
+ "Content": content,
+ "IdempotencyKey": idempotency_key,
+ }
+ )
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.create_async(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return UserDefinedMessageInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/user_defined_message_subscription.py b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/user_defined_message_subscription.py
new file mode 100644
index 00000000..66923d4b
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/api/v2010/account/call/user_defined_message_subscription.py
@@ -0,0 +1,300 @@
+r"""
+ This code was generated by
+ ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __
+ | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/
+ | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \
+
+ Twilio - Api
+ This is the public Twilio REST API.
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ https://openapi-generator.tech
+ Do not edit the class manually.
+"""
+
+from datetime import datetime
+from typing import Any, Dict, Optional, Union
+from twilio.base import deserialize, values
+from twilio.base.instance_context import InstanceContext
+from twilio.base.instance_resource import InstanceResource
+from twilio.base.list_resource import ListResource
+from twilio.base.version import Version
+
+
+class UserDefinedMessageSubscriptionInstance(InstanceResource):
+ """
+ :ivar account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that subscribed to the User Defined Messages.
+ :ivar call_sid: The SID of the [Call](https://www.twilio.com/docs/voice/api/call-resource) the User Defined Message Subscription is associated with. This refers to the Call SID that is producing the User Defined Messages.
+ :ivar sid: The SID that uniquely identifies this User Defined Message Subscription.
+ :ivar date_created: The date that this User Defined Message Subscription was created, given in RFC 2822 format.
+ :ivar uri: The URI of the User Defined Message Subscription Resource, relative to `https://api.twilio.com`.
+ """
+
+ def __init__(
+ self,
+ version: Version,
+ payload: Dict[str, Any],
+ account_sid: str,
+ call_sid: str,
+ sid: Optional[str] = None,
+ ):
+ super().__init__(version)
+
+ self.account_sid: Optional[str] = payload.get("account_sid")
+ self.call_sid: Optional[str] = payload.get("call_sid")
+ self.sid: Optional[str] = payload.get("sid")
+ self.date_created: Optional[datetime] = deserialize.rfc2822_datetime(
+ payload.get("date_created")
+ )
+ self.uri: Optional[str] = payload.get("uri")
+
+ self._solution = {
+ "account_sid": account_sid,
+ "call_sid": call_sid,
+ "sid": sid or self.sid,
+ }
+ self._context: Optional[UserDefinedMessageSubscriptionContext] = None
+
+ @property
+ def _proxy(self) -> "UserDefinedMessageSubscriptionContext":
+ """
+ Generate an instance context for the instance, the context is capable of
+ performing various actions. All instance actions are proxied to the context
+
+ :returns: UserDefinedMessageSubscriptionContext for this UserDefinedMessageSubscriptionInstance
+ """
+ if self._context is None:
+ self._context = UserDefinedMessageSubscriptionContext(
+ self._version,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ sid=self._solution["sid"],
+ )
+ return self._context
+
+ def delete(self) -> bool:
+ """
+ Deletes the UserDefinedMessageSubscriptionInstance
+
+
+ :returns: True if delete succeeds, False otherwise
+ """
+ return self._proxy.delete()
+
+ async def delete_async(self) -> bool:
+ """
+ Asynchronous coroutine that deletes the UserDefinedMessageSubscriptionInstance
+
+
+ :returns: True if delete succeeds, False otherwise
+ """
+ return await self._proxy.delete_async()
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(
+ context
+ )
+
+
+class UserDefinedMessageSubscriptionContext(InstanceContext):
+
+ def __init__(self, version: Version, account_sid: str, call_sid: str, sid: str):
+ """
+ Initialize the UserDefinedMessageSubscriptionContext
+
+ :param version: Version that contains the resource
+ :param account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that subscribed to the User Defined Messages.
+ :param call_sid: The SID of the [Call](https://www.twilio.com/docs/voice/api/call-resource) the User Defined Message Subscription is associated with. This refers to the Call SID that is producing the User Defined Messages.
+ :param sid: The SID that uniquely identifies this User Defined Message Subscription.
+ """
+ super().__init__(version)
+
+ # Path Solution
+ self._solution = {
+ "account_sid": account_sid,
+ "call_sid": call_sid,
+ "sid": sid,
+ }
+ self._uri = "/Accounts/{account_sid}/Calls/{call_sid}/UserDefinedMessageSubscriptions/{sid}.json".format(
+ **self._solution
+ )
+
+ def delete(self) -> bool:
+ """
+ Deletes the UserDefinedMessageSubscriptionInstance
+
+
+ :returns: True if delete succeeds, False otherwise
+ """
+
+ headers = values.of({})
+
+ return self._version.delete(method="DELETE", uri=self._uri, headers=headers)
+
+ async def delete_async(self) -> bool:
+ """
+ Asynchronous coroutine that deletes the UserDefinedMessageSubscriptionInstance
+
+
+ :returns: True if delete succeeds, False otherwise
+ """
+
+ headers = values.of({})
+
+ return await self._version.delete_async(
+ method="DELETE", uri=self._uri, headers=headers
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "".format(
+ context
+ )
+
+
+class UserDefinedMessageSubscriptionList(ListResource):
+
+ def __init__(self, version: Version, account_sid: str, call_sid: str):
+ """
+ Initialize the UserDefinedMessageSubscriptionList
+
+ :param version: Version that contains the resource
+ :param account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that subscribed to the User Defined Messages.
+ :param call_sid: The SID of the [Call](https://www.twilio.com/docs/voice/api/call-resource) the User Defined Messages subscription is associated with. This refers to the Call SID that is producing the user defined messages.
+
+ """
+ super().__init__(version)
+
+ # Path Solution
+ self._solution = {
+ "account_sid": account_sid,
+ "call_sid": call_sid,
+ }
+ self._uri = "/Accounts/{account_sid}/Calls/{call_sid}/UserDefinedMessageSubscriptions.json".format(
+ **self._solution
+ )
+
+ def create(
+ self,
+ callback: str,
+ idempotency_key: Union[str, object] = values.unset,
+ method: Union[str, object] = values.unset,
+ ) -> UserDefinedMessageSubscriptionInstance:
+ """
+ Create the UserDefinedMessageSubscriptionInstance
+
+ :param callback: The URL we should call using the `method` to send user defined events to your application. URLs must contain a valid hostname (underscores are not permitted).
+ :param idempotency_key: A unique string value to identify API call. This should be a unique string value per API call and can be a randomly generated.
+ :param method: The HTTP method Twilio will use when requesting the above `Url`. Either `GET` or `POST`. Default is `POST`.
+
+ :returns: The created UserDefinedMessageSubscriptionInstance
+ """
+
+ data = values.of(
+ {
+ "Callback": callback,
+ "IdempotencyKey": idempotency_key,
+ "Method": method,
+ }
+ )
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = self._version.create(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return UserDefinedMessageSubscriptionInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ )
+
+ async def create_async(
+ self,
+ callback: str,
+ idempotency_key: Union[str, object] = values.unset,
+ method: Union[str, object] = values.unset,
+ ) -> UserDefinedMessageSubscriptionInstance:
+ """
+ Asynchronously create the UserDefinedMessageSubscriptionInstance
+
+ :param callback: The URL we should call using the `method` to send user defined events to your application. URLs must contain a valid hostname (underscores are not permitted).
+ :param idempotency_key: A unique string value to identify API call. This should be a unique string value per API call and can be a randomly generated.
+ :param method: The HTTP method Twilio will use when requesting the above `Url`. Either `GET` or `POST`. Default is `POST`.
+
+ :returns: The created UserDefinedMessageSubscriptionInstance
+ """
+
+ data = values.of(
+ {
+ "Callback": callback,
+ "IdempotencyKey": idempotency_key,
+ "Method": method,
+ }
+ )
+ headers = values.of({"Content-Type": "application/x-www-form-urlencoded"})
+
+ headers["Content-Type"] = "application/x-www-form-urlencoded"
+
+ headers["Accept"] = "application/json"
+
+ payload = await self._version.create_async(
+ method="POST", uri=self._uri, data=data, headers=headers
+ )
+
+ return UserDefinedMessageSubscriptionInstance(
+ self._version,
+ payload,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ )
+
+ def get(self, sid: str) -> UserDefinedMessageSubscriptionContext:
+ """
+ Constructs a UserDefinedMessageSubscriptionContext
+
+ :param sid: The SID that uniquely identifies this User Defined Message Subscription.
+ """
+ return UserDefinedMessageSubscriptionContext(
+ self._version,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ sid=sid,
+ )
+
+ def __call__(self, sid: str) -> UserDefinedMessageSubscriptionContext:
+ """
+ Constructs a UserDefinedMessageSubscriptionContext
+
+ :param sid: The SID that uniquely identifies this User Defined Message Subscription.
+ """
+ return UserDefinedMessageSubscriptionContext(
+ self._version,
+ account_sid=self._solution["account_sid"],
+ call_sid=self._solution["call_sid"],
+ sid=sid,
+ )
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ return ""
diff --git a/venv/Lib/site-packages/twilio/rest/api/v2010/account/conference/__init__.py b/venv/Lib/site-packages/twilio/rest/api/v2010/account/conference/__init__.py
new file mode 100644
index 00000000..672d9d0f
--- /dev/null
+++ b/venv/Lib/site-packages/twilio/rest/api/v2010/account/conference/__init__.py
@@ -0,0 +1,791 @@
+r"""
+ This code was generated by
+ ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __
+ | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/
+ | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \
+
+ Twilio - Api
+ This is the public Twilio REST API.
+
+ NOTE: This class is auto generated by OpenAPI Generator.
+ https://openapi-generator.tech
+ Do not edit the class manually.
+"""
+
+from datetime import date, datetime
+from typing import Any, Dict, List, Optional, Union, Iterator, AsyncIterator
+from twilio.base import deserialize, serialize, values
+from twilio.base.instance_context import InstanceContext
+from twilio.base.instance_resource import InstanceResource
+from twilio.base.list_resource import ListResource
+from twilio.base.version import Version
+from twilio.base.page import Page
+from twilio.rest.api.v2010.account.conference.participant import ParticipantList
+from twilio.rest.api.v2010.account.conference.recording import RecordingList
+
+
+class ConferenceInstance(InstanceResource):
+
+ class ReasonConferenceEnded(object):
+ CONFERENCE_ENDED_VIA_API = "conference-ended-via-api"
+ PARTICIPANT_WITH_END_CONFERENCE_ON_EXIT_LEFT = (
+ "participant-with-end-conference-on-exit-left"
+ )
+ PARTICIPANT_WITH_END_CONFERENCE_ON_EXIT_KICKED = (
+ "participant-with-end-conference-on-exit-kicked"
+ )
+ LAST_PARTICIPANT_KICKED = "last-participant-kicked"
+ LAST_PARTICIPANT_LEFT = "last-participant-left"
+
+ class Status(object):
+ INIT = "init"
+ IN_PROGRESS = "in-progress"
+ COMPLETED = "completed"
+
+ class UpdateStatus(object):
+ COMPLETED = "completed"
+
+ """
+ :ivar account_sid: The SID of the [Account](https://www.twilio.com/docs/iam/api/account) that created this Conference resource.
+ :ivar date_created: The date and time in UTC that this resource was created specified in [RFC 2822](https://www.ietf.org/rfc/rfc2822.txt) format.
+ :ivar date_updated: The date and time in UTC that this resource was last updated, specified in [RFC 2822](https://www.ietf.org/rfc/rfc2822.txt) format.
+ :ivar api_version: The API version used to create this conference.
+ :ivar friendly_name: A string that you assigned to describe this conference room. Maximum length is 128 characters.
+ :ivar region: A string that represents the Twilio Region where the conference audio was mixed. May be `us1`, `us2`, `ie1`, `de1`, `sg1`, `br1`, `au1`, and `jp1`. Basic conference audio will always be mixed in `us1`. Global Conference audio will be mixed nearest to the majority of participants.
+ :ivar sid: The unique, Twilio-provided string used to identify this Conference resource.
+ :ivar status:
+ :ivar uri: The URI of this resource, relative to `https://api.twilio.com`.
+ :ivar subresource_uris: A list of related resources identified by their URIs relative to `https://api.twilio.com`.
+ :ivar reason_conference_ended:
+ :ivar call_sid_ending_conference: The call SID that caused the conference to end.
+ """
+
+ def __init__(
+ self,
+ version: Version,
+ payload: Dict[str, Any],
+ account_sid: str,
+ sid: Optional[str] = None,
+ ):
+ super().__init__(version)
+
+ self.account_sid: Optional[str] = payload.get("account_sid")
+ self.date_created: Optional[datetime] = deserialize.rfc2822_datetime(
+ payload.get("date_created")
+ )
+ self.date_updated: Optional[datetime] = deserialize.rfc2822_datetime(
+ payload.get("date_updated")
+ )
+ self.api_version: Optional[str] = payload.get("api_version")
+ self.friendly_name: Optional[str] = payload.get("friendly_name")
+ self.region: Optional[str] = payload.get("region")
+ self.sid: Optional[str] = payload.get("sid")
+ self.status: Optional["ConferenceInstance.Status"] = payload.get("status")
+ self.uri: Optional[str] = payload.get("uri")
+ self.subresource_uris: Optional[Dict[str, object]] = payload.get(
+ "subresource_uris"
+ )
+ self.reason_conference_ended: Optional[
+ "ConferenceInstance.ReasonConferenceEnded"
+ ] = payload.get("reason_conference_ended")
+ self.call_sid_ending_conference: Optional[str] = payload.get(
+ "call_sid_ending_conference"
+ )
+
+ self._solution = {
+ "account_sid": account_sid,
+ "sid": sid or self.sid,
+ }
+ self._context: Optional[ConferenceContext] = None
+
+ @property
+ def _proxy(self) -> "ConferenceContext":
+ """
+ Generate an instance context for the instance, the context is capable of
+ performing various actions. All instance actions are proxied to the context
+
+ :returns: ConferenceContext for this ConferenceInstance
+ """
+ if self._context is None:
+ self._context = ConferenceContext(
+ self._version,
+ account_sid=self._solution["account_sid"],
+ sid=self._solution["sid"],
+ )
+ return self._context
+
+ def fetch(self) -> "ConferenceInstance":
+ """
+ Fetch the ConferenceInstance
+
+
+ :returns: The fetched ConferenceInstance
+ """
+ return self._proxy.fetch()
+
+ async def fetch_async(self) -> "ConferenceInstance":
+ """
+ Asynchronous coroutine to fetch the ConferenceInstance
+
+
+ :returns: The fetched ConferenceInstance
+ """
+ return await self._proxy.fetch_async()
+
+ def update(
+ self,
+ status: Union["ConferenceInstance.UpdateStatus", object] = values.unset,
+ announce_url: Union[str, object] = values.unset,
+ announce_method: Union[str, object] = values.unset,
+ ) -> "ConferenceInstance":
+ """
+ Update the ConferenceInstance
+
+ :param status:
+ :param announce_url: The URL we should call to announce something into the conference. The URL may return an MP3 file, a WAV file, or a TwiML document that contains ``, ``, ``, or `` verbs.
+ :param announce_method: The HTTP method used to call `announce_url`. Can be: `GET` or `POST` and the default is `POST`
+
+ :returns: The updated ConferenceInstance
+ """
+ return self._proxy.update(
+ status=status,
+ announce_url=announce_url,
+ announce_method=announce_method,
+ )
+
+ async def update_async(
+ self,
+ status: Union["ConferenceInstance.UpdateStatus", object] = values.unset,
+ announce_url: Union[str, object] = values.unset,
+ announce_method: Union[str, object] = values.unset,
+ ) -> "ConferenceInstance":
+ """
+ Asynchronous coroutine to update the ConferenceInstance
+
+ :param status:
+ :param announce_url: The URL we should call to announce something into the conference. The URL may return an MP3 file, a WAV file, or a TwiML document that contains ``, ``, ``, or `` verbs.
+ :param announce_method: The HTTP method used to call `announce_url`. Can be: `GET` or `POST` and the default is `POST`
+
+ :returns: The updated ConferenceInstance
+ """
+ return await self._proxy.update_async(
+ status=status,
+ announce_url=announce_url,
+ announce_method=announce_method,
+ )
+
+ @property
+ def participants(self) -> ParticipantList:
+ """
+ Access the participants
+ """
+ return self._proxy.participants
+
+ @property
+ def recordings(self) -> RecordingList:
+ """
+ Access the recordings
+ """
+ return self._proxy.recordings
+
+ def __repr__(self) -> str:
+ """
+ Provide a friendly representation
+
+ :returns: Machine friendly representation
+ """
+ context = " ".join("{}={}".format(k, v) for k, v in self._solution.items())
+ return "