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

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/absl_py-2.4.0.dist-info/INSTALLER +1 -0
  2. lib/python3.12/site-packages/absl_py-2.4.0.dist-info/METADATA +100 -0
  3. lib/python3.12/site-packages/absl_py-2.4.0.dist-info/RECORD +53 -0
  4. lib/python3.12/site-packages/absl_py-2.4.0.dist-info/WHEEL +4 -0
  5. lib/python3.12/site-packages/absl_py-2.4.0.dist-info/licenses/AUTHORS +7 -0
  6. lib/python3.12/site-packages/absl_py-2.4.0.dist-info/licenses/LICENSE +202 -0
  7. lib/python3.12/site-packages/fastapi/__pycache__/__init__.cpython-312.pyc +0 -0
  8. lib/python3.12/site-packages/fastapi/__pycache__/__main__.cpython-312.pyc +0 -0
  9. lib/python3.12/site-packages/fastapi/__pycache__/_compat.cpython-312.pyc +0 -0
  10. lib/python3.12/site-packages/fastapi/__pycache__/applications.cpython-312.pyc +0 -0
  11. lib/python3.12/site-packages/fastapi/__pycache__/background.cpython-312.pyc +0 -0
  12. lib/python3.12/site-packages/fastapi/__pycache__/cli.cpython-312.pyc +0 -0
  13. lib/python3.12/site-packages/fastapi/__pycache__/concurrency.cpython-312.pyc +0 -0
  14. lib/python3.12/site-packages/fastapi/__pycache__/datastructures.cpython-312.pyc +0 -0
  15. lib/python3.12/site-packages/fastapi/__pycache__/encoders.cpython-312.pyc +0 -0
  16. lib/python3.12/site-packages/fastapi/__pycache__/exception_handlers.cpython-312.pyc +0 -0
  17. lib/python3.12/site-packages/fastapi/__pycache__/exceptions.cpython-312.pyc +0 -0
  18. lib/python3.12/site-packages/fastapi/__pycache__/logger.cpython-312.pyc +0 -0
  19. lib/python3.12/site-packages/fastapi/__pycache__/params.cpython-312.pyc +0 -0
  20. lib/python3.12/site-packages/fastapi/__pycache__/requests.cpython-312.pyc +0 -0
  21. lib/python3.12/site-packages/fastapi/__pycache__/responses.cpython-312.pyc +0 -0
  22. lib/python3.12/site-packages/fastapi/__pycache__/routing.cpython-312.pyc +0 -0
  23. lib/python3.12/site-packages/fastapi/__pycache__/staticfiles.cpython-312.pyc +0 -0
  24. lib/python3.12/site-packages/fastapi/__pycache__/templating.cpython-312.pyc +0 -0
  25. lib/python3.12/site-packages/fastapi/__pycache__/testclient.cpython-312.pyc +0 -0
  26. lib/python3.12/site-packages/fastapi/__pycache__/types.cpython-312.pyc +0 -0
  27. lib/python3.12/site-packages/fastapi/__pycache__/utils.cpython-312.pyc +0 -0
  28. lib/python3.12/site-packages/fastapi/__pycache__/websockets.cpython-312.pyc +0 -0
  29. lib/python3.12/site-packages/fastapi/dependencies/__init__.py +0 -0
  30. lib/python3.12/site-packages/fastapi/dependencies/__pycache__/__init__.cpython-312.pyc +0 -0
  31. lib/python3.12/site-packages/fastapi/dependencies/__pycache__/models.cpython-312.pyc +0 -0
  32. lib/python3.12/site-packages/fastapi/dependencies/__pycache__/utils.cpython-312.pyc +0 -0
  33. lib/python3.12/site-packages/fastapi/dependencies/models.py +37 -0
  34. lib/python3.12/site-packages/fastapi/dependencies/utils.py +980 -0
  35. lib/python3.12/site-packages/fastapi/middleware/__init__.py +1 -0
  36. lib/python3.12/site-packages/fastapi/middleware/__pycache__/__init__.cpython-312.pyc +0 -0
  37. lib/python3.12/site-packages/fastapi/middleware/__pycache__/cors.cpython-312.pyc +0 -0
  38. lib/python3.12/site-packages/fastapi/middleware/__pycache__/gzip.cpython-312.pyc +0 -0
  39. lib/python3.12/site-packages/fastapi/middleware/__pycache__/httpsredirect.cpython-312.pyc +0 -0
  40. lib/python3.12/site-packages/fastapi/middleware/__pycache__/trustedhost.cpython-312.pyc +0 -0
  41. lib/python3.12/site-packages/fastapi/middleware/__pycache__/wsgi.cpython-312.pyc +0 -0
  42. lib/python3.12/site-packages/fastapi/middleware/cors.py +1 -0
  43. lib/python3.12/site-packages/fastapi/middleware/gzip.py +1 -0
  44. lib/python3.12/site-packages/fastapi/middleware/httpsredirect.py +3 -0
  45. lib/python3.12/site-packages/fastapi/middleware/trustedhost.py +3 -0
  46. lib/python3.12/site-packages/fastapi/middleware/wsgi.py +1 -0
  47. lib/python3.12/site-packages/git/__pycache__/__init__.cpython-312.pyc +0 -0
  48. lib/python3.12/site-packages/git/__pycache__/cmd.cpython-312.pyc +0 -0
  49. lib/python3.12/site-packages/git/__pycache__/compat.cpython-312.pyc +0 -0
  50. lib/python3.12/site-packages/git/__pycache__/config.cpython-312.pyc +0 -0
