ZhengyangZhang commited on
Commit
45b097b
·
verified ·
1 Parent(s): 9d4b6c6

Add files using upload-large-folder tool

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. lib/python3.12/site-packages/cloudpickle-3.1.2.dist-info/INSTALLER +1 -0
  2. lib/python3.12/site-packages/cloudpickle-3.1.2.dist-info/METADATA +187 -0
  3. lib/python3.12/site-packages/cloudpickle-3.1.2.dist-info/RECORD +11 -0
  4. lib/python3.12/site-packages/cloudpickle-3.1.2.dist-info/WHEEL +4 -0
  5. lib/python3.12/site-packages/cloudpickle-3.1.2.dist-info/licenses/LICENSE +32 -0
  6. lib/python3.12/site-packages/compressed_tensors-0.9.3.dist-info/INSTALLER +1 -0
  7. lib/python3.12/site-packages/compressed_tensors-0.9.3.dist-info/METADATA +169 -0
  8. lib/python3.12/site-packages/compressed_tensors-0.9.3.dist-info/RECORD +101 -0
  9. lib/python3.12/site-packages/compressed_tensors-0.9.3.dist-info/REQUESTED +0 -0
  10. lib/python3.12/site-packages/compressed_tensors-0.9.3.dist-info/WHEEL +5 -0
  11. lib/python3.12/site-packages/compressed_tensors-0.9.3.dist-info/licenses/LICENSE +201 -0
  12. lib/python3.12/site-packages/compressed_tensors-0.9.3.dist-info/top_level.txt +1 -0
  13. lib/python3.12/site-packages/fastapi/__init__.py +25 -0
  14. lib/python3.12/site-packages/fastapi/__main__.py +3 -0
  15. lib/python3.12/site-packages/fastapi/__pycache__/param_functions.cpython-312.pyc +0 -0
  16. lib/python3.12/site-packages/fastapi/_compat.py +659 -0
  17. lib/python3.12/site-packages/fastapi/applications.py +0 -0
  18. lib/python3.12/site-packages/fastapi/background.py +59 -0
  19. lib/python3.12/site-packages/fastapi/cli.py +13 -0
  20. lib/python3.12/site-packages/fastapi/concurrency.py +39 -0
  21. lib/python3.12/site-packages/fastapi/datastructures.py +204 -0
  22. lib/python3.12/site-packages/fastapi/encoders.py +343 -0
  23. lib/python3.12/site-packages/fastapi/exception_handlers.py +34 -0
  24. lib/python3.12/site-packages/fastapi/exceptions.py +176 -0
  25. lib/python3.12/site-packages/fastapi/logger.py +3 -0
  26. lib/python3.12/site-packages/fastapi/openapi/__init__.py +0 -0
  27. lib/python3.12/site-packages/fastapi/openapi/__pycache__/__init__.cpython-312.pyc +0 -0
  28. lib/python3.12/site-packages/fastapi/openapi/__pycache__/constants.cpython-312.pyc +0 -0
  29. lib/python3.12/site-packages/fastapi/openapi/__pycache__/docs.cpython-312.pyc +0 -0
  30. lib/python3.12/site-packages/fastapi/openapi/__pycache__/models.cpython-312.pyc +0 -0
  31. lib/python3.12/site-packages/fastapi/openapi/__pycache__/utils.cpython-312.pyc +0 -0
  32. lib/python3.12/site-packages/fastapi/openapi/constants.py +3 -0
  33. lib/python3.12/site-packages/fastapi/openapi/docs.py +344 -0
  34. lib/python3.12/site-packages/fastapi/openapi/models.py +445 -0
  35. lib/python3.12/site-packages/fastapi/openapi/utils.py +569 -0
  36. lib/python3.12/site-packages/fastapi/param_functions.py +2360 -0
  37. lib/python3.12/site-packages/fastapi/params.py +786 -0
  38. lib/python3.12/site-packages/fastapi/py.typed +0 -0
  39. lib/python3.12/site-packages/fastapi/requests.py +2 -0
  40. lib/python3.12/site-packages/fastapi/responses.py +48 -0
  41. lib/python3.12/site-packages/fastapi/routing.py +0 -0
  42. lib/python3.12/site-packages/fastapi/security/__init__.py +15 -0
  43. lib/python3.12/site-packages/fastapi/security/__pycache__/__init__.cpython-312.pyc +0 -0
  44. lib/python3.12/site-packages/fastapi/security/__pycache__/api_key.cpython-312.pyc +0 -0
  45. lib/python3.12/site-packages/fastapi/security/__pycache__/base.cpython-312.pyc +0 -0
  46. lib/python3.12/site-packages/fastapi/security/__pycache__/http.cpython-312.pyc +0 -0
  47. lib/python3.12/site-packages/fastapi/security/__pycache__/oauth2.cpython-312.pyc +0 -0
  48. lib/python3.12/site-packages/fastapi/security/__pycache__/open_id_connect_url.cpython-312.pyc +0 -0
  49. lib/python3.12/site-packages/fastapi/security/__pycache__/utils.cpython-312.pyc +0 -0
  50. lib/python3.12/site-packages/fastapi/security/api_key.py +288 -0