lib/python3.12/site-packages/absl_py-2.4.0.dist-info/INSTALLER ADDED
@@ -0,0 +1 @@
 
 
1
+ pip
lib/python3.12/site-packages/absl_py-2.4.0.dist-info/METADATA ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Metadata-Version: 2.4
2
+ Name: absl-py
3
+ Version: 2.4.0
4
+ Summary: Abseil Python Common Libraries, see https://github.com/abseil/abseil-py.
5
+ Project-URL: Changelog, https://github.com/abseil/abseil-py/blob/main/CHANGELOG.md
6
+ Project-URL: Documentation, https://abseil.io/docs/python/
7
+ Project-URL: Issues, https://github.com/abseil/abseil-py/issues
8
+ Project-URL: Source, https://github.com/abseil/abseil-py
9
+ Author: The Abseil Authors
10
+ License-Expression: Apache-2.0
11
+ License-File: AUTHORS
12
+ License-File: LICENSE
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: Apache Software License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Programming Language :: Python :: 3.14
23
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
+ Requires-Python: >=3.10
25
+ Description-Content-Type: text/markdown
26
+
27
+ [![Package version](https://img.shields.io/pypi/v/absl-py)](https://pypi.org/project/absl-py)
28
+ [![Supported Python versions](https://img.shields.io/pypi/pyversions/absl-py.svg?style=flat-square)](https://pypi.org/project/absl-py)
29
+ [![License](https://img.shields.io/github/license/abseil/abseil-py)](https://github.com/abseil/abseil-py/blob/main/LICENSE)
30
+ [![Build Status](https://github.com/abseil/abseil-py/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/abseil/abseil-py/actions)
31
+ [![Overall downloads](https://pepy.tech/badge/absl-py)](https://pepy.tech/project/absl-py)
32
+ [![Last month downloads](https://pepy.tech/badge/absl-py/month)](https://pepy.tech/project/absl-py)
33
+
34
+ # Abseil Python Common Libraries
35
+
36
+ This repository is a collection of Python library code for building Python
37
+ applications. The code is collected from Google's own Python code base, and has
38
+ been extensively tested and used in production.
39
+
40
+ ## Features
41
+
42
+ * Simple application startup
43
+ * Distributed commandline flags system
44
+ * Custom logging module with additional features
45
+ * Testing utilities
46
+
47
+ ## Getting Started
48
+
49
+ ### Installation
50
+
51
+ To install the package, simply run:
52
+
53
+ ```bash
54
+ pip install absl-py
55
+ ```
56
+
57
+ Or install from source:
58
+
59
+ ```bash
60
+ pip install .
61
+ ```
62
+
63
+ ### Running Tests
64
+
65
+ To run Abseil tests, you can clone the git repo and run
66
+ [bazel](https://bazel.build/):
67
+
68
+ ```bash
69
+ git clone https://github.com/abseil/abseil-py.git
70
+ cd abseil-py
71
+ bazel test absl/...
72
+ ```
73
+
74
+ Please also validate the type annotations against the latest mypy:
75
+
76
+ ```bash
77
+ pip install mypy
78
+ mypy absl
79
+ ```
80
+
81
+ ### Example Code
82
+
83
+ Please refer to
84
+ [smoke_tests/sample_app.py](https://github.com/abseil/abseil-py/blob/main/smoke_tests/sample_app.py)
85
+ as an example to get started.
86
+
87
+ ## Documentation
88
+
89
+ See the [Abseil Python Developer Guide](https://abseil.io/docs/python/).
90
+
91
+ ## Future Releases
92
+
93
+ The current repository includes an initial set of libraries for early adoption.
94
+ More components and interoperability with Abseil C++ Common Libraries
95
+ will come in future releases.
96
+
97
+ ## License
98
+
99
+ The Abseil Python library is licensed under the terms of the Apache
100
+ license. See [LICENSE](LICENSE) for more information.
lib/python3.12/site-packages/absl_py-2.4.0.dist-info/RECORD ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ absl/__init__.py,sha256=tQJRn_5rbQ5gWoXdkGAV-fJSGFCOGH6fFBI1NxLx5ho,607
2
+ absl/__pycache__/__init__.cpython-312.pyc,,
3
+ absl/__pycache__/app.cpython-312.pyc,,
4
+ absl/__pycache__/command_name.cpython-312.pyc,,
5
+ absl/app.py,sha256=zC4tAKcK054F7kSrR7pzSCEDqNcJKLVb2AkvjIlmvl8,17065
6
+ absl/app.pyi,sha256=YTcQS7o1DBFyFNgMpdykmvP3g4OljSwp3BuX9sSSLIM,1814
7
+ absl/command_name.py,sha256=FgWUMHmlX0yQxEuMPXxFxn5ayWWZSLB0cq8Vx361TpU,2283
8
+ absl/flags/__init__.py,sha256=n_uLeSK-15_1DKLb0wXivmt6A8xvADDC87D1yoJdqVU,7665
9
+ absl/flags/__pycache__/__init__.cpython-312.pyc,,
10
+ absl/flags/__pycache__/_argument_parser.cpython-312.pyc,,
11
+ absl/flags/__pycache__/_defines.cpython-312.pyc,,
12
+ absl/flags/__pycache__/_exceptions.cpython-312.pyc,,
13
+ absl/flags/__pycache__/_flag.cpython-312.pyc,,
14
+ absl/flags/__pycache__/_flagvalues.cpython-312.pyc,,
15
+ absl/flags/__pycache__/_helpers.cpython-312.pyc,,
16
+ absl/flags/__pycache__/_validators.cpython-312.pyc,,
17
+ absl/flags/__pycache__/_validators_classes.cpython-312.pyc,,
18
+ absl/flags/__pycache__/argparse_flags.cpython-312.pyc,,
19
+ absl/flags/_argument_parser.py,sha256=XFIDxu1I8NjgBZhUdzSLUwDHhXFvOC-SbI8FsVmWZ_0,20531
20
+ absl/flags/_defines.py,sha256=P3DLHYAaSgXSBlRgBN6QOS6oRcNUYNtzeapL5EQJ5LA,52499
21
+ absl/flags/_exceptions.py,sha256=FZzlzhvkjqPImTxXqbS1pSPYKr_TvtOd5ellvoiVLDI,3619
22
+ absl/flags/_flag.py,sha256=fOv_KC7t1e-BoabTP3iYHR1dUkTf2yhgfAWonjhByEQ,19891
23
+ absl/flags/_flagvalues.py,sha256=QqCMTxHIJdwqYwlYhZ76nuXzsJQtF20RTzq-x0S_tPg,55319
24
+ absl/flags/_helpers.py,sha256=0cWFV4XFLkcHWu-du6es8sCsWl26k1dZ6fqCPsWZ68k,13301
25
+ absl/flags/_validators.py,sha256=VcsJtZzohliNxsI974NECYpeozD8rswHNHXggrQ4BLo,14140
26
+ absl/flags/_validators_classes.py,sha256=PGUWzO7v3wPOHb9leIKKzry3q-pPeKCoMB_O7prLdnY,6093
27
+ absl/flags/argparse_flags.py,sha256=usJudgMpy3P6Vvq7-LmJNa2Rj3ygHM3hwDTGd1mbAzc,14386
28
+ absl/logging/__init__.py,sha256=3quWtll8Cb949CYs-VOC1AnxdBqClX8ab55VB28knVs,43883
29
+ absl/logging/__init__.pyi,sha256=7yyq5rAJfkBFRaD8iqOTsLW-xhMAIDJ5ub4r3Has04U,5984
30
+ absl/logging/__pycache__/__init__.cpython-312.pyc,,
31
+ absl/logging/__pycache__/converter.cpython-312.pyc,,
32
+ absl/logging/converter.py,sha256=6eBymfv9UNkog0BGat4HPWlxC_oSqvHcQ46jnSdtaMg,6323
33
+ absl/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
+ absl/testing/__init__.py,sha256=7cM57swk2T1Hc5wxmt-JpcaR6xfdPJyL_lyRqgODvuM,584
35
+ absl/testing/__pycache__/__init__.cpython-312.pyc,,
36
+ absl/testing/__pycache__/_bazelize_command.cpython-312.pyc,,
37
+ absl/testing/__pycache__/_pretty_print_reporter.cpython-312.pyc,,
38
+ absl/testing/__pycache__/absltest.cpython-312.pyc,,
39
+ absl/testing/__pycache__/flagsaver.cpython-312.pyc,,
40
+ absl/testing/__pycache__/parameterized.cpython-312.pyc,,
41
+ absl/testing/__pycache__/xml_reporter.cpython-312.pyc,,
42
+ absl/testing/_bazelize_command.py,sha256=qpioV02ln2sBBJ9kdlHgNpKk8_wxdz2hJGKbG6EWZMI,2287
43
+ absl/testing/_pretty_print_reporter.py,sha256=PZh9NXSXBbXDi0FOk-BOmpse8LXa92Er16tgyBRogMs,3065
44
+ absl/testing/absltest.py,sha256=CkUgJ54S4LJ1RwjNISv4pEW_N9kZBrNDpnzQ1YGPOlc,104586
45
+ absl/testing/flagsaver.py,sha256=BeftLpNxJctYtd041tECgCSglQVFKSsQ4KBFT9D_m5k,13291
46
+ absl/testing/parameterized.py,sha256=TpTlWTUXjikGeUDE45AgubvnmHsPbFNj-wUtAwT-e6E,27817
47
+ absl/testing/xml_reporter.py,sha256=Q0keNHVOh3L9zXwNIzWCjXcWYlCM9ZJxdjMaYyHF3dw,21424
48
+ absl_py-2.4.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
49
+ absl_py-2.4.0.dist-info/METADATA,sha256=Eh8VboTinee1rj1-UDeBjw_KiicKBxJBi6H0zB1Sq0g,3283
50
+ absl_py-2.4.0.dist-info/RECORD,,
51
+ absl_py-2.4.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
52
+ absl_py-2.4.0.dist-info/licenses/AUTHORS,sha256=YoLudsylaQg7W5mLn4FroQMuEnuNx8RpQrhkd_xvv6U,296
53
+ absl_py-2.4.0.dist-info/licenses/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
lib/python3.12/site-packages/absl_py-2.4.0.dist-info/WHEEL ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.28.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
lib/python3.12/site-packages/absl_py-2.4.0.dist-info/licenses/AUTHORS ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ # This is the list of Abseil authors for copyright purposes.
2
+ #
3
+ # This does not necessarily list everyone who has contributed code, since in
4
+ # some cases, their employer may be the copyright holder. To see the full list
5
+ # of contributors, see the revision history in source control.
6
+
7
+ Google Inc.
lib/python3.12/site-packages/absl_py-2.4.0.dist-info/licenses/LICENSE ADDED
@@ -0,0 +1,202 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ Apache License
3
+ Version 2.0, January 2004
4
+ http://www.apache.org/licenses/
5
+
6
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7
+
8
+ 1. Definitions.
9
+
10
+ "License" shall mean the terms and conditions for use, reproduction,
11
+ and distribution as defined by Sections 1 through 9 of this document.
12
+
13
+ "Licensor" shall mean the copyright owner or entity authorized by
14
+ the copyright owner that is granting the License.
15
+
16
+ "Legal Entity" shall mean the union of the acting entity and all
17
+ other entities that control, are controlled by, or are under common
18
+ control with that entity. For the purposes of this definition,
19
+ "control" means (i) the power, direct or indirect, to cause the
20
+ direction or management of such entity, whether by contract or
21
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
22
+ outstanding shares, or (iii) beneficial ownership of such entity.
23
+
24
+ "You" (or "Your") shall mean an individual or Legal Entity
25
+ exercising permissions granted by this License.
26
+
27
+ "Source" form shall mean the preferred form for making modifications,
28
+ including but not limited to software source code, documentation
29
+ source, and configuration files.
30
+
31
+ "Object" form shall mean any form resulting from mechanical
32
+ transformation or translation of a Source form, including but
33
+ not limited to compiled object code, generated documentation,
34
+ and conversions to other media types.
35
+
36
+ "Work" shall mean the work of authorship, whether in Source or
37
+ Object form, made available under the License, as indicated by a
38
+ copyright notice that is included in or attached to the work
39
+ (an example is provided in the Appendix below).
40
+
41
+ "Derivative Works" shall mean any work, whether in Source or Object
42
+ form, that is based on (or derived from) the Work and for which the
43
+ editorial revisions, annotations, elaborations, or other modifications
44
+ represent, as a whole, an original work of authorship. For the purposes
45
+ of this License, Derivative Works shall not include works that remain
46
+ separable from, or merely link (or bind by name) to the interfaces of,
47
+ the Work and Derivative Works thereof.
48
+
49
+ "Contribution" shall mean any work of authorship, including
50
+ the original version of the Work and any modifications or additions
51
+ to that Work or Derivative Works thereof, that is intentionally
52
+ submitted to Licensor for inclusion in the Work by the copyright owner
53
+ or by an individual or Legal Entity authorized to submit on behalf of
54
+ the copyright owner. For the purposes of this definition, "submitted"
55
+ means any form of electronic, verbal, or written communication sent
56
+ to the Licensor or its representatives, including but not limited to
57
+ communication on electronic mailing lists, source code control systems,
58
+ and issue tracking systems that are managed by, or on behalf of, the
59
+ Licensor for the purpose of discussing and improving the Work, but
60
+ excluding communication that is conspicuously marked or otherwise
61
+ designated in writing by the copyright owner as "Not a Contribution."
62
+
63
+ "Contributor" shall mean Licensor and any individual or Legal Entity
64
+ on behalf of whom a Contribution has been received by Licensor and
65
+ subsequently incorporated within the Work.
66
+
67
+ 2. Grant of Copyright License. Subject to the terms and conditions of
68
+ this License, each Contributor hereby grants to You a perpetual,
69
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70
+ copyright license to reproduce, prepare Derivative Works of,
71
+ publicly display, publicly perform, sublicense, and distribute the
72
+ Work and such Derivative Works in Source or Object form.
73
+
74
+ 3. Grant of Patent License. Subject to the terms and conditions of
75
+ this License, each Contributor hereby grants to You a perpetual,
76
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77
+ (except as stated in this section) patent license to make, have made,
78
+ use, offer to sell, sell, import, and otherwise transfer the Work,
79
+ where such license applies only to those patent claims licensable
80
+ by such Contributor that are necessarily infringed by their
81
+ Contribution(s) alone or by combination of their Contribution(s)
82
+ with the Work to which such Contribution(s) was submitted. If You
83
+ institute patent litigation against any entity (including a
84
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
85
+ or a Contribution incorporated within the Work constitutes direct
86
+ or contributory patent infringement, then any patent licenses
87
+ granted to You under this License for that Work shall terminate
88
+ as of the date such litigation is filed.
89
+
90
+ 4. Redistribution. You may reproduce and distribute copies of the
91
+ Work or Derivative Works thereof in any medium, with or without
92
+ modifications, and in Source or Object form, provided that You
93
+ meet the following conditions:
94
+
95
+ (a) You must give any other recipients of the Work or
96
+ Derivative Works a copy of this License; and
97
+
98
+ (b) You must cause any modified files to carry prominent notices
99
+ stating that You changed the files; and
100
+
101
+ (c) You must retain, in the Source form of any Derivative Works
102
+ that You distribute, all copyright, patent, trademark, and
103
+ attribution notices from the Source form of the Work,
104
+ excluding those notices that do not pertain to any part of
105
+ the Derivative Works; and
106
+
107
+ (d) If the Work includes a "NOTICE" text file as part of its
108
+ distribution, then any Derivative Works that You distribute must
109
+ include a readable copy of the attribution notices contained
110
+ within such NOTICE file, excluding those notices that do not
111
+ pertain to any part of the Derivative Works, in at least one
112
+ of the following places: within a NOTICE text file distributed
113
+ as part of the Derivative Works; within the Source form or
114
+ documentation, if provided along with the Derivative Works; or,
115
+ within a display generated by the Derivative Works, if and
116
+ wherever such third-party notices normally appear. The contents
117
+ of the NOTICE file are for informational purposes only and
118
+ do not modify the License. You may add Your own attribution
119
+ notices within Derivative Works that You distribute, alongside
120
+ or as an addendum to the NOTICE text from the Work, provided
121
+ that such additional attribution notices cannot be construed
122
+ as modifying the License.
123
+
124
+ You may add Your own copyright statement to Your modifications and
125
+ may provide additional or different license terms and conditions
126
+ for use, reproduction, or distribution of Your modifications, or
127
+ for any such Derivative Works as a whole, provided Your use,
128
+ reproduction, and distribution of the Work otherwise complies with
129
+ the conditions stated in this License.
130
+
131
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
132
+ any Contribution intentionally submitted for inclusion in the Work
133
+ by You to the Licensor shall be under the terms and conditions of
134
+ this License, without any additional terms or conditions.
135
+ Notwithstanding the above, nothing herein shall supersede or modify
136
+ the terms of any separate license agreement you may have executed
137
+ with Licensor regarding such Contributions.
138
+
139
+ 6. Trademarks. This License does not grant permission to use the trade
140
+ names, trademarks, service marks, or product names of the Licensor,
141
+ except as required for reasonable and customary use in describing the
142
+ origin of the Work and reproducing the content of the NOTICE file.
143
+
144
+ 7. Disclaimer of Warranty. Unless required by applicable law or
145
+ agreed to in writing, Licensor provides the Work (and each
146
+ Contributor provides its Contributions) on an "AS IS" BASIS,
147
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148
+ implied, including, without limitation, any warranties or conditions
149
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150
+ PARTICULAR PURPOSE. You are solely responsible for determining the
151
+ appropriateness of using or redistributing the Work and assume any
152
+ risks associated with Your exercise of permissions under this License.
153
+
154
+ 8. Limitation of Liability. In no event and under no legal theory,
155
+ whether in tort (including negligence), contract, or otherwise,
156
+ unless required by applicable law (such as deliberate and grossly
157
+ negligent acts) or agreed to in writing, shall any Contributor be
158
+ liable to You for damages, including any direct, indirect, special,
159
+ incidental, or consequential damages of any character arising as a
160
+ result of this License or out of the use or inability to use the
161
+ Work (including but not limited to damages for loss of goodwill,
162
+ work stoppage, computer failure or malfunction, or any and all
163
+ other commercial damages or losses), even if such Contributor
164
+ has been advised of the possibility of such damages.
165
+
166
+ 9. Accepting Warranty or Additional Liability. While redistributing
167
+ the Work or Derivative Works thereof, You may choose to offer,
168
+ and charge a fee for, acceptance of support, warranty, indemnity,
169
+ or other liability obligations and/or rights consistent with this
170
+ License. However, in accepting such obligations, You may act only
171
+ on Your own behalf and on Your sole responsibility, not on behalf
172
+ of any other Contributor, and only if You agree to indemnify,
173
+ defend, and hold each Contributor harmless for any liability
174
+ incurred by, or claims asserted against, such Contributor by reason
175
+ of your accepting any such warranty or additional liability.
176
+
177
+ END OF TERMS AND CONDITIONS
178
+
179
+ APPENDIX: How to apply the Apache License to your work.
180
+
181
+ To apply the Apache License to your work, attach the following
182
+ boilerplate notice, with the fields enclosed by brackets "[]"
183
+ replaced with your own identifying information. (Don't include
184
+ the brackets!) The text should be enclosed in the appropriate
185
+ comment syntax for the file format. We also recommend that a
186
+ file or class name and description of purpose be included on the
187
+ same "printed page" as the copyright notice for easier
188
+ identification within third-party archives.
189
+
190
+ Copyright [yyyy] [name of copyright owner]
191
+
192
+ Licensed under the Apache License, Version 2.0 (the "License");
193
+ you may not use this file except in compliance with the License.
194
+ You may obtain a copy of the License at
195
+
196
+ http://www.apache.org/licenses/LICENSE-2.0
197
+
198
+ Unless required by applicable law or agreed to in writing, software
199
+ distributed under the License is distributed on an "AS IS" BASIS,
200
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201
+ See the License for the specific language governing permissions and
202
+ limitations under the License.
lib/python3.12/site-packages/fastapi/__pycache__/__init__.cpython-312.pyc ADDED
Binary file (1.1 kB). View file
 
lib/python3.12/site-packages/fastapi/__pycache__/__main__.cpython-312.pyc ADDED
Binary file (248 Bytes). View file
 
lib/python3.12/site-packages/fastapi/__pycache__/_compat.cpython-312.pyc ADDED
Binary file (27.9 kB). View file
 
lib/python3.12/site-packages/fastapi/__pycache__/applications.cpython-312.pyc ADDED
Binary file (84.1 kB). View file
 
lib/python3.12/site-packages/fastapi/__pycache__/background.cpython-312.pyc ADDED
Binary file (2.37 kB). View file
 
lib/python3.12/site-packages/fastapi/__pycache__/cli.cpython-312.pyc ADDED
Binary file (662 Bytes). View file
 
lib/python3.12/site-packages/fastapi/__pycache__/concurrency.cpython-312.pyc ADDED
Binary file (1.68 kB). View file
 
lib/python3.12/site-packages/fastapi/__pycache__/datastructures.cpython-312.pyc ADDED
Binary file (8.15 kB). View file
 
lib/python3.12/site-packages/fastapi/__pycache__/encoders.cpython-312.pyc ADDED
Binary file (10.9 kB). View file
 
lib/python3.12/site-packages/fastapi/__pycache__/exception_handlers.cpython-312.pyc ADDED
Binary file (2.08 kB). View file
 
lib/python3.12/site-packages/fastapi/__pycache__/exceptions.cpython-312.pyc ADDED
Binary file (7.16 kB). View file
 
lib/python3.12/site-packages/fastapi/__pycache__/logger.cpython-312.pyc ADDED
Binary file (288 Bytes). View file
 
lib/python3.12/site-packages/fastapi/__pycache__/params.cpython-312.pyc ADDED
Binary file (25 kB). View file
 
lib/python3.12/site-packages/fastapi/__pycache__/requests.cpython-312.pyc ADDED
Binary file (277 Bytes). View file
 
lib/python3.12/site-packages/fastapi/__pycache__/responses.cpython-312.pyc ADDED
Binary file (2.41 kB). View file
 
lib/python3.12/site-packages/fastapi/__pycache__/routing.cpython-312.pyc ADDED
Binary file (82 kB). View file
 
lib/python3.12/site-packages/fastapi/__pycache__/staticfiles.cpython-312.pyc ADDED
Binary file (249 Bytes). View file
 
lib/python3.12/site-packages/fastapi/__pycache__/templating.cpython-312.pyc ADDED
Binary file (251 Bytes). View file
 
lib/python3.12/site-packages/fastapi/__pycache__/testclient.cpython-312.pyc ADDED
Binary file (246 Bytes). View file
 
lib/python3.12/site-packages/fastapi/__pycache__/types.cpython-312.pyc ADDED
Binary file (757 Bytes). View file
 
lib/python3.12/site-packages/fastapi/__pycache__/utils.cpython-312.pyc ADDED
Binary file (8.38 kB). View file
 
lib/python3.12/site-packages/fastapi/__pycache__/websockets.cpython-312.pyc ADDED
Binary file (326 Bytes). View file
 
lib/python3.12/site-packages/fastapi/dependencies/__init__.py ADDED
File without changes
lib/python3.12/site-packages/fastapi/dependencies/__pycache__/__init__.cpython-312.pyc ADDED
Binary file (199 Bytes). View file
 
lib/python3.12/site-packages/fastapi/dependencies/__pycache__/models.cpython-312.pyc ADDED
Binary file (2.74 kB). View file
 
lib/python3.12/site-packages/fastapi/dependencies/__pycache__/utils.cpython-312.pyc ADDED
Binary file (38.1 kB). View file
 
lib/python3.12/site-packages/fastapi/dependencies/models.py ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from dataclasses import dataclass, field
2
+ from typing import Any, Callable, List, Optional, Sequence, Tuple
3
+
4
+ from fastapi._compat import ModelField
5
+ from fastapi.security.base import SecurityBase
6
+
7
+
8
+ @dataclass
9
+ class SecurityRequirement:
10
+ security_scheme: SecurityBase
11
+ scopes: Optional[Sequence[str]] = None
12
+
13
+
14
+ @dataclass
15
+ class Dependant:
16
+ path_params: List[ModelField] = field(default_factory=list)
17
+ query_params: List[ModelField] = field(default_factory=list)
18
+ header_params: List[ModelField] = field(default_factory=list)
19
+ cookie_params: List[ModelField] = field(default_factory=list)
20
+ body_params: List[ModelField] = field(default_factory=list)
21
+ dependencies: List["Dependant"] = field(default_factory=list)
22
+ security_requirements: List[SecurityRequirement] = field(default_factory=list)
23
+ name: Optional[str] = None
24
+ call: Optional[Callable[..., Any]] = None
25
+ request_param_name: Optional[str] = None
26
+ websocket_param_name: Optional[str] = None
27
+ http_connection_param_name: Optional[str] = None
28
+ response_param_name: Optional[str] = None
29
+ background_tasks_param_name: Optional[str] = None
30
+ security_scopes_param_name: Optional[str] = None
31
+ security_scopes: Optional[List[str]] = None
32
+ use_cache: bool = True
33
+ path: Optional[str] = None
34
+ cache_key: Tuple[Optional[Callable[..., Any]], Tuple[str, ...]] = field(init=False)
35
+
36
+ def __post_init__(self) -> None:
37
+ self.cache_key = (self.call, tuple(sorted(set(self.security_scopes or []))))
lib/python3.12/site-packages/fastapi/dependencies/utils.py ADDED
@@ -0,0 +1,980 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import inspect
2
+ from contextlib import AsyncExitStack, contextmanager
3
+ from copy import copy, deepcopy
4
+ from dataclasses import dataclass
5
+ from typing import (
6
+ Any,
7
+ Callable,
8
+ Coroutine,
9
+ Dict,
10
+ ForwardRef,
11
+ List,
12
+ Mapping,
13
+ Optional,
14
+ Sequence,
15
+ Tuple,
16
+ Type,
17
+ Union,
18
+ cast,
19
+ )
20
+
21
+ import anyio
22
+ from fastapi import params
23
+ from fastapi._compat import (
24
+ PYDANTIC_V2,
25
+ ErrorWrapper,
26
+ ModelField,
27
+ RequiredParam,
28
+ Undefined,
29
+ _regenerate_error_with_loc,
30
+ copy_field_info,
31
+ create_body_model,
32
+ evaluate_forwardref,
33
+ field_annotation_is_scalar,
34
+ get_annotation_from_field_info,
35
+ get_cached_model_fields,
36
+ get_missing_field_error,
37
+ is_bytes_field,
38
+ is_bytes_sequence_field,
39
+ is_scalar_field,
40
+ is_scalar_sequence_field,
41
+ is_sequence_field,
42
+ is_uploadfile_or_nonable_uploadfile_annotation,
43
+ is_uploadfile_sequence_annotation,
44
+ lenient_issubclass,
45
+ sequence_types,
46
+ serialize_sequence_value,
47
+ value_is_sequence,
48
+ )
49
+ from fastapi.background import BackgroundTasks
50
+ from fastapi.concurrency import (
51
+ asynccontextmanager,
52
+ contextmanager_in_threadpool,
53
+ )
54
+ from fastapi.dependencies.models import Dependant, SecurityRequirement
55
+ from fastapi.logger import logger
56
+ from fastapi.security.base import SecurityBase
57
+ from fastapi.security.oauth2 import OAuth2, SecurityScopes
58
+ from fastapi.security.open_id_connect_url import OpenIdConnect
59
+ from fastapi.utils import create_model_field, get_path_param_names
60
+ from pydantic import BaseModel
61
+ from pydantic.fields import FieldInfo
62
+ from starlette.background import BackgroundTasks as StarletteBackgroundTasks
63
+ from starlette.concurrency import run_in_threadpool
64
+ from starlette.datastructures import (
65
+ FormData,
66
+ Headers,
67
+ ImmutableMultiDict,
68
+ QueryParams,
69
+ UploadFile,
70
+ )
71
+ from starlette.requests import HTTPConnection, Request
72
+ from starlette.responses import Response
73
+ from starlette.websockets import WebSocket
74
+ from typing_extensions import Annotated, get_args, get_origin
75
+
76
+ multipart_not_installed_error = (
77
+ 'Form data requires "python-multipart" to be installed. \n'
78
+ 'You can install "python-multipart" with: \n\n'
79
+ "pip install python-multipart\n"
80
+ )
81
+ multipart_incorrect_install_error = (
82
+ 'Form data requires "python-multipart" to be installed. '
83
+ 'It seems you installed "multipart" instead. \n'
84
+ 'You can remove "multipart" with: \n\n'
85
+ "pip uninstall multipart\n\n"
86
+ 'And then install "python-multipart" with: \n\n'
87
+ "pip install python-multipart\n"
88
+ )
89
+
90
+
91
+ def ensure_multipart_is_installed() -> None:
92
+ try:
93
+ from python_multipart import __version__
94
+
95
+ # Import an attribute that can be mocked/deleted in testing
96
+ assert __version__ > "0.0.12"
97
+ except (ImportError, AssertionError):
98
+ try:
99
+ # __version__ is available in both multiparts, and can be mocked
100
+ from multipart import __version__ # type: ignore[no-redef,import-untyped]
101
+
102
+ assert __version__
103
+ try:
104
+ # parse_options_header is only available in the right multipart
105
+ from multipart.multipart import ( # type: ignore[import-untyped]
106
+ parse_options_header,
107
+ )
108
+
109
+ assert parse_options_header
110
+ except ImportError:
111
+ logger.error(multipart_incorrect_install_error)
112
+ raise RuntimeError(multipart_incorrect_install_error) from None
113
+ except ImportError:
114
+ logger.error(multipart_not_installed_error)
115
+ raise RuntimeError(multipart_not_installed_error) from None
116
+
117
+
118
+ def get_param_sub_dependant(
119
+ *,
120
+ param_name: str,
121
+ depends: params.Depends,
122
+ path: str,
123
+ security_scopes: Optional[List[str]] = None,
124
+ ) -> Dependant:
125
+ assert depends.dependency
126
+ return get_sub_dependant(
127
+ depends=depends,
128
+ dependency=depends.dependency,
129
+ path=path,
130
+ name=param_name,
131
+ security_scopes=security_scopes,
132
+ )
133
+
134
+
135
+ def get_parameterless_sub_dependant(*, depends: params.Depends, path: str) -> Dependant:
136
+ assert callable(depends.dependency), (
137
+ "A parameter-less dependency must have a callable dependency"
138
+ )
139
+ return get_sub_dependant(depends=depends, dependency=depends.dependency, path=path)
140
+
141
+
142
+ def get_sub_dependant(
143
+ *,
144
+ depends: params.Depends,
145
+ dependency: Callable[..., Any],
146
+ path: str,
147
+ name: Optional[str] = None,
148
+ security_scopes: Optional[List[str]] = None,
149
+ ) -> Dependant:
150
+ security_requirement = None
151
+ security_scopes = security_scopes or []
152
+ if isinstance(depends, params.Security):
153
+ dependency_scopes = depends.scopes
154
+ security_scopes.extend(dependency_scopes)
155
+ if isinstance(dependency, SecurityBase):
156
+ use_scopes: List[str] = []
157
+ if isinstance(dependency, (OAuth2, OpenIdConnect)):
158
+ use_scopes = security_scopes
159
+ security_requirement = SecurityRequirement(
160
+ security_scheme=dependency, scopes=use_scopes
161
+ )
162
+ sub_dependant = get_dependant(
163
+ path=path,
164
+ call=dependency,
165
+ name=name,
166
+ security_scopes=security_scopes,
167
+ use_cache=depends.use_cache,
168
+ )
169
+ if security_requirement:
170
+ sub_dependant.security_requirements.append(security_requirement)
171
+ return sub_dependant
172
+
173
+
174
+ CacheKey = Tuple[Optional[Callable[..., Any]], Tuple[str, ...]]
175
+
176
+
177
+ def get_flat_dependant(
178
+ dependant: Dependant,
179
+ *,
180
+ skip_repeats: bool = False,
181
+ visited: Optional[List[CacheKey]] = None,
182
+ ) -> Dependant:
183
+ if visited is None:
184
+ visited = []
185
+ visited.append(dependant.cache_key)
186
+
187
+ flat_dependant = Dependant(
188
+ path_params=dependant.path_params.copy(),
189
+ query_params=dependant.query_params.copy(),
190
+ header_params=dependant.header_params.copy(),
191
+ cookie_params=dependant.cookie_params.copy(),
192
+ body_params=dependant.body_params.copy(),
193
+ security_requirements=dependant.security_requirements.copy(),
194
+ use_cache=dependant.use_cache,
195
+ path=dependant.path,
196
+ )
197
+ for sub_dependant in dependant.dependencies:
198
+ if skip_repeats and sub_dependant.cache_key in visited:
199
+ continue
200
+ flat_sub = get_flat_dependant(
201
+ sub_dependant, skip_repeats=skip_repeats, visited=visited
202
+ )
203
+ flat_dependant.path_params.extend(flat_sub.path_params)
204
+ flat_dependant.query_params.extend(flat_sub.query_params)
205
+ flat_dependant.header_params.extend(flat_sub.header_params)
206
+ flat_dependant.cookie_params.extend(flat_sub.cookie_params)
207
+ flat_dependant.body_params.extend(flat_sub.body_params)
208
+ flat_dependant.security_requirements.extend(flat_sub.security_requirements)
209
+ return flat_dependant
210
+
211
+
212
+ def _get_flat_fields_from_params(fields: List[ModelField]) -> List[ModelField]:
213
+ if not fields:
214
+ return fields
215
+ first_field = fields[0]
216
+ if len(fields) == 1 and lenient_issubclass(first_field.type_, BaseModel):
217
+ fields_to_extract = get_cached_model_fields(first_field.type_)
218
+ return fields_to_extract
219
+ return fields
220
+
221
+
222
+ def get_flat_params(dependant: Dependant) -> List[ModelField]:
223
+ flat_dependant = get_flat_dependant(dependant, skip_repeats=True)
224
+ path_params = _get_flat_fields_from_params(flat_dependant.path_params)
225
+ query_params = _get_flat_fields_from_params(flat_dependant.query_params)
226
+ header_params = _get_flat_fields_from_params(flat_dependant.header_params)
227
+ cookie_params = _get_flat_fields_from_params(flat_dependant.cookie_params)
228
+ return path_params + query_params + header_params + cookie_params
229
+
230
+
231
+ def get_typed_signature(call: Callable[..., Any]) -> inspect.Signature:
232
+ signature = inspect.signature(call)
233
+ globalns = getattr(call, "__globals__", {})
234
+ typed_params = [
235
+ inspect.Parameter(
236
+ name=param.name,
237
+ kind=param.kind,
238
+ default=param.default,
239
+ annotation=get_typed_annotation(param.annotation, globalns),
240
+ )
241
+ for param in signature.parameters.values()
242
+ ]
243
+ typed_signature = inspect.Signature(typed_params)
244
+ return typed_signature
245
+
246
+
247
+ def get_typed_annotation(annotation: Any, globalns: Dict[str, Any]) -> Any:
248
+ if isinstance(annotation, str):
249
+ annotation = ForwardRef(annotation)
250
+ annotation = evaluate_forwardref(annotation, globalns, globalns)
251
+ return annotation
252
+
253
+
254
+ def get_typed_return_annotation(call: Callable[..., Any]) -> Any:
255
+ signature = inspect.signature(call)
256
+ annotation = signature.return_annotation
257
+
258
+ if annotation is inspect.Signature.empty:
259
+ return None
260
+
261
+ globalns = getattr(call, "__globals__", {})
262
+ return get_typed_annotation(annotation, globalns)
263
+
264
+
265
+ def get_dependant(
266
+ *,
267
+ path: str,
268
+ call: Callable[..., Any],
269
+ name: Optional[str] = None,
270
+ security_scopes: Optional[List[str]] = None,
271
+ use_cache: bool = True,
272
+ ) -> Dependant:
273
+ path_param_names = get_path_param_names(path)
274
+ endpoint_signature = get_typed_signature(call)
275
+ signature_params = endpoint_signature.parameters
276
+ dependant = Dependant(
277
+ call=call,
278
+ name=name,
279
+ path=path,
280
+ security_scopes=security_scopes,
281
+ use_cache=use_cache,
282
+ )
283
+ for param_name, param in signature_params.items():
284
+ is_path_param = param_name in path_param_names
285
+ param_details = analyze_param(
286
+ param_name=param_name,
287
+ annotation=param.annotation,
288
+ value=param.default,
289
+ is_path_param=is_path_param,
290
+ )
291
+ if param_details.depends is not None:
292
+ sub_dependant = get_param_sub_dependant(
293
+ param_name=param_name,
294
+ depends=param_details.depends,
295
+ path=path,
296
+ security_scopes=security_scopes,
297
+ )
298
+ dependant.dependencies.append(sub_dependant)
299
+ continue
300
+ if add_non_field_param_to_dependency(
301
+ param_name=param_name,
302
+ type_annotation=param_details.type_annotation,
303
+ dependant=dependant,
304
+ ):
305
+ assert param_details.field is None, (
306
+ f"Cannot specify multiple FastAPI annotations for {param_name!r}"
307
+ )
308
+ continue
309
+ assert param_details.field is not None
310
+ if isinstance(param_details.field.field_info, params.Body):
311
+ dependant.body_params.append(param_details.field)
312
+ else:
313
+ add_param_to_fields(field=param_details.field, dependant=dependant)
314
+ return dependant
315
+
316
+
317
+ def add_non_field_param_to_dependency(
318
+ *, param_name: str, type_annotation: Any, dependant: Dependant
319
+ ) -> Optional[bool]:
320
+ if lenient_issubclass(type_annotation, Request):
321
+ dependant.request_param_name = param_name
322
+ return True
323
+ elif lenient_issubclass(type_annotation, WebSocket):
324
+ dependant.websocket_param_name = param_name
325
+ return True
326
+ elif lenient_issubclass(type_annotation, HTTPConnection):
327
+ dependant.http_connection_param_name = param_name
328
+ return True
329
+ elif lenient_issubclass(type_annotation, Response):
330
+ dependant.response_param_name = param_name
331
+ return True
332
+ elif lenient_issubclass(type_annotation, StarletteBackgroundTasks):
333
+ dependant.background_tasks_param_name = param_name
334
+ return True
335
+ elif lenient_issubclass(type_annotation, SecurityScopes):
336
+ dependant.security_scopes_param_name = param_name
337
+ return True
338
+ return None
339
+
340
+
341
+ @dataclass
342
+ class ParamDetails:
343
+ type_annotation: Any
344
+ depends: Optional[params.Depends]
345
+ field: Optional[ModelField]
346
+
347
+
348
+ def analyze_param(
349
+ *,
350
+ param_name: str,
351
+ annotation: Any,
352
+ value: Any,
353
+ is_path_param: bool,
354
+ ) -> ParamDetails:
355
+ field_info = None
356
+ depends = None
357
+ type_annotation: Any = Any
358
+ use_annotation: Any = Any
359
+ if annotation is not inspect.Signature.empty:
360
+ use_annotation = annotation
361
+ type_annotation = annotation
362
+ # Extract Annotated info
363
+ if get_origin(use_annotation) is Annotated:
364
+ annotated_args = get_args(annotation)
365
+ type_annotation = annotated_args[0]
366
+ fastapi_annotations = [
367
+ arg
368
+ for arg in annotated_args[1:]
369
+ if isinstance(arg, (FieldInfo, params.Depends))
370
+ ]
371
+ fastapi_specific_annotations = [
372
+ arg
373
+ for arg in fastapi_annotations
374
+ if isinstance(arg, (params.Param, params.Body, params.Depends))
375
+ ]
376
+ if fastapi_specific_annotations:
377
+ fastapi_annotation: Union[FieldInfo, params.Depends, None] = (
378
+ fastapi_specific_annotations[-1]
379
+ )
380
+ else:
381
+ fastapi_annotation = None
382
+ # Set default for Annotated FieldInfo
383
+ if isinstance(fastapi_annotation, FieldInfo):
384
+ # Copy `field_info` because we mutate `field_info.default` below.
385
+ field_info = copy_field_info(
386
+ field_info=fastapi_annotation, annotation=use_annotation
387
+ )
388
+ assert (
389
+ field_info.default is Undefined or field_info.default is RequiredParam
390
+ ), (
391
+ f"`{field_info.__class__.__name__}` default value cannot be set in"
392
+ f" `Annotated` for {param_name!r}. Set the default value with `=` instead."
393
+ )
394
+ if value is not inspect.Signature.empty:
395
+ assert not is_path_param, "Path parameters cannot have default values"
396
+ field_info.default = value
397
+ else:
398
+ field_info.default = RequiredParam
399
+ # Get Annotated Depends
400
+ elif isinstance(fastapi_annotation, params.Depends):
401
+ depends = fastapi_annotation
402
+ # Get Depends from default value
403
+ if isinstance(value, params.Depends):
404
+ assert depends is None, (
405
+ "Cannot specify `Depends` in `Annotated` and default value"
406
+ f" together for {param_name!r}"
407
+ )
408
+ assert field_info is None, (
409
+ "Cannot specify a FastAPI annotation in `Annotated` and `Depends` as a"
410
+ f" default value together for {param_name!r}"
411
+ )
412
+ depends = value
413
+ # Get FieldInfo from default value
414
+ elif isinstance(value, FieldInfo):
415
+ assert field_info is None, (
416
+ "Cannot specify FastAPI annotations in `Annotated` and default value"
417
+ f" together for {param_name!r}"
418
+ )
419
+ field_info = value
420
+ if PYDANTIC_V2:
421
+ field_info.annotation = type_annotation
422
+
423
+ # Get Depends from type annotation
424
+ if depends is not None and depends.dependency is None:
425
+ # Copy `depends` before mutating it
426
+ depends = copy(depends)
427
+ depends.dependency = type_annotation
428
+
429
+ # Handle non-param type annotations like Request
430
+ if lenient_issubclass(
431
+ type_annotation,
432
+ (
433
+ Request,
434
+ WebSocket,
435
+ HTTPConnection,
436
+ Response,
437
+ StarletteBackgroundTasks,
438
+ SecurityScopes,
439
+ ),
440
+ ):
441
+ assert depends is None, f"Cannot specify `Depends` for type {type_annotation!r}"
442
+ assert field_info is None, (
443
+ f"Cannot specify FastAPI annotation for type {type_annotation!r}"
444
+ )
445
+ # Handle default assignations, neither field_info nor depends was not found in Annotated nor default value
446
+ elif field_info is None and depends is None:
447
+ default_value = value if value is not inspect.Signature.empty else RequiredParam
448
+ if is_path_param:
449
+ # We might check here that `default_value is RequiredParam`, but the fact is that the same
450
+ # parameter might sometimes be a path parameter and sometimes not. See
451
+ # `tests/test_infer_param_optionality.py` for an example.
452
+ field_info = params.Path(annotation=use_annotation)
453
+ elif is_uploadfile_or_nonable_uploadfile_annotation(
454
+ type_annotation
455
+ ) or is_uploadfile_sequence_annotation(type_annotation):
456
+ field_info = params.File(annotation=use_annotation, default=default_value)
457
+ elif not field_annotation_is_scalar(annotation=type_annotation):
458
+ field_info = params.Body(annotation=use_annotation, default=default_value)
459
+ else:
460
+ field_info = params.Query(annotation=use_annotation, default=default_value)
461
+
462
+ field = None
463
+ # It's a field_info, not a dependency
464
+ if field_info is not None:
465
+ # Handle field_info.in_
466
+ if is_path_param:
467
+ assert isinstance(field_info, params.Path), (
468
+ f"Cannot use `{field_info.__class__.__name__}` for path param"
469
+ f" {param_name!r}"
470
+ )
471
+ elif (
472
+ isinstance(field_info, params.Param)
473
+ and getattr(field_info, "in_", None) is None
474
+ ):
475
+ field_info.in_ = params.ParamTypes.query
476
+ use_annotation_from_field_info = get_annotation_from_field_info(
477
+ use_annotation,
478
+ field_info,
479
+ param_name,
480
+ )
481
+ if isinstance(field_info, params.Form):
482
+ ensure_multipart_is_installed()
483
+ if not field_info.alias and getattr(field_info, "convert_underscores", None):
484
+ alias = param_name.replace("_", "-")
485
+ else:
486
+ alias = field_info.alias or param_name
487
+ field_info.alias = alias
488
+ field = create_model_field(
489
+ name=param_name,
490
+ type_=use_annotation_from_field_info,
491
+ default=field_info.default,
492
+ alias=alias,
493
+ required=field_info.default in (RequiredParam, Undefined),
494
+ field_info=field_info,
495
+ )
496
+ if is_path_param:
497
+ assert is_scalar_field(field=field), (
498
+ "Path params must be of one of the supported types"
499
+ )
500
+ elif isinstance(field_info, params.Query):
501
+ assert (
502
+ is_scalar_field(field)
503
+ or is_scalar_sequence_field(field)
504
+ or (
505
+ lenient_issubclass(field.type_, BaseModel)
506
+ # For Pydantic v1
507
+ and getattr(field, "shape", 1) == 1
508
+ )
509
+ )
510
+
511
+ return ParamDetails(type_annotation=type_annotation, depends=depends, field=field)
512
+
513
+
514
+ def add_param_to_fields(*, field: ModelField, dependant: Dependant) -> None:
515
+ field_info = field.field_info
516
+ field_info_in = getattr(field_info, "in_", None)
517
+ if field_info_in == params.ParamTypes.path:
518
+ dependant.path_params.append(field)
519
+ elif field_info_in == params.ParamTypes.query:
520
+ dependant.query_params.append(field)
521
+ elif field_info_in == params.ParamTypes.header:
522
+ dependant.header_params.append(field)
523
+ else:
524
+ assert field_info_in == params.ParamTypes.cookie, (
525
+ f"non-body parameters must be in path, query, header or cookie: {field.name}"
526
+ )
527
+ dependant.cookie_params.append(field)
528
+
529
+
530
+ def is_coroutine_callable(call: Callable[..., Any]) -> bool:
531
+ if inspect.isroutine(call):
532
+ return inspect.iscoroutinefunction(call)
533
+ if inspect.isclass(call):
534
+ return False
535
+ dunder_call = getattr(call, "__call__", None) # noqa: B004
536
+ return inspect.iscoroutinefunction(dunder_call)
537
+
538
+
539
+ def is_async_gen_callable(call: Callable[..., Any]) -> bool:
540
+ if inspect.isasyncgenfunction(call):
541
+ return True
542
+ dunder_call = getattr(call, "__call__", None) # noqa: B004
543
+ return inspect.isasyncgenfunction(dunder_call)
544
+
545
+
546
+ def is_gen_callable(call: Callable[..., Any]) -> bool:
547
+ if inspect.isgeneratorfunction(call):
548
+ return True
549
+ dunder_call = getattr(call, "__call__", None) # noqa: B004
550
+ return inspect.isgeneratorfunction(dunder_call)
551
+
552
+
553
+ async def solve_generator(
554
+ *, call: Callable[..., Any], stack: AsyncExitStack, sub_values: Dict[str, Any]
555
+ ) -> Any:
556
+ if is_gen_callable(call):
557
+ cm = contextmanager_in_threadpool(contextmanager(call)(**sub_values))
558
+ elif is_async_gen_callable(call):
559
+ cm = asynccontextmanager(call)(**sub_values)
560
+ return await stack.enter_async_context(cm)
561
+
562
+
563
+ @dataclass
564
+ class SolvedDependency:
565
+ values: Dict[str, Any]
566
+ errors: List[Any]
567
+ background_tasks: Optional[StarletteBackgroundTasks]
568
+ response: Response
569
+ dependency_cache: Dict[Tuple[Callable[..., Any], Tuple[str]], Any]
570
+
571
+
572
+ async def solve_dependencies(
573
+ *,
574
+ request: Union[Request, WebSocket],
575
+ dependant: Dependant,
576
+ body: Optional[Union[Dict[str, Any], FormData]] = None,
577
+ background_tasks: Optional[StarletteBackgroundTasks] = None,
578
+ response: Optional[Response] = None,
579
+ dependency_overrides_provider: Optional[Any] = None,
580
+ dependency_cache: Optional[Dict[Tuple[Callable[..., Any], Tuple[str]], Any]] = None,
581
+ async_exit_stack: AsyncExitStack,
582
+ embed_body_fields: bool,
583
+ ) -> SolvedDependency:
584
+ values: Dict[str, Any] = {}
585
+ errors: List[Any] = []
586
+ if response is None:
587
+ response = Response()
588
+ del response.headers["content-length"]
589
+ response.status_code = None # type: ignore
590
+ dependency_cache = dependency_cache or {}
591
+ sub_dependant: Dependant
592
+ for sub_dependant in dependant.dependencies:
593
+ sub_dependant.call = cast(Callable[..., Any], sub_dependant.call)
594
+ sub_dependant.cache_key = cast(
595
+ Tuple[Callable[..., Any], Tuple[str]], sub_dependant.cache_key
596
+ )
597
+ call = sub_dependant.call
598
+ use_sub_dependant = sub_dependant
599
+ if (
600
+ dependency_overrides_provider
601
+ and dependency_overrides_provider.dependency_overrides
602
+ ):
603
+ original_call = sub_dependant.call
604
+ call = getattr(
605
+ dependency_overrides_provider, "dependency_overrides", {}
606
+ ).get(original_call, original_call)
607
+ use_path: str = sub_dependant.path # type: ignore
608
+ use_sub_dependant = get_dependant(
609
+ path=use_path,
610
+ call=call,
611
+ name=sub_dependant.name,
612
+ security_scopes=sub_dependant.security_scopes,
613
+ )
614
+
615
+ solved_result = await solve_dependencies(
616
+ request=request,
617
+ dependant=use_sub_dependant,
618
+ body=body,
619
+ background_tasks=background_tasks,
620
+ response=response,
621
+ dependency_overrides_provider=dependency_overrides_provider,
622
+ dependency_cache=dependency_cache,
623
+ async_exit_stack=async_exit_stack,
624
+ embed_body_fields=embed_body_fields,
625
+ )
626
+ background_tasks = solved_result.background_tasks
627
+ dependency_cache.update(solved_result.dependency_cache)
628
+ if solved_result.errors:
629
+ errors.extend(solved_result.errors)
630
+ continue
631
+ if sub_dependant.use_cache and sub_dependant.cache_key in dependency_cache:
632
+ solved = dependency_cache[sub_dependant.cache_key]
633
+ elif is_gen_callable(call) or is_async_gen_callable(call):
634
+ solved = await solve_generator(
635
+ call=call, stack=async_exit_stack, sub_values=solved_result.values
636
+ )
637
+ elif is_coroutine_callable(call):
638
+ solved = await call(**solved_result.values)
639
+ else:
640
+ solved = await run_in_threadpool(call, **solved_result.values)
641
+ if sub_dependant.name is not None:
642
+ values[sub_dependant.name] = solved
643
+ if sub_dependant.cache_key not in dependency_cache:
644
+ dependency_cache[sub_dependant.cache_key] = solved
645
+ path_values, path_errors = request_params_to_args(
646
+ dependant.path_params, request.path_params
647
+ )
648
+ query_values, query_errors = request_params_to_args(
649
+ dependant.query_params, request.query_params
650
+ )
651
+ header_values, header_errors = request_params_to_args(
652
+ dependant.header_params, request.headers
653
+ )
654
+ cookie_values, cookie_errors = request_params_to_args(
655
+ dependant.cookie_params, request.cookies
656
+ )
657
+ values.update(path_values)
658
+ values.update(query_values)
659
+ values.update(header_values)
660
+ values.update(cookie_values)
661
+ errors += path_errors + query_errors + header_errors + cookie_errors
662
+ if dependant.body_params:
663
+ (
664
+ body_values,
665
+ body_errors,
666
+ ) = await request_body_to_args( # body_params checked above
667
+ body_fields=dependant.body_params,
668
+ received_body=body,
669
+ embed_body_fields=embed_body_fields,
670
+ )
671
+ values.update(body_values)
672
+ errors.extend(body_errors)
673
+ if dependant.http_connection_param_name:
674
+ values[dependant.http_connection_param_name] = request
675
+ if dependant.request_param_name and isinstance(request, Request):
676
+ values[dependant.request_param_name] = request
677
+ elif dependant.websocket_param_name and isinstance(request, WebSocket):
678
+ values[dependant.websocket_param_name] = request
679
+ if dependant.background_tasks_param_name:
680
+ if background_tasks is None:
681
+ background_tasks = BackgroundTasks()
682
+ values[dependant.background_tasks_param_name] = background_tasks
683
+ if dependant.response_param_name:
684
+ values[dependant.response_param_name] = response
685
+ if dependant.security_scopes_param_name:
686
+ values[dependant.security_scopes_param_name] = SecurityScopes(
687
+ scopes=dependant.security_scopes
688
+ )
689
+ return SolvedDependency(
690
+ values=values,
691
+ errors=errors,
692
+ background_tasks=background_tasks,
693
+ response=response,
694
+ dependency_cache=dependency_cache,
695
+ )
696
+
697
+
698
+ def _validate_value_with_model_field(
699
+ *, field: ModelField, value: Any, values: Dict[str, Any], loc: Tuple[str, ...]
700
+ ) -> Tuple[Any, List[Any]]:
701
+ if value is None:
702
+ if field.required:
703
+ return None, [get_missing_field_error(loc=loc)]
704
+ else:
705
+ return deepcopy(field.default), []
706
+ v_, errors_ = field.validate(value, values, loc=loc)
707
+ if isinstance(errors_, ErrorWrapper):
708
+ return None, [errors_]
709
+ elif isinstance(errors_, list):
710
+ new_errors = _regenerate_error_with_loc(errors=errors_, loc_prefix=())
711
+ return None, new_errors
712
+ else:
713
+ return v_, []
714
+
715
+
716
+ def _get_multidict_value(
717
+ field: ModelField, values: Mapping[str, Any], alias: Union[str, None] = None
718
+ ) -> Any:
719
+ alias = alias or field.alias
720
+ if is_sequence_field(field) and isinstance(values, (ImmutableMultiDict, Headers)):
721
+ value = values.getlist(alias)
722
+ else:
723
+ value = values.get(alias, None)
724
+ if (
725
+ value is None
726
+ or (
727
+ isinstance(field.field_info, params.Form)
728
+ and isinstance(value, str) # For type checks
729
+ and value == ""
730
+ )
731
+ or (is_sequence_field(field) and len(value) == 0)
732
+ ):
733
+ if field.required:
734
+ return
735
+ else:
736
+ return deepcopy(field.default)
737
+ return value
738
+
739
+
740
+ def request_params_to_args(
741
+ fields: Sequence[ModelField],
742
+ received_params: Union[Mapping[str, Any], QueryParams, Headers],
743
+ ) -> Tuple[Dict[str, Any], List[Any]]:
744
+ values: Dict[str, Any] = {}
745
+ errors: List[Dict[str, Any]] = []
746
+
747
+ if not fields:
748
+ return values, errors
749
+
750
+ first_field = fields[0]
751
+ fields_to_extract = fields
752
+ single_not_embedded_field = False
753
+ default_convert_underscores = True
754
+ if len(fields) == 1 and lenient_issubclass(first_field.type_, BaseModel):
755
+ fields_to_extract = get_cached_model_fields(first_field.type_)
756
+ single_not_embedded_field = True
757
+ # If headers are in a Pydantic model, the way to disable convert_underscores
758
+ # would be with Header(convert_underscores=False) at the Pydantic model level
759
+ default_convert_underscores = getattr(
760
+ first_field.field_info, "convert_underscores", True
761
+ )
762
+
763
+ params_to_process: Dict[str, Any] = {}
764
+
765
+ processed_keys = set()
766
+
767
+ for field in fields_to_extract:
768
+ alias = None
769
+ if isinstance(received_params, Headers):
770
+ # Handle fields extracted from a Pydantic Model for a header, each field
771
+ # doesn't have a FieldInfo of type Header with the default convert_underscores=True
772
+ convert_underscores = getattr(
773
+ field.field_info, "convert_underscores", default_convert_underscores
774
+ )
775
+ if convert_underscores:
776
+ alias = (
777
+ field.alias
778
+ if field.alias != field.name
779
+ else field.name.replace("_", "-")
780
+ )
781
+ value = _get_multidict_value(field, received_params, alias=alias)
782
+ if value is not None:
783
+ params_to_process[field.name] = value
784
+ processed_keys.add(alias or field.alias)
785
+ processed_keys.add(field.name)
786
+
787
+ for key, value in received_params.items():
788
+ if key not in processed_keys:
789
+ params_to_process[key] = value
790
+
791
+ if single_not_embedded_field:
792
+ field_info = first_field.field_info
793
+ assert isinstance(field_info, params.Param), (
794
+ "Params must be subclasses of Param"
795
+ )
796
+ loc: Tuple[str, ...] = (field_info.in_.value,)
797
+ v_, errors_ = _validate_value_with_model_field(
798
+ field=first_field, value=params_to_process, values=values, loc=loc
799
+ )
800
+ return {first_field.name: v_}, errors_
801
+
802
+ for field in fields:
803
+ value = _get_multidict_value(field, received_params)
804
+ field_info = field.field_info
805
+ assert isinstance(field_info, params.Param), (
806
+ "Params must be subclasses of Param"
807
+ )
808
+ loc = (field_info.in_.value, field.alias)
809
+ v_, errors_ = _validate_value_with_model_field(
810
+ field=field, value=value, values=values, loc=loc
811
+ )
812
+ if errors_:
813
+ errors.extend(errors_)
814
+ else:
815
+ values[field.name] = v_
816
+ return values, errors
817
+
818
+
819
+ def _should_embed_body_fields(fields: List[ModelField]) -> bool:
820
+ if not fields:
821
+ return False
822
+ # More than one dependency could have the same field, it would show up as multiple
823
+ # fields but it's the same one, so count them by name
824
+ body_param_names_set = {field.name for field in fields}
825
+ # A top level field has to be a single field, not multiple
826
+ if len(body_param_names_set) > 1:
827
+ return True
828
+ first_field = fields[0]
829
+ # If it explicitly specifies it is embedded, it has to be embedded
830
+ if getattr(first_field.field_info, "embed", None):
831
+ return True
832
+ # If it's a Form (or File) field, it has to be a BaseModel to be top level
833
+ # otherwise it has to be embedded, so that the key value pair can be extracted
834
+ if isinstance(first_field.field_info, params.Form) and not lenient_issubclass(
835
+ first_field.type_, BaseModel
836
+ ):
837
+ return True
838
+ return False
839
+
840
+
841
+ async def _extract_form_body(
842
+ body_fields: List[ModelField],
843
+ received_body: FormData,
844
+ ) -> Dict[str, Any]:
845
+ values = {}
846
+ first_field = body_fields[0]
847
+ first_field_info = first_field.field_info
848
+
849
+ for field in body_fields:
850
+ value = _get_multidict_value(field, received_body)
851
+ if (
852
+ isinstance(first_field_info, params.File)
853
+ and is_bytes_field(field)
854
+ and isinstance(value, UploadFile)
855
+ ):
856
+ value = await value.read()
857
+ elif (
858
+ is_bytes_sequence_field(field)
859
+ and isinstance(first_field_info, params.File)
860
+ and value_is_sequence(value)
861
+ ):
862
+ # For types
863
+ assert isinstance(value, sequence_types) # type: ignore[arg-type]
864
+ results: List[Union[bytes, str]] = []
865
+
866
+ async def process_fn(
867
+ fn: Callable[[], Coroutine[Any, Any, Any]],
868
+ ) -> None:
869
+ result = await fn()
870
+ results.append(result) # noqa: B023
871
+
872
+ async with anyio.create_task_group() as tg:
873
+ for sub_value in value:
874
+ tg.start_soon(process_fn, sub_value.read)
875
+ value = serialize_sequence_value(field=field, value=results)
876
+ if value is not None:
877
+ values[field.alias] = value
878
+ for key, value in received_body.items():
879
+ if key not in values:
880
+ values[key] = value
881
+ return values
882
+
883
+
884
+ async def request_body_to_args(
885
+ body_fields: List[ModelField],
886
+ received_body: Optional[Union[Dict[str, Any], FormData]],
887
+ embed_body_fields: bool,
888
+ ) -> Tuple[Dict[str, Any], List[Dict[str, Any]]]:
889
+ values: Dict[str, Any] = {}
890
+ errors: List[Dict[str, Any]] = []
891
+ assert body_fields, "request_body_to_args() should be called with fields"
892
+ single_not_embedded_field = len(body_fields) == 1 and not embed_body_fields
893
+ first_field = body_fields[0]
894
+ body_to_process = received_body
895
+
896
+ fields_to_extract: List[ModelField] = body_fields
897
+
898
+ if single_not_embedded_field and lenient_issubclass(first_field.type_, BaseModel):
899
+ fields_to_extract = get_cached_model_fields(first_field.type_)
900
+
901
+ if isinstance(received_body, FormData):
902
+ body_to_process = await _extract_form_body(fields_to_extract, received_body)
903
+
904
+ if single_not_embedded_field:
905
+ loc: Tuple[str, ...] = ("body",)
906
+ v_, errors_ = _validate_value_with_model_field(
907
+ field=first_field, value=body_to_process, values=values, loc=loc
908
+ )
909
+ return {first_field.name: v_}, errors_
910
+ for field in body_fields:
911
+ loc = ("body", field.alias)
912
+ value: Optional[Any] = None
913
+ if body_to_process is not None:
914
+ try:
915
+ value = body_to_process.get(field.alias)
916
+ # If the received body is a list, not a dict
917
+ except AttributeError:
918
+ errors.append(get_missing_field_error(loc))
919
+ continue
920
+ v_, errors_ = _validate_value_with_model_field(
921
+ field=field, value=value, values=values, loc=loc
922
+ )
923
+ if errors_:
924
+ errors.extend(errors_)
925
+ else:
926
+ values[field.name] = v_
927
+ return values, errors
928
+
929
+
930
+ def get_body_field(
931
+ *, flat_dependant: Dependant, name: str, embed_body_fields: bool
932
+ ) -> Optional[ModelField]:
933
+ """
934
+ Get a ModelField representing the request body for a path operation, combining
935
+ all body parameters into a single field if necessary.
936
+
937
+ Used to check if it's form data (with `isinstance(body_field, params.Form)`)
938
+ or JSON and to generate the JSON Schema for a request body.
939
+
940
+ This is **not** used to validate/parse the request body, that's done with each
941
+ individual body parameter.
942
+ """
943
+ if not flat_dependant.body_params:
944
+ return None
945
+ first_param = flat_dependant.body_params[0]
946
+ if not embed_body_fields:
947
+ return first_param
948
+ model_name = "Body_" + name
949
+ BodyModel = create_body_model(
950
+ fields=flat_dependant.body_params, model_name=model_name
951
+ )
952
+ required = any(True for f in flat_dependant.body_params if f.required)
953
+ BodyFieldInfo_kwargs: Dict[str, Any] = {
954
+ "annotation": BodyModel,
955
+ "alias": "body",
956
+ }
957
+ if not required:
958
+ BodyFieldInfo_kwargs["default"] = None
959
+ if any(isinstance(f.field_info, params.File) for f in flat_dependant.body_params):
960
+ BodyFieldInfo: Type[params.Body] = params.File
961
+ elif any(isinstance(f.field_info, params.Form) for f in flat_dependant.body_params):
962
+ BodyFieldInfo = params.Form
963
+ else:
964
+ BodyFieldInfo = params.Body
965
+
966
+ body_param_media_types = [
967
+ f.field_info.media_type
968
+ for f in flat_dependant.body_params
969
+ if isinstance(f.field_info, params.Body)
970
+ ]
971
+ if len(set(body_param_media_types)) == 1:
972
+ BodyFieldInfo_kwargs["media_type"] = body_param_media_types[0]
973
+ final_field = create_model_field(
974
+ name="body",
975
+ type_=BodyModel,
976
+ required=required,
977
+ alias="body",
978
+ field_info=BodyFieldInfo(**BodyFieldInfo_kwargs),
979
+ )
980
+ return final_field
lib/python3.12/site-packages/fastapi/middleware/__init__.py ADDED
@@ -0,0 +1 @@
 
 
1
+ from starlette.middleware import Middleware as Middleware
lib/python3.12/site-packages/fastapi/middleware/__pycache__/__init__.cpython-312.pyc ADDED
Binary file (255 Bytes). View file
 
lib/python3.12/site-packages/fastapi/middleware/__pycache__/cors.cpython-312.pyc ADDED
Binary file (260 Bytes). View file
 
lib/python3.12/site-packages/fastapi/middleware/__pycache__/gzip.cpython-312.pyc ADDED
Binary file (260 Bytes). View file
 
lib/python3.12/site-packages/fastapi/middleware/__pycache__/httpsredirect.cpython-312.pyc ADDED
Binary file (289 Bytes). View file
 
lib/python3.12/site-packages/fastapi/middleware/__pycache__/trustedhost.cpython-312.pyc ADDED
Binary file (283 Bytes). View file
 
lib/python3.12/site-packages/fastapi/middleware/__pycache__/wsgi.cpython-312.pyc ADDED
Binary file (260 Bytes). View file
 
lib/python3.12/site-packages/fastapi/middleware/cors.py ADDED
@@ -0,0 +1 @@
 
 
1
+ from starlette.middleware.cors import CORSMiddleware as CORSMiddleware # noqa
lib/python3.12/site-packages/fastapi/middleware/gzip.py ADDED
@@ -0,0 +1 @@
 
 
1
+ from starlette.middleware.gzip import GZipMiddleware as GZipMiddleware # noqa
lib/python3.12/site-packages/fastapi/middleware/httpsredirect.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ from starlette.middleware.httpsredirect import ( # noqa
2
+ HTTPSRedirectMiddleware as HTTPSRedirectMiddleware,
3
+ )
lib/python3.12/site-packages/fastapi/middleware/trustedhost.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ from starlette.middleware.trustedhost import ( # noqa
2
+ TrustedHostMiddleware as TrustedHostMiddleware,
3
+ )
lib/python3.12/site-packages/fastapi/middleware/wsgi.py ADDED
@@ -0,0 +1 @@
 
 
1
+ from starlette.middleware.wsgi import WSGIMiddleware as WSGIMiddleware # noqa
lib/python3.12/site-packages/git/__pycache__/__init__.cpython-312.pyc ADDED
Binary file (6.12 kB). View file
 
lib/python3.12/site-packages/git/__pycache__/cmd.cpython-312.pyc ADDED
Binary file (63.8 kB). View file
 
lib/python3.12/site-packages/git/__pycache__/compat.cpython-312.pyc ADDED
Binary file (4.46 kB). View file
 
lib/python3.12/site-packages/git/__pycache__/config.cpython-312.pyc ADDED
Binary file (40.7 kB). View file