lib/python3.12/site-packages/cloudpickle-3.1.2.dist-info/INSTALLER ADDED
@@ -0,0 +1 @@
 
 
1
+ pip
lib/python3.12/site-packages/cloudpickle-3.1.2.dist-info/METADATA ADDED
@@ -0,0 +1,187 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Metadata-Version: 2.4
2
+ Name: cloudpickle
3
+ Version: 3.1.2
4
+ Summary: Pickler class to extend the standard pickle.Pickler functionality
5
+ Home-page: https://github.com/cloudpipe/cloudpickle
6
+ Author: The cloudpickle developer team
7
+ Author-email: cloudpipe@googlegroups.com
8
+ Requires-Python: >=3.8
9
+ Description-Content-Type: text/markdown
10
+ License: BSD-3-Clause
11
+ Classifier: Development Status :: 5 - Production/Stable
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: BSD License
14
+ Classifier: Operating System :: POSIX
15
+ Classifier: Operating System :: Microsoft :: Windows
16
+ Classifier: Operating System :: MacOS :: MacOS X
17
+ Classifier: Programming Language :: Python :: 3.8
18
+ Classifier: Programming Language :: Python :: 3.9
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Programming Language :: Python :: 3.13
23
+ Classifier: Programming Language :: Python :: 3.14
24
+ Classifier: Programming Language :: Python :: Implementation :: CPython
25
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
26
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
27
+ Classifier: Topic :: Scientific/Engineering
28
+ Classifier: Topic :: System :: Distributed Computing
29
+ License-File: LICENSE
30
+
31
+ # cloudpickle
32
+
33
+ [![Automated Tests](https://github.com/cloudpipe/cloudpickle/workflows/Automated%20Tests/badge.svg?branch=master&event=push)](https://github.com/cloudpipe/cloudpickle/actions)
34
+ [![codecov.io](https://codecov.io/github/cloudpipe/cloudpickle/coverage.svg?branch=master)](https://codecov.io/github/cloudpipe/cloudpickle?branch=master)
35
+
36
+ `cloudpickle` makes it possible to serialize Python constructs not supported
37
+ by the default `pickle` module from the Python standard library.
38
+
39
+ `cloudpickle` is especially useful for **cluster computing** where Python
40
+ code is shipped over the network to execute on remote hosts, possibly close
41
+ to the data.
42
+
43
+ Among other things, `cloudpickle` supports pickling for **lambda functions**
44
+ along with **functions and classes defined interactively** in the
45
+ `__main__` module (for instance in a script, a shell or a Jupyter notebook).
46
+
47
+ Cloudpickle can only be used to send objects between the **exact same version
48
+ of Python**.
49
+
50
+ Using `cloudpickle` for **long-term object storage is not supported and
51
+ strongly discouraged.**
52
+
53
+ **Security notice**: one should **only load pickle data from trusted sources** as
54
+ otherwise `pickle.load` can lead to arbitrary code execution resulting in a critical
55
+ security vulnerability.
56
+
57
+
58
+ Installation
59
+ ------------
60
+
61
+ The latest release of `cloudpickle` is available from
62
+ [pypi](https://pypi.python.org/pypi/cloudpickle):
63
+
64
+ pip install cloudpickle
65
+
66
+
67
+ Examples
68
+ --------
69
+
70
+ Pickling a lambda expression:
71
+
72
+ ```python
73
+ >>> import cloudpickle
74
+ >>> squared = lambda x: x ** 2
75
+ >>> pickled_lambda = cloudpickle.dumps(squared)
76
+
77
+ >>> import pickle
78
+ >>> new_squared = pickle.loads(pickled_lambda)
79
+ >>> new_squared(2)
80
+ 4
81
+ ```
82
+
83
+ Pickling a function interactively defined in a Python shell session
84
+ (in the `__main__` module):
85
+
86
+ ```python
87
+ >>> CONSTANT = 42
88
+ >>> def my_function(data: int) -> int:
89
+ ... return data + CONSTANT
90
+ ...
91
+ >>> pickled_function = cloudpickle.dumps(my_function)
92
+ >>> depickled_function = pickle.loads(pickled_function)
93
+ >>> depickled_function
94
+ <function __main__.my_function(data:int) -> int>
95
+ >>> depickled_function(43)
96
+ 85
97
+ ```
98
+
99
+
100
+ Overriding pickle's serialization mechanism for importable constructs:
101
+ ----------------------------------------------------------------------
102
+
103
+ An important difference between `cloudpickle` and `pickle` is that
104
+ `cloudpickle` can serialize a function or class **by value**, whereas `pickle`
105
+ can only serialize it **by reference**. Serialization by reference treats
106
+ functions and classes as attributes of modules, and pickles them through
107
+ instructions that trigger the import of their module at load time.
108
+ Serialization by reference is thus limited in that it assumes that the module
109
+ containing the function or class is available/importable in the unpickling
110
+ environment. This assumption breaks when pickling constructs defined in an
111
+ interactive session, a case that is automatically detected by `cloudpickle`,
112
+ that pickles such constructs **by value**.
113
+
114
+ Another case where the importability assumption is expected to break is when
115
+ developing a module in a distributed execution environment: the worker
116
+ processes may not have access to the said module, for example if they live on a
117
+ different machine than the process in which the module is being developed. By
118
+ itself, `cloudpickle` cannot detect such "locally importable" modules and
119
+ switch to serialization by value; instead, it relies on its default mode, which
120
+ is serialization by reference. However, since `cloudpickle 2.0.0`, one can
121
+ explicitly specify modules for which serialization by value should be used,
122
+ using the
123
+ `register_pickle_by_value(module)`/`/unregister_pickle_by_value(module)` API:
124
+
125
+ ```python
126
+ >>> import cloudpickle
127
+ >>> import my_module
128
+ >>> cloudpickle.register_pickle_by_value(my_module)
129
+ >>> cloudpickle.dumps(my_module.my_function) # my_function is pickled by value
130
+ >>> cloudpickle.unregister_pickle_by_value(my_module)
131
+ >>> cloudpickle.dumps(my_module.my_function) # my_function is pickled by reference
132
+ ```
133
+
134
+ Using this API, there is no need to re-install the new version of the module on
135
+ all the worker nodes nor to restart the workers: restarting the client Python
136
+ process with the new source code is enough.
137
+
138
+ Note that this feature is still **experimental**, and may fail in the following
139
+ situations:
140
+
141
+ - If the body of a function/class pickled by value contains an `import` statement:
142
+ ```python
143
+ >>> def f():
144
+ >>> ... from another_module import g
145
+ >>> ... # calling f in the unpickling environment may fail if another_module
146
+ >>> ... # is unavailable
147
+ >>> ... return g() + 1
148
+ ```
149
+
150
+ - If a function pickled by reference uses a function pickled by value during its execution.
151
+
152
+
153
+ Running the tests
154
+ -----------------
155
+
156
+ - With `tox`, to test run the tests for all the supported versions of
157
+ Python and PyPy:
158
+
159
+ pip install tox
160
+ tox
161
+
162
+ or alternatively for a specific environment:
163
+
164
+ tox -e py312
165
+
166
+
167
+ - With `pytest` to only run the tests for your current version of
168
+ Python:
169
+
170
+ pip install -r dev-requirements.txt
171
+ PYTHONPATH='.:tests' pytest
172
+
173
+ History
174
+ -------
175
+
176
+ `cloudpickle` was initially developed by [picloud.com](http://web.archive.org/web/20140721022102/http://blog.picloud.com/2013/11/17/picloud-has-joined-dropbox/) and shipped as part of
177
+ the client SDK.
178
+
179
+ A copy of `cloudpickle.py` was included as part of PySpark, the Python
180
+ interface to [Apache Spark](https://spark.apache.org/). Davies Liu, Josh
181
+ Rosen, Thom Neale and other Apache Spark developers improved it significantly,
182
+ most notably to add support for PyPy and Python 3.
183
+
184
+ The aim of the `cloudpickle` project is to make that work available to a wider
185
+ audience outside of the Spark ecosystem and to make it easier to improve it
186
+ further notably with the help of a dedicated non-regression test suite.
187
+
lib/python3.12/site-packages/cloudpickle-3.1.2.dist-info/RECORD ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ cloudpickle-3.1.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
2
+ cloudpickle-3.1.2.dist-info/METADATA,sha256=PQJjv-nuTyOyRL3K_3OsvnoZV-v4J0O2rkJpOtxI1yE,7079
3
+ cloudpickle-3.1.2.dist-info/RECORD,,
4
+ cloudpickle-3.1.2.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
5
+ cloudpickle-3.1.2.dist-info/licenses/LICENSE,sha256=MCnqNBc-n9wjOtMV3GsQC9HqcfUpscGvl2ZKJy_cVfU,1754
6
+ cloudpickle/__init__.py,sha256=ErKyvqqAErOkbCowrizhGpN9DN-TaD22QtqI9CQ9sDw,308
7
+ cloudpickle/__pycache__/__init__.cpython-312.pyc,,
8
+ cloudpickle/__pycache__/cloudpickle.cpython-312.pyc,,
9
+ cloudpickle/__pycache__/cloudpickle_fast.cpython-312.pyc,,
10
+ cloudpickle/cloudpickle.py,sha256=KcLA_uAxp2KuMJb9vaTVve7FLFUQu7mYkD3dCscxeRc,58874
11
+ cloudpickle/cloudpickle_fast.py,sha256=AI5ZKf2AbLNxD8lXyLDpKZyzeZ2ofFtdK1ZWFq_ec1c,323
lib/python3.12/site-packages/cloudpickle-3.1.2.dist-info/WHEEL ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ Wheel-Version: 1.0
2
+ Generator: flit 3.12.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
lib/python3.12/site-packages/cloudpickle-3.1.2.dist-info/licenses/LICENSE ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ This module was extracted from the `cloud` package, developed by
2
+ PiCloud, Inc.
3
+
4
+ Copyright (c) 2015, Cloudpickle contributors.
5
+ Copyright (c) 2012, Regents of the University of California.
6
+ Copyright (c) 2009 PiCloud, Inc. http://www.picloud.com.
7
+ All rights reserved.
8
+
9
+ Redistribution and use in source and binary forms, with or without
10
+ modification, are permitted provided that the following conditions
11
+ are met:
12
+ * Redistributions of source code must retain the above copyright
13
+ notice, this list of conditions and the following disclaimer.
14
+ * Redistributions in binary form must reproduce the above copyright
15
+ notice, this list of conditions and the following disclaimer in the
16
+ documentation and/or other materials provided with the distribution.
17
+ * Neither the name of the University of California, Berkeley nor the
18
+ names of its contributors may be used to endorse or promote
19
+ products derived from this software without specific prior written
20
+ permission.
21
+
22
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26
+ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
28
+ TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
lib/python3.12/site-packages/compressed_tensors-0.9.3.dist-info/INSTALLER ADDED
@@ -0,0 +1 @@
 
 
1
+ pip
lib/python3.12/site-packages/compressed_tensors-0.9.3.dist-info/METADATA ADDED
@@ -0,0 +1,169 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Metadata-Version: 2.4
2
+ Name: compressed-tensors
3
+ Version: 0.9.3
4
+ Summary: Library for utilization of compressed safetensors of neural network models
5
+ Home-page: https://github.com/neuralmagic/compressed-tensors
6
+ Author: Neuralmagic, Inc.
7
+ Author-email: support@neuralmagic.com
8
+ License: Apache 2.0
9
+ Description-Content-Type: text/markdown
10
+ License-File: LICENSE
11
+ Requires-Dist: torch>=1.7.0
12
+ Requires-Dist: transformers
13
+ Requires-Dist: pydantic>=2.0
14
+ Provides-Extra: dev
15
+ Requires-Dist: black==22.12.0; extra == "dev"
16
+ Requires-Dist: isort==5.8.0; extra == "dev"
17
+ Requires-Dist: wheel>=0.36.2; extra == "dev"
18
+ Requires-Dist: flake8>=3.8.3; extra == "dev"
19
+ Requires-Dist: pytest>=6.0.0; extra == "dev"
20
+ Requires-Dist: nbconvert>=7.16.3; extra == "dev"
21
+ Provides-Extra: accelerate
22
+ Requires-Dist: accelerate; extra == "accelerate"
23
+ Dynamic: author
24
+ Dynamic: author-email
25
+ Dynamic: description
26
+ Dynamic: description-content-type
27
+ Dynamic: home-page
28
+ Dynamic: license
29
+ Dynamic: license-file
30
+ Dynamic: provides-extra
31
+ Dynamic: requires-dist
32
+ Dynamic: summary
33
+
34
+ # compressed-tensors
35
+
36
+ The `compressed-tensors` library extends the [safetensors](https://github.com/huggingface/safetensors) format, providing a versatile and efficient way to store and manage compressed tensor data. This library supports various quantization and sparsity schemes, making it a unified format for handling different model optimizations like GPTQ, AWQ, SmoothQuant, INT8, FP8, SparseGPT, and more.
37
+
38
+ ## Why `compressed-tensors`?
39
+
40
+ As model compression becomes increasingly important for efficient deployment of LLMs, the landscape of quantization and compression techniques has become increasingly fragmented.
41
+ Each method often comes with its own storage format and loading procedures, making it challenging to work with multiple techniques or switch between them.
42
+ `compressed-tensors` addresses this by providing a single, extensible format that can represent a wide variety of compression schemes.
43
+
44
+ * **Unified Checkpoint Format**: Supports various compression schemes in a single, consistent format.
45
+ * **Wide Compatibility**: Works with popular quantization methods like GPTQ, SmoothQuant, and FP8. See [llm-compressor](https://github.com/vllm-project/llm-compressor)
46
+ * **Flexible Quantization Support**:
47
+ * Weight-only quantization (e.g., W4A16, W8A16, WnA16)
48
+ * Activation quantization (e.g., W8A8)
49
+ * KV cache quantization
50
+ * Non-uniform schemes (different layers can be quantized in different ways!)
51
+ * **Sparsity Support**: Handles both unstructured and semi-structured (e.g., 2:4) sparsity patterns.
52
+ * **Open-Source Integration**: Designed to work seamlessly with Hugging Face models and PyTorch.
53
+
54
+ This allows developers and researchers to easily experiment with composing different quantization methods, simplify model deployment pipelines, and reduce the overhead of supporting multiple compression formats in inference engines.
55
+
56
+ ## Installation
57
+
58
+ ### From [PyPI](https://pypi.org/project/compressed-tensors)
59
+
60
+ Stable release:
61
+ ```bash
62
+ pip install compressed-tensors
63
+ ```
64
+
65
+ Nightly release:
66
+ ```bash
67
+ pip install compressed-tensors-nightly
68
+ ```
69
+
70
+ ### From Source
71
+
72
+ ```bash
73
+ git clone https://github.com/neuralmagic/compressed-tensors
74
+ cd compressed-tensors
75
+ pip install -e .
76
+ ```
77
+
78
+ ## Getting started
79
+
80
+ ### Saving/Loading Compressed Tensors (Bitmask Compression)
81
+
82
+ The function `save_compressed` uses the `compression_format` argument to apply compression to tensors.
83
+ The function `load_compressed` reverses the process: converts the compressed weights on disk to decompressed weights in device memory.
84
+
85
+ ```python
86
+ from compressed_tensors import save_compressed, load_compressed, BitmaskConfig
87
+ from torch import Tensor
88
+ from typing import Dict
89
+
90
+ # the example BitmaskConfig method efficiently compresses
91
+ # tensors with large number of zero entries
92
+ compression_config = BitmaskConfig()
93
+
94
+ tensors: Dict[str, Tensor] = {"tensor_1": Tensor(
95
+ [[0.0, 0.0, 0.0],
96
+ [1.0, 1.0, 1.0]]
97
+ )}
98
+ # compress tensors using BitmaskConfig compression format (save them efficiently on disk)
99
+ save_compressed(tensors, "model.safetensors", compression_format=compression_config.format)
100
+
101
+ # decompress tensors (load_compressed returns a generator for memory efficiency)
102
+ decompressed_tensors = {}
103
+ for tensor_name, tensor in load_compressed("model.safetensors", compression_config = compression_config):
104
+ decompressed_tensors[tensor_name] = tensor
105
+ ```
106
+
107
+ ## Saving/Loading Compressed Models (Bitmask Compression)
108
+
109
+ We can apply bitmask compression to a whole model. For more detailed example see `example` directory.
110
+ ```python
111
+ from compressed_tensors import save_compressed_model, load_compressed, BitmaskConfig
112
+ from transformers import AutoModelForCausalLM
113
+
114
+ model_name = "neuralmagic/llama2.c-stories110M-pruned50"
115
+ model = AutoModelForCausalLM.from_pretrained(model_name, torch_dtype="auto")
116
+
117
+ original_state_dict = model.state_dict()
118
+
119
+ compression_config = BitmaskConfig()
120
+
121
+ # save compressed model weights
122
+ save_compressed_model(model, "compressed_model.safetensors", compression_format=compression_config.format)
123
+
124
+ # load compressed model weights (`dict` turns generator into a dictionary)
125
+ state_dict = dict(load_compressed("compressed_model.safetensors", compression_config))
126
+ ```
127
+
128
+ For more in-depth tutorial on bitmask compression, refer to the [notebook](https://github.com/neuralmagic/compressed-tensors/blob/d707c5b84bc3fef164aebdcd97cb6eaa571982f8/examples/bitmask_compression.ipynb).
129
+
130
+
131
+ ## Saving a Compressed Model with PTQ
132
+
133
+ We can use compressed-tensors to run basic post training quantization (PTQ) and save the quantized model compressed on disk
134
+
135
+ ```python
136
+ model_name = "TinyLlama/TinyLlama-1.1B-intermediate-step-1431k-3T"
137
+ model = AutoModelForCausalLM.from_pretrained(model_name, device_map="cuda:0", torch_dtype="auto")
138
+
139
+ config = QuantizationConfig.parse_file("./examples/bit_packing/int4_config.json")
140
+ config.quantization_status = QuantizationStatus.CALIBRATION
141
+ apply_quantization_config(model, config)
142
+
143
+ dataset = load_dataset("ptb_text_only")["train"]
144
+ tokenizer = AutoTokenizer.from_pretrained(model_name)
145
+
146
+ def tokenize_function(examples):
147
+ return tokenizer(examples["sentence"], padding=False, truncation=True, max_length=1024)
148
+
149
+ tokenized_dataset = dataset.map(tokenize_function, batched=True)
150
+ data_loader = DataLoader(tokenized_dataset, batch_size=1, collate_fn=DefaultDataCollator())
151
+
152
+ with torch.no_grad():
153
+ for idx, sample in tqdm(enumerate(data_loader), desc="Running calibration"):
154
+ sample = {key: value.to(device) for key,value in sample.items()}
155
+ _ = model(**sample)
156
+
157
+ if idx >= 512:
158
+ break
159
+
160
+ model.apply(freeze_module_quantization)
161
+ model.apply(compress_quantized_weights)
162
+
163
+ output_dir = "./ex_llama1.1b_w4a16_packed_quantize"
164
+ compressor = ModelCompressor(quantization_config=config)
165
+ compressed_state_dict = compressor.compress(model)
166
+ model.save_pretrained(output_dir, state_dict=compressed_state_dict)
167
+ ```
168
+
169
+ For more in-depth tutorial on quantization compression, refer to the [notebook](./examples/quantize_and_pack_int4.ipynb).
lib/python3.12/site-packages/compressed_tensors-0.9.3.dist-info/RECORD ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ compressed_tensors-0.9.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
2
+ compressed_tensors-0.9.3.dist-info/METADATA,sha256=zs3aFaG-BGV9hqJbW9Zwzex0TVcM5sPZhiaeVx2qjR0,6997
3
+ compressed_tensors-0.9.3.dist-info/RECORD,,
4
+ compressed_tensors-0.9.3.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ compressed_tensors-0.9.3.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
6
+ compressed_tensors-0.9.3.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
7
+ compressed_tensors-0.9.3.dist-info/top_level.txt,sha256=w2i-GyPs2s1UwVxvutSvN_lM22SXC2hQFBmoMcPnV7Y,19
8
+ compressed_tensors/__init__.py,sha256=UtKmifNeBCSE2TZSAfduVNNzHY-3V7bLjZ7n7RuXLOE,812
9
+ compressed_tensors/__pycache__/__init__.cpython-312.pyc,,
10
+ compressed_tensors/__pycache__/base.cpython-312.pyc,,
11
+ compressed_tensors/__pycache__/version.cpython-312.pyc,,
12
+ compressed_tensors/base.py,sha256=73HYH7HY7O2roC89yG_piPFnZwrBfn_i7HmKl90SKc0,875
13
+ compressed_tensors/compressors/__init__.py,sha256=smSygTSfcfuujRrAXDc6uZm4L_ccV1tWZewqVnOb4lM,825
14
+ compressed_tensors/compressors/__pycache__/__init__.cpython-312.pyc,,
15
+ compressed_tensors/compressors/__pycache__/base.cpython-312.pyc,,
16
+ compressed_tensors/compressors/__pycache__/helpers.cpython-312.pyc,,
17
+ compressed_tensors/compressors/base.py,sha256=x8dQrWVEurynXw03yHJZTaAmrRTOsdZJoHjmvs0IKwk,7002
18
+ compressed_tensors/compressors/helpers.py,sha256=OK6qxX9j3bHwF9JfIYSGMgBJe2PWjlTA3byXKCJaTIQ,5431
19
+ compressed_tensors/compressors/model_compressors/__init__.py,sha256=5RGGPFu4YqEt_aOdFSQYFYFDjcZFJN0CsMqRtDZz3Js,666
20
+ compressed_tensors/compressors/model_compressors/__pycache__/__init__.cpython-312.pyc,,
21
+ compressed_tensors/compressors/model_compressors/__pycache__/model_compressor.cpython-312.pyc,,
22
+ compressed_tensors/compressors/model_compressors/model_compressor.py,sha256=n0gcrKwefJuO6b4LNjCynJQf7NNqNHDcoLlzZgTCPGc,23080
23
+ compressed_tensors/compressors/quantized_compressors/__init__.py,sha256=09UJq68Pht6Bf-4iP9xYl3tetKsncNPHD8IAGbePsr4,714
24
+ compressed_tensors/compressors/quantized_compressors/__pycache__/__init__.cpython-312.pyc,,
25
+ compressed_tensors/compressors/quantized_compressors/__pycache__/base.cpython-312.pyc,,
26
+ compressed_tensors/compressors/quantized_compressors/__pycache__/naive_quantized.cpython-312.pyc,,
27
+ compressed_tensors/compressors/quantized_compressors/__pycache__/pack_quantized.cpython-312.pyc,,
28
+ compressed_tensors/compressors/quantized_compressors/base.py,sha256=GXTSWgFAhksbno94Ulpth9-YM4a7NsDlx4oQGGB0swQ,8567
29
+ compressed_tensors/compressors/quantized_compressors/naive_quantized.py,sha256=fd0KlkSx6bvZ3xwIkK3jEUdPSUPs56Eua4dEDOtzKW0,5150
30
+ compressed_tensors/compressors/quantized_compressors/pack_quantized.py,sha256=zH2PocRe_T5yt1-3kLdZH9AUQWQyaVOi4U9nEJiYaWA,8509
31
+ compressed_tensors/compressors/sparse_compressors/__init__.py,sha256=Atuz-OdEgn8OCUhx7Ovd6gXdyImAI186uCR-uR0t_Nk,737
32
+ compressed_tensors/compressors/sparse_compressors/__pycache__/__init__.cpython-312.pyc,,
33
+ compressed_tensors/compressors/sparse_compressors/__pycache__/base.cpython-312.pyc,,
34
+ compressed_tensors/compressors/sparse_compressors/__pycache__/dense.cpython-312.pyc,,
35
+ compressed_tensors/compressors/sparse_compressors/__pycache__/sparse_24_bitmask.cpython-312.pyc,,
36
+ compressed_tensors/compressors/sparse_compressors/__pycache__/sparse_bitmask.cpython-312.pyc,,
37
+ compressed_tensors/compressors/sparse_compressors/base.py,sha256=CVWbs3sd7GKJEoWOIKImABQ01VOTX8dlF2AQaEVPotw,5883
38
+ compressed_tensors/compressors/sparse_compressors/dense.py,sha256=_uW_HISeDNz4yboSZWoh6GwrkUE6HFibzPQSKrHOCkg,1505
39
+ compressed_tensors/compressors/sparse_compressors/sparse_24_bitmask.py,sha256=mEKSSgpXookqYSJw3mlyP6cYYKD-eaIvpQMvi4JO6TY,8807
40
+ compressed_tensors/compressors/sparse_compressors/sparse_bitmask.py,sha256=S8vW0FI9ep_XtUQOxj0P5utJt3vKEYOHjWEPp-Xd9aY,5820
41
+ compressed_tensors/compressors/sparse_quantized_compressors/__init__.py,sha256=4f_cwcKXB1nVVMoiKgTFAc8jAPjPLElo-Df_EDm1_xw,675
42
+ compressed_tensors/compressors/sparse_quantized_compressors/__pycache__/__init__.cpython-312.pyc,,
43
+ compressed_tensors/compressors/sparse_quantized_compressors/__pycache__/marlin_24.cpython-312.pyc,,
44
+ compressed_tensors/compressors/sparse_quantized_compressors/marlin_24.py,sha256=xY0CdHXAzVHeDeSCD_I-5UZKcntKzd3FiKSP-ZqcSBs,9614
45
+ compressed_tensors/config/__init__.py,sha256=8sOoZ6xvYSC79mBvEtO8l6xk4PC80d29AnnJiGMrY2M,737
46
+ compressed_tensors/config/__pycache__/__init__.cpython-312.pyc,,
47
+ compressed_tensors/config/__pycache__/base.cpython-312.pyc,,
48
+ compressed_tensors/config/__pycache__/dense.cpython-312.pyc,,
49
+ compressed_tensors/config/__pycache__/sparse_24_bitmask.cpython-312.pyc,,
50
+ compressed_tensors/config/__pycache__/sparse_bitmask.cpython-312.pyc,,
51
+ compressed_tensors/config/base.py,sha256=R3iUmFf1MslEjin5LgwQbmfJHIsS7Uw0UIxfn780uqY,3479
52
+ compressed_tensors/config/dense.py,sha256=NgSxnFCnckU9-iunxEaqiFwqgdO7YYxlWKR74jNbjks,1317
53
+ compressed_tensors/config/sparse_24_bitmask.py,sha256=Lhj39zT2V1hxftprvxvneyhv45ShlXOKd75DBbDTyTE,1401
54
+ compressed_tensors/config/sparse_bitmask.py,sha256=pZUboRNZTu6NajGOQEFExoPknak5ynVAUeiiYpS1Gt8,1308
55
+ compressed_tensors/linear/__init__.py,sha256=fH6rjBYAxuwrTzBTlTjTgCYNyh6TCvCqajCz4Im4YrA,617
56
+ compressed_tensors/linear/__pycache__/__init__.cpython-312.pyc,,
57
+ compressed_tensors/linear/__pycache__/compressed_linear.cpython-312.pyc,,
58
+ compressed_tensors/linear/compressed_linear.py,sha256=_m6XpNcI53eeSHO8VdiuAM6UBTdpDhn5Ivd8iRMwEKc,3980
59
+ compressed_tensors/quantization/__init__.py,sha256=83J5bPB7PavN2TfCoW7_vEDhfYpm4TDrqYO9vdSQ5bk,760
60
+ compressed_tensors/quantization/__pycache__/__init__.cpython-312.pyc,,
61
+ compressed_tensors/quantization/__pycache__/quant_args.cpython-312.pyc,,
62
+ compressed_tensors/quantization/__pycache__/quant_config.cpython-312.pyc,,
63
+ compressed_tensors/quantization/__pycache__/quant_scheme.cpython-312.pyc,,
64
+ compressed_tensors/quantization/lifecycle/__init__.py,sha256=_uItzFWusyV74Zco_pHLOTdE9a83cL-R-ZdyQrBkIyw,772
65
+ compressed_tensors/quantization/lifecycle/__pycache__/__init__.cpython-312.pyc,,
66
+ compressed_tensors/quantization/lifecycle/__pycache__/apply.cpython-312.pyc,,
67
+ compressed_tensors/quantization/lifecycle/__pycache__/compressed.cpython-312.pyc,,
68
+ compressed_tensors/quantization/lifecycle/__pycache__/forward.cpython-312.pyc,,
69
+ compressed_tensors/quantization/lifecycle/__pycache__/helpers.cpython-312.pyc,,
70
+ compressed_tensors/quantization/lifecycle/__pycache__/initialize.cpython-312.pyc,,
71
+ compressed_tensors/quantization/lifecycle/apply.py,sha256=lZmCCSm1_o79iUAy460w6Bv9FaOvntVisMdS-dN9fnk,16594
72
+ compressed_tensors/quantization/lifecycle/compressed.py,sha256=Fj9n66IN0EWsOAkBHg3O0GlOQpxstqjCcs0ttzMXrJ0,2296
73
+ compressed_tensors/quantization/lifecycle/forward.py,sha256=DOWouUqfaLA4Qhg-ojVVBdhhSAlgZqFC26vZARxE0ko,12961
74
+ compressed_tensors/quantization/lifecycle/helpers.py,sha256=C0mhy2vJ0fCjVeN4kFNhw8Eq1wkteBGHiZ36RVLThRY,944
75
+ compressed_tensors/quantization/lifecycle/initialize.py,sha256=sK3PLm69N91QepBuq-83Qd2Br6XcOmRDpD5qo_WWNJo,7469
76
+ compressed_tensors/quantization/quant_args.py,sha256=sKpb8DcNObidjXjNol1Tn_Iih3ZXBycSp-fyz68TGhY,9117
77
+ compressed_tensors/quantization/quant_config.py,sha256=vx06wBo91p4LCb3Vzd-2eCTUeIf_Sz2ZXRP263eQyjQ,10385
78
+ compressed_tensors/quantization/quant_scheme.py,sha256=eQ0JrRZ80GX69fpwW87VzPzzhajhk4mUaJScjk82OY4,6010
79
+ compressed_tensors/quantization/utils/__init__.py,sha256=VdtEmP0bvuND_IGQnyqUPc5lnFp-1_yD7StKSX4x80w,656
80
+ compressed_tensors/quantization/utils/__pycache__/__init__.cpython-312.pyc,,
81
+ compressed_tensors/quantization/utils/__pycache__/helpers.cpython-312.pyc,,
82
+ compressed_tensors/quantization/utils/helpers.py,sha256=DBP-sGRpGAY01K0LFE7qqonNj4hkTYL_mXrMs2LtAD8,14100
83
+ compressed_tensors/registry/__init__.py,sha256=FwLSNYqfIrb5JD_6OK_MT4_svvKTN_nEhpgQlQvGbjI,658
84
+ compressed_tensors/registry/__pycache__/__init__.cpython-312.pyc,,
85
+ compressed_tensors/registry/__pycache__/registry.cpython-312.pyc,,
86
+ compressed_tensors/registry/registry.py,sha256=vRcjVB1ITfSbfYUaGndBBmqhip_5vsS62weorVg0iXo,11896
87
+ compressed_tensors/utils/__init__.py,sha256=gS4gSU2pwcAbsKj-6YMaqhm25udFy6ISYaWBf-myRSM,808
88
+ compressed_tensors/utils/__pycache__/__init__.cpython-312.pyc,,
89
+ compressed_tensors/utils/__pycache__/helpers.cpython-312.pyc,,
90
+ compressed_tensors/utils/__pycache__/offload.cpython-312.pyc,,
91
+ compressed_tensors/utils/__pycache__/permutations_24.cpython-312.pyc,,
92
+ compressed_tensors/utils/__pycache__/permute.cpython-312.pyc,,
93
+ compressed_tensors/utils/__pycache__/safetensors_load.cpython-312.pyc,,
94
+ compressed_tensors/utils/__pycache__/semi_structured_conversions.cpython-312.pyc,,
95
+ compressed_tensors/utils/helpers.py,sha256=RrNvzD08naEjEiXdU-FdZjQVda1nQywu1hA_GCDj0vg,10415
96
+ compressed_tensors/utils/offload.py,sha256=H4aAg21zUvJM2uwE6QCNYazX_p_o41yQUAgLLWBqR0w,14079
97
+ compressed_tensors/utils/permutations_24.py,sha256=kx6fsfDHebx94zsSzhXGyCyuC9sVyah6BUUir_StT28,2530
98
+ compressed_tensors/utils/permute.py,sha256=V6tJLKo3Syccj-viv4F7ZKZgJeCB-hl-dK8RKI_kBwI,2355
99
+ compressed_tensors/utils/safetensors_load.py,sha256=5SeM2hzLh77Ne8Vk7qR6-km7cf8bhov41ExpWITqX3A,11470
100
+ compressed_tensors/utils/semi_structured_conversions.py,sha256=XKNffPum54kPASgqKzgKvyeqWPAkair2XEQXjkp7ho8,13489
101
+ compressed_tensors/version.py,sha256=X4y5lqlF1QFUgl25iumzagpg3dzyVoLP6i82HZEhCJA,1585
lib/python3.12/site-packages/compressed_tensors-0.9.3.dist-info/REQUESTED ADDED
File without changes
lib/python3.12/site-packages/compressed_tensors-0.9.3.dist-info/WHEEL ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (78.1.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
lib/python3.12/site-packages/compressed_tensors-0.9.3.dist-info/licenses/LICENSE ADDED
@@ -0,0 +1,201 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright [yyyy] [name of copyright owner]
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
lib/python3.12/site-packages/compressed_tensors-0.9.3.dist-info/top_level.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ compressed_tensors
lib/python3.12/site-packages/fastapi/__init__.py ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """FastAPI framework, high performance, easy to learn, fast to code, ready for production"""
2
+
3
+ __version__ = "0.115.12"
4
+
5
+ from starlette import status as status
6
+
7
+ from .applications import FastAPI as FastAPI
8
+ from .background import BackgroundTasks as BackgroundTasks
9
+ from .datastructures import UploadFile as UploadFile
10
+ from .exceptions import HTTPException as HTTPException
11
+ from .exceptions import WebSocketException as WebSocketException
12
+ from .param_functions import Body as Body
13
+ from .param_functions import Cookie as Cookie
14
+ from .param_functions import Depends as Depends
15
+ from .param_functions import File as File
16
+ from .param_functions import Form as Form
17
+ from .param_functions import Header as Header
18
+ from .param_functions import Path as Path
19
+ from .param_functions import Query as Query
20
+ from .param_functions import Security as Security
21
+ from .requests import Request as Request
22
+ from .responses import Response as Response
23
+ from .routing import APIRouter as APIRouter
24
+ from .websockets import WebSocket as WebSocket
25
+ from .websockets import WebSocketDisconnect as WebSocketDisconnect
lib/python3.12/site-packages/fastapi/__main__.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ from fastapi.cli import main
2
+
3
+ main()
lib/python3.12/site-packages/fastapi/__pycache__/param_functions.cpython-312.pyc ADDED
Binary file (35.1 kB). View file
 
lib/python3.12/site-packages/fastapi/_compat.py ADDED
@@ -0,0 +1,659 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from collections import deque
2
+ from copy import copy
3
+ from dataclasses import dataclass, is_dataclass
4
+ from enum import Enum
5
+ from functools import lru_cache
6
+ from typing import (
7
+ Any,
8
+ Callable,
9
+ Deque,
10
+ Dict,
11
+ FrozenSet,
12
+ List,
13
+ Mapping,
14
+ Sequence,
15
+ Set,
16
+ Tuple,
17
+ Type,
18
+ Union,
19
+ )
20
+
21
+ from fastapi.exceptions import RequestErrorModel
22
+ from fastapi.types import IncEx, ModelNameMap, UnionType
23
+ from pydantic import BaseModel, create_model
24
+ from pydantic.version import VERSION as PYDANTIC_VERSION
25
+ from starlette.datastructures import UploadFile
26
+ from typing_extensions import Annotated, Literal, get_args, get_origin
27
+
28
+ PYDANTIC_VERSION_MINOR_TUPLE = tuple(int(x) for x in PYDANTIC_VERSION.split(".")[:2])
29
+ PYDANTIC_V2 = PYDANTIC_VERSION_MINOR_TUPLE[0] == 2
30
+
31
+
32
+ sequence_annotation_to_type = {
33
+ Sequence: list,
34
+ List: list,
35
+ list: list,
36
+ Tuple: tuple,
37
+ tuple: tuple,
38
+ Set: set,
39
+ set: set,
40
+ FrozenSet: frozenset,
41
+ frozenset: frozenset,
42
+ Deque: deque,
43
+ deque: deque,
44
+ }
45
+
46
+ sequence_types = tuple(sequence_annotation_to_type.keys())
47
+
48
+ Url: Type[Any]
49
+
50
+ if PYDANTIC_V2:
51
+ from pydantic import PydanticSchemaGenerationError as PydanticSchemaGenerationError
52
+ from pydantic import TypeAdapter
53
+ from pydantic import ValidationError as ValidationError
54
+ from pydantic._internal._schema_generation_shared import ( # type: ignore[attr-defined]
55
+ GetJsonSchemaHandler as GetJsonSchemaHandler,
56
+ )
57
+ from pydantic._internal._typing_extra import eval_type_lenient
58
+ from pydantic._internal._utils import lenient_issubclass as lenient_issubclass
59
+ from pydantic.fields import FieldInfo
60
+ from pydantic.json_schema import GenerateJsonSchema as GenerateJsonSchema
61
+ from pydantic.json_schema import JsonSchemaValue as JsonSchemaValue
62
+ from pydantic_core import CoreSchema as CoreSchema
63
+ from pydantic_core import PydanticUndefined, PydanticUndefinedType
64
+ from pydantic_core import Url as Url
65
+
66
+ try:
67
+ from pydantic_core.core_schema import (
68
+ with_info_plain_validator_function as with_info_plain_validator_function,
69
+ )
70
+ except ImportError: # pragma: no cover
71
+ from pydantic_core.core_schema import (
72
+ general_plain_validator_function as with_info_plain_validator_function, # noqa: F401
73
+ )
74
+
75
+ RequiredParam = PydanticUndefined
76
+ Undefined = PydanticUndefined
77
+ UndefinedType = PydanticUndefinedType
78
+ evaluate_forwardref = eval_type_lenient
79
+ Validator = Any
80
+
81
+ class BaseConfig:
82
+ pass
83
+
84
+ class ErrorWrapper(Exception):
85
+ pass
86
+
87
+ @dataclass
88
+ class ModelField:
89
+ field_info: FieldInfo
90
+ name: str
91
+ mode: Literal["validation", "serialization"] = "validation"
92
+
93
+ @property
94
+ def alias(self) -> str:
95
+ a = self.field_info.alias
96
+ return a if a is not None else self.name
97
+
98
+ @property
99
+ def required(self) -> bool:
100
+ return self.field_info.is_required()
101
+
102
+ @property
103
+ def default(self) -> Any:
104
+ return self.get_default()
105
+
106
+ @property
107
+ def type_(self) -> Any:
108
+ return self.field_info.annotation
109
+
110
+ def __post_init__(self) -> None:
111
+ self._type_adapter: TypeAdapter[Any] = TypeAdapter(
112
+ Annotated[self.field_info.annotation, self.field_info]
113
+ )
114
+
115
+ def get_default(self) -> Any:
116
+ if self.field_info.is_required():
117
+ return Undefined
118
+ return self.field_info.get_default(call_default_factory=True)
119
+
120
+ def validate(
121
+ self,
122
+ value: Any,
123
+ values: Dict[str, Any] = {}, # noqa: B006
124
+ *,
125
+ loc: Tuple[Union[int, str], ...] = (),
126
+ ) -> Tuple[Any, Union[List[Dict[str, Any]], None]]:
127
+ try:
128
+ return (
129
+ self._type_adapter.validate_python(value, from_attributes=True),
130
+ None,
131
+ )
132
+ except ValidationError as exc:
133
+ return None, _regenerate_error_with_loc(
134
+ errors=exc.errors(include_url=False), loc_prefix=loc
135
+ )
136
+
137
+ def serialize(
138
+ self,
139
+ value: Any,
140
+ *,
141
+ mode: Literal["json", "python"] = "json",
142
+ include: Union[IncEx, None] = None,
143
+ exclude: Union[IncEx, None] = None,
144
+ by_alias: bool = True,
145
+ exclude_unset: bool = False,
146
+ exclude_defaults: bool = False,
147
+ exclude_none: bool = False,
148
+ ) -> Any:
149
+ # What calls this code passes a value that already called
150
+ # self._type_adapter.validate_python(value)
151
+ return self._type_adapter.dump_python(
152
+ value,
153
+ mode=mode,
154
+ include=include,
155
+ exclude=exclude,
156
+ by_alias=by_alias,
157
+ exclude_unset=exclude_unset,
158
+ exclude_defaults=exclude_defaults,
159
+ exclude_none=exclude_none,
160
+ )
161
+
162
+ def __hash__(self) -> int:
163
+ # Each ModelField is unique for our purposes, to allow making a dict from
164
+ # ModelField to its JSON Schema.
165
+ return id(self)
166
+
167
+ def get_annotation_from_field_info(
168
+ annotation: Any, field_info: FieldInfo, field_name: str
169
+ ) -> Any:
170
+ return annotation
171
+
172
+ def _normalize_errors(errors: Sequence[Any]) -> List[Dict[str, Any]]:
173
+ return errors # type: ignore[return-value]
174
+
175
+ def _model_rebuild(model: Type[BaseModel]) -> None:
176
+ model.model_rebuild()
177
+
178
+ def _model_dump(
179
+ model: BaseModel, mode: Literal["json", "python"] = "json", **kwargs: Any
180
+ ) -> Any:
181
+ return model.model_dump(mode=mode, **kwargs)
182
+
183
+ def _get_model_config(model: BaseModel) -> Any:
184
+ return model.model_config
185
+
186
+ def get_schema_from_model_field(
187
+ *,
188
+ field: ModelField,
189
+ schema_generator: GenerateJsonSchema,
190
+ model_name_map: ModelNameMap,
191
+ field_mapping: Dict[
192
+ Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
193
+ ],
194
+ separate_input_output_schemas: bool = True,
195
+ ) -> Dict[str, Any]:
196
+ override_mode: Union[Literal["validation"], None] = (
197
+ None if separate_input_output_schemas else "validation"
198
+ )
199
+ # This expects that GenerateJsonSchema was already used to generate the definitions
200
+ json_schema = field_mapping[(field, override_mode or field.mode)]
201
+ if "$ref" not in json_schema:
202
+ # TODO remove when deprecating Pydantic v1
203
+ # Ref: https://github.com/pydantic/pydantic/blob/d61792cc42c80b13b23e3ffa74bc37ec7c77f7d1/pydantic/schema.py#L207
204
+ json_schema["title"] = (
205
+ field.field_info.title or field.alias.title().replace("_", " ")
206
+ )
207
+ return json_schema
208
+
209
+ def get_compat_model_name_map(fields: List[ModelField]) -> ModelNameMap:
210
+ return {}
211
+
212
+ def get_definitions(
213
+ *,
214
+ fields: List[ModelField],
215
+ schema_generator: GenerateJsonSchema,
216
+ model_name_map: ModelNameMap,
217
+ separate_input_output_schemas: bool = True,
218
+ ) -> Tuple[
219
+ Dict[
220
+ Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
221
+ ],
222
+ Dict[str, Dict[str, Any]],
223
+ ]:
224
+ override_mode: Union[Literal["validation"], None] = (
225
+ None if separate_input_output_schemas else "validation"
226
+ )
227
+ inputs = [
228
+ (field, override_mode or field.mode, field._type_adapter.core_schema)
229
+ for field in fields
230
+ ]
231
+ field_mapping, definitions = schema_generator.generate_definitions(
232
+ inputs=inputs
233
+ )
234
+ return field_mapping, definitions # type: ignore[return-value]
235
+
236
+ def is_scalar_field(field: ModelField) -> bool:
237
+ from fastapi import params
238
+
239
+ return field_annotation_is_scalar(
240
+ field.field_info.annotation
241
+ ) and not isinstance(field.field_info, params.Body)
242
+
243
+ def is_sequence_field(field: ModelField) -> bool:
244
+ return field_annotation_is_sequence(field.field_info.annotation)
245
+
246
+ def is_scalar_sequence_field(field: ModelField) -> bool:
247
+ return field_annotation_is_scalar_sequence(field.field_info.annotation)
248
+
249
+ def is_bytes_field(field: ModelField) -> bool:
250
+ return is_bytes_or_nonable_bytes_annotation(field.type_)
251
+
252
+ def is_bytes_sequence_field(field: ModelField) -> bool:
253
+ return is_bytes_sequence_annotation(field.type_)
254
+
255
+ def copy_field_info(*, field_info: FieldInfo, annotation: Any) -> FieldInfo:
256
+ cls = type(field_info)
257
+ merged_field_info = cls.from_annotation(annotation)
258
+ new_field_info = copy(field_info)
259
+ new_field_info.metadata = merged_field_info.metadata
260
+ new_field_info.annotation = merged_field_info.annotation
261
+ return new_field_info
262
+
263
+ def serialize_sequence_value(*, field: ModelField, value: Any) -> Sequence[Any]:
264
+ origin_type = (
265
+ get_origin(field.field_info.annotation) or field.field_info.annotation
266
+ )
267
+ assert issubclass(origin_type, sequence_types) # type: ignore[arg-type]
268
+ return sequence_annotation_to_type[origin_type](value) # type: ignore[no-any-return]
269
+
270
+ def get_missing_field_error(loc: Tuple[str, ...]) -> Dict[str, Any]:
271
+ error = ValidationError.from_exception_data(
272
+ "Field required", [{"type": "missing", "loc": loc, "input": {}}]
273
+ ).errors(include_url=False)[0]
274
+ error["input"] = None
275
+ return error # type: ignore[return-value]
276
+
277
+ def create_body_model(
278
+ *, fields: Sequence[ModelField], model_name: str
279
+ ) -> Type[BaseModel]:
280
+ field_params = {f.name: (f.field_info.annotation, f.field_info) for f in fields}
281
+ BodyModel: Type[BaseModel] = create_model(model_name, **field_params) # type: ignore[call-overload]
282
+ return BodyModel
283
+
284
+ def get_model_fields(model: Type[BaseModel]) -> List[ModelField]:
285
+ return [
286
+ ModelField(field_info=field_info, name=name)
287
+ for name, field_info in model.model_fields.items()
288
+ ]
289
+
290
+ else:
291
+ from fastapi.openapi.constants import REF_PREFIX as REF_PREFIX
292
+ from pydantic import AnyUrl as Url # noqa: F401
293
+ from pydantic import ( # type: ignore[assignment]
294
+ BaseConfig as BaseConfig, # noqa: F401
295
+ )
296
+ from pydantic import ValidationError as ValidationError # noqa: F401
297
+ from pydantic.class_validators import ( # type: ignore[no-redef]
298
+ Validator as Validator, # noqa: F401
299
+ )
300
+ from pydantic.error_wrappers import ( # type: ignore[no-redef]
301
+ ErrorWrapper as ErrorWrapper, # noqa: F401
302
+ )
303
+ from pydantic.errors import MissingError
304
+ from pydantic.fields import ( # type: ignore[attr-defined]
305
+ SHAPE_FROZENSET,
306
+ SHAPE_LIST,
307
+ SHAPE_SEQUENCE,
308
+ SHAPE_SET,
309
+ SHAPE_SINGLETON,
310
+ SHAPE_TUPLE,
311
+ SHAPE_TUPLE_ELLIPSIS,
312
+ )
313
+ from pydantic.fields import FieldInfo as FieldInfo
314
+ from pydantic.fields import ( # type: ignore[no-redef,attr-defined]
315
+ ModelField as ModelField, # noqa: F401
316
+ )
317
+
318
+ # Keeping old "Required" functionality from Pydantic V1, without
319
+ # shadowing typing.Required.
320
+ RequiredParam: Any = Ellipsis # type: ignore[no-redef]
321
+ from pydantic.fields import ( # type: ignore[no-redef,attr-defined]
322
+ Undefined as Undefined,
323
+ )
324
+ from pydantic.fields import ( # type: ignore[no-redef, attr-defined]
325
+ UndefinedType as UndefinedType, # noqa: F401
326
+ )
327
+ from pydantic.schema import (
328
+ field_schema,
329
+ get_flat_models_from_fields,
330
+ get_model_name_map,
331
+ model_process_schema,
332
+ )
333
+ from pydantic.schema import ( # type: ignore[no-redef] # noqa: F401
334
+ get_annotation_from_field_info as get_annotation_from_field_info,
335
+ )
336
+ from pydantic.typing import ( # type: ignore[no-redef]
337
+ evaluate_forwardref as evaluate_forwardref, # noqa: F401
338
+ )
339
+ from pydantic.utils import ( # type: ignore[no-redef]
340
+ lenient_issubclass as lenient_issubclass, # noqa: F401
341
+ )
342
+
343
+ GetJsonSchemaHandler = Any # type: ignore[assignment,misc]
344
+ JsonSchemaValue = Dict[str, Any] # type: ignore[misc]
345
+ CoreSchema = Any # type: ignore[assignment,misc]
346
+
347
+ sequence_shapes = {
348
+ SHAPE_LIST,
349
+ SHAPE_SET,
350
+ SHAPE_FROZENSET,
351
+ SHAPE_TUPLE,
352
+ SHAPE_SEQUENCE,
353
+ SHAPE_TUPLE_ELLIPSIS,
354
+ }
355
+ sequence_shape_to_type = {
356
+ SHAPE_LIST: list,
357
+ SHAPE_SET: set,
358
+ SHAPE_TUPLE: tuple,
359
+ SHAPE_SEQUENCE: list,
360
+ SHAPE_TUPLE_ELLIPSIS: list,
361
+ }
362
+
363
+ @dataclass
364
+ class GenerateJsonSchema: # type: ignore[no-redef]
365
+ ref_template: str
366
+
367
+ class PydanticSchemaGenerationError(Exception): # type: ignore[no-redef]
368
+ pass
369
+
370
+ def with_info_plain_validator_function( # type: ignore[misc]
371
+ function: Callable[..., Any],
372
+ *,
373
+ ref: Union[str, None] = None,
374
+ metadata: Any = None,
375
+ serialization: Any = None,
376
+ ) -> Any:
377
+ return {}
378
+
379
+ def get_model_definitions(
380
+ *,
381
+ flat_models: Set[Union[Type[BaseModel], Type[Enum]]],
382
+ model_name_map: Dict[Union[Type[BaseModel], Type[Enum]], str],
383
+ ) -> Dict[str, Any]:
384
+ definitions: Dict[str, Dict[str, Any]] = {}
385
+ for model in flat_models:
386
+ m_schema, m_definitions, m_nested_models = model_process_schema(
387
+ model, model_name_map=model_name_map, ref_prefix=REF_PREFIX
388
+ )
389
+ definitions.update(m_definitions)
390
+ model_name = model_name_map[model]
391
+ if "description" in m_schema:
392
+ m_schema["description"] = m_schema["description"].split("\f")[0]
393
+ definitions[model_name] = m_schema
394
+ return definitions
395
+
396
+ def is_pv1_scalar_field(field: ModelField) -> bool:
397
+ from fastapi import params
398
+
399
+ field_info = field.field_info
400
+ if not (
401
+ field.shape == SHAPE_SINGLETON # type: ignore[attr-defined]
402
+ and not lenient_issubclass(field.type_, BaseModel)
403
+ and not lenient_issubclass(field.type_, dict)
404
+ and not field_annotation_is_sequence(field.type_)
405
+ and not is_dataclass(field.type_)
406
+ and not isinstance(field_info, params.Body)
407
+ ):
408
+ return False
409
+ if field.sub_fields: # type: ignore[attr-defined]
410
+ if not all(
411
+ is_pv1_scalar_field(f)
412
+ for f in field.sub_fields # type: ignore[attr-defined]
413
+ ):
414
+ return False
415
+ return True
416
+
417
+ def is_pv1_scalar_sequence_field(field: ModelField) -> bool:
418
+ if (field.shape in sequence_shapes) and not lenient_issubclass( # type: ignore[attr-defined]
419
+ field.type_, BaseModel
420
+ ):
421
+ if field.sub_fields is not None: # type: ignore[attr-defined]
422
+ for sub_field in field.sub_fields: # type: ignore[attr-defined]
423
+ if not is_pv1_scalar_field(sub_field):
424
+ return False
425
+ return True
426
+ if _annotation_is_sequence(field.type_):
427
+ return True
428
+ return False
429
+
430
+ def _normalize_errors(errors: Sequence[Any]) -> List[Dict[str, Any]]:
431
+ use_errors: List[Any] = []
432
+ for error in errors:
433
+ if isinstance(error, ErrorWrapper):
434
+ new_errors = ValidationError( # type: ignore[call-arg]
435
+ errors=[error], model=RequestErrorModel
436
+ ).errors()
437
+ use_errors.extend(new_errors)
438
+ elif isinstance(error, list):
439
+ use_errors.extend(_normalize_errors(error))
440
+ else:
441
+ use_errors.append(error)
442
+ return use_errors
443
+
444
+ def _model_rebuild(model: Type[BaseModel]) -> None:
445
+ model.update_forward_refs()
446
+
447
+ def _model_dump(
448
+ model: BaseModel, mode: Literal["json", "python"] = "json", **kwargs: Any
449
+ ) -> Any:
450
+ return model.dict(**kwargs)
451
+
452
+ def _get_model_config(model: BaseModel) -> Any:
453
+ return model.__config__ # type: ignore[attr-defined]
454
+
455
+ def get_schema_from_model_field(
456
+ *,
457
+ field: ModelField,
458
+ schema_generator: GenerateJsonSchema,
459
+ model_name_map: ModelNameMap,
460
+ field_mapping: Dict[
461
+ Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
462
+ ],
463
+ separate_input_output_schemas: bool = True,
464
+ ) -> Dict[str, Any]:
465
+ # This expects that GenerateJsonSchema was already used to generate the definitions
466
+ return field_schema( # type: ignore[no-any-return]
467
+ field, model_name_map=model_name_map, ref_prefix=REF_PREFIX
468
+ )[0]
469
+
470
+ def get_compat_model_name_map(fields: List[ModelField]) -> ModelNameMap:
471
+ models = get_flat_models_from_fields(fields, known_models=set())
472
+ return get_model_name_map(models) # type: ignore[no-any-return]
473
+
474
+ def get_definitions(
475
+ *,
476
+ fields: List[ModelField],
477
+ schema_generator: GenerateJsonSchema,
478
+ model_name_map: ModelNameMap,
479
+ separate_input_output_schemas: bool = True,
480
+ ) -> Tuple[
481
+ Dict[
482
+ Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
483
+ ],
484
+ Dict[str, Dict[str, Any]],
485
+ ]:
486
+ models = get_flat_models_from_fields(fields, known_models=set())
487
+ return {}, get_model_definitions(
488
+ flat_models=models, model_name_map=model_name_map
489
+ )
490
+
491
+ def is_scalar_field(field: ModelField) -> bool:
492
+ return is_pv1_scalar_field(field)
493
+
494
+ def is_sequence_field(field: ModelField) -> bool:
495
+ return field.shape in sequence_shapes or _annotation_is_sequence(field.type_) # type: ignore[attr-defined]
496
+
497
+ def is_scalar_sequence_field(field: ModelField) -> bool:
498
+ return is_pv1_scalar_sequence_field(field)
499
+
500
+ def is_bytes_field(field: ModelField) -> bool:
501
+ return lenient_issubclass(field.type_, bytes)
502
+
503
+ def is_bytes_sequence_field(field: ModelField) -> bool:
504
+ return field.shape in sequence_shapes and lenient_issubclass(field.type_, bytes) # type: ignore[attr-defined]
505
+
506
+ def copy_field_info(*, field_info: FieldInfo, annotation: Any) -> FieldInfo:
507
+ return copy(field_info)
508
+
509
+ def serialize_sequence_value(*, field: ModelField, value: Any) -> Sequence[Any]:
510
+ return sequence_shape_to_type[field.shape](value) # type: ignore[no-any-return,attr-defined]
511
+
512
+ def get_missing_field_error(loc: Tuple[str, ...]) -> Dict[str, Any]:
513
+ missing_field_error = ErrorWrapper(MissingError(), loc=loc) # type: ignore[call-arg]
514
+ new_error = ValidationError([missing_field_error], RequestErrorModel)
515
+ return new_error.errors()[0] # type: ignore[return-value]
516
+
517
+ def create_body_model(
518
+ *, fields: Sequence[ModelField], model_name: str
519
+ ) -> Type[BaseModel]:
520
+ BodyModel = create_model(model_name)
521
+ for f in fields:
522
+ BodyModel.__fields__[f.name] = f # type: ignore[index]
523
+ return BodyModel
524
+
525
+ def get_model_fields(model: Type[BaseModel]) -> List[ModelField]:
526
+ return list(model.__fields__.values()) # type: ignore[attr-defined]
527
+
528
+
529
+ def _regenerate_error_with_loc(
530
+ *, errors: Sequence[Any], loc_prefix: Tuple[Union[str, int], ...]
531
+ ) -> List[Dict[str, Any]]:
532
+ updated_loc_errors: List[Any] = [
533
+ {**err, "loc": loc_prefix + err.get("loc", ())}
534
+ for err in _normalize_errors(errors)
535
+ ]
536
+
537
+ return updated_loc_errors
538
+
539
+
540
+ def _annotation_is_sequence(annotation: Union[Type[Any], None]) -> bool:
541
+ if lenient_issubclass(annotation, (str, bytes)):
542
+ return False
543
+ return lenient_issubclass(annotation, sequence_types)
544
+
545
+
546
+ def field_annotation_is_sequence(annotation: Union[Type[Any], None]) -> bool:
547
+ origin = get_origin(annotation)
548
+ if origin is Union or origin is UnionType:
549
+ for arg in get_args(annotation):
550
+ if field_annotation_is_sequence(arg):
551
+ return True
552
+ return False
553
+ return _annotation_is_sequence(annotation) or _annotation_is_sequence(
554
+ get_origin(annotation)
555
+ )
556
+
557
+
558
+ def value_is_sequence(value: Any) -> bool:
559
+ return isinstance(value, sequence_types) and not isinstance(value, (str, bytes)) # type: ignore[arg-type]
560
+
561
+
562
+ def _annotation_is_complex(annotation: Union[Type[Any], None]) -> bool:
563
+ return (
564
+ lenient_issubclass(annotation, (BaseModel, Mapping, UploadFile))
565
+ or _annotation_is_sequence(annotation)
566
+ or is_dataclass(annotation)
567
+ )
568
+
569
+
570
+ def field_annotation_is_complex(annotation: Union[Type[Any], None]) -> bool:
571
+ origin = get_origin(annotation)
572
+ if origin is Union or origin is UnionType:
573
+ return any(field_annotation_is_complex(arg) for arg in get_args(annotation))
574
+
575
+ return (
576
+ _annotation_is_complex(annotation)
577
+ or _annotation_is_complex(origin)
578
+ or hasattr(origin, "__pydantic_core_schema__")
579
+ or hasattr(origin, "__get_pydantic_core_schema__")
580
+ )
581
+
582
+
583
+ def field_annotation_is_scalar(annotation: Any) -> bool:
584
+ # handle Ellipsis here to make tuple[int, ...] work nicely
585
+ return annotation is Ellipsis or not field_annotation_is_complex(annotation)
586
+
587
+
588
+ def field_annotation_is_scalar_sequence(annotation: Union[Type[Any], None]) -> bool:
589
+ origin = get_origin(annotation)
590
+ if origin is Union or origin is UnionType:
591
+ at_least_one_scalar_sequence = False
592
+ for arg in get_args(annotation):
593
+ if field_annotation_is_scalar_sequence(arg):
594
+ at_least_one_scalar_sequence = True
595
+ continue
596
+ elif not field_annotation_is_scalar(arg):
597
+ return False
598
+ return at_least_one_scalar_sequence
599
+ return field_annotation_is_sequence(annotation) and all(
600
+ field_annotation_is_scalar(sub_annotation)
601
+ for sub_annotation in get_args(annotation)
602
+ )
603
+
604
+
605
+ def is_bytes_or_nonable_bytes_annotation(annotation: Any) -> bool:
606
+ if lenient_issubclass(annotation, bytes):
607
+ return True
608
+ origin = get_origin(annotation)
609
+ if origin is Union or origin is UnionType:
610
+ for arg in get_args(annotation):
611
+ if lenient_issubclass(arg, bytes):
612
+ return True
613
+ return False
614
+
615
+
616
+ def is_uploadfile_or_nonable_uploadfile_annotation(annotation: Any) -> bool:
617
+ if lenient_issubclass(annotation, UploadFile):
618
+ return True
619
+ origin = get_origin(annotation)
620
+ if origin is Union or origin is UnionType:
621
+ for arg in get_args(annotation):
622
+ if lenient_issubclass(arg, UploadFile):
623
+ return True
624
+ return False
625
+
626
+
627
+ def is_bytes_sequence_annotation(annotation: Any) -> bool:
628
+ origin = get_origin(annotation)
629
+ if origin is Union or origin is UnionType:
630
+ at_least_one = False
631
+ for arg in get_args(annotation):
632
+ if is_bytes_sequence_annotation(arg):
633
+ at_least_one = True
634
+ continue
635
+ return at_least_one
636
+ return field_annotation_is_sequence(annotation) and all(
637
+ is_bytes_or_nonable_bytes_annotation(sub_annotation)
638
+ for sub_annotation in get_args(annotation)
639
+ )
640
+
641
+
642
+ def is_uploadfile_sequence_annotation(annotation: Any) -> bool:
643
+ origin = get_origin(annotation)
644
+ if origin is Union or origin is UnionType:
645
+ at_least_one = False
646
+ for arg in get_args(annotation):
647
+ if is_uploadfile_sequence_annotation(arg):
648
+ at_least_one = True
649
+ continue
650
+ return at_least_one
651
+ return field_annotation_is_sequence(annotation) and all(
652
+ is_uploadfile_or_nonable_uploadfile_annotation(sub_annotation)
653
+ for sub_annotation in get_args(annotation)
654
+ )
655
+
656
+
657
+ @lru_cache
658
+ def get_cached_model_fields(model: Type[BaseModel]) -> List[ModelField]:
659
+ return get_model_fields(model)
lib/python3.12/site-packages/fastapi/applications.py ADDED
The diff for this file is too large to render. See raw diff
 
lib/python3.12/site-packages/fastapi/background.py ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Any, Callable
2
+
3
+ from starlette.background import BackgroundTasks as StarletteBackgroundTasks
4
+ from typing_extensions import Annotated, Doc, ParamSpec
5
+
6
+ P = ParamSpec("P")
7
+
8
+
9
+ class BackgroundTasks(StarletteBackgroundTasks):
10
+ """
11
+ A collection of background tasks that will be called after a response has been
12
+ sent to the client.
13
+
14
+ Read more about it in the
15
+ [FastAPI docs for Background Tasks](https://fastapi.tiangolo.com/tutorial/background-tasks/).
16
+
17
+ ## Example
18
+
19
+ ```python
20
+ from fastapi import BackgroundTasks, FastAPI
21
+
22
+ app = FastAPI()
23
+
24
+
25
+ def write_notification(email: str, message=""):
26
+ with open("log.txt", mode="w") as email_file:
27
+ content = f"notification for {email}: {message}"
28
+ email_file.write(content)
29
+
30
+
31
+ @app.post("/send-notification/{email}")
32
+ async def send_notification(email: str, background_tasks: BackgroundTasks):
33
+ background_tasks.add_task(write_notification, email, message="some notification")
34
+ return {"message": "Notification sent in the background"}
35
+ ```
36
+ """
37
+
38
+ def add_task(
39
+ self,
40
+ func: Annotated[
41
+ Callable[P, Any],
42
+ Doc(
43
+ """
44
+ The function to call after the response is sent.
45
+
46
+ It can be a regular `def` function or an `async def` function.
47
+ """
48
+ ),
49
+ ],
50
+ *args: P.args,
51
+ **kwargs: P.kwargs,
52
+ ) -> None:
53
+ """
54
+ Add a function to be called in the background after the response is sent.
55
+
56
+ Read more about it in the
57
+ [FastAPI docs for Background Tasks](https://fastapi.tiangolo.com/tutorial/background-tasks/).
58
+ """
59
+ return super().add_task(func, *args, **kwargs)
lib/python3.12/site-packages/fastapi/cli.py ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ try:
2
+ from fastapi_cli.cli import main as cli_main
3
+
4
+ except ImportError: # pragma: no cover
5
+ cli_main = None # type: ignore
6
+
7
+
8
+ def main() -> None:
9
+ if not cli_main: # type: ignore[truthy-function]
10
+ message = 'To use the fastapi command, please install "fastapi[standard]":\n\n\tpip install "fastapi[standard]"\n'
11
+ print(message)
12
+ raise RuntimeError(message) # noqa: B904
13
+ cli_main()
lib/python3.12/site-packages/fastapi/concurrency.py ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from contextlib import asynccontextmanager as asynccontextmanager
2
+ from typing import AsyncGenerator, ContextManager, TypeVar
3
+
4
+ import anyio.to_thread
5
+ from anyio import CapacityLimiter
6
+ from starlette.concurrency import iterate_in_threadpool as iterate_in_threadpool # noqa
7
+ from starlette.concurrency import run_in_threadpool as run_in_threadpool # noqa
8
+ from starlette.concurrency import ( # noqa
9
+ run_until_first_complete as run_until_first_complete,
10
+ )
11
+
12
+ _T = TypeVar("_T")
13
+
14
+
15
+ @asynccontextmanager
16
+ async def contextmanager_in_threadpool(
17
+ cm: ContextManager[_T],
18
+ ) -> AsyncGenerator[_T, None]:
19
+ # blocking __exit__ from running waiting on a free thread
20
+ # can create race conditions/deadlocks if the context manager itself
21
+ # has its own internal pool (e.g. a database connection pool)
22
+ # to avoid this we let __exit__ run without a capacity limit
23
+ # since we're creating a new limiter for each call, any non-zero limit
24
+ # works (1 is arbitrary)
25
+ exit_limiter = CapacityLimiter(1)
26
+ try:
27
+ yield await run_in_threadpool(cm.__enter__)
28
+ except Exception as e:
29
+ ok = bool(
30
+ await anyio.to_thread.run_sync(
31
+ cm.__exit__, type(e), e, e.__traceback__, limiter=exit_limiter
32
+ )
33
+ )
34
+ if not ok:
35
+ raise e
36
+ else:
37
+ await anyio.to_thread.run_sync(
38
+ cm.__exit__, None, None, None, limiter=exit_limiter
39
+ )
lib/python3.12/site-packages/fastapi/datastructures.py ADDED
@@ -0,0 +1,204 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import (
2
+ Any,
3
+ BinaryIO,
4
+ Callable,
5
+ Dict,
6
+ Iterable,
7
+ Optional,
8
+ Type,
9
+ TypeVar,
10
+ cast,
11
+ )
12
+
13
+ from fastapi._compat import (
14
+ PYDANTIC_V2,
15
+ CoreSchema,
16
+ GetJsonSchemaHandler,
17
+ JsonSchemaValue,
18
+ with_info_plain_validator_function,
19
+ )
20
+ from starlette.datastructures import URL as URL # noqa: F401
21
+ from starlette.datastructures import Address as Address # noqa: F401
22
+ from starlette.datastructures import FormData as FormData # noqa: F401
23
+ from starlette.datastructures import Headers as Headers # noqa: F401
24
+ from starlette.datastructures import QueryParams as QueryParams # noqa: F401
25
+ from starlette.datastructures import State as State # noqa: F401
26
+ from starlette.datastructures import UploadFile as StarletteUploadFile
27
+ from typing_extensions import Annotated, Doc
28
+
29
+
30
+ class UploadFile(StarletteUploadFile):
31
+ """
32
+ A file uploaded in a request.
33
+
34
+ Define it as a *path operation function* (or dependency) parameter.
35
+
36
+ If you are using a regular `def` function, you can use the `upload_file.file`
37
+ attribute to access the raw standard Python file (blocking, not async), useful and
38
+ needed for non-async code.
39
+
40
+ Read more about it in the
41
+ [FastAPI docs for Request Files](https://fastapi.tiangolo.com/tutorial/request-files/).
42
+
43
+ ## Example
44
+
45
+ ```python
46
+ from typing import Annotated
47
+
48
+ from fastapi import FastAPI, File, UploadFile
49
+
50
+ app = FastAPI()
51
+
52
+
53
+ @app.post("/files/")
54
+ async def create_file(file: Annotated[bytes, File()]):
55
+ return {"file_size": len(file)}
56
+
57
+
58
+ @app.post("/uploadfile/")
59
+ async def create_upload_file(file: UploadFile):
60
+ return {"filename": file.filename}
61
+ ```
62
+ """
63
+
64
+ file: Annotated[
65
+ BinaryIO,
66
+ Doc("The standard Python file object (non-async)."),
67
+ ]
68
+ filename: Annotated[Optional[str], Doc("The original file name.")]
69
+ size: Annotated[Optional[int], Doc("The size of the file in bytes.")]
70
+ headers: Annotated[Headers, Doc("The headers of the request.")]
71
+ content_type: Annotated[
72
+ Optional[str], Doc("The content type of the request, from the headers.")
73
+ ]
74
+
75
+ async def write(
76
+ self,
77
+ data: Annotated[
78
+ bytes,
79
+ Doc(
80
+ """
81
+ The bytes to write to the file.
82
+ """
83
+ ),
84
+ ],
85
+ ) -> None:
86
+ """
87
+ Write some bytes to the file.
88
+
89
+ You normally wouldn't use this from a file you read in a request.
90
+
91
+ To be awaitable, compatible with async, this is run in threadpool.
92
+ """
93
+ return await super().write(data)
94
+
95
+ async def read(
96
+ self,
97
+ size: Annotated[
98
+ int,
99
+ Doc(
100
+ """
101
+ The number of bytes to read from the file.
102
+ """
103
+ ),
104
+ ] = -1,
105
+ ) -> bytes:
106
+ """
107
+ Read some bytes from the file.
108
+
109
+ To be awaitable, compatible with async, this is run in threadpool.
110
+ """
111
+ return await super().read(size)
112
+
113
+ async def seek(
114
+ self,
115
+ offset: Annotated[
116
+ int,
117
+ Doc(
118
+ """
119
+ The position in bytes to seek to in the file.
120
+ """
121
+ ),
122
+ ],
123
+ ) -> None:
124
+ """
125
+ Move to a position in the file.
126
+
127
+ Any next read or write will be done from that position.
128
+
129
+ To be awaitable, compatible with async, this is run in threadpool.
130
+ """
131
+ return await super().seek(offset)
132
+
133
+ async def close(self) -> None:
134
+ """
135
+ Close the file.
136
+
137
+ To be awaitable, compatible with async, this is run in threadpool.
138
+ """
139
+ return await super().close()
140
+
141
+ @classmethod
142
+ def __get_validators__(cls: Type["UploadFile"]) -> Iterable[Callable[..., Any]]:
143
+ yield cls.validate
144
+
145
+ @classmethod
146
+ def validate(cls: Type["UploadFile"], v: Any) -> Any:
147
+ if not isinstance(v, StarletteUploadFile):
148
+ raise ValueError(f"Expected UploadFile, received: {type(v)}")
149
+ return v
150
+
151
+ @classmethod
152
+ def _validate(cls, __input_value: Any, _: Any) -> "UploadFile":
153
+ if not isinstance(__input_value, StarletteUploadFile):
154
+ raise ValueError(f"Expected UploadFile, received: {type(__input_value)}")
155
+ return cast(UploadFile, __input_value)
156
+
157
+ if not PYDANTIC_V2:
158
+
159
+ @classmethod
160
+ def __modify_schema__(cls, field_schema: Dict[str, Any]) -> None:
161
+ field_schema.update({"type": "string", "format": "binary"})
162
+
163
+ @classmethod
164
+ def __get_pydantic_json_schema__(
165
+ cls, core_schema: CoreSchema, handler: GetJsonSchemaHandler
166
+ ) -> JsonSchemaValue:
167
+ return {"type": "string", "format": "binary"}
168
+
169
+ @classmethod
170
+ def __get_pydantic_core_schema__(
171
+ cls, source: Type[Any], handler: Callable[[Any], CoreSchema]
172
+ ) -> CoreSchema:
173
+ return with_info_plain_validator_function(cls._validate)
174
+
175
+
176
+ class DefaultPlaceholder:
177
+ """
178
+ You shouldn't use this class directly.
179
+
180
+ It's used internally to recognize when a default value has been overwritten, even
181
+ if the overridden default value was truthy.
182
+ """
183
+
184
+ def __init__(self, value: Any):
185
+ self.value = value
186
+
187
+ def __bool__(self) -> bool:
188
+ return bool(self.value)
189
+
190
+ def __eq__(self, o: object) -> bool:
191
+ return isinstance(o, DefaultPlaceholder) and o.value == self.value
192
+
193
+
194
+ DefaultType = TypeVar("DefaultType")
195
+
196
+
197
+ def Default(value: DefaultType) -> DefaultType:
198
+ """
199
+ You shouldn't use this function directly.
200
+
201
+ It's used internally to recognize when a default value has been overwritten, even
202
+ if the overridden default value was truthy.
203
+ """
204
+ return DefaultPlaceholder(value) # type: ignore
lib/python3.12/site-packages/fastapi/encoders.py ADDED
@@ -0,0 +1,343 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import dataclasses
2
+ import datetime
3
+ from collections import defaultdict, deque
4
+ from decimal import Decimal
5
+ from enum import Enum
6
+ from ipaddress import (
7
+ IPv4Address,
8
+ IPv4Interface,
9
+ IPv4Network,
10
+ IPv6Address,
11
+ IPv6Interface,
12
+ IPv6Network,
13
+ )
14
+ from pathlib import Path, PurePath
15
+ from re import Pattern
16
+ from types import GeneratorType
17
+ from typing import Any, Callable, Dict, List, Optional, Tuple, Type, Union
18
+ from uuid import UUID
19
+
20
+ from fastapi.types import IncEx
21
+ from pydantic import BaseModel
22
+ from pydantic.color import Color
23
+ from pydantic.networks import AnyUrl, NameEmail
24
+ from pydantic.types import SecretBytes, SecretStr
25
+ from typing_extensions import Annotated, Doc
26
+
27
+ from ._compat import PYDANTIC_V2, UndefinedType, Url, _model_dump
28
+
29
+
30
+ # Taken from Pydantic v1 as is
31
+ def isoformat(o: Union[datetime.date, datetime.time]) -> str:
32
+ return o.isoformat()
33
+
34
+
35
+ # Taken from Pydantic v1 as is
36
+ # TODO: pv2 should this return strings instead?
37
+ def decimal_encoder(dec_value: Decimal) -> Union[int, float]:
38
+ """
39
+ Encodes a Decimal as int of there's no exponent, otherwise float
40
+
41
+ This is useful when we use ConstrainedDecimal to represent Numeric(x,0)
42
+ where a integer (but not int typed) is used. Encoding this as a float
43
+ results in failed round-tripping between encode and parse.
44
+ Our Id type is a prime example of this.
45
+
46
+ >>> decimal_encoder(Decimal("1.0"))
47
+ 1.0
48
+
49
+ >>> decimal_encoder(Decimal("1"))
50
+ 1
51
+ """
52
+ if dec_value.as_tuple().exponent >= 0: # type: ignore[operator]
53
+ return int(dec_value)
54
+ else:
55
+ return float(dec_value)
56
+
57
+
58
+ ENCODERS_BY_TYPE: Dict[Type[Any], Callable[[Any], Any]] = {
59
+ bytes: lambda o: o.decode(),
60
+ Color: str,
61
+ datetime.date: isoformat,
62
+ datetime.datetime: isoformat,
63
+ datetime.time: isoformat,
64
+ datetime.timedelta: lambda td: td.total_seconds(),
65
+ Decimal: decimal_encoder,
66
+ Enum: lambda o: o.value,
67
+ frozenset: list,
68
+ deque: list,
69
+ GeneratorType: list,
70
+ IPv4Address: str,
71
+ IPv4Interface: str,
72
+ IPv4Network: str,
73
+ IPv6Address: str,
74
+ IPv6Interface: str,
75
+ IPv6Network: str,
76
+ NameEmail: str,
77
+ Path: str,
78
+ Pattern: lambda o: o.pattern,
79
+ SecretBytes: str,
80
+ SecretStr: str,
81
+ set: list,
82
+ UUID: str,
83
+ Url: str,
84
+ AnyUrl: str,
85
+ }
86
+
87
+
88
+ def generate_encoders_by_class_tuples(
89
+ type_encoder_map: Dict[Any, Callable[[Any], Any]],
90
+ ) -> Dict[Callable[[Any], Any], Tuple[Any, ...]]:
91
+ encoders_by_class_tuples: Dict[Callable[[Any], Any], Tuple[Any, ...]] = defaultdict(
92
+ tuple
93
+ )
94
+ for type_, encoder in type_encoder_map.items():
95
+ encoders_by_class_tuples[encoder] += (type_,)
96
+ return encoders_by_class_tuples
97
+
98
+
99
+ encoders_by_class_tuples = generate_encoders_by_class_tuples(ENCODERS_BY_TYPE)
100
+
101
+
102
+ def jsonable_encoder(
103
+ obj: Annotated[
104
+ Any,
105
+ Doc(
106
+ """
107
+ The input object to convert to JSON.
108
+ """
109
+ ),
110
+ ],
111
+ include: Annotated[
112
+ Optional[IncEx],
113
+ Doc(
114
+ """
115
+ Pydantic's `include` parameter, passed to Pydantic models to set the
116
+ fields to include.
117
+ """
118
+ ),
119
+ ] = None,
120
+ exclude: Annotated[
121
+ Optional[IncEx],
122
+ Doc(
123
+ """
124
+ Pydantic's `exclude` parameter, passed to Pydantic models to set the
125
+ fields to exclude.
126
+ """
127
+ ),
128
+ ] = None,
129
+ by_alias: Annotated[
130
+ bool,
131
+ Doc(
132
+ """
133
+ Pydantic's `by_alias` parameter, passed to Pydantic models to define if
134
+ the output should use the alias names (when provided) or the Python
135
+ attribute names. In an API, if you set an alias, it's probably because you
136
+ want to use it in the result, so you probably want to leave this set to
137
+ `True`.
138
+ """
139
+ ),
140
+ ] = True,
141
+ exclude_unset: Annotated[
142
+ bool,
143
+ Doc(
144
+ """
145
+ Pydantic's `exclude_unset` parameter, passed to Pydantic models to define
146
+ if it should exclude from the output the fields that were not explicitly
147
+ set (and that only had their default values).
148
+ """
149
+ ),
150
+ ] = False,
151
+ exclude_defaults: Annotated[
152
+ bool,
153
+ Doc(
154
+ """
155
+ Pydantic's `exclude_defaults` parameter, passed to Pydantic models to define
156
+ if it should exclude from the output the fields that had the same default
157
+ value, even when they were explicitly set.
158
+ """
159
+ ),
160
+ ] = False,
161
+ exclude_none: Annotated[
162
+ bool,
163
+ Doc(
164
+ """
165
+ Pydantic's `exclude_none` parameter, passed to Pydantic models to define
166
+ if it should exclude from the output any fields that have a `None` value.
167
+ """
168
+ ),
169
+ ] = False,
170
+ custom_encoder: Annotated[
171
+ Optional[Dict[Any, Callable[[Any], Any]]],
172
+ Doc(
173
+ """
174
+ Pydantic's `custom_encoder` parameter, passed to Pydantic models to define
175
+ a custom encoder.
176
+ """
177
+ ),
178
+ ] = None,
179
+ sqlalchemy_safe: Annotated[
180
+ bool,
181
+ Doc(
182
+ """
183
+ Exclude from the output any fields that start with the name `_sa`.
184
+
185
+ This is mainly a hack for compatibility with SQLAlchemy objects, they
186
+ store internal SQLAlchemy-specific state in attributes named with `_sa`,
187
+ and those objects can't (and shouldn't be) serialized to JSON.
188
+ """
189
+ ),
190
+ ] = True,
191
+ ) -> Any:
192
+ """
193
+ Convert any object to something that can be encoded in JSON.
194
+
195
+ This is used internally by FastAPI to make sure anything you return can be
196
+ encoded as JSON before it is sent to the client.
197
+
198
+ You can also use it yourself, for example to convert objects before saving them
199
+ in a database that supports only JSON.
200
+
201
+ Read more about it in the
202
+ [FastAPI docs for JSON Compatible Encoder](https://fastapi.tiangolo.com/tutorial/encoder/).
203
+ """
204
+ custom_encoder = custom_encoder or {}
205
+ if custom_encoder:
206
+ if type(obj) in custom_encoder:
207
+ return custom_encoder[type(obj)](obj)
208
+ else:
209
+ for encoder_type, encoder_instance in custom_encoder.items():
210
+ if isinstance(obj, encoder_type):
211
+ return encoder_instance(obj)
212
+ if include is not None and not isinstance(include, (set, dict)):
213
+ include = set(include)
214
+ if exclude is not None and not isinstance(exclude, (set, dict)):
215
+ exclude = set(exclude)
216
+ if isinstance(obj, BaseModel):
217
+ # TODO: remove when deprecating Pydantic v1
218
+ encoders: Dict[Any, Any] = {}
219
+ if not PYDANTIC_V2:
220
+ encoders = getattr(obj.__config__, "json_encoders", {}) # type: ignore[attr-defined]
221
+ if custom_encoder:
222
+ encoders.update(custom_encoder)
223
+ obj_dict = _model_dump(
224
+ obj,
225
+ mode="json",
226
+ include=include,
227
+ exclude=exclude,
228
+ by_alias=by_alias,
229
+ exclude_unset=exclude_unset,
230
+ exclude_none=exclude_none,
231
+ exclude_defaults=exclude_defaults,
232
+ )
233
+ if "__root__" in obj_dict:
234
+ obj_dict = obj_dict["__root__"]
235
+ return jsonable_encoder(
236
+ obj_dict,
237
+ exclude_none=exclude_none,
238
+ exclude_defaults=exclude_defaults,
239
+ # TODO: remove when deprecating Pydantic v1
240
+ custom_encoder=encoders,
241
+ sqlalchemy_safe=sqlalchemy_safe,
242
+ )
243
+ if dataclasses.is_dataclass(obj):
244
+ obj_dict = dataclasses.asdict(obj)
245
+ return jsonable_encoder(
246
+ obj_dict,
247
+ include=include,
248
+ exclude=exclude,
249
+ by_alias=by_alias,
250
+ exclude_unset=exclude_unset,
251
+ exclude_defaults=exclude_defaults,
252
+ exclude_none=exclude_none,
253
+ custom_encoder=custom_encoder,
254
+ sqlalchemy_safe=sqlalchemy_safe,
255
+ )
256
+ if isinstance(obj, Enum):
257
+ return obj.value
258
+ if isinstance(obj, PurePath):
259
+ return str(obj)
260
+ if isinstance(obj, (str, int, float, type(None))):
261
+ return obj
262
+ if isinstance(obj, UndefinedType):
263
+ return None
264
+ if isinstance(obj, dict):
265
+ encoded_dict = {}
266
+ allowed_keys = set(obj.keys())
267
+ if include is not None:
268
+ allowed_keys &= set(include)
269
+ if exclude is not None:
270
+ allowed_keys -= set(exclude)
271
+ for key, value in obj.items():
272
+ if (
273
+ (
274
+ not sqlalchemy_safe
275
+ or (not isinstance(key, str))
276
+ or (not key.startswith("_sa"))
277
+ )
278
+ and (value is not None or not exclude_none)
279
+ and key in allowed_keys
280
+ ):
281
+ encoded_key = jsonable_encoder(
282
+ key,
283
+ by_alias=by_alias,
284
+ exclude_unset=exclude_unset,
285
+ exclude_none=exclude_none,
286
+ custom_encoder=custom_encoder,
287
+ sqlalchemy_safe=sqlalchemy_safe,
288
+ )
289
+ encoded_value = jsonable_encoder(
290
+ value,
291
+ by_alias=by_alias,
292
+ exclude_unset=exclude_unset,
293
+ exclude_none=exclude_none,
294
+ custom_encoder=custom_encoder,
295
+ sqlalchemy_safe=sqlalchemy_safe,
296
+ )
297
+ encoded_dict[encoded_key] = encoded_value
298
+ return encoded_dict
299
+ if isinstance(obj, (list, set, frozenset, GeneratorType, tuple, deque)):
300
+ encoded_list = []
301
+ for item in obj:
302
+ encoded_list.append(
303
+ jsonable_encoder(
304
+ item,
305
+ include=include,
306
+ exclude=exclude,
307
+ by_alias=by_alias,
308
+ exclude_unset=exclude_unset,
309
+ exclude_defaults=exclude_defaults,
310
+ exclude_none=exclude_none,
311
+ custom_encoder=custom_encoder,
312
+ sqlalchemy_safe=sqlalchemy_safe,
313
+ )
314
+ )
315
+ return encoded_list
316
+
317
+ if type(obj) in ENCODERS_BY_TYPE:
318
+ return ENCODERS_BY_TYPE[type(obj)](obj)
319
+ for encoder, classes_tuple in encoders_by_class_tuples.items():
320
+ if isinstance(obj, classes_tuple):
321
+ return encoder(obj)
322
+
323
+ try:
324
+ data = dict(obj)
325
+ except Exception as e:
326
+ errors: List[Exception] = []
327
+ errors.append(e)
328
+ try:
329
+ data = vars(obj)
330
+ except Exception as e:
331
+ errors.append(e)
332
+ raise ValueError(errors) from e
333
+ return jsonable_encoder(
334
+ data,
335
+ include=include,
336
+ exclude=exclude,
337
+ by_alias=by_alias,
338
+ exclude_unset=exclude_unset,
339
+ exclude_defaults=exclude_defaults,
340
+ exclude_none=exclude_none,
341
+ custom_encoder=custom_encoder,
342
+ sqlalchemy_safe=sqlalchemy_safe,
343
+ )
lib/python3.12/site-packages/fastapi/exception_handlers.py ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi.encoders import jsonable_encoder
2
+ from fastapi.exceptions import RequestValidationError, WebSocketRequestValidationError
3
+ from fastapi.utils import is_body_allowed_for_status_code
4
+ from fastapi.websockets import WebSocket
5
+ from starlette.exceptions import HTTPException
6
+ from starlette.requests import Request
7
+ from starlette.responses import JSONResponse, Response
8
+ from starlette.status import HTTP_422_UNPROCESSABLE_ENTITY, WS_1008_POLICY_VIOLATION
9
+
10
+
11
+ async def http_exception_handler(request: Request, exc: HTTPException) -> Response:
12
+ headers = getattr(exc, "headers", None)
13
+ if not is_body_allowed_for_status_code(exc.status_code):
14
+ return Response(status_code=exc.status_code, headers=headers)
15
+ return JSONResponse(
16
+ {"detail": exc.detail}, status_code=exc.status_code, headers=headers
17
+ )
18
+
19
+
20
+ async def request_validation_exception_handler(
21
+ request: Request, exc: RequestValidationError
22
+ ) -> JSONResponse:
23
+ return JSONResponse(
24
+ status_code=HTTP_422_UNPROCESSABLE_ENTITY,
25
+ content={"detail": jsonable_encoder(exc.errors())},
26
+ )
27
+
28
+
29
+ async def websocket_request_validation_exception_handler(
30
+ websocket: WebSocket, exc: WebSocketRequestValidationError
31
+ ) -> None:
32
+ await websocket.close(
33
+ code=WS_1008_POLICY_VIOLATION, reason=jsonable_encoder(exc.errors())
34
+ )
lib/python3.12/site-packages/fastapi/exceptions.py ADDED
@@ -0,0 +1,176 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Any, Dict, Optional, Sequence, Type, Union
2
+
3
+ from pydantic import BaseModel, create_model
4
+ from starlette.exceptions import HTTPException as StarletteHTTPException
5
+ from starlette.exceptions import WebSocketException as StarletteWebSocketException
6
+ from typing_extensions import Annotated, Doc
7
+
8
+
9
+ class HTTPException(StarletteHTTPException):
10
+ """
11
+ An HTTP exception you can raise in your own code to show errors to the client.
12
+
13
+ This is for client errors, invalid authentication, invalid data, etc. Not for server
14
+ errors in your code.
15
+
16
+ Read more about it in the
17
+ [FastAPI docs for Handling Errors](https://fastapi.tiangolo.com/tutorial/handling-errors/).
18
+
19
+ ## Example
20
+
21
+ ```python
22
+ from fastapi import FastAPI, HTTPException
23
+
24
+ app = FastAPI()
25
+
26
+ items = {"foo": "The Foo Wrestlers"}
27
+
28
+
29
+ @app.get("/items/{item_id}")
30
+ async def read_item(item_id: str):
31
+ if item_id not in items:
32
+ raise HTTPException(status_code=404, detail="Item not found")
33
+ return {"item": items[item_id]}
34
+ ```
35
+ """
36
+
37
+ def __init__(
38
+ self,
39
+ status_code: Annotated[
40
+ int,
41
+ Doc(
42
+ """
43
+ HTTP status code to send to the client.
44
+ """
45
+ ),
46
+ ],
47
+ detail: Annotated[
48
+ Any,
49
+ Doc(
50
+ """
51
+ Any data to be sent to the client in the `detail` key of the JSON
52
+ response.
53
+ """
54
+ ),
55
+ ] = None,
56
+ headers: Annotated[
57
+ Optional[Dict[str, str]],
58
+ Doc(
59
+ """
60
+ Any headers to send to the client in the response.
61
+ """
62
+ ),
63
+ ] = None,
64
+ ) -> None:
65
+ super().__init__(status_code=status_code, detail=detail, headers=headers)
66
+
67
+
68
+ class WebSocketException(StarletteWebSocketException):
69
+ """
70
+ A WebSocket exception you can raise in your own code to show errors to the client.
71
+
72
+ This is for client errors, invalid authentication, invalid data, etc. Not for server
73
+ errors in your code.
74
+
75
+ Read more about it in the
76
+ [FastAPI docs for WebSockets](https://fastapi.tiangolo.com/advanced/websockets/).
77
+
78
+ ## Example
79
+
80
+ ```python
81
+ from typing import Annotated
82
+
83
+ from fastapi import (
84
+ Cookie,
85
+ FastAPI,
86
+ WebSocket,
87
+ WebSocketException,
88
+ status,
89
+ )
90
+
91
+ app = FastAPI()
92
+
93
+ @app.websocket("/items/{item_id}/ws")
94
+ async def websocket_endpoint(
95
+ *,
96
+ websocket: WebSocket,
97
+ session: Annotated[str | None, Cookie()] = None,
98
+ item_id: str,
99
+ ):
100
+ if session is None:
101
+ raise WebSocketException(code=status.WS_1008_POLICY_VIOLATION)
102
+ await websocket.accept()
103
+ while True:
104
+ data = await websocket.receive_text()
105
+ await websocket.send_text(f"Session cookie is: {session}")
106
+ await websocket.send_text(f"Message text was: {data}, for item ID: {item_id}")
107
+ ```
108
+ """
109
+
110
+ def __init__(
111
+ self,
112
+ code: Annotated[
113
+ int,
114
+ Doc(
115
+ """
116
+ A closing code from the
117
+ [valid codes defined in the specification](https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.1).
118
+ """
119
+ ),
120
+ ],
121
+ reason: Annotated[
122
+ Union[str, None],
123
+ Doc(
124
+ """
125
+ The reason to close the WebSocket connection.
126
+
127
+ It is UTF-8-encoded data. The interpretation of the reason is up to the
128
+ application, it is not specified by the WebSocket specification.
129
+
130
+ It could contain text that could be human-readable or interpretable
131
+ by the client code, etc.
132
+ """
133
+ ),
134
+ ] = None,
135
+ ) -> None:
136
+ super().__init__(code=code, reason=reason)
137
+
138
+
139
+ RequestErrorModel: Type[BaseModel] = create_model("Request")
140
+ WebSocketErrorModel: Type[BaseModel] = create_model("WebSocket")
141
+
142
+
143
+ class FastAPIError(RuntimeError):
144
+ """
145
+ A generic, FastAPI-specific error.
146
+ """
147
+
148
+
149
+ class ValidationException(Exception):
150
+ def __init__(self, errors: Sequence[Any]) -> None:
151
+ self._errors = errors
152
+
153
+ def errors(self) -> Sequence[Any]:
154
+ return self._errors
155
+
156
+
157
+ class RequestValidationError(ValidationException):
158
+ def __init__(self, errors: Sequence[Any], *, body: Any = None) -> None:
159
+ super().__init__(errors)
160
+ self.body = body
161
+
162
+
163
+ class WebSocketRequestValidationError(ValidationException):
164
+ pass
165
+
166
+
167
+ class ResponseValidationError(ValidationException):
168
+ def __init__(self, errors: Sequence[Any], *, body: Any = None) -> None:
169
+ super().__init__(errors)
170
+ self.body = body
171
+
172
+ def __str__(self) -> str:
173
+ message = f"{len(self._errors)} validation errors:\n"
174
+ for err in self._errors:
175
+ message += f" {err}\n"
176
+ return message
lib/python3.12/site-packages/fastapi/logger.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ import logging
2
+
3
+ logger = logging.getLogger("fastapi")
lib/python3.12/site-packages/fastapi/openapi/__init__.py ADDED
File without changes
lib/python3.12/site-packages/fastapi/openapi/__pycache__/__init__.cpython-312.pyc ADDED
Binary file (194 Bytes). View file
 
lib/python3.12/site-packages/fastapi/openapi/__pycache__/constants.cpython-312.pyc ADDED
Binary file (364 Bytes). View file
 
lib/python3.12/site-packages/fastapi/openapi/__pycache__/docs.cpython-312.pyc ADDED
Binary file (10.8 kB). View file
 
lib/python3.12/site-packages/fastapi/openapi/__pycache__/models.cpython-312.pyc ADDED
Binary file (23 kB). View file
 
lib/python3.12/site-packages/fastapi/openapi/__pycache__/utils.cpython-312.pyc ADDED
Binary file (21.1 kB). View file
 
lib/python3.12/site-packages/fastapi/openapi/constants.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ METHODS_WITH_BODY = {"GET", "HEAD", "POST", "PUT", "DELETE", "PATCH"}
2
+ REF_PREFIX = "#/components/schemas/"
3
+ REF_TEMPLATE = "#/components/schemas/{model}"
lib/python3.12/site-packages/fastapi/openapi/docs.py ADDED
@@ -0,0 +1,344 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ from typing import Any, Dict, Optional
3
+
4
+ from fastapi.encoders import jsonable_encoder
5
+ from starlette.responses import HTMLResponse
6
+ from typing_extensions import Annotated, Doc
7
+
8
+ swagger_ui_default_parameters: Annotated[
9
+ Dict[str, Any],
10
+ Doc(
11
+ """
12
+ Default configurations for Swagger UI.
13
+
14
+ You can use it as a template to add any other configurations needed.
15
+ """
16
+ ),
17
+ ] = {
18
+ "dom_id": "#swagger-ui",
19
+ "layout": "BaseLayout",
20
+ "deepLinking": True,
21
+ "showExtensions": True,
22
+ "showCommonExtensions": True,
23
+ }
24
+
25
+
26
+ def get_swagger_ui_html(
27
+ *,
28
+ openapi_url: Annotated[
29
+ str,
30
+ Doc(
31
+ """
32
+ The OpenAPI URL that Swagger UI should load and use.
33
+
34
+ This is normally done automatically by FastAPI using the default URL
35
+ `/openapi.json`.
36
+ """
37
+ ),
38
+ ],
39
+ title: Annotated[
40
+ str,
41
+ Doc(
42
+ """
43
+ The HTML `<title>` content, normally shown in the browser tab.
44
+ """
45
+ ),
46
+ ],
47
+ swagger_js_url: Annotated[
48
+ str,
49
+ Doc(
50
+ """
51
+ The URL to use to load the Swagger UI JavaScript.
52
+
53
+ It is normally set to a CDN URL.
54
+ """
55
+ ),
56
+ ] = "https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui-bundle.js",
57
+ swagger_css_url: Annotated[
58
+ str,
59
+ Doc(
60
+ """
61
+ The URL to use to load the Swagger UI CSS.
62
+
63
+ It is normally set to a CDN URL.
64
+ """
65
+ ),
66
+ ] = "https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui.css",
67
+ swagger_favicon_url: Annotated[
68
+ str,
69
+ Doc(
70
+ """
71
+ The URL of the favicon to use. It is normally shown in the browser tab.
72
+ """
73
+ ),
74
+ ] = "https://fastapi.tiangolo.com/img/favicon.png",
75
+ oauth2_redirect_url: Annotated[
76
+ Optional[str],
77
+ Doc(
78
+ """
79
+ The OAuth2 redirect URL, it is normally automatically handled by FastAPI.
80
+ """
81
+ ),
82
+ ] = None,
83
+ init_oauth: Annotated[
84
+ Optional[Dict[str, Any]],
85
+ Doc(
86
+ """
87
+ A dictionary with Swagger UI OAuth2 initialization configurations.
88
+ """
89
+ ),
90
+ ] = None,
91
+ swagger_ui_parameters: Annotated[
92
+ Optional[Dict[str, Any]],
93
+ Doc(
94
+ """
95
+ Configuration parameters for Swagger UI.
96
+
97
+ It defaults to [swagger_ui_default_parameters][fastapi.openapi.docs.swagger_ui_default_parameters].
98
+ """
99
+ ),
100
+ ] = None,
101
+ ) -> HTMLResponse:
102
+ """
103
+ Generate and return the HTML that loads Swagger UI for the interactive
104
+ API docs (normally served at `/docs`).
105
+
106
+ You would only call this function yourself if you needed to override some parts,
107
+ for example the URLs to use to load Swagger UI's JavaScript and CSS.
108
+
109
+ Read more about it in the
110
+ [FastAPI docs for Configure Swagger UI](https://fastapi.tiangolo.com/how-to/configure-swagger-ui/)
111
+ and the [FastAPI docs for Custom Docs UI Static Assets (Self-Hosting)](https://fastapi.tiangolo.com/how-to/custom-docs-ui-assets/).
112
+ """
113
+ current_swagger_ui_parameters = swagger_ui_default_parameters.copy()
114
+ if swagger_ui_parameters:
115
+ current_swagger_ui_parameters.update(swagger_ui_parameters)
116
+
117
+ html = f"""
118
+ <!DOCTYPE html>
119
+ <html>
120
+ <head>
121
+ <link type="text/css" rel="stylesheet" href="{swagger_css_url}">
122
+ <link rel="shortcut icon" href="{swagger_favicon_url}">
123
+ <title>{title}</title>
124
+ </head>
125
+ <body>
126
+ <div id="swagger-ui">
127
+ </div>
128
+ <script src="{swagger_js_url}"></script>
129
+ <!-- `SwaggerUIBundle` is now available on the page -->
130
+ <script>
131
+ const ui = SwaggerUIBundle({{
132
+ url: '{openapi_url}',
133
+ """
134
+
135
+ for key, value in current_swagger_ui_parameters.items():
136
+ html += f"{json.dumps(key)}: {json.dumps(jsonable_encoder(value))},\n"
137
+
138
+ if oauth2_redirect_url:
139
+ html += f"oauth2RedirectUrl: window.location.origin + '{oauth2_redirect_url}',"
140
+
141
+ html += """
142
+ presets: [
143
+ SwaggerUIBundle.presets.apis,
144
+ SwaggerUIBundle.SwaggerUIStandalonePreset
145
+ ],
146
+ })"""
147
+
148
+ if init_oauth:
149
+ html += f"""
150
+ ui.initOAuth({json.dumps(jsonable_encoder(init_oauth))})
151
+ """
152
+
153
+ html += """
154
+ </script>
155
+ </body>
156
+ </html>
157
+ """
158
+ return HTMLResponse(html)
159
+
160
+
161
+ def get_redoc_html(
162
+ *,
163
+ openapi_url: Annotated[
164
+ str,
165
+ Doc(
166
+ """
167
+ The OpenAPI URL that ReDoc should load and use.
168
+
169
+ This is normally done automatically by FastAPI using the default URL
170
+ `/openapi.json`.
171
+ """
172
+ ),
173
+ ],
174
+ title: Annotated[
175
+ str,
176
+ Doc(
177
+ """
178
+ The HTML `<title>` content, normally shown in the browser tab.
179
+ """
180
+ ),
181
+ ],
182
+ redoc_js_url: Annotated[
183
+ str,
184
+ Doc(
185
+ """
186
+ The URL to use to load the ReDoc JavaScript.
187
+
188
+ It is normally set to a CDN URL.
189
+ """
190
+ ),
191
+ ] = "https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js",
192
+ redoc_favicon_url: Annotated[
193
+ str,
194
+ Doc(
195
+ """
196
+ The URL of the favicon to use. It is normally shown in the browser tab.
197
+ """
198
+ ),
199
+ ] = "https://fastapi.tiangolo.com/img/favicon.png",
200
+ with_google_fonts: Annotated[
201
+ bool,
202
+ Doc(
203
+ """
204
+ Load and use Google Fonts.
205
+ """
206
+ ),
207
+ ] = True,
208
+ ) -> HTMLResponse:
209
+ """
210
+ Generate and return the HTML response that loads ReDoc for the alternative
211
+ API docs (normally served at `/redoc`).
212
+
213
+ You would only call this function yourself if you needed to override some parts,
214
+ for example the URLs to use to load ReDoc's JavaScript and CSS.
215
+
216
+ Read more about it in the
217
+ [FastAPI docs for Custom Docs UI Static Assets (Self-Hosting)](https://fastapi.tiangolo.com/how-to/custom-docs-ui-assets/).
218
+ """
219
+ html = f"""
220
+ <!DOCTYPE html>
221
+ <html>
222
+ <head>
223
+ <title>{title}</title>
224
+ <!-- needed for adaptive design -->
225
+ <meta charset="utf-8"/>
226
+ <meta name="viewport" content="width=device-width, initial-scale=1">
227
+ """
228
+ if with_google_fonts:
229
+ html += """
230
+ <link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet">
231
+ """
232
+ html += f"""
233
+ <link rel="shortcut icon" href="{redoc_favicon_url}">
234
+ <!--
235
+ ReDoc doesn't change outer page styles
236
+ -->
237
+ <style>
238
+ body {{
239
+ margin: 0;
240
+ padding: 0;
241
+ }}
242
+ </style>
243
+ </head>
244
+ <body>
245
+ <noscript>
246
+ ReDoc requires Javascript to function. Please enable it to browse the documentation.
247
+ </noscript>
248
+ <redoc spec-url="{openapi_url}"></redoc>
249
+ <script src="{redoc_js_url}"> </script>
250
+ </body>
251
+ </html>
252
+ """
253
+ return HTMLResponse(html)
254
+
255
+
256
+ def get_swagger_ui_oauth2_redirect_html() -> HTMLResponse:
257
+ """
258
+ Generate the HTML response with the OAuth2 redirection for Swagger UI.
259
+
260
+ You normally don't need to use or change this.
261
+ """
262
+ # copied from https://github.com/swagger-api/swagger-ui/blob/v4.14.0/dist/oauth2-redirect.html
263
+ html = """
264
+ <!doctype html>
265
+ <html lang="en-US">
266
+ <head>
267
+ <title>Swagger UI: OAuth2 Redirect</title>
268
+ </head>
269
+ <body>
270
+ <script>
271
+ 'use strict';
272
+ function run () {
273
+ var oauth2 = window.opener.swaggerUIRedirectOauth2;
274
+ var sentState = oauth2.state;
275
+ var redirectUrl = oauth2.redirectUrl;
276
+ var isValid, qp, arr;
277
+
278
+ if (/code|token|error/.test(window.location.hash)) {
279
+ qp = window.location.hash.substring(1).replace('?', '&');
280
+ } else {
281
+ qp = location.search.substring(1);
282
+ }
283
+
284
+ arr = qp.split("&");
285
+ arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';});
286
+ qp = qp ? JSON.parse('{' + arr.join() + '}',
287
+ function (key, value) {
288
+ return key === "" ? value : decodeURIComponent(value);
289
+ }
290
+ ) : {};
291
+
292
+ isValid = qp.state === sentState;
293
+
294
+ if ((
295
+ oauth2.auth.schema.get("flow") === "accessCode" ||
296
+ oauth2.auth.schema.get("flow") === "authorizationCode" ||
297
+ oauth2.auth.schema.get("flow") === "authorization_code"
298
+ ) && !oauth2.auth.code) {
299
+ if (!isValid) {
300
+ oauth2.errCb({
301
+ authId: oauth2.auth.name,
302
+ source: "auth",
303
+ level: "warning",
304
+ message: "Authorization may be unsafe, passed state was changed in server. The passed state wasn't returned from auth server."
305
+ });
306
+ }
307
+
308
+ if (qp.code) {
309
+ delete oauth2.state;
310
+ oauth2.auth.code = qp.code;
311
+ oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl});
312
+ } else {
313
+ let oauthErrorMsg;
314
+ if (qp.error) {
315
+ oauthErrorMsg = "["+qp.error+"]: " +
316
+ (qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") +
317
+ (qp.error_uri ? "More info: "+qp.error_uri : "");
318
+ }
319
+
320
+ oauth2.errCb({
321
+ authId: oauth2.auth.name,
322
+ source: "auth",
323
+ level: "error",
324
+ message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server."
325
+ });
326
+ }
327
+ } else {
328
+ oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl});
329
+ }
330
+ window.close();
331
+ }
332
+
333
+ if (document.readyState !== 'loading') {
334
+ run();
335
+ } else {
336
+ document.addEventListener('DOMContentLoaded', function () {
337
+ run();
338
+ });
339
+ }
340
+ </script>
341
+ </body>
342
+ </html>
343
+ """
344
+ return HTMLResponse(content=html)
lib/python3.12/site-packages/fastapi/openapi/models.py ADDED
@@ -0,0 +1,445 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from enum import Enum
2
+ from typing import Any, Callable, Dict, Iterable, List, Optional, Set, Type, Union
3
+
4
+ from fastapi._compat import (
5
+ PYDANTIC_V2,
6
+ CoreSchema,
7
+ GetJsonSchemaHandler,
8
+ JsonSchemaValue,
9
+ _model_rebuild,
10
+ with_info_plain_validator_function,
11
+ )
12
+ from fastapi.logger import logger
13
+ from pydantic import AnyUrl, BaseModel, Field
14
+ from typing_extensions import Annotated, Literal, TypedDict
15
+ from typing_extensions import deprecated as typing_deprecated
16
+
17
+ try:
18
+ import email_validator
19
+
20
+ assert email_validator # make autoflake ignore the unused import
21
+ from pydantic import EmailStr
22
+ except ImportError: # pragma: no cover
23
+
24
+ class EmailStr(str): # type: ignore
25
+ @classmethod
26
+ def __get_validators__(cls) -> Iterable[Callable[..., Any]]:
27
+ yield cls.validate
28
+
29
+ @classmethod
30
+ def validate(cls, v: Any) -> str:
31
+ logger.warning(
32
+ "email-validator not installed, email fields will be treated as str.\n"
33
+ "To install, run: pip install email-validator"
34
+ )
35
+ return str(v)
36
+
37
+ @classmethod
38
+ def _validate(cls, __input_value: Any, _: Any) -> str:
39
+ logger.warning(
40
+ "email-validator not installed, email fields will be treated as str.\n"
41
+ "To install, run: pip install email-validator"
42
+ )
43
+ return str(__input_value)
44
+
45
+ @classmethod
46
+ def __get_pydantic_json_schema__(
47
+ cls, core_schema: CoreSchema, handler: GetJsonSchemaHandler
48
+ ) -> JsonSchemaValue:
49
+ return {"type": "string", "format": "email"}
50
+
51
+ @classmethod
52
+ def __get_pydantic_core_schema__(
53
+ cls, source: Type[Any], handler: Callable[[Any], CoreSchema]
54
+ ) -> CoreSchema:
55
+ return with_info_plain_validator_function(cls._validate)
56
+
57
+
58
+ class BaseModelWithConfig(BaseModel):
59
+ if PYDANTIC_V2:
60
+ model_config = {"extra": "allow"}
61
+
62
+ else:
63
+
64
+ class Config:
65
+ extra = "allow"
66
+
67
+
68
+ class Contact(BaseModelWithConfig):
69
+ name: Optional[str] = None
70
+ url: Optional[AnyUrl] = None
71
+ email: Optional[EmailStr] = None
72
+
73
+
74
+ class License(BaseModelWithConfig):
75
+ name: str
76
+ identifier: Optional[str] = None
77
+ url: Optional[AnyUrl] = None
78
+
79
+
80
+ class Info(BaseModelWithConfig):
81
+ title: str
82
+ summary: Optional[str] = None
83
+ description: Optional[str] = None
84
+ termsOfService: Optional[str] = None
85
+ contact: Optional[Contact] = None
86
+ license: Optional[License] = None
87
+ version: str
88
+
89
+
90
+ class ServerVariable(BaseModelWithConfig):
91
+ enum: Annotated[Optional[List[str]], Field(min_length=1)] = None
92
+ default: str
93
+ description: Optional[str] = None
94
+
95
+
96
+ class Server(BaseModelWithConfig):
97
+ url: Union[AnyUrl, str]
98
+ description: Optional[str] = None
99
+ variables: Optional[Dict[str, ServerVariable]] = None
100
+
101
+
102
+ class Reference(BaseModel):
103
+ ref: str = Field(alias="$ref")
104
+
105
+
106
+ class Discriminator(BaseModel):
107
+ propertyName: str
108
+ mapping: Optional[Dict[str, str]] = None
109
+
110
+
111
+ class XML(BaseModelWithConfig):
112
+ name: Optional[str] = None
113
+ namespace: Optional[str] = None
114
+ prefix: Optional[str] = None
115
+ attribute: Optional[bool] = None
116
+ wrapped: Optional[bool] = None
117
+
118
+
119
+ class ExternalDocumentation(BaseModelWithConfig):
120
+ description: Optional[str] = None
121
+ url: AnyUrl
122
+
123
+
124
+ class Schema(BaseModelWithConfig):
125
+ # Ref: JSON Schema 2020-12: https://json-schema.org/draft/2020-12/json-schema-core.html#name-the-json-schema-core-vocabu
126
+ # Core Vocabulary
127
+ schema_: Optional[str] = Field(default=None, alias="$schema")
128
+ vocabulary: Optional[str] = Field(default=None, alias="$vocabulary")
129
+ id: Optional[str] = Field(default=None, alias="$id")
130
+ anchor: Optional[str] = Field(default=None, alias="$anchor")
131
+ dynamicAnchor: Optional[str] = Field(default=None, alias="$dynamicAnchor")
132
+ ref: Optional[str] = Field(default=None, alias="$ref")
133
+ dynamicRef: Optional[str] = Field(default=None, alias="$dynamicRef")
134
+ defs: Optional[Dict[str, "SchemaOrBool"]] = Field(default=None, alias="$defs")
135
+ comment: Optional[str] = Field(default=None, alias="$comment")
136
+ # Ref: JSON Schema 2020-12: https://json-schema.org/draft/2020-12/json-schema-core.html#name-a-vocabulary-for-applying-s
137
+ # A Vocabulary for Applying Subschemas
138
+ allOf: Optional[List["SchemaOrBool"]] = None
139
+ anyOf: Optional[List["SchemaOrBool"]] = None
140
+ oneOf: Optional[List["SchemaOrBool"]] = None
141
+ not_: Optional["SchemaOrBool"] = Field(default=None, alias="not")
142
+ if_: Optional["SchemaOrBool"] = Field(default=None, alias="if")
143
+ then: Optional["SchemaOrBool"] = None
144
+ else_: Optional["SchemaOrBool"] = Field(default=None, alias="else")
145
+ dependentSchemas: Optional[Dict[str, "SchemaOrBool"]] = None
146
+ prefixItems: Optional[List["SchemaOrBool"]] = None
147
+ # TODO: uncomment and remove below when deprecating Pydantic v1
148
+ # It generales a list of schemas for tuples, before prefixItems was available
149
+ # items: Optional["SchemaOrBool"] = None
150
+ items: Optional[Union["SchemaOrBool", List["SchemaOrBool"]]] = None
151
+ contains: Optional["SchemaOrBool"] = None
152
+ properties: Optional[Dict[str, "SchemaOrBool"]] = None
153
+ patternProperties: Optional[Dict[str, "SchemaOrBool"]] = None
154
+ additionalProperties: Optional["SchemaOrBool"] = None
155
+ propertyNames: Optional["SchemaOrBool"] = None
156
+ unevaluatedItems: Optional["SchemaOrBool"] = None
157
+ unevaluatedProperties: Optional["SchemaOrBool"] = None
158
+ # Ref: JSON Schema Validation 2020-12: https://json-schema.org/draft/2020-12/json-schema-validation.html#name-a-vocabulary-for-structural
159
+ # A Vocabulary for Structural Validation
160
+ type: Optional[str] = None
161
+ enum: Optional[List[Any]] = None
162
+ const: Optional[Any] = None
163
+ multipleOf: Optional[float] = Field(default=None, gt=0)
164
+ maximum: Optional[float] = None
165
+ exclusiveMaximum: Optional[float] = None
166
+ minimum: Optional[float] = None
167
+ exclusiveMinimum: Optional[float] = None
168
+ maxLength: Optional[int] = Field(default=None, ge=0)
169
+ minLength: Optional[int] = Field(default=None, ge=0)
170
+ pattern: Optional[str] = None
171
+ maxItems: Optional[int] = Field(default=None, ge=0)
172
+ minItems: Optional[int] = Field(default=None, ge=0)
173
+ uniqueItems: Optional[bool] = None
174
+ maxContains: Optional[int] = Field(default=None, ge=0)
175
+ minContains: Optional[int] = Field(default=None, ge=0)
176
+ maxProperties: Optional[int] = Field(default=None, ge=0)
177
+ minProperties: Optional[int] = Field(default=None, ge=0)
178
+ required: Optional[List[str]] = None
179
+ dependentRequired: Optional[Dict[str, Set[str]]] = None
180
+ # Ref: JSON Schema Validation 2020-12: https://json-schema.org/draft/2020-12/json-schema-validation.html#name-vocabularies-for-semantic-c
181
+ # Vocabularies for Semantic Content With "format"
182
+ format: Optional[str] = None
183
+ # Ref: JSON Schema Validation 2020-12: https://json-schema.org/draft/2020-12/json-schema-validation.html#name-a-vocabulary-for-the-conten
184
+ # A Vocabulary for the Contents of String-Encoded Data
185
+ contentEncoding: Optional[str] = None
186
+ contentMediaType: Optional[str] = None
187
+ contentSchema: Optional["SchemaOrBool"] = None
188
+ # Ref: JSON Schema Validation 2020-12: https://json-schema.org/draft/2020-12/json-schema-validation.html#name-a-vocabulary-for-basic-meta
189
+ # A Vocabulary for Basic Meta-Data Annotations
190
+ title: Optional[str] = None
191
+ description: Optional[str] = None
192
+ default: Optional[Any] = None
193
+ deprecated: Optional[bool] = None
194
+ readOnly: Optional[bool] = None
195
+ writeOnly: Optional[bool] = None
196
+ examples: Optional[List[Any]] = None
197
+ # Ref: OpenAPI 3.1.0: https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#schema-object
198
+ # Schema Object
199
+ discriminator: Optional[Discriminator] = None
200
+ xml: Optional[XML] = None
201
+ externalDocs: Optional[ExternalDocumentation] = None
202
+ example: Annotated[
203
+ Optional[Any],
204
+ typing_deprecated(
205
+ "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
206
+ "although still supported. Use examples instead."
207
+ ),
208
+ ] = None
209
+
210
+
211
+ # Ref: https://json-schema.org/draft/2020-12/json-schema-core.html#name-json-schema-documents
212
+ # A JSON Schema MUST be an object or a boolean.
213
+ SchemaOrBool = Union[Schema, bool]
214
+
215
+
216
+ class Example(TypedDict, total=False):
217
+ summary: Optional[str]
218
+ description: Optional[str]
219
+ value: Optional[Any]
220
+ externalValue: Optional[AnyUrl]
221
+
222
+ if PYDANTIC_V2: # type: ignore [misc]
223
+ __pydantic_config__ = {"extra": "allow"}
224
+
225
+ else:
226
+
227
+ class Config:
228
+ extra = "allow"
229
+
230
+
231
+ class ParameterInType(Enum):
232
+ query = "query"
233
+ header = "header"
234
+ path = "path"
235
+ cookie = "cookie"
236
+
237
+
238
+ class Encoding(BaseModelWithConfig):
239
+ contentType: Optional[str] = None
240
+ headers: Optional[Dict[str, Union["Header", Reference]]] = None
241
+ style: Optional[str] = None
242
+ explode: Optional[bool] = None
243
+ allowReserved: Optional[bool] = None
244
+
245
+
246
+ class MediaType(BaseModelWithConfig):
247
+ schema_: Optional[Union[Schema, Reference]] = Field(default=None, alias="schema")
248
+ example: Optional[Any] = None
249
+ examples: Optional[Dict[str, Union[Example, Reference]]] = None
250
+ encoding: Optional[Dict[str, Encoding]] = None
251
+
252
+
253
+ class ParameterBase(BaseModelWithConfig):
254
+ description: Optional[str] = None
255
+ required: Optional[bool] = None
256
+ deprecated: Optional[bool] = None
257
+ # Serialization rules for simple scenarios
258
+ style: Optional[str] = None
259
+ explode: Optional[bool] = None
260
+ allowReserved: Optional[bool] = None
261
+ schema_: Optional[Union[Schema, Reference]] = Field(default=None, alias="schema")
262
+ example: Optional[Any] = None
263
+ examples: Optional[Dict[str, Union[Example, Reference]]] = None
264
+ # Serialization rules for more complex scenarios
265
+ content: Optional[Dict[str, MediaType]] = None
266
+
267
+
268
+ class Parameter(ParameterBase):
269
+ name: str
270
+ in_: ParameterInType = Field(alias="in")
271
+
272
+
273
+ class Header(ParameterBase):
274
+ pass
275
+
276
+
277
+ class RequestBody(BaseModelWithConfig):
278
+ description: Optional[str] = None
279
+ content: Dict[str, MediaType]
280
+ required: Optional[bool] = None
281
+
282
+
283
+ class Link(BaseModelWithConfig):
284
+ operationRef: Optional[str] = None
285
+ operationId: Optional[str] = None
286
+ parameters: Optional[Dict[str, Union[Any, str]]] = None
287
+ requestBody: Optional[Union[Any, str]] = None
288
+ description: Optional[str] = None
289
+ server: Optional[Server] = None
290
+
291
+
292
+ class Response(BaseModelWithConfig):
293
+ description: str
294
+ headers: Optional[Dict[str, Union[Header, Reference]]] = None
295
+ content: Optional[Dict[str, MediaType]] = None
296
+ links: Optional[Dict[str, Union[Link, Reference]]] = None
297
+
298
+
299
+ class Operation(BaseModelWithConfig):
300
+ tags: Optional[List[str]] = None
301
+ summary: Optional[str] = None
302
+ description: Optional[str] = None
303
+ externalDocs: Optional[ExternalDocumentation] = None
304
+ operationId: Optional[str] = None
305
+ parameters: Optional[List[Union[Parameter, Reference]]] = None
306
+ requestBody: Optional[Union[RequestBody, Reference]] = None
307
+ # Using Any for Specification Extensions
308
+ responses: Optional[Dict[str, Union[Response, Any]]] = None
309
+ callbacks: Optional[Dict[str, Union[Dict[str, "PathItem"], Reference]]] = None
310
+ deprecated: Optional[bool] = None
311
+ security: Optional[List[Dict[str, List[str]]]] = None
312
+ servers: Optional[List[Server]] = None
313
+
314
+
315
+ class PathItem(BaseModelWithConfig):
316
+ ref: Optional[str] = Field(default=None, alias="$ref")
317
+ summary: Optional[str] = None
318
+ description: Optional[str] = None
319
+ get: Optional[Operation] = None
320
+ put: Optional[Operation] = None
321
+ post: Optional[Operation] = None
322
+ delete: Optional[Operation] = None
323
+ options: Optional[Operation] = None
324
+ head: Optional[Operation] = None
325
+ patch: Optional[Operation] = None
326
+ trace: Optional[Operation] = None
327
+ servers: Optional[List[Server]] = None
328
+ parameters: Optional[List[Union[Parameter, Reference]]] = None
329
+
330
+
331
+ class SecuritySchemeType(Enum):
332
+ apiKey = "apiKey"
333
+ http = "http"
334
+ oauth2 = "oauth2"
335
+ openIdConnect = "openIdConnect"
336
+
337
+
338
+ class SecurityBase(BaseModelWithConfig):
339
+ type_: SecuritySchemeType = Field(alias="type")
340
+ description: Optional[str] = None
341
+
342
+
343
+ class APIKeyIn(Enum):
344
+ query = "query"
345
+ header = "header"
346
+ cookie = "cookie"
347
+
348
+
349
+ class APIKey(SecurityBase):
350
+ type_: SecuritySchemeType = Field(default=SecuritySchemeType.apiKey, alias="type")
351
+ in_: APIKeyIn = Field(alias="in")
352
+ name: str
353
+
354
+
355
+ class HTTPBase(SecurityBase):
356
+ type_: SecuritySchemeType = Field(default=SecuritySchemeType.http, alias="type")
357
+ scheme: str
358
+
359
+
360
+ class HTTPBearer(HTTPBase):
361
+ scheme: Literal["bearer"] = "bearer"
362
+ bearerFormat: Optional[str] = None
363
+
364
+
365
+ class OAuthFlow(BaseModelWithConfig):
366
+ refreshUrl: Optional[str] = None
367
+ scopes: Dict[str, str] = {}
368
+
369
+
370
+ class OAuthFlowImplicit(OAuthFlow):
371
+ authorizationUrl: str
372
+
373
+
374
+ class OAuthFlowPassword(OAuthFlow):
375
+ tokenUrl: str
376
+
377
+
378
+ class OAuthFlowClientCredentials(OAuthFlow):
379
+ tokenUrl: str
380
+
381
+
382
+ class OAuthFlowAuthorizationCode(OAuthFlow):
383
+ authorizationUrl: str
384
+ tokenUrl: str
385
+
386
+
387
+ class OAuthFlows(BaseModelWithConfig):
388
+ implicit: Optional[OAuthFlowImplicit] = None
389
+ password: Optional[OAuthFlowPassword] = None
390
+ clientCredentials: Optional[OAuthFlowClientCredentials] = None
391
+ authorizationCode: Optional[OAuthFlowAuthorizationCode] = None
392
+
393
+
394
+ class OAuth2(SecurityBase):
395
+ type_: SecuritySchemeType = Field(default=SecuritySchemeType.oauth2, alias="type")
396
+ flows: OAuthFlows
397
+
398
+
399
+ class OpenIdConnect(SecurityBase):
400
+ type_: SecuritySchemeType = Field(
401
+ default=SecuritySchemeType.openIdConnect, alias="type"
402
+ )
403
+ openIdConnectUrl: str
404
+
405
+
406
+ SecurityScheme = Union[APIKey, HTTPBase, OAuth2, OpenIdConnect, HTTPBearer]
407
+
408
+
409
+ class Components(BaseModelWithConfig):
410
+ schemas: Optional[Dict[str, Union[Schema, Reference]]] = None
411
+ responses: Optional[Dict[str, Union[Response, Reference]]] = None
412
+ parameters: Optional[Dict[str, Union[Parameter, Reference]]] = None
413
+ examples: Optional[Dict[str, Union[Example, Reference]]] = None
414
+ requestBodies: Optional[Dict[str, Union[RequestBody, Reference]]] = None
415
+ headers: Optional[Dict[str, Union[Header, Reference]]] = None
416
+ securitySchemes: Optional[Dict[str, Union[SecurityScheme, Reference]]] = None
417
+ links: Optional[Dict[str, Union[Link, Reference]]] = None
418
+ # Using Any for Specification Extensions
419
+ callbacks: Optional[Dict[str, Union[Dict[str, PathItem], Reference, Any]]] = None
420
+ pathItems: Optional[Dict[str, Union[PathItem, Reference]]] = None
421
+
422
+
423
+ class Tag(BaseModelWithConfig):
424
+ name: str
425
+ description: Optional[str] = None
426
+ externalDocs: Optional[ExternalDocumentation] = None
427
+
428
+
429
+ class OpenAPI(BaseModelWithConfig):
430
+ openapi: str
431
+ info: Info
432
+ jsonSchemaDialect: Optional[str] = None
433
+ servers: Optional[List[Server]] = None
434
+ # Using Any for Specification Extensions
435
+ paths: Optional[Dict[str, Union[PathItem, Any]]] = None
436
+ webhooks: Optional[Dict[str, Union[PathItem, Reference]]] = None
437
+ components: Optional[Components] = None
438
+ security: Optional[List[Dict[str, List[str]]]] = None
439
+ tags: Optional[List[Tag]] = None
440
+ externalDocs: Optional[ExternalDocumentation] = None
441
+
442
+
443
+ _model_rebuild(Schema)
444
+ _model_rebuild(Operation)
445
+ _model_rebuild(Encoding)
lib/python3.12/site-packages/fastapi/openapi/utils.py ADDED
@@ -0,0 +1,569 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import http.client
2
+ import inspect
3
+ import warnings
4
+ from typing import Any, Dict, List, Optional, Sequence, Set, Tuple, Type, Union, cast
5
+
6
+ from fastapi import routing
7
+ from fastapi._compat import (
8
+ GenerateJsonSchema,
9
+ JsonSchemaValue,
10
+ ModelField,
11
+ Undefined,
12
+ get_compat_model_name_map,
13
+ get_definitions,
14
+ get_schema_from_model_field,
15
+ lenient_issubclass,
16
+ )
17
+ from fastapi.datastructures import DefaultPlaceholder
18
+ from fastapi.dependencies.models import Dependant
19
+ from fastapi.dependencies.utils import (
20
+ _get_flat_fields_from_params,
21
+ get_flat_dependant,
22
+ get_flat_params,
23
+ )
24
+ from fastapi.encoders import jsonable_encoder
25
+ from fastapi.openapi.constants import METHODS_WITH_BODY, REF_PREFIX, REF_TEMPLATE
26
+ from fastapi.openapi.models import OpenAPI
27
+ from fastapi.params import Body, ParamTypes
28
+ from fastapi.responses import Response
29
+ from fastapi.types import ModelNameMap
30
+ from fastapi.utils import (
31
+ deep_dict_update,
32
+ generate_operation_id_for_path,
33
+ is_body_allowed_for_status_code,
34
+ )
35
+ from pydantic import BaseModel
36
+ from starlette.responses import JSONResponse
37
+ from starlette.routing import BaseRoute
38
+ from starlette.status import HTTP_422_UNPROCESSABLE_ENTITY
39
+ from typing_extensions import Literal
40
+
41
+ validation_error_definition = {
42
+ "title": "ValidationError",
43
+ "type": "object",
44
+ "properties": {
45
+ "loc": {
46
+ "title": "Location",
47
+ "type": "array",
48
+ "items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
49
+ },
50
+ "msg": {"title": "Message", "type": "string"},
51
+ "type": {"title": "Error Type", "type": "string"},
52
+ },
53
+ "required": ["loc", "msg", "type"],
54
+ }
55
+
56
+ validation_error_response_definition = {
57
+ "title": "HTTPValidationError",
58
+ "type": "object",
59
+ "properties": {
60
+ "detail": {
61
+ "title": "Detail",
62
+ "type": "array",
63
+ "items": {"$ref": REF_PREFIX + "ValidationError"},
64
+ }
65
+ },
66
+ }
67
+
68
+ status_code_ranges: Dict[str, str] = {
69
+ "1XX": "Information",
70
+ "2XX": "Success",
71
+ "3XX": "Redirection",
72
+ "4XX": "Client Error",
73
+ "5XX": "Server Error",
74
+ "DEFAULT": "Default Response",
75
+ }
76
+
77
+
78
+ def get_openapi_security_definitions(
79
+ flat_dependant: Dependant,
80
+ ) -> Tuple[Dict[str, Any], List[Dict[str, Any]]]:
81
+ security_definitions = {}
82
+ operation_security = []
83
+ for security_requirement in flat_dependant.security_requirements:
84
+ security_definition = jsonable_encoder(
85
+ security_requirement.security_scheme.model,
86
+ by_alias=True,
87
+ exclude_none=True,
88
+ )
89
+ security_name = security_requirement.security_scheme.scheme_name
90
+ security_definitions[security_name] = security_definition
91
+ operation_security.append({security_name: security_requirement.scopes})
92
+ return security_definitions, operation_security
93
+
94
+
95
+ def _get_openapi_operation_parameters(
96
+ *,
97
+ dependant: Dependant,
98
+ schema_generator: GenerateJsonSchema,
99
+ model_name_map: ModelNameMap,
100
+ field_mapping: Dict[
101
+ Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
102
+ ],
103
+ separate_input_output_schemas: bool = True,
104
+ ) -> List[Dict[str, Any]]:
105
+ parameters = []
106
+ flat_dependant = get_flat_dependant(dependant, skip_repeats=True)
107
+ path_params = _get_flat_fields_from_params(flat_dependant.path_params)
108
+ query_params = _get_flat_fields_from_params(flat_dependant.query_params)
109
+ header_params = _get_flat_fields_from_params(flat_dependant.header_params)
110
+ cookie_params = _get_flat_fields_from_params(flat_dependant.cookie_params)
111
+ parameter_groups = [
112
+ (ParamTypes.path, path_params),
113
+ (ParamTypes.query, query_params),
114
+ (ParamTypes.header, header_params),
115
+ (ParamTypes.cookie, cookie_params),
116
+ ]
117
+ default_convert_underscores = True
118
+ if len(flat_dependant.header_params) == 1:
119
+ first_field = flat_dependant.header_params[0]
120
+ if lenient_issubclass(first_field.type_, BaseModel):
121
+ default_convert_underscores = getattr(
122
+ first_field.field_info, "convert_underscores", True
123
+ )
124
+ for param_type, param_group in parameter_groups:
125
+ for param in param_group:
126
+ field_info = param.field_info
127
+ # field_info = cast(Param, field_info)
128
+ if not getattr(field_info, "include_in_schema", True):
129
+ continue
130
+ param_schema = get_schema_from_model_field(
131
+ field=param,
132
+ schema_generator=schema_generator,
133
+ model_name_map=model_name_map,
134
+ field_mapping=field_mapping,
135
+ separate_input_output_schemas=separate_input_output_schemas,
136
+ )
137
+ name = param.alias
138
+ convert_underscores = getattr(
139
+ param.field_info,
140
+ "convert_underscores",
141
+ default_convert_underscores,
142
+ )
143
+ if (
144
+ param_type == ParamTypes.header
145
+ and param.alias == param.name
146
+ and convert_underscores
147
+ ):
148
+ name = param.name.replace("_", "-")
149
+
150
+ parameter = {
151
+ "name": name,
152
+ "in": param_type.value,
153
+ "required": param.required,
154
+ "schema": param_schema,
155
+ }
156
+ if field_info.description:
157
+ parameter["description"] = field_info.description
158
+ openapi_examples = getattr(field_info, "openapi_examples", None)
159
+ example = getattr(field_info, "example", None)
160
+ if openapi_examples:
161
+ parameter["examples"] = jsonable_encoder(openapi_examples)
162
+ elif example != Undefined:
163
+ parameter["example"] = jsonable_encoder(example)
164
+ if getattr(field_info, "deprecated", None):
165
+ parameter["deprecated"] = True
166
+ parameters.append(parameter)
167
+ return parameters
168
+
169
+
170
+ def get_openapi_operation_request_body(
171
+ *,
172
+ body_field: Optional[ModelField],
173
+ schema_generator: GenerateJsonSchema,
174
+ model_name_map: ModelNameMap,
175
+ field_mapping: Dict[
176
+ Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
177
+ ],
178
+ separate_input_output_schemas: bool = True,
179
+ ) -> Optional[Dict[str, Any]]:
180
+ if not body_field:
181
+ return None
182
+ assert isinstance(body_field, ModelField)
183
+ body_schema = get_schema_from_model_field(
184
+ field=body_field,
185
+ schema_generator=schema_generator,
186
+ model_name_map=model_name_map,
187
+ field_mapping=field_mapping,
188
+ separate_input_output_schemas=separate_input_output_schemas,
189
+ )
190
+ field_info = cast(Body, body_field.field_info)
191
+ request_media_type = field_info.media_type
192
+ required = body_field.required
193
+ request_body_oai: Dict[str, Any] = {}
194
+ if required:
195
+ request_body_oai["required"] = required
196
+ request_media_content: Dict[str, Any] = {"schema": body_schema}
197
+ if field_info.openapi_examples:
198
+ request_media_content["examples"] = jsonable_encoder(
199
+ field_info.openapi_examples
200
+ )
201
+ elif field_info.example != Undefined:
202
+ request_media_content["example"] = jsonable_encoder(field_info.example)
203
+ request_body_oai["content"] = {request_media_type: request_media_content}
204
+ return request_body_oai
205
+
206
+
207
+ def generate_operation_id(
208
+ *, route: routing.APIRoute, method: str
209
+ ) -> str: # pragma: nocover
210
+ warnings.warn(
211
+ "fastapi.openapi.utils.generate_operation_id() was deprecated, "
212
+ "it is not used internally, and will be removed soon",
213
+ DeprecationWarning,
214
+ stacklevel=2,
215
+ )
216
+ if route.operation_id:
217
+ return route.operation_id
218
+ path: str = route.path_format
219
+ return generate_operation_id_for_path(name=route.name, path=path, method=method)
220
+
221
+
222
+ def generate_operation_summary(*, route: routing.APIRoute, method: str) -> str:
223
+ if route.summary:
224
+ return route.summary
225
+ return route.name.replace("_", " ").title()
226
+
227
+
228
+ def get_openapi_operation_metadata(
229
+ *, route: routing.APIRoute, method: str, operation_ids: Set[str]
230
+ ) -> Dict[str, Any]:
231
+ operation: Dict[str, Any] = {}
232
+ if route.tags:
233
+ operation["tags"] = route.tags
234
+ operation["summary"] = generate_operation_summary(route=route, method=method)
235
+ if route.description:
236
+ operation["description"] = route.description
237
+ operation_id = route.operation_id or route.unique_id
238
+ if operation_id in operation_ids:
239
+ message = (
240
+ f"Duplicate Operation ID {operation_id} for function "
241
+ + f"{route.endpoint.__name__}"
242
+ )
243
+ file_name = getattr(route.endpoint, "__globals__", {}).get("__file__")
244
+ if file_name:
245
+ message += f" at {file_name}"
246
+ warnings.warn(message, stacklevel=1)
247
+ operation_ids.add(operation_id)
248
+ operation["operationId"] = operation_id
249
+ if route.deprecated:
250
+ operation["deprecated"] = route.deprecated
251
+ return operation
252
+
253
+
254
+ def get_openapi_path(
255
+ *,
256
+ route: routing.APIRoute,
257
+ operation_ids: Set[str],
258
+ schema_generator: GenerateJsonSchema,
259
+ model_name_map: ModelNameMap,
260
+ field_mapping: Dict[
261
+ Tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue
262
+ ],
263
+ separate_input_output_schemas: bool = True,
264
+ ) -> Tuple[Dict[str, Any], Dict[str, Any], Dict[str, Any]]:
265
+ path = {}
266
+ security_schemes: Dict[str, Any] = {}
267
+ definitions: Dict[str, Any] = {}
268
+ assert route.methods is not None, "Methods must be a list"
269
+ if isinstance(route.response_class, DefaultPlaceholder):
270
+ current_response_class: Type[Response] = route.response_class.value
271
+ else:
272
+ current_response_class = route.response_class
273
+ assert current_response_class, "A response class is needed to generate OpenAPI"
274
+ route_response_media_type: Optional[str] = current_response_class.media_type
275
+ if route.include_in_schema:
276
+ for method in route.methods:
277
+ operation = get_openapi_operation_metadata(
278
+ route=route, method=method, operation_ids=operation_ids
279
+ )
280
+ parameters: List[Dict[str, Any]] = []
281
+ flat_dependant = get_flat_dependant(route.dependant, skip_repeats=True)
282
+ security_definitions, operation_security = get_openapi_security_definitions(
283
+ flat_dependant=flat_dependant
284
+ )
285
+ if operation_security:
286
+ operation.setdefault("security", []).extend(operation_security)
287
+ if security_definitions:
288
+ security_schemes.update(security_definitions)
289
+ operation_parameters = _get_openapi_operation_parameters(
290
+ dependant=route.dependant,
291
+ schema_generator=schema_generator,
292
+ model_name_map=model_name_map,
293
+ field_mapping=field_mapping,
294
+ separate_input_output_schemas=separate_input_output_schemas,
295
+ )
296
+ parameters.extend(operation_parameters)
297
+ if parameters:
298
+ all_parameters = {
299
+ (param["in"], param["name"]): param for param in parameters
300
+ }
301
+ required_parameters = {
302
+ (param["in"], param["name"]): param
303
+ for param in parameters
304
+ if param.get("required")
305
+ }
306
+ # Make sure required definitions of the same parameter take precedence
307
+ # over non-required definitions
308
+ all_parameters.update(required_parameters)
309
+ operation["parameters"] = list(all_parameters.values())
310
+ if method in METHODS_WITH_BODY:
311
+ request_body_oai = get_openapi_operation_request_body(
312
+ body_field=route.body_field,
313
+ schema_generator=schema_generator,
314
+ model_name_map=model_name_map,
315
+ field_mapping=field_mapping,
316
+ separate_input_output_schemas=separate_input_output_schemas,
317
+ )
318
+ if request_body_oai:
319
+ operation["requestBody"] = request_body_oai
320
+ if route.callbacks:
321
+ callbacks = {}
322
+ for callback in route.callbacks:
323
+ if isinstance(callback, routing.APIRoute):
324
+ (
325
+ cb_path,
326
+ cb_security_schemes,
327
+ cb_definitions,
328
+ ) = get_openapi_path(
329
+ route=callback,
330
+ operation_ids=operation_ids,
331
+ schema_generator=schema_generator,
332
+ model_name_map=model_name_map,
333
+ field_mapping=field_mapping,
334
+ separate_input_output_schemas=separate_input_output_schemas,
335
+ )
336
+ callbacks[callback.name] = {callback.path: cb_path}
337
+ operation["callbacks"] = callbacks
338
+ if route.status_code is not None:
339
+ status_code = str(route.status_code)
340
+ else:
341
+ # It would probably make more sense for all response classes to have an
342
+ # explicit default status_code, and to extract it from them, instead of
343
+ # doing this inspection tricks, that would probably be in the future
344
+ # TODO: probably make status_code a default class attribute for all
345
+ # responses in Starlette
346
+ response_signature = inspect.signature(current_response_class.__init__)
347
+ status_code_param = response_signature.parameters.get("status_code")
348
+ if status_code_param is not None:
349
+ if isinstance(status_code_param.default, int):
350
+ status_code = str(status_code_param.default)
351
+ operation.setdefault("responses", {}).setdefault(status_code, {})[
352
+ "description"
353
+ ] = route.response_description
354
+ if route_response_media_type and is_body_allowed_for_status_code(
355
+ route.status_code
356
+ ):
357
+ response_schema = {"type": "string"}
358
+ if lenient_issubclass(current_response_class, JSONResponse):
359
+ if route.response_field:
360
+ response_schema = get_schema_from_model_field(
361
+ field=route.response_field,
362
+ schema_generator=schema_generator,
363
+ model_name_map=model_name_map,
364
+ field_mapping=field_mapping,
365
+ separate_input_output_schemas=separate_input_output_schemas,
366
+ )
367
+ else:
368
+ response_schema = {}
369
+ operation.setdefault("responses", {}).setdefault(
370
+ status_code, {}
371
+ ).setdefault("content", {}).setdefault(route_response_media_type, {})[
372
+ "schema"
373
+ ] = response_schema
374
+ if route.responses:
375
+ operation_responses = operation.setdefault("responses", {})
376
+ for (
377
+ additional_status_code,
378
+ additional_response,
379
+ ) in route.responses.items():
380
+ process_response = additional_response.copy()
381
+ process_response.pop("model", None)
382
+ status_code_key = str(additional_status_code).upper()
383
+ if status_code_key == "DEFAULT":
384
+ status_code_key = "default"
385
+ openapi_response = operation_responses.setdefault(
386
+ status_code_key, {}
387
+ )
388
+ assert isinstance(process_response, dict), (
389
+ "An additional response must be a dict"
390
+ )
391
+ field = route.response_fields.get(additional_status_code)
392
+ additional_field_schema: Optional[Dict[str, Any]] = None
393
+ if field:
394
+ additional_field_schema = get_schema_from_model_field(
395
+ field=field,
396
+ schema_generator=schema_generator,
397
+ model_name_map=model_name_map,
398
+ field_mapping=field_mapping,
399
+ separate_input_output_schemas=separate_input_output_schemas,
400
+ )
401
+ media_type = route_response_media_type or "application/json"
402
+ additional_schema = (
403
+ process_response.setdefault("content", {})
404
+ .setdefault(media_type, {})
405
+ .setdefault("schema", {})
406
+ )
407
+ deep_dict_update(additional_schema, additional_field_schema)
408
+ status_text: Optional[str] = status_code_ranges.get(
409
+ str(additional_status_code).upper()
410
+ ) or http.client.responses.get(int(additional_status_code))
411
+ description = (
412
+ process_response.get("description")
413
+ or openapi_response.get("description")
414
+ or status_text
415
+ or "Additional Response"
416
+ )
417
+ deep_dict_update(openapi_response, process_response)
418
+ openapi_response["description"] = description
419
+ http422 = str(HTTP_422_UNPROCESSABLE_ENTITY)
420
+ all_route_params = get_flat_params(route.dependant)
421
+ if (all_route_params or route.body_field) and not any(
422
+ status in operation["responses"]
423
+ for status in [http422, "4XX", "default"]
424
+ ):
425
+ operation["responses"][http422] = {
426
+ "description": "Validation Error",
427
+ "content": {
428
+ "application/json": {
429
+ "schema": {"$ref": REF_PREFIX + "HTTPValidationError"}
430
+ }
431
+ },
432
+ }
433
+ if "ValidationError" not in definitions:
434
+ definitions.update(
435
+ {
436
+ "ValidationError": validation_error_definition,
437
+ "HTTPValidationError": validation_error_response_definition,
438
+ }
439
+ )
440
+ if route.openapi_extra:
441
+ deep_dict_update(operation, route.openapi_extra)
442
+ path[method.lower()] = operation
443
+ return path, security_schemes, definitions
444
+
445
+
446
+ def get_fields_from_routes(
447
+ routes: Sequence[BaseRoute],
448
+ ) -> List[ModelField]:
449
+ body_fields_from_routes: List[ModelField] = []
450
+ responses_from_routes: List[ModelField] = []
451
+ request_fields_from_routes: List[ModelField] = []
452
+ callback_flat_models: List[ModelField] = []
453
+ for route in routes:
454
+ if getattr(route, "include_in_schema", None) and isinstance(
455
+ route, routing.APIRoute
456
+ ):
457
+ if route.body_field:
458
+ assert isinstance(route.body_field, ModelField), (
459
+ "A request body must be a Pydantic Field"
460
+ )
461
+ body_fields_from_routes.append(route.body_field)
462
+ if route.response_field:
463
+ responses_from_routes.append(route.response_field)
464
+ if route.response_fields:
465
+ responses_from_routes.extend(route.response_fields.values())
466
+ if route.callbacks:
467
+ callback_flat_models.extend(get_fields_from_routes(route.callbacks))
468
+ params = get_flat_params(route.dependant)
469
+ request_fields_from_routes.extend(params)
470
+
471
+ flat_models = callback_flat_models + list(
472
+ body_fields_from_routes + responses_from_routes + request_fields_from_routes
473
+ )
474
+ return flat_models
475
+
476
+
477
+ def get_openapi(
478
+ *,
479
+ title: str,
480
+ version: str,
481
+ openapi_version: str = "3.1.0",
482
+ summary: Optional[str] = None,
483
+ description: Optional[str] = None,
484
+ routes: Sequence[BaseRoute],
485
+ webhooks: Optional[Sequence[BaseRoute]] = None,
486
+ tags: Optional[List[Dict[str, Any]]] = None,
487
+ servers: Optional[List[Dict[str, Union[str, Any]]]] = None,
488
+ terms_of_service: Optional[str] = None,
489
+ contact: Optional[Dict[str, Union[str, Any]]] = None,
490
+ license_info: Optional[Dict[str, Union[str, Any]]] = None,
491
+ separate_input_output_schemas: bool = True,
492
+ ) -> Dict[str, Any]:
493
+ info: Dict[str, Any] = {"title": title, "version": version}
494
+ if summary:
495
+ info["summary"] = summary
496
+ if description:
497
+ info["description"] = description
498
+ if terms_of_service:
499
+ info["termsOfService"] = terms_of_service
500
+ if contact:
501
+ info["contact"] = contact
502
+ if license_info:
503
+ info["license"] = license_info
504
+ output: Dict[str, Any] = {"openapi": openapi_version, "info": info}
505
+ if servers:
506
+ output["servers"] = servers
507
+ components: Dict[str, Dict[str, Any]] = {}
508
+ paths: Dict[str, Dict[str, Any]] = {}
509
+ webhook_paths: Dict[str, Dict[str, Any]] = {}
510
+ operation_ids: Set[str] = set()
511
+ all_fields = get_fields_from_routes(list(routes or []) + list(webhooks or []))
512
+ model_name_map = get_compat_model_name_map(all_fields)
513
+ schema_generator = GenerateJsonSchema(ref_template=REF_TEMPLATE)
514
+ field_mapping, definitions = get_definitions(
515
+ fields=all_fields,
516
+ schema_generator=schema_generator,
517
+ model_name_map=model_name_map,
518
+ separate_input_output_schemas=separate_input_output_schemas,
519
+ )
520
+ for route in routes or []:
521
+ if isinstance(route, routing.APIRoute):
522
+ result = get_openapi_path(
523
+ route=route,
524
+ operation_ids=operation_ids,
525
+ schema_generator=schema_generator,
526
+ model_name_map=model_name_map,
527
+ field_mapping=field_mapping,
528
+ separate_input_output_schemas=separate_input_output_schemas,
529
+ )
530
+ if result:
531
+ path, security_schemes, path_definitions = result
532
+ if path:
533
+ paths.setdefault(route.path_format, {}).update(path)
534
+ if security_schemes:
535
+ components.setdefault("securitySchemes", {}).update(
536
+ security_schemes
537
+ )
538
+ if path_definitions:
539
+ definitions.update(path_definitions)
540
+ for webhook in webhooks or []:
541
+ if isinstance(webhook, routing.APIRoute):
542
+ result = get_openapi_path(
543
+ route=webhook,
544
+ operation_ids=operation_ids,
545
+ schema_generator=schema_generator,
546
+ model_name_map=model_name_map,
547
+ field_mapping=field_mapping,
548
+ separate_input_output_schemas=separate_input_output_schemas,
549
+ )
550
+ if result:
551
+ path, security_schemes, path_definitions = result
552
+ if path:
553
+ webhook_paths.setdefault(webhook.path_format, {}).update(path)
554
+ if security_schemes:
555
+ components.setdefault("securitySchemes", {}).update(
556
+ security_schemes
557
+ )
558
+ if path_definitions:
559
+ definitions.update(path_definitions)
560
+ if definitions:
561
+ components["schemas"] = {k: definitions[k] for k in sorted(definitions)}
562
+ if components:
563
+ output["components"] = components
564
+ output["paths"] = paths
565
+ if webhook_paths:
566
+ output["webhooks"] = webhook_paths
567
+ if tags:
568
+ output["tags"] = tags
569
+ return jsonable_encoder(OpenAPI(**output), by_alias=True, exclude_none=True) # type: ignore
lib/python3.12/site-packages/fastapi/param_functions.py ADDED
@@ -0,0 +1,2360 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Any, Callable, Dict, List, Optional, Sequence, Union
2
+
3
+ from fastapi import params
4
+ from fastapi._compat import Undefined
5
+ from fastapi.openapi.models import Example
6
+ from typing_extensions import Annotated, Doc, deprecated
7
+
8
+ _Unset: Any = Undefined
9
+
10
+
11
+ def Path( # noqa: N802
12
+ default: Annotated[
13
+ Any,
14
+ Doc(
15
+ """
16
+ Default value if the parameter field is not set.
17
+
18
+ This doesn't affect `Path` parameters as the value is always required.
19
+ The parameter is available only for compatibility.
20
+ """
21
+ ),
22
+ ] = ...,
23
+ *,
24
+ default_factory: Annotated[
25
+ Union[Callable[[], Any], None],
26
+ Doc(
27
+ """
28
+ A callable to generate the default value.
29
+
30
+ This doesn't affect `Path` parameters as the value is always required.
31
+ The parameter is available only for compatibility.
32
+ """
33
+ ),
34
+ ] = _Unset,
35
+ alias: Annotated[
36
+ Optional[str],
37
+ Doc(
38
+ """
39
+ An alternative name for the parameter field.
40
+
41
+ This will be used to extract the data and for the generated OpenAPI.
42
+ It is particularly useful when you can't use the name you want because it
43
+ is a Python reserved keyword or similar.
44
+ """
45
+ ),
46
+ ] = None,
47
+ alias_priority: Annotated[
48
+ Union[int, None],
49
+ Doc(
50
+ """
51
+ Priority of the alias. This affects whether an alias generator is used.
52
+ """
53
+ ),
54
+ ] = _Unset,
55
+ # TODO: update when deprecating Pydantic v1, import these types
56
+ # validation_alias: str | AliasPath | AliasChoices | None
57
+ validation_alias: Annotated[
58
+ Union[str, None],
59
+ Doc(
60
+ """
61
+ 'Whitelist' validation step. The parameter field will be the single one
62
+ allowed by the alias or set of aliases defined.
63
+ """
64
+ ),
65
+ ] = None,
66
+ serialization_alias: Annotated[
67
+ Union[str, None],
68
+ Doc(
69
+ """
70
+ 'Blacklist' validation step. The vanilla parameter field will be the
71
+ single one of the alias' or set of aliases' fields and all the other
72
+ fields will be ignored at serialization time.
73
+ """
74
+ ),
75
+ ] = None,
76
+ title: Annotated[
77
+ Optional[str],
78
+ Doc(
79
+ """
80
+ Human-readable title.
81
+ """
82
+ ),
83
+ ] = None,
84
+ description: Annotated[
85
+ Optional[str],
86
+ Doc(
87
+ """
88
+ Human-readable description.
89
+ """
90
+ ),
91
+ ] = None,
92
+ gt: Annotated[
93
+ Optional[float],
94
+ Doc(
95
+ """
96
+ Greater than. If set, value must be greater than this. Only applicable to
97
+ numbers.
98
+ """
99
+ ),
100
+ ] = None,
101
+ ge: Annotated[
102
+ Optional[float],
103
+ Doc(
104
+ """
105
+ Greater than or equal. If set, value must be greater than or equal to
106
+ this. Only applicable to numbers.
107
+ """
108
+ ),
109
+ ] = None,
110
+ lt: Annotated[
111
+ Optional[float],
112
+ Doc(
113
+ """
114
+ Less than. If set, value must be less than this. Only applicable to numbers.
115
+ """
116
+ ),
117
+ ] = None,
118
+ le: Annotated[
119
+ Optional[float],
120
+ Doc(
121
+ """
122
+ Less than or equal. If set, value must be less than or equal to this.
123
+ Only applicable to numbers.
124
+ """
125
+ ),
126
+ ] = None,
127
+ min_length: Annotated[
128
+ Optional[int],
129
+ Doc(
130
+ """
131
+ Minimum length for strings.
132
+ """
133
+ ),
134
+ ] = None,
135
+ max_length: Annotated[
136
+ Optional[int],
137
+ Doc(
138
+ """
139
+ Maximum length for strings.
140
+ """
141
+ ),
142
+ ] = None,
143
+ pattern: Annotated[
144
+ Optional[str],
145
+ Doc(
146
+ """
147
+ RegEx pattern for strings.
148
+ """
149
+ ),
150
+ ] = None,
151
+ regex: Annotated[
152
+ Optional[str],
153
+ Doc(
154
+ """
155
+ RegEx pattern for strings.
156
+ """
157
+ ),
158
+ deprecated(
159
+ "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
160
+ ),
161
+ ] = None,
162
+ discriminator: Annotated[
163
+ Union[str, None],
164
+ Doc(
165
+ """
166
+ Parameter field name for discriminating the type in a tagged union.
167
+ """
168
+ ),
169
+ ] = None,
170
+ strict: Annotated[
171
+ Union[bool, None],
172
+ Doc(
173
+ """
174
+ If `True`, strict validation is applied to the field.
175
+ """
176
+ ),
177
+ ] = _Unset,
178
+ multiple_of: Annotated[
179
+ Union[float, None],
180
+ Doc(
181
+ """
182
+ Value must be a multiple of this. Only applicable to numbers.
183
+ """
184
+ ),
185
+ ] = _Unset,
186
+ allow_inf_nan: Annotated[
187
+ Union[bool, None],
188
+ Doc(
189
+ """
190
+ Allow `inf`, `-inf`, `nan`. Only applicable to numbers.
191
+ """
192
+ ),
193
+ ] = _Unset,
194
+ max_digits: Annotated[
195
+ Union[int, None],
196
+ Doc(
197
+ """
198
+ Maximum number of allow digits for strings.
199
+ """
200
+ ),
201
+ ] = _Unset,
202
+ decimal_places: Annotated[
203
+ Union[int, None],
204
+ Doc(
205
+ """
206
+ Maximum number of decimal places allowed for numbers.
207
+ """
208
+ ),
209
+ ] = _Unset,
210
+ examples: Annotated[
211
+ Optional[List[Any]],
212
+ Doc(
213
+ """
214
+ Example values for this field.
215
+ """
216
+ ),
217
+ ] = None,
218
+ example: Annotated[
219
+ Optional[Any],
220
+ deprecated(
221
+ "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
222
+ "although still supported. Use examples instead."
223
+ ),
224
+ ] = _Unset,
225
+ openapi_examples: Annotated[
226
+ Optional[Dict[str, Example]],
227
+ Doc(
228
+ """
229
+ OpenAPI-specific examples.
230
+
231
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
232
+
233
+ Swagger UI (that provides the `/docs` interface) has better support for the
234
+ OpenAPI-specific examples than the JSON Schema `examples`, that's the main
235
+ use case for this.
236
+
237
+ Read more about it in the
238
+ [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/#using-the-openapi_examples-parameter).
239
+ """
240
+ ),
241
+ ] = None,
242
+ deprecated: Annotated[
243
+ Union[deprecated, str, bool, None],
244
+ Doc(
245
+ """
246
+ Mark this parameter field as deprecated.
247
+
248
+ It will affect the generated OpenAPI (e.g. visible at `/docs`).
249
+ """
250
+ ),
251
+ ] = None,
252
+ include_in_schema: Annotated[
253
+ bool,
254
+ Doc(
255
+ """
256
+ To include (or not) this parameter field in the generated OpenAPI.
257
+ You probably don't need it, but it's available.
258
+
259
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
260
+ """
261
+ ),
262
+ ] = True,
263
+ json_schema_extra: Annotated[
264
+ Union[Dict[str, Any], None],
265
+ Doc(
266
+ """
267
+ Any additional JSON schema data.
268
+ """
269
+ ),
270
+ ] = None,
271
+ **extra: Annotated[
272
+ Any,
273
+ Doc(
274
+ """
275
+ Include extra fields used by the JSON Schema.
276
+ """
277
+ ),
278
+ deprecated(
279
+ """
280
+ The `extra` kwargs is deprecated. Use `json_schema_extra` instead.
281
+ """
282
+ ),
283
+ ],
284
+ ) -> Any:
285
+ """
286
+ Declare a path parameter for a *path operation*.
287
+
288
+ Read more about it in the
289
+ [FastAPI docs for Path Parameters and Numeric Validations](https://fastapi.tiangolo.com/tutorial/path-params-numeric-validations/).
290
+
291
+ ```python
292
+ from typing import Annotated
293
+
294
+ from fastapi import FastAPI, Path
295
+
296
+ app = FastAPI()
297
+
298
+
299
+ @app.get("/items/{item_id}")
300
+ async def read_items(
301
+ item_id: Annotated[int, Path(title="The ID of the item to get")],
302
+ ):
303
+ return {"item_id": item_id}
304
+ ```
305
+ """
306
+ return params.Path(
307
+ default=default,
308
+ default_factory=default_factory,
309
+ alias=alias,
310
+ alias_priority=alias_priority,
311
+ validation_alias=validation_alias,
312
+ serialization_alias=serialization_alias,
313
+ title=title,
314
+ description=description,
315
+ gt=gt,
316
+ ge=ge,
317
+ lt=lt,
318
+ le=le,
319
+ min_length=min_length,
320
+ max_length=max_length,
321
+ pattern=pattern,
322
+ regex=regex,
323
+ discriminator=discriminator,
324
+ strict=strict,
325
+ multiple_of=multiple_of,
326
+ allow_inf_nan=allow_inf_nan,
327
+ max_digits=max_digits,
328
+ decimal_places=decimal_places,
329
+ example=example,
330
+ examples=examples,
331
+ openapi_examples=openapi_examples,
332
+ deprecated=deprecated,
333
+ include_in_schema=include_in_schema,
334
+ json_schema_extra=json_schema_extra,
335
+ **extra,
336
+ )
337
+
338
+
339
+ def Query( # noqa: N802
340
+ default: Annotated[
341
+ Any,
342
+ Doc(
343
+ """
344
+ Default value if the parameter field is not set.
345
+ """
346
+ ),
347
+ ] = Undefined,
348
+ *,
349
+ default_factory: Annotated[
350
+ Union[Callable[[], Any], None],
351
+ Doc(
352
+ """
353
+ A callable to generate the default value.
354
+
355
+ This doesn't affect `Path` parameters as the value is always required.
356
+ The parameter is available only for compatibility.
357
+ """
358
+ ),
359
+ ] = _Unset,
360
+ alias: Annotated[
361
+ Optional[str],
362
+ Doc(
363
+ """
364
+ An alternative name for the parameter field.
365
+
366
+ This will be used to extract the data and for the generated OpenAPI.
367
+ It is particularly useful when you can't use the name you want because it
368
+ is a Python reserved keyword or similar.
369
+ """
370
+ ),
371
+ ] = None,
372
+ alias_priority: Annotated[
373
+ Union[int, None],
374
+ Doc(
375
+ """
376
+ Priority of the alias. This affects whether an alias generator is used.
377
+ """
378
+ ),
379
+ ] = _Unset,
380
+ # TODO: update when deprecating Pydantic v1, import these types
381
+ # validation_alias: str | AliasPath | AliasChoices | None
382
+ validation_alias: Annotated[
383
+ Union[str, None],
384
+ Doc(
385
+ """
386
+ 'Whitelist' validation step. The parameter field will be the single one
387
+ allowed by the alias or set of aliases defined.
388
+ """
389
+ ),
390
+ ] = None,
391
+ serialization_alias: Annotated[
392
+ Union[str, None],
393
+ Doc(
394
+ """
395
+ 'Blacklist' validation step. The vanilla parameter field will be the
396
+ single one of the alias' or set of aliases' fields and all the other
397
+ fields will be ignored at serialization time.
398
+ """
399
+ ),
400
+ ] = None,
401
+ title: Annotated[
402
+ Optional[str],
403
+ Doc(
404
+ """
405
+ Human-readable title.
406
+ """
407
+ ),
408
+ ] = None,
409
+ description: Annotated[
410
+ Optional[str],
411
+ Doc(
412
+ """
413
+ Human-readable description.
414
+ """
415
+ ),
416
+ ] = None,
417
+ gt: Annotated[
418
+ Optional[float],
419
+ Doc(
420
+ """
421
+ Greater than. If set, value must be greater than this. Only applicable to
422
+ numbers.
423
+ """
424
+ ),
425
+ ] = None,
426
+ ge: Annotated[
427
+ Optional[float],
428
+ Doc(
429
+ """
430
+ Greater than or equal. If set, value must be greater than or equal to
431
+ this. Only applicable to numbers.
432
+ """
433
+ ),
434
+ ] = None,
435
+ lt: Annotated[
436
+ Optional[float],
437
+ Doc(
438
+ """
439
+ Less than. If set, value must be less than this. Only applicable to numbers.
440
+ """
441
+ ),
442
+ ] = None,
443
+ le: Annotated[
444
+ Optional[float],
445
+ Doc(
446
+ """
447
+ Less than or equal. If set, value must be less than or equal to this.
448
+ Only applicable to numbers.
449
+ """
450
+ ),
451
+ ] = None,
452
+ min_length: Annotated[
453
+ Optional[int],
454
+ Doc(
455
+ """
456
+ Minimum length for strings.
457
+ """
458
+ ),
459
+ ] = None,
460
+ max_length: Annotated[
461
+ Optional[int],
462
+ Doc(
463
+ """
464
+ Maximum length for strings.
465
+ """
466
+ ),
467
+ ] = None,
468
+ pattern: Annotated[
469
+ Optional[str],
470
+ Doc(
471
+ """
472
+ RegEx pattern for strings.
473
+ """
474
+ ),
475
+ ] = None,
476
+ regex: Annotated[
477
+ Optional[str],
478
+ Doc(
479
+ """
480
+ RegEx pattern for strings.
481
+ """
482
+ ),
483
+ deprecated(
484
+ "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
485
+ ),
486
+ ] = None,
487
+ discriminator: Annotated[
488
+ Union[str, None],
489
+ Doc(
490
+ """
491
+ Parameter field name for discriminating the type in a tagged union.
492
+ """
493
+ ),
494
+ ] = None,
495
+ strict: Annotated[
496
+ Union[bool, None],
497
+ Doc(
498
+ """
499
+ If `True`, strict validation is applied to the field.
500
+ """
501
+ ),
502
+ ] = _Unset,
503
+ multiple_of: Annotated[
504
+ Union[float, None],
505
+ Doc(
506
+ """
507
+ Value must be a multiple of this. Only applicable to numbers.
508
+ """
509
+ ),
510
+ ] = _Unset,
511
+ allow_inf_nan: Annotated[
512
+ Union[bool, None],
513
+ Doc(
514
+ """
515
+ Allow `inf`, `-inf`, `nan`. Only applicable to numbers.
516
+ """
517
+ ),
518
+ ] = _Unset,
519
+ max_digits: Annotated[
520
+ Union[int, None],
521
+ Doc(
522
+ """
523
+ Maximum number of allow digits for strings.
524
+ """
525
+ ),
526
+ ] = _Unset,
527
+ decimal_places: Annotated[
528
+ Union[int, None],
529
+ Doc(
530
+ """
531
+ Maximum number of decimal places allowed for numbers.
532
+ """
533
+ ),
534
+ ] = _Unset,
535
+ examples: Annotated[
536
+ Optional[List[Any]],
537
+ Doc(
538
+ """
539
+ Example values for this field.
540
+ """
541
+ ),
542
+ ] = None,
543
+ example: Annotated[
544
+ Optional[Any],
545
+ deprecated(
546
+ "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
547
+ "although still supported. Use examples instead."
548
+ ),
549
+ ] = _Unset,
550
+ openapi_examples: Annotated[
551
+ Optional[Dict[str, Example]],
552
+ Doc(
553
+ """
554
+ OpenAPI-specific examples.
555
+
556
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
557
+
558
+ Swagger UI (that provides the `/docs` interface) has better support for the
559
+ OpenAPI-specific examples than the JSON Schema `examples`, that's the main
560
+ use case for this.
561
+
562
+ Read more about it in the
563
+ [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/#using-the-openapi_examples-parameter).
564
+ """
565
+ ),
566
+ ] = None,
567
+ deprecated: Annotated[
568
+ Union[deprecated, str, bool, None],
569
+ Doc(
570
+ """
571
+ Mark this parameter field as deprecated.
572
+
573
+ It will affect the generated OpenAPI (e.g. visible at `/docs`).
574
+ """
575
+ ),
576
+ ] = None,
577
+ include_in_schema: Annotated[
578
+ bool,
579
+ Doc(
580
+ """
581
+ To include (or not) this parameter field in the generated OpenAPI.
582
+ You probably don't need it, but it's available.
583
+
584
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
585
+ """
586
+ ),
587
+ ] = True,
588
+ json_schema_extra: Annotated[
589
+ Union[Dict[str, Any], None],
590
+ Doc(
591
+ """
592
+ Any additional JSON schema data.
593
+ """
594
+ ),
595
+ ] = None,
596
+ **extra: Annotated[
597
+ Any,
598
+ Doc(
599
+ """
600
+ Include extra fields used by the JSON Schema.
601
+ """
602
+ ),
603
+ deprecated(
604
+ """
605
+ The `extra` kwargs is deprecated. Use `json_schema_extra` instead.
606
+ """
607
+ ),
608
+ ],
609
+ ) -> Any:
610
+ return params.Query(
611
+ default=default,
612
+ default_factory=default_factory,
613
+ alias=alias,
614
+ alias_priority=alias_priority,
615
+ validation_alias=validation_alias,
616
+ serialization_alias=serialization_alias,
617
+ title=title,
618
+ description=description,
619
+ gt=gt,
620
+ ge=ge,
621
+ lt=lt,
622
+ le=le,
623
+ min_length=min_length,
624
+ max_length=max_length,
625
+ pattern=pattern,
626
+ regex=regex,
627
+ discriminator=discriminator,
628
+ strict=strict,
629
+ multiple_of=multiple_of,
630
+ allow_inf_nan=allow_inf_nan,
631
+ max_digits=max_digits,
632
+ decimal_places=decimal_places,
633
+ example=example,
634
+ examples=examples,
635
+ openapi_examples=openapi_examples,
636
+ deprecated=deprecated,
637
+ include_in_schema=include_in_schema,
638
+ json_schema_extra=json_schema_extra,
639
+ **extra,
640
+ )
641
+
642
+
643
+ def Header( # noqa: N802
644
+ default: Annotated[
645
+ Any,
646
+ Doc(
647
+ """
648
+ Default value if the parameter field is not set.
649
+ """
650
+ ),
651
+ ] = Undefined,
652
+ *,
653
+ default_factory: Annotated[
654
+ Union[Callable[[], Any], None],
655
+ Doc(
656
+ """
657
+ A callable to generate the default value.
658
+
659
+ This doesn't affect `Path` parameters as the value is always required.
660
+ The parameter is available only for compatibility.
661
+ """
662
+ ),
663
+ ] = _Unset,
664
+ alias: Annotated[
665
+ Optional[str],
666
+ Doc(
667
+ """
668
+ An alternative name for the parameter field.
669
+
670
+ This will be used to extract the data and for the generated OpenAPI.
671
+ It is particularly useful when you can't use the name you want because it
672
+ is a Python reserved keyword or similar.
673
+ """
674
+ ),
675
+ ] = None,
676
+ alias_priority: Annotated[
677
+ Union[int, None],
678
+ Doc(
679
+ """
680
+ Priority of the alias. This affects whether an alias generator is used.
681
+ """
682
+ ),
683
+ ] = _Unset,
684
+ # TODO: update when deprecating Pydantic v1, import these types
685
+ # validation_alias: str | AliasPath | AliasChoices | None
686
+ validation_alias: Annotated[
687
+ Union[str, None],
688
+ Doc(
689
+ """
690
+ 'Whitelist' validation step. The parameter field will be the single one
691
+ allowed by the alias or set of aliases defined.
692
+ """
693
+ ),
694
+ ] = None,
695
+ serialization_alias: Annotated[
696
+ Union[str, None],
697
+ Doc(
698
+ """
699
+ 'Blacklist' validation step. The vanilla parameter field will be the
700
+ single one of the alias' or set of aliases' fields and all the other
701
+ fields will be ignored at serialization time.
702
+ """
703
+ ),
704
+ ] = None,
705
+ convert_underscores: Annotated[
706
+ bool,
707
+ Doc(
708
+ """
709
+ Automatically convert underscores to hyphens in the parameter field name.
710
+
711
+ Read more about it in the
712
+ [FastAPI docs for Header Parameters](https://fastapi.tiangolo.com/tutorial/header-params/#automatic-conversion)
713
+ """
714
+ ),
715
+ ] = True,
716
+ title: Annotated[
717
+ Optional[str],
718
+ Doc(
719
+ """
720
+ Human-readable title.
721
+ """
722
+ ),
723
+ ] = None,
724
+ description: Annotated[
725
+ Optional[str],
726
+ Doc(
727
+ """
728
+ Human-readable description.
729
+ """
730
+ ),
731
+ ] = None,
732
+ gt: Annotated[
733
+ Optional[float],
734
+ Doc(
735
+ """
736
+ Greater than. If set, value must be greater than this. Only applicable to
737
+ numbers.
738
+ """
739
+ ),
740
+ ] = None,
741
+ ge: Annotated[
742
+ Optional[float],
743
+ Doc(
744
+ """
745
+ Greater than or equal. If set, value must be greater than or equal to
746
+ this. Only applicable to numbers.
747
+ """
748
+ ),
749
+ ] = None,
750
+ lt: Annotated[
751
+ Optional[float],
752
+ Doc(
753
+ """
754
+ Less than. If set, value must be less than this. Only applicable to numbers.
755
+ """
756
+ ),
757
+ ] = None,
758
+ le: Annotated[
759
+ Optional[float],
760
+ Doc(
761
+ """
762
+ Less than or equal. If set, value must be less than or equal to this.
763
+ Only applicable to numbers.
764
+ """
765
+ ),
766
+ ] = None,
767
+ min_length: Annotated[
768
+ Optional[int],
769
+ Doc(
770
+ """
771
+ Minimum length for strings.
772
+ """
773
+ ),
774
+ ] = None,
775
+ max_length: Annotated[
776
+ Optional[int],
777
+ Doc(
778
+ """
779
+ Maximum length for strings.
780
+ """
781
+ ),
782
+ ] = None,
783
+ pattern: Annotated[
784
+ Optional[str],
785
+ Doc(
786
+ """
787
+ RegEx pattern for strings.
788
+ """
789
+ ),
790
+ ] = None,
791
+ regex: Annotated[
792
+ Optional[str],
793
+ Doc(
794
+ """
795
+ RegEx pattern for strings.
796
+ """
797
+ ),
798
+ deprecated(
799
+ "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
800
+ ),
801
+ ] = None,
802
+ discriminator: Annotated[
803
+ Union[str, None],
804
+ Doc(
805
+ """
806
+ Parameter field name for discriminating the type in a tagged union.
807
+ """
808
+ ),
809
+ ] = None,
810
+ strict: Annotated[
811
+ Union[bool, None],
812
+ Doc(
813
+ """
814
+ If `True`, strict validation is applied to the field.
815
+ """
816
+ ),
817
+ ] = _Unset,
818
+ multiple_of: Annotated[
819
+ Union[float, None],
820
+ Doc(
821
+ """
822
+ Value must be a multiple of this. Only applicable to numbers.
823
+ """
824
+ ),
825
+ ] = _Unset,
826
+ allow_inf_nan: Annotated[
827
+ Union[bool, None],
828
+ Doc(
829
+ """
830
+ Allow `inf`, `-inf`, `nan`. Only applicable to numbers.
831
+ """
832
+ ),
833
+ ] = _Unset,
834
+ max_digits: Annotated[
835
+ Union[int, None],
836
+ Doc(
837
+ """
838
+ Maximum number of allow digits for strings.
839
+ """
840
+ ),
841
+ ] = _Unset,
842
+ decimal_places: Annotated[
843
+ Union[int, None],
844
+ Doc(
845
+ """
846
+ Maximum number of decimal places allowed for numbers.
847
+ """
848
+ ),
849
+ ] = _Unset,
850
+ examples: Annotated[
851
+ Optional[List[Any]],
852
+ Doc(
853
+ """
854
+ Example values for this field.
855
+ """
856
+ ),
857
+ ] = None,
858
+ example: Annotated[
859
+ Optional[Any],
860
+ deprecated(
861
+ "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
862
+ "although still supported. Use examples instead."
863
+ ),
864
+ ] = _Unset,
865
+ openapi_examples: Annotated[
866
+ Optional[Dict[str, Example]],
867
+ Doc(
868
+ """
869
+ OpenAPI-specific examples.
870
+
871
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
872
+
873
+ Swagger UI (that provides the `/docs` interface) has better support for the
874
+ OpenAPI-specific examples than the JSON Schema `examples`, that's the main
875
+ use case for this.
876
+
877
+ Read more about it in the
878
+ [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/#using-the-openapi_examples-parameter).
879
+ """
880
+ ),
881
+ ] = None,
882
+ deprecated: Annotated[
883
+ Union[deprecated, str, bool, None],
884
+ Doc(
885
+ """
886
+ Mark this parameter field as deprecated.
887
+
888
+ It will affect the generated OpenAPI (e.g. visible at `/docs`).
889
+ """
890
+ ),
891
+ ] = None,
892
+ include_in_schema: Annotated[
893
+ bool,
894
+ Doc(
895
+ """
896
+ To include (or not) this parameter field in the generated OpenAPI.
897
+ You probably don't need it, but it's available.
898
+
899
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
900
+ """
901
+ ),
902
+ ] = True,
903
+ json_schema_extra: Annotated[
904
+ Union[Dict[str, Any], None],
905
+ Doc(
906
+ """
907
+ Any additional JSON schema data.
908
+ """
909
+ ),
910
+ ] = None,
911
+ **extra: Annotated[
912
+ Any,
913
+ Doc(
914
+ """
915
+ Include extra fields used by the JSON Schema.
916
+ """
917
+ ),
918
+ deprecated(
919
+ """
920
+ The `extra` kwargs is deprecated. Use `json_schema_extra` instead.
921
+ """
922
+ ),
923
+ ],
924
+ ) -> Any:
925
+ return params.Header(
926
+ default=default,
927
+ default_factory=default_factory,
928
+ alias=alias,
929
+ alias_priority=alias_priority,
930
+ validation_alias=validation_alias,
931
+ serialization_alias=serialization_alias,
932
+ convert_underscores=convert_underscores,
933
+ title=title,
934
+ description=description,
935
+ gt=gt,
936
+ ge=ge,
937
+ lt=lt,
938
+ le=le,
939
+ min_length=min_length,
940
+ max_length=max_length,
941
+ pattern=pattern,
942
+ regex=regex,
943
+ discriminator=discriminator,
944
+ strict=strict,
945
+ multiple_of=multiple_of,
946
+ allow_inf_nan=allow_inf_nan,
947
+ max_digits=max_digits,
948
+ decimal_places=decimal_places,
949
+ example=example,
950
+ examples=examples,
951
+ openapi_examples=openapi_examples,
952
+ deprecated=deprecated,
953
+ include_in_schema=include_in_schema,
954
+ json_schema_extra=json_schema_extra,
955
+ **extra,
956
+ )
957
+
958
+
959
+ def Cookie( # noqa: N802
960
+ default: Annotated[
961
+ Any,
962
+ Doc(
963
+ """
964
+ Default value if the parameter field is not set.
965
+ """
966
+ ),
967
+ ] = Undefined,
968
+ *,
969
+ default_factory: Annotated[
970
+ Union[Callable[[], Any], None],
971
+ Doc(
972
+ """
973
+ A callable to generate the default value.
974
+
975
+ This doesn't affect `Path` parameters as the value is always required.
976
+ The parameter is available only for compatibility.
977
+ """
978
+ ),
979
+ ] = _Unset,
980
+ alias: Annotated[
981
+ Optional[str],
982
+ Doc(
983
+ """
984
+ An alternative name for the parameter field.
985
+
986
+ This will be used to extract the data and for the generated OpenAPI.
987
+ It is particularly useful when you can't use the name you want because it
988
+ is a Python reserved keyword or similar.
989
+ """
990
+ ),
991
+ ] = None,
992
+ alias_priority: Annotated[
993
+ Union[int, None],
994
+ Doc(
995
+ """
996
+ Priority of the alias. This affects whether an alias generator is used.
997
+ """
998
+ ),
999
+ ] = _Unset,
1000
+ # TODO: update when deprecating Pydantic v1, import these types
1001
+ # validation_alias: str | AliasPath | AliasChoices | None
1002
+ validation_alias: Annotated[
1003
+ Union[str, None],
1004
+ Doc(
1005
+ """
1006
+ 'Whitelist' validation step. The parameter field will be the single one
1007
+ allowed by the alias or set of aliases defined.
1008
+ """
1009
+ ),
1010
+ ] = None,
1011
+ serialization_alias: Annotated[
1012
+ Union[str, None],
1013
+ Doc(
1014
+ """
1015
+ 'Blacklist' validation step. The vanilla parameter field will be the
1016
+ single one of the alias' or set of aliases' fields and all the other
1017
+ fields will be ignored at serialization time.
1018
+ """
1019
+ ),
1020
+ ] = None,
1021
+ title: Annotated[
1022
+ Optional[str],
1023
+ Doc(
1024
+ """
1025
+ Human-readable title.
1026
+ """
1027
+ ),
1028
+ ] = None,
1029
+ description: Annotated[
1030
+ Optional[str],
1031
+ Doc(
1032
+ """
1033
+ Human-readable description.
1034
+ """
1035
+ ),
1036
+ ] = None,
1037
+ gt: Annotated[
1038
+ Optional[float],
1039
+ Doc(
1040
+ """
1041
+ Greater than. If set, value must be greater than this. Only applicable to
1042
+ numbers.
1043
+ """
1044
+ ),
1045
+ ] = None,
1046
+ ge: Annotated[
1047
+ Optional[float],
1048
+ Doc(
1049
+ """
1050
+ Greater than or equal. If set, value must be greater than or equal to
1051
+ this. Only applicable to numbers.
1052
+ """
1053
+ ),
1054
+ ] = None,
1055
+ lt: Annotated[
1056
+ Optional[float],
1057
+ Doc(
1058
+ """
1059
+ Less than. If set, value must be less than this. Only applicable to numbers.
1060
+ """
1061
+ ),
1062
+ ] = None,
1063
+ le: Annotated[
1064
+ Optional[float],
1065
+ Doc(
1066
+ """
1067
+ Less than or equal. If set, value must be less than or equal to this.
1068
+ Only applicable to numbers.
1069
+ """
1070
+ ),
1071
+ ] = None,
1072
+ min_length: Annotated[
1073
+ Optional[int],
1074
+ Doc(
1075
+ """
1076
+ Minimum length for strings.
1077
+ """
1078
+ ),
1079
+ ] = None,
1080
+ max_length: Annotated[
1081
+ Optional[int],
1082
+ Doc(
1083
+ """
1084
+ Maximum length for strings.
1085
+ """
1086
+ ),
1087
+ ] = None,
1088
+ pattern: Annotated[
1089
+ Optional[str],
1090
+ Doc(
1091
+ """
1092
+ RegEx pattern for strings.
1093
+ """
1094
+ ),
1095
+ ] = None,
1096
+ regex: Annotated[
1097
+ Optional[str],
1098
+ Doc(
1099
+ """
1100
+ RegEx pattern for strings.
1101
+ """
1102
+ ),
1103
+ deprecated(
1104
+ "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
1105
+ ),
1106
+ ] = None,
1107
+ discriminator: Annotated[
1108
+ Union[str, None],
1109
+ Doc(
1110
+ """
1111
+ Parameter field name for discriminating the type in a tagged union.
1112
+ """
1113
+ ),
1114
+ ] = None,
1115
+ strict: Annotated[
1116
+ Union[bool, None],
1117
+ Doc(
1118
+ """
1119
+ If `True`, strict validation is applied to the field.
1120
+ """
1121
+ ),
1122
+ ] = _Unset,
1123
+ multiple_of: Annotated[
1124
+ Union[float, None],
1125
+ Doc(
1126
+ """
1127
+ Value must be a multiple of this. Only applicable to numbers.
1128
+ """
1129
+ ),
1130
+ ] = _Unset,
1131
+ allow_inf_nan: Annotated[
1132
+ Union[bool, None],
1133
+ Doc(
1134
+ """
1135
+ Allow `inf`, `-inf`, `nan`. Only applicable to numbers.
1136
+ """
1137
+ ),
1138
+ ] = _Unset,
1139
+ max_digits: Annotated[
1140
+ Union[int, None],
1141
+ Doc(
1142
+ """
1143
+ Maximum number of allow digits for strings.
1144
+ """
1145
+ ),
1146
+ ] = _Unset,
1147
+ decimal_places: Annotated[
1148
+ Union[int, None],
1149
+ Doc(
1150
+ """
1151
+ Maximum number of decimal places allowed for numbers.
1152
+ """
1153
+ ),
1154
+ ] = _Unset,
1155
+ examples: Annotated[
1156
+ Optional[List[Any]],
1157
+ Doc(
1158
+ """
1159
+ Example values for this field.
1160
+ """
1161
+ ),
1162
+ ] = None,
1163
+ example: Annotated[
1164
+ Optional[Any],
1165
+ deprecated(
1166
+ "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
1167
+ "although still supported. Use examples instead."
1168
+ ),
1169
+ ] = _Unset,
1170
+ openapi_examples: Annotated[
1171
+ Optional[Dict[str, Example]],
1172
+ Doc(
1173
+ """
1174
+ OpenAPI-specific examples.
1175
+
1176
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
1177
+
1178
+ Swagger UI (that provides the `/docs` interface) has better support for the
1179
+ OpenAPI-specific examples than the JSON Schema `examples`, that's the main
1180
+ use case for this.
1181
+
1182
+ Read more about it in the
1183
+ [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/#using-the-openapi_examples-parameter).
1184
+ """
1185
+ ),
1186
+ ] = None,
1187
+ deprecated: Annotated[
1188
+ Union[deprecated, str, bool, None],
1189
+ Doc(
1190
+ """
1191
+ Mark this parameter field as deprecated.
1192
+
1193
+ It will affect the generated OpenAPI (e.g. visible at `/docs`).
1194
+ """
1195
+ ),
1196
+ ] = None,
1197
+ include_in_schema: Annotated[
1198
+ bool,
1199
+ Doc(
1200
+ """
1201
+ To include (or not) this parameter field in the generated OpenAPI.
1202
+ You probably don't need it, but it's available.
1203
+
1204
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
1205
+ """
1206
+ ),
1207
+ ] = True,
1208
+ json_schema_extra: Annotated[
1209
+ Union[Dict[str, Any], None],
1210
+ Doc(
1211
+ """
1212
+ Any additional JSON schema data.
1213
+ """
1214
+ ),
1215
+ ] = None,
1216
+ **extra: Annotated[
1217
+ Any,
1218
+ Doc(
1219
+ """
1220
+ Include extra fields used by the JSON Schema.
1221
+ """
1222
+ ),
1223
+ deprecated(
1224
+ """
1225
+ The `extra` kwargs is deprecated. Use `json_schema_extra` instead.
1226
+ """
1227
+ ),
1228
+ ],
1229
+ ) -> Any:
1230
+ return params.Cookie(
1231
+ default=default,
1232
+ default_factory=default_factory,
1233
+ alias=alias,
1234
+ alias_priority=alias_priority,
1235
+ validation_alias=validation_alias,
1236
+ serialization_alias=serialization_alias,
1237
+ title=title,
1238
+ description=description,
1239
+ gt=gt,
1240
+ ge=ge,
1241
+ lt=lt,
1242
+ le=le,
1243
+ min_length=min_length,
1244
+ max_length=max_length,
1245
+ pattern=pattern,
1246
+ regex=regex,
1247
+ discriminator=discriminator,
1248
+ strict=strict,
1249
+ multiple_of=multiple_of,
1250
+ allow_inf_nan=allow_inf_nan,
1251
+ max_digits=max_digits,
1252
+ decimal_places=decimal_places,
1253
+ example=example,
1254
+ examples=examples,
1255
+ openapi_examples=openapi_examples,
1256
+ deprecated=deprecated,
1257
+ include_in_schema=include_in_schema,
1258
+ json_schema_extra=json_schema_extra,
1259
+ **extra,
1260
+ )
1261
+
1262
+
1263
+ def Body( # noqa: N802
1264
+ default: Annotated[
1265
+ Any,
1266
+ Doc(
1267
+ """
1268
+ Default value if the parameter field is not set.
1269
+ """
1270
+ ),
1271
+ ] = Undefined,
1272
+ *,
1273
+ default_factory: Annotated[
1274
+ Union[Callable[[], Any], None],
1275
+ Doc(
1276
+ """
1277
+ A callable to generate the default value.
1278
+
1279
+ This doesn't affect `Path` parameters as the value is always required.
1280
+ The parameter is available only for compatibility.
1281
+ """
1282
+ ),
1283
+ ] = _Unset,
1284
+ embed: Annotated[
1285
+ Union[bool, None],
1286
+ Doc(
1287
+ """
1288
+ When `embed` is `True`, the parameter will be expected in a JSON body as a
1289
+ key instead of being the JSON body itself.
1290
+
1291
+ This happens automatically when more than one `Body` parameter is declared.
1292
+
1293
+ Read more about it in the
1294
+ [FastAPI docs for Body - Multiple Parameters](https://fastapi.tiangolo.com/tutorial/body-multiple-params/#embed-a-single-body-parameter).
1295
+ """
1296
+ ),
1297
+ ] = None,
1298
+ media_type: Annotated[
1299
+ str,
1300
+ Doc(
1301
+ """
1302
+ The media type of this parameter field. Changing it would affect the
1303
+ generated OpenAPI, but currently it doesn't affect the parsing of the data.
1304
+ """
1305
+ ),
1306
+ ] = "application/json",
1307
+ alias: Annotated[
1308
+ Optional[str],
1309
+ Doc(
1310
+ """
1311
+ An alternative name for the parameter field.
1312
+
1313
+ This will be used to extract the data and for the generated OpenAPI.
1314
+ It is particularly useful when you can't use the name you want because it
1315
+ is a Python reserved keyword or similar.
1316
+ """
1317
+ ),
1318
+ ] = None,
1319
+ alias_priority: Annotated[
1320
+ Union[int, None],
1321
+ Doc(
1322
+ """
1323
+ Priority of the alias. This affects whether an alias generator is used.
1324
+ """
1325
+ ),
1326
+ ] = _Unset,
1327
+ # TODO: update when deprecating Pydantic v1, import these types
1328
+ # validation_alias: str | AliasPath | AliasChoices | None
1329
+ validation_alias: Annotated[
1330
+ Union[str, None],
1331
+ Doc(
1332
+ """
1333
+ 'Whitelist' validation step. The parameter field will be the single one
1334
+ allowed by the alias or set of aliases defined.
1335
+ """
1336
+ ),
1337
+ ] = None,
1338
+ serialization_alias: Annotated[
1339
+ Union[str, None],
1340
+ Doc(
1341
+ """
1342
+ 'Blacklist' validation step. The vanilla parameter field will be the
1343
+ single one of the alias' or set of aliases' fields and all the other
1344
+ fields will be ignored at serialization time.
1345
+ """
1346
+ ),
1347
+ ] = None,
1348
+ title: Annotated[
1349
+ Optional[str],
1350
+ Doc(
1351
+ """
1352
+ Human-readable title.
1353
+ """
1354
+ ),
1355
+ ] = None,
1356
+ description: Annotated[
1357
+ Optional[str],
1358
+ Doc(
1359
+ """
1360
+ Human-readable description.
1361
+ """
1362
+ ),
1363
+ ] = None,
1364
+ gt: Annotated[
1365
+ Optional[float],
1366
+ Doc(
1367
+ """
1368
+ Greater than. If set, value must be greater than this. Only applicable to
1369
+ numbers.
1370
+ """
1371
+ ),
1372
+ ] = None,
1373
+ ge: Annotated[
1374
+ Optional[float],
1375
+ Doc(
1376
+ """
1377
+ Greater than or equal. If set, value must be greater than or equal to
1378
+ this. Only applicable to numbers.
1379
+ """
1380
+ ),
1381
+ ] = None,
1382
+ lt: Annotated[
1383
+ Optional[float],
1384
+ Doc(
1385
+ """
1386
+ Less than. If set, value must be less than this. Only applicable to numbers.
1387
+ """
1388
+ ),
1389
+ ] = None,
1390
+ le: Annotated[
1391
+ Optional[float],
1392
+ Doc(
1393
+ """
1394
+ Less than or equal. If set, value must be less than or equal to this.
1395
+ Only applicable to numbers.
1396
+ """
1397
+ ),
1398
+ ] = None,
1399
+ min_length: Annotated[
1400
+ Optional[int],
1401
+ Doc(
1402
+ """
1403
+ Minimum length for strings.
1404
+ """
1405
+ ),
1406
+ ] = None,
1407
+ max_length: Annotated[
1408
+ Optional[int],
1409
+ Doc(
1410
+ """
1411
+ Maximum length for strings.
1412
+ """
1413
+ ),
1414
+ ] = None,
1415
+ pattern: Annotated[
1416
+ Optional[str],
1417
+ Doc(
1418
+ """
1419
+ RegEx pattern for strings.
1420
+ """
1421
+ ),
1422
+ ] = None,
1423
+ regex: Annotated[
1424
+ Optional[str],
1425
+ Doc(
1426
+ """
1427
+ RegEx pattern for strings.
1428
+ """
1429
+ ),
1430
+ deprecated(
1431
+ "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
1432
+ ),
1433
+ ] = None,
1434
+ discriminator: Annotated[
1435
+ Union[str, None],
1436
+ Doc(
1437
+ """
1438
+ Parameter field name for discriminating the type in a tagged union.
1439
+ """
1440
+ ),
1441
+ ] = None,
1442
+ strict: Annotated[
1443
+ Union[bool, None],
1444
+ Doc(
1445
+ """
1446
+ If `True`, strict validation is applied to the field.
1447
+ """
1448
+ ),
1449
+ ] = _Unset,
1450
+ multiple_of: Annotated[
1451
+ Union[float, None],
1452
+ Doc(
1453
+ """
1454
+ Value must be a multiple of this. Only applicable to numbers.
1455
+ """
1456
+ ),
1457
+ ] = _Unset,
1458
+ allow_inf_nan: Annotated[
1459
+ Union[bool, None],
1460
+ Doc(
1461
+ """
1462
+ Allow `inf`, `-inf`, `nan`. Only applicable to numbers.
1463
+ """
1464
+ ),
1465
+ ] = _Unset,
1466
+ max_digits: Annotated[
1467
+ Union[int, None],
1468
+ Doc(
1469
+ """
1470
+ Maximum number of allow digits for strings.
1471
+ """
1472
+ ),
1473
+ ] = _Unset,
1474
+ decimal_places: Annotated[
1475
+ Union[int, None],
1476
+ Doc(
1477
+ """
1478
+ Maximum number of decimal places allowed for numbers.
1479
+ """
1480
+ ),
1481
+ ] = _Unset,
1482
+ examples: Annotated[
1483
+ Optional[List[Any]],
1484
+ Doc(
1485
+ """
1486
+ Example values for this field.
1487
+ """
1488
+ ),
1489
+ ] = None,
1490
+ example: Annotated[
1491
+ Optional[Any],
1492
+ deprecated(
1493
+ "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
1494
+ "although still supported. Use examples instead."
1495
+ ),
1496
+ ] = _Unset,
1497
+ openapi_examples: Annotated[
1498
+ Optional[Dict[str, Example]],
1499
+ Doc(
1500
+ """
1501
+ OpenAPI-specific examples.
1502
+
1503
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
1504
+
1505
+ Swagger UI (that provides the `/docs` interface) has better support for the
1506
+ OpenAPI-specific examples than the JSON Schema `examples`, that's the main
1507
+ use case for this.
1508
+
1509
+ Read more about it in the
1510
+ [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/#using-the-openapi_examples-parameter).
1511
+ """
1512
+ ),
1513
+ ] = None,
1514
+ deprecated: Annotated[
1515
+ Union[deprecated, str, bool, None],
1516
+ Doc(
1517
+ """
1518
+ Mark this parameter field as deprecated.
1519
+
1520
+ It will affect the generated OpenAPI (e.g. visible at `/docs`).
1521
+ """
1522
+ ),
1523
+ ] = None,
1524
+ include_in_schema: Annotated[
1525
+ bool,
1526
+ Doc(
1527
+ """
1528
+ To include (or not) this parameter field in the generated OpenAPI.
1529
+ You probably don't need it, but it's available.
1530
+
1531
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
1532
+ """
1533
+ ),
1534
+ ] = True,
1535
+ json_schema_extra: Annotated[
1536
+ Union[Dict[str, Any], None],
1537
+ Doc(
1538
+ """
1539
+ Any additional JSON schema data.
1540
+ """
1541
+ ),
1542
+ ] = None,
1543
+ **extra: Annotated[
1544
+ Any,
1545
+ Doc(
1546
+ """
1547
+ Include extra fields used by the JSON Schema.
1548
+ """
1549
+ ),
1550
+ deprecated(
1551
+ """
1552
+ The `extra` kwargs is deprecated. Use `json_schema_extra` instead.
1553
+ """
1554
+ ),
1555
+ ],
1556
+ ) -> Any:
1557
+ return params.Body(
1558
+ default=default,
1559
+ default_factory=default_factory,
1560
+ embed=embed,
1561
+ media_type=media_type,
1562
+ alias=alias,
1563
+ alias_priority=alias_priority,
1564
+ validation_alias=validation_alias,
1565
+ serialization_alias=serialization_alias,
1566
+ title=title,
1567
+ description=description,
1568
+ gt=gt,
1569
+ ge=ge,
1570
+ lt=lt,
1571
+ le=le,
1572
+ min_length=min_length,
1573
+ max_length=max_length,
1574
+ pattern=pattern,
1575
+ regex=regex,
1576
+ discriminator=discriminator,
1577
+ strict=strict,
1578
+ multiple_of=multiple_of,
1579
+ allow_inf_nan=allow_inf_nan,
1580
+ max_digits=max_digits,
1581
+ decimal_places=decimal_places,
1582
+ example=example,
1583
+ examples=examples,
1584
+ openapi_examples=openapi_examples,
1585
+ deprecated=deprecated,
1586
+ include_in_schema=include_in_schema,
1587
+ json_schema_extra=json_schema_extra,
1588
+ **extra,
1589
+ )
1590
+
1591
+
1592
+ def Form( # noqa: N802
1593
+ default: Annotated[
1594
+ Any,
1595
+ Doc(
1596
+ """
1597
+ Default value if the parameter field is not set.
1598
+ """
1599
+ ),
1600
+ ] = Undefined,
1601
+ *,
1602
+ default_factory: Annotated[
1603
+ Union[Callable[[], Any], None],
1604
+ Doc(
1605
+ """
1606
+ A callable to generate the default value.
1607
+
1608
+ This doesn't affect `Path` parameters as the value is always required.
1609
+ The parameter is available only for compatibility.
1610
+ """
1611
+ ),
1612
+ ] = _Unset,
1613
+ media_type: Annotated[
1614
+ str,
1615
+ Doc(
1616
+ """
1617
+ The media type of this parameter field. Changing it would affect the
1618
+ generated OpenAPI, but currently it doesn't affect the parsing of the data.
1619
+ """
1620
+ ),
1621
+ ] = "application/x-www-form-urlencoded",
1622
+ alias: Annotated[
1623
+ Optional[str],
1624
+ Doc(
1625
+ """
1626
+ An alternative name for the parameter field.
1627
+
1628
+ This will be used to extract the data and for the generated OpenAPI.
1629
+ It is particularly useful when you can't use the name you want because it
1630
+ is a Python reserved keyword or similar.
1631
+ """
1632
+ ),
1633
+ ] = None,
1634
+ alias_priority: Annotated[
1635
+ Union[int, None],
1636
+ Doc(
1637
+ """
1638
+ Priority of the alias. This affects whether an alias generator is used.
1639
+ """
1640
+ ),
1641
+ ] = _Unset,
1642
+ # TODO: update when deprecating Pydantic v1, import these types
1643
+ # validation_alias: str | AliasPath | AliasChoices | None
1644
+ validation_alias: Annotated[
1645
+ Union[str, None],
1646
+ Doc(
1647
+ """
1648
+ 'Whitelist' validation step. The parameter field will be the single one
1649
+ allowed by the alias or set of aliases defined.
1650
+ """
1651
+ ),
1652
+ ] = None,
1653
+ serialization_alias: Annotated[
1654
+ Union[str, None],
1655
+ Doc(
1656
+ """
1657
+ 'Blacklist' validation step. The vanilla parameter field will be the
1658
+ single one of the alias' or set of aliases' fields and all the other
1659
+ fields will be ignored at serialization time.
1660
+ """
1661
+ ),
1662
+ ] = None,
1663
+ title: Annotated[
1664
+ Optional[str],
1665
+ Doc(
1666
+ """
1667
+ Human-readable title.
1668
+ """
1669
+ ),
1670
+ ] = None,
1671
+ description: Annotated[
1672
+ Optional[str],
1673
+ Doc(
1674
+ """
1675
+ Human-readable description.
1676
+ """
1677
+ ),
1678
+ ] = None,
1679
+ gt: Annotated[
1680
+ Optional[float],
1681
+ Doc(
1682
+ """
1683
+ Greater than. If set, value must be greater than this. Only applicable to
1684
+ numbers.
1685
+ """
1686
+ ),
1687
+ ] = None,
1688
+ ge: Annotated[
1689
+ Optional[float],
1690
+ Doc(
1691
+ """
1692
+ Greater than or equal. If set, value must be greater than or equal to
1693
+ this. Only applicable to numbers.
1694
+ """
1695
+ ),
1696
+ ] = None,
1697
+ lt: Annotated[
1698
+ Optional[float],
1699
+ Doc(
1700
+ """
1701
+ Less than. If set, value must be less than this. Only applicable to numbers.
1702
+ """
1703
+ ),
1704
+ ] = None,
1705
+ le: Annotated[
1706
+ Optional[float],
1707
+ Doc(
1708
+ """
1709
+ Less than or equal. If set, value must be less than or equal to this.
1710
+ Only applicable to numbers.
1711
+ """
1712
+ ),
1713
+ ] = None,
1714
+ min_length: Annotated[
1715
+ Optional[int],
1716
+ Doc(
1717
+ """
1718
+ Minimum length for strings.
1719
+ """
1720
+ ),
1721
+ ] = None,
1722
+ max_length: Annotated[
1723
+ Optional[int],
1724
+ Doc(
1725
+ """
1726
+ Maximum length for strings.
1727
+ """
1728
+ ),
1729
+ ] = None,
1730
+ pattern: Annotated[
1731
+ Optional[str],
1732
+ Doc(
1733
+ """
1734
+ RegEx pattern for strings.
1735
+ """
1736
+ ),
1737
+ ] = None,
1738
+ regex: Annotated[
1739
+ Optional[str],
1740
+ Doc(
1741
+ """
1742
+ RegEx pattern for strings.
1743
+ """
1744
+ ),
1745
+ deprecated(
1746
+ "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
1747
+ ),
1748
+ ] = None,
1749
+ discriminator: Annotated[
1750
+ Union[str, None],
1751
+ Doc(
1752
+ """
1753
+ Parameter field name for discriminating the type in a tagged union.
1754
+ """
1755
+ ),
1756
+ ] = None,
1757
+ strict: Annotated[
1758
+ Union[bool, None],
1759
+ Doc(
1760
+ """
1761
+ If `True`, strict validation is applied to the field.
1762
+ """
1763
+ ),
1764
+ ] = _Unset,
1765
+ multiple_of: Annotated[
1766
+ Union[float, None],
1767
+ Doc(
1768
+ """
1769
+ Value must be a multiple of this. Only applicable to numbers.
1770
+ """
1771
+ ),
1772
+ ] = _Unset,
1773
+ allow_inf_nan: Annotated[
1774
+ Union[bool, None],
1775
+ Doc(
1776
+ """
1777
+ Allow `inf`, `-inf`, `nan`. Only applicable to numbers.
1778
+ """
1779
+ ),
1780
+ ] = _Unset,
1781
+ max_digits: Annotated[
1782
+ Union[int, None],
1783
+ Doc(
1784
+ """
1785
+ Maximum number of allow digits for strings.
1786
+ """
1787
+ ),
1788
+ ] = _Unset,
1789
+ decimal_places: Annotated[
1790
+ Union[int, None],
1791
+ Doc(
1792
+ """
1793
+ Maximum number of decimal places allowed for numbers.
1794
+ """
1795
+ ),
1796
+ ] = _Unset,
1797
+ examples: Annotated[
1798
+ Optional[List[Any]],
1799
+ Doc(
1800
+ """
1801
+ Example values for this field.
1802
+ """
1803
+ ),
1804
+ ] = None,
1805
+ example: Annotated[
1806
+ Optional[Any],
1807
+ deprecated(
1808
+ "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
1809
+ "although still supported. Use examples instead."
1810
+ ),
1811
+ ] = _Unset,
1812
+ openapi_examples: Annotated[
1813
+ Optional[Dict[str, Example]],
1814
+ Doc(
1815
+ """
1816
+ OpenAPI-specific examples.
1817
+
1818
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
1819
+
1820
+ Swagger UI (that provides the `/docs` interface) has better support for the
1821
+ OpenAPI-specific examples than the JSON Schema `examples`, that's the main
1822
+ use case for this.
1823
+
1824
+ Read more about it in the
1825
+ [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/#using-the-openapi_examples-parameter).
1826
+ """
1827
+ ),
1828
+ ] = None,
1829
+ deprecated: Annotated[
1830
+ Union[deprecated, str, bool, None],
1831
+ Doc(
1832
+ """
1833
+ Mark this parameter field as deprecated.
1834
+
1835
+ It will affect the generated OpenAPI (e.g. visible at `/docs`).
1836
+ """
1837
+ ),
1838
+ ] = None,
1839
+ include_in_schema: Annotated[
1840
+ bool,
1841
+ Doc(
1842
+ """
1843
+ To include (or not) this parameter field in the generated OpenAPI.
1844
+ You probably don't need it, but it's available.
1845
+
1846
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
1847
+ """
1848
+ ),
1849
+ ] = True,
1850
+ json_schema_extra: Annotated[
1851
+ Union[Dict[str, Any], None],
1852
+ Doc(
1853
+ """
1854
+ Any additional JSON schema data.
1855
+ """
1856
+ ),
1857
+ ] = None,
1858
+ **extra: Annotated[
1859
+ Any,
1860
+ Doc(
1861
+ """
1862
+ Include extra fields used by the JSON Schema.
1863
+ """
1864
+ ),
1865
+ deprecated(
1866
+ """
1867
+ The `extra` kwargs is deprecated. Use `json_schema_extra` instead.
1868
+ """
1869
+ ),
1870
+ ],
1871
+ ) -> Any:
1872
+ return params.Form(
1873
+ default=default,
1874
+ default_factory=default_factory,
1875
+ media_type=media_type,
1876
+ alias=alias,
1877
+ alias_priority=alias_priority,
1878
+ validation_alias=validation_alias,
1879
+ serialization_alias=serialization_alias,
1880
+ title=title,
1881
+ description=description,
1882
+ gt=gt,
1883
+ ge=ge,
1884
+ lt=lt,
1885
+ le=le,
1886
+ min_length=min_length,
1887
+ max_length=max_length,
1888
+ pattern=pattern,
1889
+ regex=regex,
1890
+ discriminator=discriminator,
1891
+ strict=strict,
1892
+ multiple_of=multiple_of,
1893
+ allow_inf_nan=allow_inf_nan,
1894
+ max_digits=max_digits,
1895
+ decimal_places=decimal_places,
1896
+ example=example,
1897
+ examples=examples,
1898
+ openapi_examples=openapi_examples,
1899
+ deprecated=deprecated,
1900
+ include_in_schema=include_in_schema,
1901
+ json_schema_extra=json_schema_extra,
1902
+ **extra,
1903
+ )
1904
+
1905
+
1906
+ def File( # noqa: N802
1907
+ default: Annotated[
1908
+ Any,
1909
+ Doc(
1910
+ """
1911
+ Default value if the parameter field is not set.
1912
+ """
1913
+ ),
1914
+ ] = Undefined,
1915
+ *,
1916
+ default_factory: Annotated[
1917
+ Union[Callable[[], Any], None],
1918
+ Doc(
1919
+ """
1920
+ A callable to generate the default value.
1921
+
1922
+ This doesn't affect `Path` parameters as the value is always required.
1923
+ The parameter is available only for compatibility.
1924
+ """
1925
+ ),
1926
+ ] = _Unset,
1927
+ media_type: Annotated[
1928
+ str,
1929
+ Doc(
1930
+ """
1931
+ The media type of this parameter field. Changing it would affect the
1932
+ generated OpenAPI, but currently it doesn't affect the parsing of the data.
1933
+ """
1934
+ ),
1935
+ ] = "multipart/form-data",
1936
+ alias: Annotated[
1937
+ Optional[str],
1938
+ Doc(
1939
+ """
1940
+ An alternative name for the parameter field.
1941
+
1942
+ This will be used to extract the data and for the generated OpenAPI.
1943
+ It is particularly useful when you can't use the name you want because it
1944
+ is a Python reserved keyword or similar.
1945
+ """
1946
+ ),
1947
+ ] = None,
1948
+ alias_priority: Annotated[
1949
+ Union[int, None],
1950
+ Doc(
1951
+ """
1952
+ Priority of the alias. This affects whether an alias generator is used.
1953
+ """
1954
+ ),
1955
+ ] = _Unset,
1956
+ # TODO: update when deprecating Pydantic v1, import these types
1957
+ # validation_alias: str | AliasPath | AliasChoices | None
1958
+ validation_alias: Annotated[
1959
+ Union[str, None],
1960
+ Doc(
1961
+ """
1962
+ 'Whitelist' validation step. The parameter field will be the single one
1963
+ allowed by the alias or set of aliases defined.
1964
+ """
1965
+ ),
1966
+ ] = None,
1967
+ serialization_alias: Annotated[
1968
+ Union[str, None],
1969
+ Doc(
1970
+ """
1971
+ 'Blacklist' validation step. The vanilla parameter field will be the
1972
+ single one of the alias' or set of aliases' fields and all the other
1973
+ fields will be ignored at serialization time.
1974
+ """
1975
+ ),
1976
+ ] = None,
1977
+ title: Annotated[
1978
+ Optional[str],
1979
+ Doc(
1980
+ """
1981
+ Human-readable title.
1982
+ """
1983
+ ),
1984
+ ] = None,
1985
+ description: Annotated[
1986
+ Optional[str],
1987
+ Doc(
1988
+ """
1989
+ Human-readable description.
1990
+ """
1991
+ ),
1992
+ ] = None,
1993
+ gt: Annotated[
1994
+ Optional[float],
1995
+ Doc(
1996
+ """
1997
+ Greater than. If set, value must be greater than this. Only applicable to
1998
+ numbers.
1999
+ """
2000
+ ),
2001
+ ] = None,
2002
+ ge: Annotated[
2003
+ Optional[float],
2004
+ Doc(
2005
+ """
2006
+ Greater than or equal. If set, value must be greater than or equal to
2007
+ this. Only applicable to numbers.
2008
+ """
2009
+ ),
2010
+ ] = None,
2011
+ lt: Annotated[
2012
+ Optional[float],
2013
+ Doc(
2014
+ """
2015
+ Less than. If set, value must be less than this. Only applicable to numbers.
2016
+ """
2017
+ ),
2018
+ ] = None,
2019
+ le: Annotated[
2020
+ Optional[float],
2021
+ Doc(
2022
+ """
2023
+ Less than or equal. If set, value must be less than or equal to this.
2024
+ Only applicable to numbers.
2025
+ """
2026
+ ),
2027
+ ] = None,
2028
+ min_length: Annotated[
2029
+ Optional[int],
2030
+ Doc(
2031
+ """
2032
+ Minimum length for strings.
2033
+ """
2034
+ ),
2035
+ ] = None,
2036
+ max_length: Annotated[
2037
+ Optional[int],
2038
+ Doc(
2039
+ """
2040
+ Maximum length for strings.
2041
+ """
2042
+ ),
2043
+ ] = None,
2044
+ pattern: Annotated[
2045
+ Optional[str],
2046
+ Doc(
2047
+ """
2048
+ RegEx pattern for strings.
2049
+ """
2050
+ ),
2051
+ ] = None,
2052
+ regex: Annotated[
2053
+ Optional[str],
2054
+ Doc(
2055
+ """
2056
+ RegEx pattern for strings.
2057
+ """
2058
+ ),
2059
+ deprecated(
2060
+ "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
2061
+ ),
2062
+ ] = None,
2063
+ discriminator: Annotated[
2064
+ Union[str, None],
2065
+ Doc(
2066
+ """
2067
+ Parameter field name for discriminating the type in a tagged union.
2068
+ """
2069
+ ),
2070
+ ] = None,
2071
+ strict: Annotated[
2072
+ Union[bool, None],
2073
+ Doc(
2074
+ """
2075
+ If `True`, strict validation is applied to the field.
2076
+ """
2077
+ ),
2078
+ ] = _Unset,
2079
+ multiple_of: Annotated[
2080
+ Union[float, None],
2081
+ Doc(
2082
+ """
2083
+ Value must be a multiple of this. Only applicable to numbers.
2084
+ """
2085
+ ),
2086
+ ] = _Unset,
2087
+ allow_inf_nan: Annotated[
2088
+ Union[bool, None],
2089
+ Doc(
2090
+ """
2091
+ Allow `inf`, `-inf`, `nan`. Only applicable to numbers.
2092
+ """
2093
+ ),
2094
+ ] = _Unset,
2095
+ max_digits: Annotated[
2096
+ Union[int, None],
2097
+ Doc(
2098
+ """
2099
+ Maximum number of allow digits for strings.
2100
+ """
2101
+ ),
2102
+ ] = _Unset,
2103
+ decimal_places: Annotated[
2104
+ Union[int, None],
2105
+ Doc(
2106
+ """
2107
+ Maximum number of decimal places allowed for numbers.
2108
+ """
2109
+ ),
2110
+ ] = _Unset,
2111
+ examples: Annotated[
2112
+ Optional[List[Any]],
2113
+ Doc(
2114
+ """
2115
+ Example values for this field.
2116
+ """
2117
+ ),
2118
+ ] = None,
2119
+ example: Annotated[
2120
+ Optional[Any],
2121
+ deprecated(
2122
+ "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
2123
+ "although still supported. Use examples instead."
2124
+ ),
2125
+ ] = _Unset,
2126
+ openapi_examples: Annotated[
2127
+ Optional[Dict[str, Example]],
2128
+ Doc(
2129
+ """
2130
+ OpenAPI-specific examples.
2131
+
2132
+ It will be added to the generated OpenAPI (e.g. visible at `/docs`).
2133
+
2134
+ Swagger UI (that provides the `/docs` interface) has better support for the
2135
+ OpenAPI-specific examples than the JSON Schema `examples`, that's the main
2136
+ use case for this.
2137
+
2138
+ Read more about it in the
2139
+ [FastAPI docs for Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/#using-the-openapi_examples-parameter).
2140
+ """
2141
+ ),
2142
+ ] = None,
2143
+ deprecated: Annotated[
2144
+ Union[deprecated, str, bool, None],
2145
+ Doc(
2146
+ """
2147
+ Mark this parameter field as deprecated.
2148
+
2149
+ It will affect the generated OpenAPI (e.g. visible at `/docs`).
2150
+ """
2151
+ ),
2152
+ ] = None,
2153
+ include_in_schema: Annotated[
2154
+ bool,
2155
+ Doc(
2156
+ """
2157
+ To include (or not) this parameter field in the generated OpenAPI.
2158
+ You probably don't need it, but it's available.
2159
+
2160
+ This affects the generated OpenAPI (e.g. visible at `/docs`).
2161
+ """
2162
+ ),
2163
+ ] = True,
2164
+ json_schema_extra: Annotated[
2165
+ Union[Dict[str, Any], None],
2166
+ Doc(
2167
+ """
2168
+ Any additional JSON schema data.
2169
+ """
2170
+ ),
2171
+ ] = None,
2172
+ **extra: Annotated[
2173
+ Any,
2174
+ Doc(
2175
+ """
2176
+ Include extra fields used by the JSON Schema.
2177
+ """
2178
+ ),
2179
+ deprecated(
2180
+ """
2181
+ The `extra` kwargs is deprecated. Use `json_schema_extra` instead.
2182
+ """
2183
+ ),
2184
+ ],
2185
+ ) -> Any:
2186
+ return params.File(
2187
+ default=default,
2188
+ default_factory=default_factory,
2189
+ media_type=media_type,
2190
+ alias=alias,
2191
+ alias_priority=alias_priority,
2192
+ validation_alias=validation_alias,
2193
+ serialization_alias=serialization_alias,
2194
+ title=title,
2195
+ description=description,
2196
+ gt=gt,
2197
+ ge=ge,
2198
+ lt=lt,
2199
+ le=le,
2200
+ min_length=min_length,
2201
+ max_length=max_length,
2202
+ pattern=pattern,
2203
+ regex=regex,
2204
+ discriminator=discriminator,
2205
+ strict=strict,
2206
+ multiple_of=multiple_of,
2207
+ allow_inf_nan=allow_inf_nan,
2208
+ max_digits=max_digits,
2209
+ decimal_places=decimal_places,
2210
+ example=example,
2211
+ examples=examples,
2212
+ openapi_examples=openapi_examples,
2213
+ deprecated=deprecated,
2214
+ include_in_schema=include_in_schema,
2215
+ json_schema_extra=json_schema_extra,
2216
+ **extra,
2217
+ )
2218
+
2219
+
2220
+ def Depends( # noqa: N802
2221
+ dependency: Annotated[
2222
+ Optional[Callable[..., Any]],
2223
+ Doc(
2224
+ """
2225
+ A "dependable" callable (like a function).
2226
+
2227
+ Don't call it directly, FastAPI will call it for you, just pass the object
2228
+ directly.
2229
+ """
2230
+ ),
2231
+ ] = None,
2232
+ *,
2233
+ use_cache: Annotated[
2234
+ bool,
2235
+ Doc(
2236
+ """
2237
+ By default, after a dependency is called the first time in a request, if
2238
+ the dependency is declared again for the rest of the request (for example
2239
+ if the dependency is needed by several dependencies), the value will be
2240
+ re-used for the rest of the request.
2241
+
2242
+ Set `use_cache` to `False` to disable this behavior and ensure the
2243
+ dependency is called again (if declared more than once) in the same request.
2244
+ """
2245
+ ),
2246
+ ] = True,
2247
+ ) -> Any:
2248
+ """
2249
+ Declare a FastAPI dependency.
2250
+
2251
+ It takes a single "dependable" callable (like a function).
2252
+
2253
+ Don't call it directly, FastAPI will call it for you.
2254
+
2255
+ Read more about it in the
2256
+ [FastAPI docs for Dependencies](https://fastapi.tiangolo.com/tutorial/dependencies/).
2257
+
2258
+ **Example**
2259
+
2260
+ ```python
2261
+ from typing import Annotated
2262
+
2263
+ from fastapi import Depends, FastAPI
2264
+
2265
+ app = FastAPI()
2266
+
2267
+
2268
+ async def common_parameters(q: str | None = None, skip: int = 0, limit: int = 100):
2269
+ return {"q": q, "skip": skip, "limit": limit}
2270
+
2271
+
2272
+ @app.get("/items/")
2273
+ async def read_items(commons: Annotated[dict, Depends(common_parameters)]):
2274
+ return commons
2275
+ ```
2276
+ """
2277
+ return params.Depends(dependency=dependency, use_cache=use_cache)
2278
+
2279
+
2280
+ def Security( # noqa: N802
2281
+ dependency: Annotated[
2282
+ Optional[Callable[..., Any]],
2283
+ Doc(
2284
+ """
2285
+ A "dependable" callable (like a function).
2286
+
2287
+ Don't call it directly, FastAPI will call it for you, just pass the object
2288
+ directly.
2289
+ """
2290
+ ),
2291
+ ] = None,
2292
+ *,
2293
+ scopes: Annotated[
2294
+ Optional[Sequence[str]],
2295
+ Doc(
2296
+ """
2297
+ OAuth2 scopes required for the *path operation* that uses this Security
2298
+ dependency.
2299
+
2300
+ The term "scope" comes from the OAuth2 specification, it seems to be
2301
+ intentionally vague and interpretable. It normally refers to permissions,
2302
+ in cases to roles.
2303
+
2304
+ These scopes are integrated with OpenAPI (and the API docs at `/docs`).
2305
+ So they are visible in the OpenAPI specification.
2306
+ )
2307
+ """
2308
+ ),
2309
+ ] = None,
2310
+ use_cache: Annotated[
2311
+ bool,
2312
+ Doc(
2313
+ """
2314
+ By default, after a dependency is called the first time in a request, if
2315
+ the dependency is declared again for the rest of the request (for example
2316
+ if the dependency is needed by several dependencies), the value will be
2317
+ re-used for the rest of the request.
2318
+
2319
+ Set `use_cache` to `False` to disable this behavior and ensure the
2320
+ dependency is called again (if declared more than once) in the same request.
2321
+ """
2322
+ ),
2323
+ ] = True,
2324
+ ) -> Any:
2325
+ """
2326
+ Declare a FastAPI Security dependency.
2327
+
2328
+ The only difference with a regular dependency is that it can declare OAuth2
2329
+ scopes that will be integrated with OpenAPI and the automatic UI docs (by default
2330
+ at `/docs`).
2331
+
2332
+ It takes a single "dependable" callable (like a function).
2333
+
2334
+ Don't call it directly, FastAPI will call it for you.
2335
+
2336
+ Read more about it in the
2337
+ [FastAPI docs for Security](https://fastapi.tiangolo.com/tutorial/security/) and
2338
+ in the
2339
+ [FastAPI docs for OAuth2 scopes](https://fastapi.tiangolo.com/advanced/security/oauth2-scopes/).
2340
+
2341
+ **Example**
2342
+
2343
+ ```python
2344
+ from typing import Annotated
2345
+
2346
+ from fastapi import Security, FastAPI
2347
+
2348
+ from .db import User
2349
+ from .security import get_current_active_user
2350
+
2351
+ app = FastAPI()
2352
+
2353
+ @app.get("/users/me/items/")
2354
+ async def read_own_items(
2355
+ current_user: Annotated[User, Security(get_current_active_user, scopes=["items"])]
2356
+ ):
2357
+ return [{"item_id": "Foo", "owner": current_user.username}]
2358
+ ```
2359
+ """
2360
+ return params.Security(dependency=dependency, scopes=scopes, use_cache=use_cache)
lib/python3.12/site-packages/fastapi/params.py ADDED
@@ -0,0 +1,786 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import warnings
2
+ from enum import Enum
3
+ from typing import Any, Callable, Dict, List, Optional, Sequence, Union
4
+
5
+ from fastapi.openapi.models import Example
6
+ from pydantic.fields import FieldInfo
7
+ from typing_extensions import Annotated, deprecated
8
+
9
+ from ._compat import (
10
+ PYDANTIC_V2,
11
+ PYDANTIC_VERSION_MINOR_TUPLE,
12
+ Undefined,
13
+ )
14
+
15
+ _Unset: Any = Undefined
16
+
17
+
18
+ class ParamTypes(Enum):
19
+ query = "query"
20
+ header = "header"
21
+ path = "path"
22
+ cookie = "cookie"
23
+
24
+
25
+ class Param(FieldInfo):
26
+ in_: ParamTypes
27
+
28
+ def __init__(
29
+ self,
30
+ default: Any = Undefined,
31
+ *,
32
+ default_factory: Union[Callable[[], Any], None] = _Unset,
33
+ annotation: Optional[Any] = None,
34
+ alias: Optional[str] = None,
35
+ alias_priority: Union[int, None] = _Unset,
36
+ # TODO: update when deprecating Pydantic v1, import these types
37
+ # validation_alias: str | AliasPath | AliasChoices | None
38
+ validation_alias: Union[str, None] = None,
39
+ serialization_alias: Union[str, None] = None,
40
+ title: Optional[str] = None,
41
+ description: Optional[str] = None,
42
+ gt: Optional[float] = None,
43
+ ge: Optional[float] = None,
44
+ lt: Optional[float] = None,
45
+ le: Optional[float] = None,
46
+ min_length: Optional[int] = None,
47
+ max_length: Optional[int] = None,
48
+ pattern: Optional[str] = None,
49
+ regex: Annotated[
50
+ Optional[str],
51
+ deprecated(
52
+ "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
53
+ ),
54
+ ] = None,
55
+ discriminator: Union[str, None] = None,
56
+ strict: Union[bool, None] = _Unset,
57
+ multiple_of: Union[float, None] = _Unset,
58
+ allow_inf_nan: Union[bool, None] = _Unset,
59
+ max_digits: Union[int, None] = _Unset,
60
+ decimal_places: Union[int, None] = _Unset,
61
+ examples: Optional[List[Any]] = None,
62
+ example: Annotated[
63
+ Optional[Any],
64
+ deprecated(
65
+ "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
66
+ "although still supported. Use examples instead."
67
+ ),
68
+ ] = _Unset,
69
+ openapi_examples: Optional[Dict[str, Example]] = None,
70
+ deprecated: Union[deprecated, str, bool, None] = None,
71
+ include_in_schema: bool = True,
72
+ json_schema_extra: Union[Dict[str, Any], None] = None,
73
+ **extra: Any,
74
+ ):
75
+ if example is not _Unset:
76
+ warnings.warn(
77
+ "`example` has been deprecated, please use `examples` instead",
78
+ category=DeprecationWarning,
79
+ stacklevel=4,
80
+ )
81
+ self.example = example
82
+ self.include_in_schema = include_in_schema
83
+ self.openapi_examples = openapi_examples
84
+ kwargs = dict(
85
+ default=default,
86
+ default_factory=default_factory,
87
+ alias=alias,
88
+ title=title,
89
+ description=description,
90
+ gt=gt,
91
+ ge=ge,
92
+ lt=lt,
93
+ le=le,
94
+ min_length=min_length,
95
+ max_length=max_length,
96
+ discriminator=discriminator,
97
+ multiple_of=multiple_of,
98
+ allow_inf_nan=allow_inf_nan,
99
+ max_digits=max_digits,
100
+ decimal_places=decimal_places,
101
+ **extra,
102
+ )
103
+ if examples is not None:
104
+ kwargs["examples"] = examples
105
+ if regex is not None:
106
+ warnings.warn(
107
+ "`regex` has been deprecated, please use `pattern` instead",
108
+ category=DeprecationWarning,
109
+ stacklevel=4,
110
+ )
111
+ current_json_schema_extra = json_schema_extra or extra
112
+ if PYDANTIC_VERSION_MINOR_TUPLE < (2, 7):
113
+ self.deprecated = deprecated
114
+ else:
115
+ kwargs["deprecated"] = deprecated
116
+ if PYDANTIC_V2:
117
+ kwargs.update(
118
+ {
119
+ "annotation": annotation,
120
+ "alias_priority": alias_priority,
121
+ "validation_alias": validation_alias,
122
+ "serialization_alias": serialization_alias,
123
+ "strict": strict,
124
+ "json_schema_extra": current_json_schema_extra,
125
+ }
126
+ )
127
+ kwargs["pattern"] = pattern or regex
128
+ else:
129
+ kwargs["regex"] = pattern or regex
130
+ kwargs.update(**current_json_schema_extra)
131
+ use_kwargs = {k: v for k, v in kwargs.items() if v is not _Unset}
132
+
133
+ super().__init__(**use_kwargs)
134
+
135
+ def __repr__(self) -> str:
136
+ return f"{self.__class__.__name__}({self.default})"
137
+
138
+
139
+ class Path(Param):
140
+ in_ = ParamTypes.path
141
+
142
+ def __init__(
143
+ self,
144
+ default: Any = ...,
145
+ *,
146
+ default_factory: Union[Callable[[], Any], None] = _Unset,
147
+ annotation: Optional[Any] = None,
148
+ alias: Optional[str] = None,
149
+ alias_priority: Union[int, None] = _Unset,
150
+ # TODO: update when deprecating Pydantic v1, import these types
151
+ # validation_alias: str | AliasPath | AliasChoices | None
152
+ validation_alias: Union[str, None] = None,
153
+ serialization_alias: Union[str, None] = None,
154
+ title: Optional[str] = None,
155
+ description: Optional[str] = None,
156
+ gt: Optional[float] = None,
157
+ ge: Optional[float] = None,
158
+ lt: Optional[float] = None,
159
+ le: Optional[float] = None,
160
+ min_length: Optional[int] = None,
161
+ max_length: Optional[int] = None,
162
+ pattern: Optional[str] = None,
163
+ regex: Annotated[
164
+ Optional[str],
165
+ deprecated(
166
+ "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
167
+ ),
168
+ ] = None,
169
+ discriminator: Union[str, None] = None,
170
+ strict: Union[bool, None] = _Unset,
171
+ multiple_of: Union[float, None] = _Unset,
172
+ allow_inf_nan: Union[bool, None] = _Unset,
173
+ max_digits: Union[int, None] = _Unset,
174
+ decimal_places: Union[int, None] = _Unset,
175
+ examples: Optional[List[Any]] = None,
176
+ example: Annotated[
177
+ Optional[Any],
178
+ deprecated(
179
+ "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
180
+ "although still supported. Use examples instead."
181
+ ),
182
+ ] = _Unset,
183
+ openapi_examples: Optional[Dict[str, Example]] = None,
184
+ deprecated: Union[deprecated, str, bool, None] = None,
185
+ include_in_schema: bool = True,
186
+ json_schema_extra: Union[Dict[str, Any], None] = None,
187
+ **extra: Any,
188
+ ):
189
+ assert default is ..., "Path parameters cannot have a default value"
190
+ self.in_ = self.in_
191
+ super().__init__(
192
+ default=default,
193
+ default_factory=default_factory,
194
+ annotation=annotation,
195
+ alias=alias,
196
+ alias_priority=alias_priority,
197
+ validation_alias=validation_alias,
198
+ serialization_alias=serialization_alias,
199
+ title=title,
200
+ description=description,
201
+ gt=gt,
202
+ ge=ge,
203
+ lt=lt,
204
+ le=le,
205
+ min_length=min_length,
206
+ max_length=max_length,
207
+ pattern=pattern,
208
+ regex=regex,
209
+ discriminator=discriminator,
210
+ strict=strict,
211
+ multiple_of=multiple_of,
212
+ allow_inf_nan=allow_inf_nan,
213
+ max_digits=max_digits,
214
+ decimal_places=decimal_places,
215
+ deprecated=deprecated,
216
+ example=example,
217
+ examples=examples,
218
+ openapi_examples=openapi_examples,
219
+ include_in_schema=include_in_schema,
220
+ json_schema_extra=json_schema_extra,
221
+ **extra,
222
+ )
223
+
224
+
225
+ class Query(Param):
226
+ in_ = ParamTypes.query
227
+
228
+ def __init__(
229
+ self,
230
+ default: Any = Undefined,
231
+ *,
232
+ default_factory: Union[Callable[[], Any], None] = _Unset,
233
+ annotation: Optional[Any] = None,
234
+ alias: Optional[str] = None,
235
+ alias_priority: Union[int, None] = _Unset,
236
+ # TODO: update when deprecating Pydantic v1, import these types
237
+ # validation_alias: str | AliasPath | AliasChoices | None
238
+ validation_alias: Union[str, None] = None,
239
+ serialization_alias: Union[str, None] = None,
240
+ title: Optional[str] = None,
241
+ description: Optional[str] = None,
242
+ gt: Optional[float] = None,
243
+ ge: Optional[float] = None,
244
+ lt: Optional[float] = None,
245
+ le: Optional[float] = None,
246
+ min_length: Optional[int] = None,
247
+ max_length: Optional[int] = None,
248
+ pattern: Optional[str] = None,
249
+ regex: Annotated[
250
+ Optional[str],
251
+ deprecated(
252
+ "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
253
+ ),
254
+ ] = None,
255
+ discriminator: Union[str, None] = None,
256
+ strict: Union[bool, None] = _Unset,
257
+ multiple_of: Union[float, None] = _Unset,
258
+ allow_inf_nan: Union[bool, None] = _Unset,
259
+ max_digits: Union[int, None] = _Unset,
260
+ decimal_places: Union[int, None] = _Unset,
261
+ examples: Optional[List[Any]] = None,
262
+ example: Annotated[
263
+ Optional[Any],
264
+ deprecated(
265
+ "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
266
+ "although still supported. Use examples instead."
267
+ ),
268
+ ] = _Unset,
269
+ openapi_examples: Optional[Dict[str, Example]] = None,
270
+ deprecated: Union[deprecated, str, bool, None] = None,
271
+ include_in_schema: bool = True,
272
+ json_schema_extra: Union[Dict[str, Any], None] = None,
273
+ **extra: Any,
274
+ ):
275
+ super().__init__(
276
+ default=default,
277
+ default_factory=default_factory,
278
+ annotation=annotation,
279
+ alias=alias,
280
+ alias_priority=alias_priority,
281
+ validation_alias=validation_alias,
282
+ serialization_alias=serialization_alias,
283
+ title=title,
284
+ description=description,
285
+ gt=gt,
286
+ ge=ge,
287
+ lt=lt,
288
+ le=le,
289
+ min_length=min_length,
290
+ max_length=max_length,
291
+ pattern=pattern,
292
+ regex=regex,
293
+ discriminator=discriminator,
294
+ strict=strict,
295
+ multiple_of=multiple_of,
296
+ allow_inf_nan=allow_inf_nan,
297
+ max_digits=max_digits,
298
+ decimal_places=decimal_places,
299
+ deprecated=deprecated,
300
+ example=example,
301
+ examples=examples,
302
+ openapi_examples=openapi_examples,
303
+ include_in_schema=include_in_schema,
304
+ json_schema_extra=json_schema_extra,
305
+ **extra,
306
+ )
307
+
308
+
309
+ class Header(Param):
310
+ in_ = ParamTypes.header
311
+
312
+ def __init__(
313
+ self,
314
+ default: Any = Undefined,
315
+ *,
316
+ default_factory: Union[Callable[[], Any], None] = _Unset,
317
+ annotation: Optional[Any] = None,
318
+ alias: Optional[str] = None,
319
+ alias_priority: Union[int, None] = _Unset,
320
+ # TODO: update when deprecating Pydantic v1, import these types
321
+ # validation_alias: str | AliasPath | AliasChoices | None
322
+ validation_alias: Union[str, None] = None,
323
+ serialization_alias: Union[str, None] = None,
324
+ convert_underscores: bool = True,
325
+ title: Optional[str] = None,
326
+ description: Optional[str] = None,
327
+ gt: Optional[float] = None,
328
+ ge: Optional[float] = None,
329
+ lt: Optional[float] = None,
330
+ le: Optional[float] = None,
331
+ min_length: Optional[int] = None,
332
+ max_length: Optional[int] = None,
333
+ pattern: Optional[str] = None,
334
+ regex: Annotated[
335
+ Optional[str],
336
+ deprecated(
337
+ "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
338
+ ),
339
+ ] = None,
340
+ discriminator: Union[str, None] = None,
341
+ strict: Union[bool, None] = _Unset,
342
+ multiple_of: Union[float, None] = _Unset,
343
+ allow_inf_nan: Union[bool, None] = _Unset,
344
+ max_digits: Union[int, None] = _Unset,
345
+ decimal_places: Union[int, None] = _Unset,
346
+ examples: Optional[List[Any]] = None,
347
+ example: Annotated[
348
+ Optional[Any],
349
+ deprecated(
350
+ "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
351
+ "although still supported. Use examples instead."
352
+ ),
353
+ ] = _Unset,
354
+ openapi_examples: Optional[Dict[str, Example]] = None,
355
+ deprecated: Union[deprecated, str, bool, None] = None,
356
+ include_in_schema: bool = True,
357
+ json_schema_extra: Union[Dict[str, Any], None] = None,
358
+ **extra: Any,
359
+ ):
360
+ self.convert_underscores = convert_underscores
361
+ super().__init__(
362
+ default=default,
363
+ default_factory=default_factory,
364
+ annotation=annotation,
365
+ alias=alias,
366
+ alias_priority=alias_priority,
367
+ validation_alias=validation_alias,
368
+ serialization_alias=serialization_alias,
369
+ title=title,
370
+ description=description,
371
+ gt=gt,
372
+ ge=ge,
373
+ lt=lt,
374
+ le=le,
375
+ min_length=min_length,
376
+ max_length=max_length,
377
+ pattern=pattern,
378
+ regex=regex,
379
+ discriminator=discriminator,
380
+ strict=strict,
381
+ multiple_of=multiple_of,
382
+ allow_inf_nan=allow_inf_nan,
383
+ max_digits=max_digits,
384
+ decimal_places=decimal_places,
385
+ deprecated=deprecated,
386
+ example=example,
387
+ examples=examples,
388
+ openapi_examples=openapi_examples,
389
+ include_in_schema=include_in_schema,
390
+ json_schema_extra=json_schema_extra,
391
+ **extra,
392
+ )
393
+
394
+
395
+ class Cookie(Param):
396
+ in_ = ParamTypes.cookie
397
+
398
+ def __init__(
399
+ self,
400
+ default: Any = Undefined,
401
+ *,
402
+ default_factory: Union[Callable[[], Any], None] = _Unset,
403
+ annotation: Optional[Any] = None,
404
+ alias: Optional[str] = None,
405
+ alias_priority: Union[int, None] = _Unset,
406
+ # TODO: update when deprecating Pydantic v1, import these types
407
+ # validation_alias: str | AliasPath | AliasChoices | None
408
+ validation_alias: Union[str, None] = None,
409
+ serialization_alias: Union[str, None] = None,
410
+ title: Optional[str] = None,
411
+ description: Optional[str] = None,
412
+ gt: Optional[float] = None,
413
+ ge: Optional[float] = None,
414
+ lt: Optional[float] = None,
415
+ le: Optional[float] = None,
416
+ min_length: Optional[int] = None,
417
+ max_length: Optional[int] = None,
418
+ pattern: Optional[str] = None,
419
+ regex: Annotated[
420
+ Optional[str],
421
+ deprecated(
422
+ "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
423
+ ),
424
+ ] = None,
425
+ discriminator: Union[str, None] = None,
426
+ strict: Union[bool, None] = _Unset,
427
+ multiple_of: Union[float, None] = _Unset,
428
+ allow_inf_nan: Union[bool, None] = _Unset,
429
+ max_digits: Union[int, None] = _Unset,
430
+ decimal_places: Union[int, None] = _Unset,
431
+ examples: Optional[List[Any]] = None,
432
+ example: Annotated[
433
+ Optional[Any],
434
+ deprecated(
435
+ "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
436
+ "although still supported. Use examples instead."
437
+ ),
438
+ ] = _Unset,
439
+ openapi_examples: Optional[Dict[str, Example]] = None,
440
+ deprecated: Union[deprecated, str, bool, None] = None,
441
+ include_in_schema: bool = True,
442
+ json_schema_extra: Union[Dict[str, Any], None] = None,
443
+ **extra: Any,
444
+ ):
445
+ super().__init__(
446
+ default=default,
447
+ default_factory=default_factory,
448
+ annotation=annotation,
449
+ alias=alias,
450
+ alias_priority=alias_priority,
451
+ validation_alias=validation_alias,
452
+ serialization_alias=serialization_alias,
453
+ title=title,
454
+ description=description,
455
+ gt=gt,
456
+ ge=ge,
457
+ lt=lt,
458
+ le=le,
459
+ min_length=min_length,
460
+ max_length=max_length,
461
+ pattern=pattern,
462
+ regex=regex,
463
+ discriminator=discriminator,
464
+ strict=strict,
465
+ multiple_of=multiple_of,
466
+ allow_inf_nan=allow_inf_nan,
467
+ max_digits=max_digits,
468
+ decimal_places=decimal_places,
469
+ deprecated=deprecated,
470
+ example=example,
471
+ examples=examples,
472
+ openapi_examples=openapi_examples,
473
+ include_in_schema=include_in_schema,
474
+ json_schema_extra=json_schema_extra,
475
+ **extra,
476
+ )
477
+
478
+
479
+ class Body(FieldInfo):
480
+ def __init__(
481
+ self,
482
+ default: Any = Undefined,
483
+ *,
484
+ default_factory: Union[Callable[[], Any], None] = _Unset,
485
+ annotation: Optional[Any] = None,
486
+ embed: Union[bool, None] = None,
487
+ media_type: str = "application/json",
488
+ alias: Optional[str] = None,
489
+ alias_priority: Union[int, None] = _Unset,
490
+ # TODO: update when deprecating Pydantic v1, import these types
491
+ # validation_alias: str | AliasPath | AliasChoices | None
492
+ validation_alias: Union[str, None] = None,
493
+ serialization_alias: Union[str, None] = None,
494
+ title: Optional[str] = None,
495
+ description: Optional[str] = None,
496
+ gt: Optional[float] = None,
497
+ ge: Optional[float] = None,
498
+ lt: Optional[float] = None,
499
+ le: Optional[float] = None,
500
+ min_length: Optional[int] = None,
501
+ max_length: Optional[int] = None,
502
+ pattern: Optional[str] = None,
503
+ regex: Annotated[
504
+ Optional[str],
505
+ deprecated(
506
+ "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
507
+ ),
508
+ ] = None,
509
+ discriminator: Union[str, None] = None,
510
+ strict: Union[bool, None] = _Unset,
511
+ multiple_of: Union[float, None] = _Unset,
512
+ allow_inf_nan: Union[bool, None] = _Unset,
513
+ max_digits: Union[int, None] = _Unset,
514
+ decimal_places: Union[int, None] = _Unset,
515
+ examples: Optional[List[Any]] = None,
516
+ example: Annotated[
517
+ Optional[Any],
518
+ deprecated(
519
+ "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
520
+ "although still supported. Use examples instead."
521
+ ),
522
+ ] = _Unset,
523
+ openapi_examples: Optional[Dict[str, Example]] = None,
524
+ deprecated: Union[deprecated, str, bool, None] = None,
525
+ include_in_schema: bool = True,
526
+ json_schema_extra: Union[Dict[str, Any], None] = None,
527
+ **extra: Any,
528
+ ):
529
+ self.embed = embed
530
+ self.media_type = media_type
531
+ if example is not _Unset:
532
+ warnings.warn(
533
+ "`example` has been deprecated, please use `examples` instead",
534
+ category=DeprecationWarning,
535
+ stacklevel=4,
536
+ )
537
+ self.example = example
538
+ self.include_in_schema = include_in_schema
539
+ self.openapi_examples = openapi_examples
540
+ kwargs = dict(
541
+ default=default,
542
+ default_factory=default_factory,
543
+ alias=alias,
544
+ title=title,
545
+ description=description,
546
+ gt=gt,
547
+ ge=ge,
548
+ lt=lt,
549
+ le=le,
550
+ min_length=min_length,
551
+ max_length=max_length,
552
+ discriminator=discriminator,
553
+ multiple_of=multiple_of,
554
+ allow_inf_nan=allow_inf_nan,
555
+ max_digits=max_digits,
556
+ decimal_places=decimal_places,
557
+ **extra,
558
+ )
559
+ if examples is not None:
560
+ kwargs["examples"] = examples
561
+ if regex is not None:
562
+ warnings.warn(
563
+ "`regex` has been deprecated, please use `pattern` instead",
564
+ category=DeprecationWarning,
565
+ stacklevel=4,
566
+ )
567
+ current_json_schema_extra = json_schema_extra or extra
568
+ if PYDANTIC_VERSION_MINOR_TUPLE < (2, 7):
569
+ self.deprecated = deprecated
570
+ else:
571
+ kwargs["deprecated"] = deprecated
572
+ if PYDANTIC_V2:
573
+ kwargs.update(
574
+ {
575
+ "annotation": annotation,
576
+ "alias_priority": alias_priority,
577
+ "validation_alias": validation_alias,
578
+ "serialization_alias": serialization_alias,
579
+ "strict": strict,
580
+ "json_schema_extra": current_json_schema_extra,
581
+ }
582
+ )
583
+ kwargs["pattern"] = pattern or regex
584
+ else:
585
+ kwargs["regex"] = pattern or regex
586
+ kwargs.update(**current_json_schema_extra)
587
+
588
+ use_kwargs = {k: v for k, v in kwargs.items() if v is not _Unset}
589
+
590
+ super().__init__(**use_kwargs)
591
+
592
+ def __repr__(self) -> str:
593
+ return f"{self.__class__.__name__}({self.default})"
594
+
595
+
596
+ class Form(Body):
597
+ def __init__(
598
+ self,
599
+ default: Any = Undefined,
600
+ *,
601
+ default_factory: Union[Callable[[], Any], None] = _Unset,
602
+ annotation: Optional[Any] = None,
603
+ media_type: str = "application/x-www-form-urlencoded",
604
+ alias: Optional[str] = None,
605
+ alias_priority: Union[int, None] = _Unset,
606
+ # TODO: update when deprecating Pydantic v1, import these types
607
+ # validation_alias: str | AliasPath | AliasChoices | None
608
+ validation_alias: Union[str, None] = None,
609
+ serialization_alias: Union[str, None] = None,
610
+ title: Optional[str] = None,
611
+ description: Optional[str] = None,
612
+ gt: Optional[float] = None,
613
+ ge: Optional[float] = None,
614
+ lt: Optional[float] = None,
615
+ le: Optional[float] = None,
616
+ min_length: Optional[int] = None,
617
+ max_length: Optional[int] = None,
618
+ pattern: Optional[str] = None,
619
+ regex: Annotated[
620
+ Optional[str],
621
+ deprecated(
622
+ "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
623
+ ),
624
+ ] = None,
625
+ discriminator: Union[str, None] = None,
626
+ strict: Union[bool, None] = _Unset,
627
+ multiple_of: Union[float, None] = _Unset,
628
+ allow_inf_nan: Union[bool, None] = _Unset,
629
+ max_digits: Union[int, None] = _Unset,
630
+ decimal_places: Union[int, None] = _Unset,
631
+ examples: Optional[List[Any]] = None,
632
+ example: Annotated[
633
+ Optional[Any],
634
+ deprecated(
635
+ "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
636
+ "although still supported. Use examples instead."
637
+ ),
638
+ ] = _Unset,
639
+ openapi_examples: Optional[Dict[str, Example]] = None,
640
+ deprecated: Union[deprecated, str, bool, None] = None,
641
+ include_in_schema: bool = True,
642
+ json_schema_extra: Union[Dict[str, Any], None] = None,
643
+ **extra: Any,
644
+ ):
645
+ super().__init__(
646
+ default=default,
647
+ default_factory=default_factory,
648
+ annotation=annotation,
649
+ media_type=media_type,
650
+ alias=alias,
651
+ alias_priority=alias_priority,
652
+ validation_alias=validation_alias,
653
+ serialization_alias=serialization_alias,
654
+ title=title,
655
+ description=description,
656
+ gt=gt,
657
+ ge=ge,
658
+ lt=lt,
659
+ le=le,
660
+ min_length=min_length,
661
+ max_length=max_length,
662
+ pattern=pattern,
663
+ regex=regex,
664
+ discriminator=discriminator,
665
+ strict=strict,
666
+ multiple_of=multiple_of,
667
+ allow_inf_nan=allow_inf_nan,
668
+ max_digits=max_digits,
669
+ decimal_places=decimal_places,
670
+ deprecated=deprecated,
671
+ example=example,
672
+ examples=examples,
673
+ openapi_examples=openapi_examples,
674
+ include_in_schema=include_in_schema,
675
+ json_schema_extra=json_schema_extra,
676
+ **extra,
677
+ )
678
+
679
+
680
+ class File(Form):
681
+ def __init__(
682
+ self,
683
+ default: Any = Undefined,
684
+ *,
685
+ default_factory: Union[Callable[[], Any], None] = _Unset,
686
+ annotation: Optional[Any] = None,
687
+ media_type: str = "multipart/form-data",
688
+ alias: Optional[str] = None,
689
+ alias_priority: Union[int, None] = _Unset,
690
+ # TODO: update when deprecating Pydantic v1, import these types
691
+ # validation_alias: str | AliasPath | AliasChoices | None
692
+ validation_alias: Union[str, None] = None,
693
+ serialization_alias: Union[str, None] = None,
694
+ title: Optional[str] = None,
695
+ description: Optional[str] = None,
696
+ gt: Optional[float] = None,
697
+ ge: Optional[float] = None,
698
+ lt: Optional[float] = None,
699
+ le: Optional[float] = None,
700
+ min_length: Optional[int] = None,
701
+ max_length: Optional[int] = None,
702
+ pattern: Optional[str] = None,
703
+ regex: Annotated[
704
+ Optional[str],
705
+ deprecated(
706
+ "Deprecated in FastAPI 0.100.0 and Pydantic v2, use `pattern` instead."
707
+ ),
708
+ ] = None,
709
+ discriminator: Union[str, None] = None,
710
+ strict: Union[bool, None] = _Unset,
711
+ multiple_of: Union[float, None] = _Unset,
712
+ allow_inf_nan: Union[bool, None] = _Unset,
713
+ max_digits: Union[int, None] = _Unset,
714
+ decimal_places: Union[int, None] = _Unset,
715
+ examples: Optional[List[Any]] = None,
716
+ example: Annotated[
717
+ Optional[Any],
718
+ deprecated(
719
+ "Deprecated in OpenAPI 3.1.0 that now uses JSON Schema 2020-12, "
720
+ "although still supported. Use examples instead."
721
+ ),
722
+ ] = _Unset,
723
+ openapi_examples: Optional[Dict[str, Example]] = None,
724
+ deprecated: Union[deprecated, str, bool, None] = None,
725
+ include_in_schema: bool = True,
726
+ json_schema_extra: Union[Dict[str, Any], None] = None,
727
+ **extra: Any,
728
+ ):
729
+ super().__init__(
730
+ default=default,
731
+ default_factory=default_factory,
732
+ annotation=annotation,
733
+ media_type=media_type,
734
+ alias=alias,
735
+ alias_priority=alias_priority,
736
+ validation_alias=validation_alias,
737
+ serialization_alias=serialization_alias,
738
+ title=title,
739
+ description=description,
740
+ gt=gt,
741
+ ge=ge,
742
+ lt=lt,
743
+ le=le,
744
+ min_length=min_length,
745
+ max_length=max_length,
746
+ pattern=pattern,
747
+ regex=regex,
748
+ discriminator=discriminator,
749
+ strict=strict,
750
+ multiple_of=multiple_of,
751
+ allow_inf_nan=allow_inf_nan,
752
+ max_digits=max_digits,
753
+ decimal_places=decimal_places,
754
+ deprecated=deprecated,
755
+ example=example,
756
+ examples=examples,
757
+ openapi_examples=openapi_examples,
758
+ include_in_schema=include_in_schema,
759
+ json_schema_extra=json_schema_extra,
760
+ **extra,
761
+ )
762
+
763
+
764
+ class Depends:
765
+ def __init__(
766
+ self, dependency: Optional[Callable[..., Any]] = None, *, use_cache: bool = True
767
+ ):
768
+ self.dependency = dependency
769
+ self.use_cache = use_cache
770
+
771
+ def __repr__(self) -> str:
772
+ attr = getattr(self.dependency, "__name__", type(self.dependency).__name__)
773
+ cache = "" if self.use_cache else ", use_cache=False"
774
+ return f"{self.__class__.__name__}({attr}{cache})"
775
+
776
+
777
+ class Security(Depends):
778
+ def __init__(
779
+ self,
780
+ dependency: Optional[Callable[..., Any]] = None,
781
+ *,
782
+ scopes: Optional[Sequence[str]] = None,
783
+ use_cache: bool = True,
784
+ ):
785
+ super().__init__(dependency=dependency, use_cache=use_cache)
786
+ self.scopes = scopes or []
lib/python3.12/site-packages/fastapi/py.typed ADDED
File without changes
lib/python3.12/site-packages/fastapi/requests.py ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ from starlette.requests import HTTPConnection as HTTPConnection # noqa: F401
2
+ from starlette.requests import Request as Request # noqa: F401
lib/python3.12/site-packages/fastapi/responses.py ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Any
2
+
3
+ from starlette.responses import FileResponse as FileResponse # noqa
4
+ from starlette.responses import HTMLResponse as HTMLResponse # noqa
5
+ from starlette.responses import JSONResponse as JSONResponse # noqa
6
+ from starlette.responses import PlainTextResponse as PlainTextResponse # noqa
7
+ from starlette.responses import RedirectResponse as RedirectResponse # noqa
8
+ from starlette.responses import Response as Response # noqa
9
+ from starlette.responses import StreamingResponse as StreamingResponse # noqa
10
+
11
+ try:
12
+ import ujson
13
+ except ImportError: # pragma: nocover
14
+ ujson = None # type: ignore
15
+
16
+
17
+ try:
18
+ import orjson
19
+ except ImportError: # pragma: nocover
20
+ orjson = None # type: ignore
21
+
22
+
23
+ class UJSONResponse(JSONResponse):
24
+ """
25
+ JSON response using the high-performance ujson library to serialize data to JSON.
26
+
27
+ Read more about it in the
28
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/).
29
+ """
30
+
31
+ def render(self, content: Any) -> bytes:
32
+ assert ujson is not None, "ujson must be installed to use UJSONResponse"
33
+ return ujson.dumps(content, ensure_ascii=False).encode("utf-8")
34
+
35
+
36
+ class ORJSONResponse(JSONResponse):
37
+ """
38
+ JSON response using the high-performance orjson library to serialize data to JSON.
39
+
40
+ Read more about it in the
41
+ [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/).
42
+ """
43
+
44
+ def render(self, content: Any) -> bytes:
45
+ assert orjson is not None, "orjson must be installed to use ORJSONResponse"
46
+ return orjson.dumps(
47
+ content, option=orjson.OPT_NON_STR_KEYS | orjson.OPT_SERIALIZE_NUMPY
48
+ )
lib/python3.12/site-packages/fastapi/routing.py ADDED
The diff for this file is too large to render. See raw diff
 
lib/python3.12/site-packages/fastapi/security/__init__.py ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from .api_key import APIKeyCookie as APIKeyCookie
2
+ from .api_key import APIKeyHeader as APIKeyHeader
3
+ from .api_key import APIKeyQuery as APIKeyQuery
4
+ from .http import HTTPAuthorizationCredentials as HTTPAuthorizationCredentials
5
+ from .http import HTTPBasic as HTTPBasic
6
+ from .http import HTTPBasicCredentials as HTTPBasicCredentials
7
+ from .http import HTTPBearer as HTTPBearer
8
+ from .http import HTTPDigest as HTTPDigest
9
+ from .oauth2 import OAuth2 as OAuth2
10
+ from .oauth2 import OAuth2AuthorizationCodeBearer as OAuth2AuthorizationCodeBearer
11
+ from .oauth2 import OAuth2PasswordBearer as OAuth2PasswordBearer
12
+ from .oauth2 import OAuth2PasswordRequestForm as OAuth2PasswordRequestForm
13
+ from .oauth2 import OAuth2PasswordRequestFormStrict as OAuth2PasswordRequestFormStrict
14
+ from .oauth2 import SecurityScopes as SecurityScopes
15
+ from .open_id_connect_url import OpenIdConnect as OpenIdConnect
lib/python3.12/site-packages/fastapi/security/__pycache__/__init__.cpython-312.pyc ADDED
Binary file (851 Bytes). View file
 
lib/python3.12/site-packages/fastapi/security/__pycache__/api_key.cpython-312.pyc ADDED
Binary file (9.7 kB). View file
 
lib/python3.12/site-packages/fastapi/security/__pycache__/base.cpython-312.pyc ADDED
Binary file (513 Bytes). View file
 
lib/python3.12/site-packages/fastapi/security/__pycache__/http.cpython-312.pyc ADDED
Binary file (13.6 kB). View file
 
lib/python3.12/site-packages/fastapi/security/__pycache__/oauth2.cpython-312.pyc ADDED
Binary file (18.3 kB). View file
 
lib/python3.12/site-packages/fastapi/security/__pycache__/open_id_connect_url.cpython-312.pyc ADDED
Binary file (3.22 kB). View file
 
lib/python3.12/site-packages/fastapi/security/__pycache__/utils.cpython-312.pyc ADDED
Binary file (606 Bytes). View file
 
lib/python3.12/site-packages/fastapi/security/api_key.py ADDED
@@ -0,0 +1,288 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Optional
2
+
3
+ from fastapi.openapi.models import APIKey, APIKeyIn
4
+ from fastapi.security.base import SecurityBase
5
+ from starlette.exceptions import HTTPException
6
+ from starlette.requests import Request
7
+ from starlette.status import HTTP_403_FORBIDDEN
8
+ from typing_extensions import Annotated, Doc
9
+
10
+
11
+ class APIKeyBase(SecurityBase):
12
+ @staticmethod
13
+ def check_api_key(api_key: Optional[str], auto_error: bool) -> Optional[str]:
14
+ if not api_key:
15
+ if auto_error:
16
+ raise HTTPException(
17
+ status_code=HTTP_403_FORBIDDEN, detail="Not authenticated"
18
+ )
19
+ return None
20
+ return api_key
21
+
22
+
23
+ class APIKeyQuery(APIKeyBase):
24
+ """
25
+ API key authentication using a query parameter.
26
+
27
+ This defines the name of the query parameter that should be provided in the request
28
+ with the API key and integrates that into the OpenAPI documentation. It extracts
29
+ the key value sent in the query parameter automatically and provides it as the
30
+ dependency result. But it doesn't define how to send that API key to the client.
31
+
32
+ ## Usage
33
+
34
+ Create an instance object and use that object as the dependency in `Depends()`.
35
+
36
+ The dependency result will be a string containing the key value.
37
+
38
+ ## Example
39
+
40
+ ```python
41
+ from fastapi import Depends, FastAPI
42
+ from fastapi.security import APIKeyQuery
43
+
44
+ app = FastAPI()
45
+
46
+ query_scheme = APIKeyQuery(name="api_key")
47
+
48
+
49
+ @app.get("/items/")
50
+ async def read_items(api_key: str = Depends(query_scheme)):
51
+ return {"api_key": api_key}
52
+ ```
53
+ """
54
+
55
+ def __init__(
56
+ self,
57
+ *,
58
+ name: Annotated[
59
+ str,
60
+ Doc("Query parameter name."),
61
+ ],
62
+ scheme_name: Annotated[
63
+ Optional[str],
64
+ Doc(
65
+ """
66
+ Security scheme name.
67
+
68
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
69
+ """
70
+ ),
71
+ ] = None,
72
+ description: Annotated[
73
+ Optional[str],
74
+ Doc(
75
+ """
76
+ Security scheme description.
77
+
78
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
79
+ """
80
+ ),
81
+ ] = None,
82
+ auto_error: Annotated[
83
+ bool,
84
+ Doc(
85
+ """
86
+ By default, if the query parameter is not provided, `APIKeyQuery` will
87
+ automatically cancel the request and send the client an error.
88
+
89
+ If `auto_error` is set to `False`, when the query parameter is not
90
+ available, instead of erroring out, the dependency result will be
91
+ `None`.
92
+
93
+ This is useful when you want to have optional authentication.
94
+
95
+ It is also useful when you want to have authentication that can be
96
+ provided in one of multiple optional ways (for example, in a query
97
+ parameter or in an HTTP Bearer token).
98
+ """
99
+ ),
100
+ ] = True,
101
+ ):
102
+ self.model: APIKey = APIKey(
103
+ **{"in": APIKeyIn.query}, # type: ignore[arg-type]
104
+ name=name,
105
+ description=description,
106
+ )
107
+ self.scheme_name = scheme_name or self.__class__.__name__
108
+ self.auto_error = auto_error
109
+
110
+ async def __call__(self, request: Request) -> Optional[str]:
111
+ api_key = request.query_params.get(self.model.name)
112
+ return self.check_api_key(api_key, self.auto_error)
113
+
114
+
115
+ class APIKeyHeader(APIKeyBase):
116
+ """
117
+ API key authentication using a header.
118
+
119
+ This defines the name of the header that should be provided in the request with
120
+ the API key and integrates that into the OpenAPI documentation. It extracts
121
+ the key value sent in the header automatically and provides it as the dependency
122
+ result. But it doesn't define how to send that key to the client.
123
+
124
+ ## Usage
125
+
126
+ Create an instance object and use that object as the dependency in `Depends()`.
127
+
128
+ The dependency result will be a string containing the key value.
129
+
130
+ ## Example
131
+
132
+ ```python
133
+ from fastapi import Depends, FastAPI
134
+ from fastapi.security import APIKeyHeader
135
+
136
+ app = FastAPI()
137
+
138
+ header_scheme = APIKeyHeader(name="x-key")
139
+
140
+
141
+ @app.get("/items/")
142
+ async def read_items(key: str = Depends(header_scheme)):
143
+ return {"key": key}
144
+ ```
145
+ """
146
+
147
+ def __init__(
148
+ self,
149
+ *,
150
+ name: Annotated[str, Doc("Header name.")],
151
+ scheme_name: Annotated[
152
+ Optional[str],
153
+ Doc(
154
+ """
155
+ Security scheme name.
156
+
157
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
158
+ """
159
+ ),
160
+ ] = None,
161
+ description: Annotated[
162
+ Optional[str],
163
+ Doc(
164
+ """
165
+ Security scheme description.
166
+
167
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
168
+ """
169
+ ),
170
+ ] = None,
171
+ auto_error: Annotated[
172
+ bool,
173
+ Doc(
174
+ """
175
+ By default, if the header is not provided, `APIKeyHeader` will
176
+ automatically cancel the request and send the client an error.
177
+
178
+ If `auto_error` is set to `False`, when the header is not available,
179
+ instead of erroring out, the dependency result will be `None`.
180
+
181
+ This is useful when you want to have optional authentication.
182
+
183
+ It is also useful when you want to have authentication that can be
184
+ provided in one of multiple optional ways (for example, in a header or
185
+ in an HTTP Bearer token).
186
+ """
187
+ ),
188
+ ] = True,
189
+ ):
190
+ self.model: APIKey = APIKey(
191
+ **{"in": APIKeyIn.header}, # type: ignore[arg-type]
192
+ name=name,
193
+ description=description,
194
+ )
195
+ self.scheme_name = scheme_name or self.__class__.__name__
196
+ self.auto_error = auto_error
197
+
198
+ async def __call__(self, request: Request) -> Optional[str]:
199
+ api_key = request.headers.get(self.model.name)
200
+ return self.check_api_key(api_key, self.auto_error)
201
+
202
+
203
+ class APIKeyCookie(APIKeyBase):
204
+ """
205
+ API key authentication using a cookie.
206
+
207
+ This defines the name of the cookie that should be provided in the request with
208
+ the API key and integrates that into the OpenAPI documentation. It extracts
209
+ the key value sent in the cookie automatically and provides it as the dependency
210
+ result. But it doesn't define how to set that cookie.
211
+
212
+ ## Usage
213
+
214
+ Create an instance object and use that object as the dependency in `Depends()`.
215
+
216
+ The dependency result will be a string containing the key value.
217
+
218
+ ## Example
219
+
220
+ ```python
221
+ from fastapi import Depends, FastAPI
222
+ from fastapi.security import APIKeyCookie
223
+
224
+ app = FastAPI()
225
+
226
+ cookie_scheme = APIKeyCookie(name="session")
227
+
228
+
229
+ @app.get("/items/")
230
+ async def read_items(session: str = Depends(cookie_scheme)):
231
+ return {"session": session}
232
+ ```
233
+ """
234
+
235
+ def __init__(
236
+ self,
237
+ *,
238
+ name: Annotated[str, Doc("Cookie name.")],
239
+ scheme_name: Annotated[
240
+ Optional[str],
241
+ Doc(
242
+ """
243
+ Security scheme name.
244
+
245
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
246
+ """
247
+ ),
248
+ ] = None,
249
+ description: Annotated[
250
+ Optional[str],
251
+ Doc(
252
+ """
253
+ Security scheme description.
254
+
255
+ It will be included in the generated OpenAPI (e.g. visible at `/docs`).
256
+ """
257
+ ),
258
+ ] = None,
259
+ auto_error: Annotated[
260
+ bool,
261
+ Doc(
262
+ """
263
+ By default, if the cookie is not provided, `APIKeyCookie` will
264
+ automatically cancel the request and send the client an error.
265
+
266
+ If `auto_error` is set to `False`, when the cookie is not available,
267
+ instead of erroring out, the dependency result will be `None`.
268
+
269
+ This is useful when you want to have optional authentication.
270
+
271
+ It is also useful when you want to have authentication that can be
272
+ provided in one of multiple optional ways (for example, in a cookie or
273
+ in an HTTP Bearer token).
274
+ """
275
+ ),
276
+ ] = True,
277
+ ):
278
+ self.model: APIKey = APIKey(
279
+ **{"in": APIKeyIn.cookie}, # type: ignore[arg-type]
280
+ name=name,
281
+ description=description,
282
+ )
283
+ self.scheme_name = scheme_name or self.__class__.__name__
284
+ self.auto_error = auto_error
285
+
286
+ async def __call__(self, request: Request) -> Optional[str]:
287
+ api_key = request.cookies.get(self.model.name)
288
+ return self.check_api_key(api_key, self.auto_error)