IMAGE TO KIMI TO LISTING CLIP
-纯 Listing 组货检索
-图片交给 Kimi 生成 10 个可组货商品检索词,再用纯 listing CLIP 索引召回;下方文本框单独用于直接检索 CLIP。
-diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 7381d4113f617434a5bd306544cb3b86dd1d02ad..0000000000000000000000000000000000000000 --- a/.gitignore +++ /dev/null @@ -1,27 +0,0 @@ -cache/ -web/cache.json -node_modules/ -cloudflare/node_modules/ -/config.json -server/config.json -server/cookie.json -server/logs/ -bundle/clip/config.json -bundle/clip/data/ -bundle/clip/models/ -*.zip -*.7z -*.rar -bundle/python/ -bundle/python-cpu/ -bundle/python-runtime/ -bundle/_delete_pending_python_gpu/ -__pycache__/ -test_*.py -build/ -runtime/*credential* -runtime/cloud-config-state.json -cloudflare/.npm-cache/ -cloudflare/.wrangler/ -cloudflare/.wrangler-config/ -cloudflare/.dev.vars diff --git a/.zipignore b/.zipignore deleted file mode 100644 index c18f6d7a78174bf330ed380f8eb517bbd00e8269..0000000000000000000000000000000000000000 --- a/.zipignore +++ /dev/null @@ -1,56 +0,0 @@ -# Git -.git/ -.gitignore - -# Python -__pycache__/ -*.py[cod] -*$py.class -*.so -.Python -*.egg-info/ -/dist/ -/build/ -*.egg - -# Node -npm-debug.log* - -# IDE -.vscode/ -.idea/ -*.swp -*.swo -*~ - -# OS -.DS_Store -Thumbs.db -desktop.ini - -# Logs -*.log -logs/ - -# Temp -tmp/ -temp/ -*.tmp -*.zip -*.7z -*.rar -test_*.py -/build/ - -# Local data and private config -cache/ -server/config.json -bundle/clip/config.json -bundle/python/ -bundle/_delete_pending_python_gpu/ - -# Large runtime files (keep models and data but exclude huge node_modules) -runtime/node/node_modules/ - -# Test outputs -test_output/ diff --git a/README.md b/README.md index 1374a39fc889d9c812d09503c70f3a63561e780c..4a957278c07a26ca82e9846b45b63bb820ab69b2 100644 --- a/README.md +++ b/README.md @@ -1,143 +1,57 @@ --- license: apache-2.0 -language: - - zh - - en +pipeline_tag: image-to-text tags: - - clip - - faiss - - ecommerce - - image-retrieval - - product-search - temu -pipeline_tag: image-feature-extraction + - product-bundling + - clip + - offline-package + - windows --- -
-
-
-
-
-
-
-
- Local listing search page served by the bundled 9990 runtime. -
+ -
-
- |
-
-
- |
-
| Smart Bundle Workflow | -Integrated Workbench | -
-
-
-
-
-
-
-
- Local listing search page served by the bundled 9990 runtime. -
- -
-
- |
-
-
- |
-
| Smart Bundle Workflow | -Integrated Workbench | -
IMAGE TO KIMI TO LISTING CLIP
-图片交给 Kimi 生成 10 个可组货商品检索词,再用纯 listing CLIP 索引召回;下方文本框单独用于直接检索 CLIP。
-
- The Real First Universal Charset Detector
-
-
-
-
-
-
-
-
-
-
- Featured Packages
-
-
-
-
-
-
-
- In other language (unofficial port - by the community)
-
-
-
-
-
-
for IP - :type d: int - :param d: dimensionality - :type ex_bits: int - :param ex_bits: number of extra bits (nb_bits - 1) - :type metric_type: int - :param metric_type: distance metric (L2 or Inner Product) - :rtype: float - :return: computed full multi-bit distance - """ - return _swigfaiss.compute_full_multibit_distance(sign_bits, ex_code, ex_fac, rotated_q, qr_base, d, ex_bits, metric_type) - -def unpack_sign_bits_from_packed(block, bbs, nsq, offset, block_stride, sign_bits_out): - r""" - Extract sign bits from PQ4-interleaved block into flat byte packing. - Like CodePackerRaBitQ::unpack_1 but sign-bits-only and with the - vector's in-block address hoisted out of the per-SQ loop. - """ - return _swigfaiss.unpack_sign_bits_from_packed(block, bbs, nsq, offset, block_stride, sign_bits_out) - -def compute_per_vector_storage_size(nb_bits, d): - r""" - Compute per-vector auxiliary storage size. - - :type nb_bits: int - :param nb_bits: number of quantization bits (1 = sign-bit only) - :type d: int - :param d: dimensionality - :rtype: int - :return: storage size in bytes - """ - return _swigfaiss.compute_per_vector_storage_size(nb_bits, d) - -def populate_block_aux_from_flat_storage(flat_storage, codes, num_vectors, bbs, M2, old_block_stride, new_block_stride, storage_size, id_map=None): - r""" - [LEGACY FORMAT SUPPORT] Migrate block data from old I/O format to new - format. - - This function is used only when reading indexes saved with the legacy format - (fourcc "Irfs"/"Iwrf") to convert them to the new embedded auxiliary data - format. Not needed for indexes saved with the new format ("Irfn"/"Iwrn"). - - Re-layouts blocks in-place and copies aux data from flat_storage. - - :type flat_storage: std::vector< uint8_t > - :param flat_storage: legacy per-vector aux data indexed by global ID - :type codes: faiss::AlignedTable< uint8_t > - :param codes: block data (will be resized and re-laid out) - :type num_vectors: int - :param num_vectors: number of vectors in this segment - :type bbs: int - :param bbs: block batch size (vectors per block) - :type M2: int - :param M2: rounded sub-quantizer count - :type old_block_stride: int - :param old_block_stride: old block size (packed codes only, or current) - :type new_block_stride: int - :param new_block_stride: new block size (packed codes + aux region) - :type storage_size: int - :param storage_size: per-vector aux storage size in bytes - :type id_map: int, optional - :param id_map: maps local offset to global ID; null = sequential - """ - return _swigfaiss.populate_block_aux_from_flat_storage(flat_storage, codes, num_vectors, bbs, M2, old_block_stride, new_block_stride, storage_size, id_map) -EDENScaleType_UNBIASED = _swigfaiss.EDENScaleType_UNBIASED -EDENScaleType_BIASED = _swigfaiss.EDENScaleType_BIASED -class EDENCodeFactors(object): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - l2_norm_term = property(_swigfaiss.EDENCodeFactors_l2_norm_term_get, _swigfaiss.EDENCodeFactors_l2_norm_term_set) - scale = property(_swigfaiss.EDENCodeFactors_scale_get, _swigfaiss.EDENCodeFactors_scale_set) - - def __init__(self): - _swigfaiss.EDENCodeFactors_swiginit(self, _swigfaiss.new_EDENCodeFactors()) - __swig_destroy__ = _swigfaiss.delete_EDENCodeFactors - -# Register EDENCodeFactors in _swigfaiss: -_swigfaiss.EDENCodeFactors_swigregister(EDENCodeFactors) -Z_MAX_BY_QB = cvar.Z_MAX_BY_QB - -class EDENFlatCodesDistanceComputer(FlatCodesDistanceComputer): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - - def __init__(self, *args, **kwargs): - raise AttributeError("No constructor defined - class is abstract") - __repr__ = _swig_repr - - def consecutive_distances_batch_8(self, first, distances): - return _swigfaiss.EDENFlatCodesDistanceComputer_consecutive_distances_batch_8(self, first, distances) - - def consecutive_distances_batch_16(self, first, distances): - return _swigfaiss.EDENFlatCodesDistanceComputer_consecutive_distances_batch_16(self, first, distances) - __swig_destroy__ = _swigfaiss.delete_EDENFlatCodesDistanceComputer - -# Register EDENFlatCodesDistanceComputer in _swigfaiss: -_swigfaiss.EDENFlatCodesDistanceComputer_swigregister(EDENFlatCodesDistanceComputer) - -def quantizer_type_for_bits(nb_bits): - return _swigfaiss.quantizer_type_for_bits(nb_bits) - -def is_eden_quantizer_type(qtype): - return _swigfaiss.is_eden_quantizer_type(qtype) - -def nb_bits_for_qtype(qtype): - return _swigfaiss.nb_bits_for_qtype(qtype) - -def packed_code_size(d, nb_bits): - return _swigfaiss.packed_code_size(d, nb_bits) - -def code_size(d, nb_bits): - return _swigfaiss.code_size(d, nb_bits) - -def extract_code(codes, index, nb_bits): - return _swigfaiss.extract_code(codes, index, nb_bits) - -def compute_codes(sq, metric_type, scale_type, x, codes, n, centroid=None): - return _swigfaiss.compute_codes(sq, metric_type, scale_type, x, codes, n, centroid) - -def decode(sq, codes, x, n, centroid=None): - return _swigfaiss.decode(sq, codes, x, n, centroid) - -def get_distance_computer(sq, metric_type, centroid=None): - return _swigfaiss.get_distance_computer(sq, metric_type, centroid) -class IndexEDEN(IndexFlatCodes): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - sq = property(_swigfaiss.IndexEDEN_sq_get, _swigfaiss.IndexEDEN_sq_set) - scale_type = property(_swigfaiss.IndexEDEN_scale_type_get, _swigfaiss.IndexEDEN_scale_type_set) - center = property(_swigfaiss.IndexEDEN_center_get, _swigfaiss.IndexEDEN_center_set) - - def __init__(self, *args): - _swigfaiss.IndexEDEN_swiginit(self, _swigfaiss.new_IndexEDEN(*args)) - - def train(self, n, x): - return _swigfaiss.IndexEDEN_train(self, n, x) - - def sa_encode(self, n, x, bytes): - return _swigfaiss.IndexEDEN_sa_encode(self, n, x, bytes) - - def sa_decode(self, n, bytes, x): - return _swigfaiss.IndexEDEN_sa_decode(self, n, bytes, x) - - def get_FlatCodesDistanceComputer(self): - return _swigfaiss.IndexEDEN_get_FlatCodesDistanceComputer(self) - - def search(self, n, x, k, distances, labels, params=None): - return _swigfaiss.IndexEDEN_search(self, n, x, k, distances, labels, params) - - def range_search(self, n, x, radius, result, params=None): - return _swigfaiss.IndexEDEN_range_search(self, n, x, radius, result, params) - __swig_destroy__ = _swigfaiss.delete_IndexEDEN - -# Register IndexEDEN in _swigfaiss: -_swigfaiss.IndexEDEN_swigregister(IndexEDEN) -class IndexIVFEDEN(IndexIVF): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - sq = property(_swigfaiss.IndexIVFEDEN_sq_get, _swigfaiss.IndexIVFEDEN_sq_set) - scale_type = property(_swigfaiss.IndexIVFEDEN_scale_type_get, _swigfaiss.IndexIVFEDEN_scale_type_set) - - def __init__(self, *args): - _swigfaiss.IndexIVFEDEN_swiginit(self, _swigfaiss.new_IndexIVFEDEN(*args)) - - def train_encoder(self, n, x, assign): - return _swigfaiss.IndexIVFEDEN_train_encoder(self, n, x, assign) - - def encode_vectors(self, n, x, list_nos, codes, include_listnos=False): - return _swigfaiss.IndexIVFEDEN_encode_vectors(self, n, x, list_nos, codes, include_listnos) - - def decode_vectors(self, n, codes, list_nos, x): - return _swigfaiss.IndexIVFEDEN_decode_vectors(self, n, codes, list_nos, x) - - def add_core(self, n, x, xids, precomputed_idx, inverted_list_context=None): - return _swigfaiss.IndexIVFEDEN_add_core(self, n, x, xids, precomputed_idx, inverted_list_context) - - def get_InvertedListScanner(self, store_pairs, sel, params): - return _swigfaiss.IndexIVFEDEN_get_InvertedListScanner(self, store_pairs, sel, params) - - def reconstruct_from_offset(self, list_no, offset, recons): - return _swigfaiss.IndexIVFEDEN_reconstruct_from_offset(self, list_no, offset, recons) - - def sa_decode(self, n, bytes, x): - return _swigfaiss.IndexIVFEDEN_sa_decode(self, n, bytes, x) - - def get_distance_computer(self): - return _swigfaiss.IndexIVFEDEN_get_distance_computer(self) - __swig_destroy__ = _swigfaiss.delete_IndexIVFEDEN - -# Register IndexIVFEDEN in _swigfaiss: -_swigfaiss.IndexIVFEDEN_swigregister(IndexIVFEDEN) -class RaBitQSearchParameters(SearchParameters): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - qb = property(_swigfaiss.RaBitQSearchParameters_qb_get, _swigfaiss.RaBitQSearchParameters_qb_set) - centered = property(_swigfaiss.RaBitQSearchParameters_centered_get, _swigfaiss.RaBitQSearchParameters_centered_set) - - def __init__(self): - _swigfaiss.RaBitQSearchParameters_swiginit(self, _swigfaiss.new_RaBitQSearchParameters()) - __swig_destroy__ = _swigfaiss.delete_RaBitQSearchParameters - -# Register RaBitQSearchParameters in _swigfaiss: -_swigfaiss.RaBitQSearchParameters_swigregister(RaBitQSearchParameters) -class IndexRaBitQ(IndexFlatCodes): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - rabitq = property(_swigfaiss.IndexRaBitQ_rabitq_get, _swigfaiss.IndexRaBitQ_rabitq_set) - center = property(_swigfaiss.IndexRaBitQ_center_get, _swigfaiss.IndexRaBitQ_center_set) - qb = property(_swigfaiss.IndexRaBitQ_qb_get, _swigfaiss.IndexRaBitQ_qb_set) - centered = property(_swigfaiss.IndexRaBitQ_centered_get, _swigfaiss.IndexRaBitQ_centered_set) - - def __init__(self, *args): - _swigfaiss.IndexRaBitQ_swiginit(self, _swigfaiss.new_IndexRaBitQ(*args)) - - def train(self, n, x): - return _swigfaiss.IndexRaBitQ_train(self, n, x) - - def sa_encode(self, n, x, bytes): - return _swigfaiss.IndexRaBitQ_sa_encode(self, n, x, bytes) - - def sa_decode(self, n, bytes, x): - return _swigfaiss.IndexRaBitQ_sa_decode(self, n, bytes, x) - - def get_FlatCodesDistanceComputer(self): - return _swigfaiss.IndexRaBitQ_get_FlatCodesDistanceComputer(self) - - def get_quantized_distance_computer(self, qb_in, centered): - return _swigfaiss.IndexRaBitQ_get_quantized_distance_computer(self, qb_in, centered) - - def search(self, n, x, k, distances, labels, params=None): - return _swigfaiss.IndexRaBitQ_search(self, n, x, k, distances, labels, params) - - def range_search(self, n, x, radius, result, params=None): - return _swigfaiss.IndexRaBitQ_range_search(self, n, x, radius, result, params) - __swig_destroy__ = _swigfaiss.delete_IndexRaBitQ - -# Register IndexRaBitQ in _swigfaiss: -_swigfaiss.IndexRaBitQ_swigregister(IndexRaBitQ) -class IndexRaBitQFastScan(IndexFastScan): - r""" - Fast-scan version of RaBitQ index that processes 32 database vectors at a - time using SIMD operations. Similar to IndexPQFastScan but adapted for - RaBitQ's bit-level quantization with factors. - - The key differences from IndexRaBitQ: - - Processes vectors in batches of 32 - - Uses 4-bit groupings for SIMD optimization (4 dimensions per 4-bit unit) - - Separates factors from quantized bits for efficient processing - - Leverages existing PQ4 FastScan infrastructure where possible - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - rabitq = property(_swigfaiss.IndexRaBitQFastScan_rabitq_get, _swigfaiss.IndexRaBitQFastScan_rabitq_set, doc=r"""RaBitQ quantizer for encoding/decoding""") - center = property(_swigfaiss.IndexRaBitQFastScan_center_get, _swigfaiss.IndexRaBitQFastScan_center_set, doc=r"""Center of all points (same as IndexRaBitQ)""") - qb = property(_swigfaiss.IndexRaBitQFastScan_qb_get, _swigfaiss.IndexRaBitQFastScan_qb_set, doc=r"""Default number of bits to quantize a query with""") - centered = property(_swigfaiss.IndexRaBitQFastScan_centered_get, _swigfaiss.IndexRaBitQFastScan_centered_set) - - def __init__(self, *args): - r""" - *Overload 1:* - build from an existing IndexRaBitQ - - | - - *Overload 2:* - build from an existing IndexRaBitQ - """ - _swigfaiss.IndexRaBitQFastScan_swiginit(self, _swigfaiss.new_IndexRaBitQFastScan(*args)) - - def train(self, n, x): - return _swigfaiss.IndexRaBitQFastScan_train(self, n, x) - - def add(self, n, x): - return _swigfaiss.IndexRaBitQFastScan_add(self, n, x) - - def compute_codes(self, codes, n, x): - return _swigfaiss.IndexRaBitQFastScan_compute_codes(self, codes, n, x) - - def compute_per_vector_storage_size(self): - r"""Compute per-vector auxiliary data size in block aux region""" - return _swigfaiss.IndexRaBitQFastScan_compute_per_vector_storage_size(self) - - def compute_float_LUT(self, lut, n, x, context): - return _swigfaiss.IndexRaBitQFastScan_compute_float_LUT(self, lut, n, x, context) - - def sa_decode(self, n, bytes, x): - return _swigfaiss.IndexRaBitQFastScan_sa_decode(self, n, bytes, x) - - def fast_scan_code_size(self): - r""" - Packed code size: (d + 7) / 8 bytes (1-bit-per-dimension sign bits, - excluding factors) - """ - return _swigfaiss.IndexRaBitQFastScan_fast_scan_code_size(self) - - def get_CodePacker(self): - r"""Return CodePackerRaBitQ with enlarged block size""" - return _swigfaiss.IndexRaBitQFastScan_get_CodePacker(self) - - def remove_ids(self, sel): - r"""Remove vectors and compact both PQ4 codes and auxiliary data""" - return _swigfaiss.IndexRaBitQFastScan_remove_ids(self, sel) - - def search(self, n, x, k, distances, labels, params=None): - return _swigfaiss.IndexRaBitQFastScan_search(self, n, x, k, distances, labels, params) - __swig_destroy__ = _swigfaiss.delete_IndexRaBitQFastScan - -# Register IndexRaBitQFastScan in _swigfaiss: -_swigfaiss.IndexRaBitQFastScan_swigregister(IndexRaBitQFastScan) -class IVFRaBitQSearchParameters(SearchParametersIVF): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - qb = property(_swigfaiss.IVFRaBitQSearchParameters_qb_get, _swigfaiss.IVFRaBitQSearchParameters_qb_set) - centered = property(_swigfaiss.IVFRaBitQSearchParameters_centered_get, _swigfaiss.IVFRaBitQSearchParameters_centered_set) - - def __init__(self): - _swigfaiss.IVFRaBitQSearchParameters_swiginit(self, _swigfaiss.new_IVFRaBitQSearchParameters()) - __swig_destroy__ = _swigfaiss.delete_IVFRaBitQSearchParameters - -# Register IVFRaBitQSearchParameters in _swigfaiss: -_swigfaiss.IVFRaBitQSearchParameters_swigregister(IVFRaBitQSearchParameters) -class IndexIVFRaBitQ(IndexIVF): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - rabitq = property(_swigfaiss.IndexIVFRaBitQ_rabitq_get, _swigfaiss.IndexIVFRaBitQ_rabitq_set) - qb = property(_swigfaiss.IndexIVFRaBitQ_qb_get, _swigfaiss.IndexIVFRaBitQ_qb_set) - - def __init__(self, *args): - _swigfaiss.IndexIVFRaBitQ_swiginit(self, _swigfaiss.new_IndexIVFRaBitQ(*args)) - - def train_encoder(self, n, x, assign): - return _swigfaiss.IndexIVFRaBitQ_train_encoder(self, n, x, assign) - - def encode_vectors(self, n, x, list_nos, codes, include_listnos=False): - return _swigfaiss.IndexIVFRaBitQ_encode_vectors(self, n, x, list_nos, codes, include_listnos) - - def decode_vectors(self, n, codes, list_nos, x): - return _swigfaiss.IndexIVFRaBitQ_decode_vectors(self, n, codes, list_nos, x) - - def add_core(self, n, x, xids, precomputed_idx, inverted_list_context=None): - return _swigfaiss.IndexIVFRaBitQ_add_core(self, n, x, xids, precomputed_idx, inverted_list_context) - - def get_InvertedListScanner(self, store_pairs, sel, params): - return _swigfaiss.IndexIVFRaBitQ_get_InvertedListScanner(self, store_pairs, sel, params) - - def reconstruct_from_offset(self, list_no, offset, recons): - return _swigfaiss.IndexIVFRaBitQ_reconstruct_from_offset(self, list_no, offset, recons) - - def sa_decode(self, n, bytes, x): - return _swigfaiss.IndexIVFRaBitQ_sa_decode(self, n, bytes, x) - - def get_distance_computer(self): - return _swigfaiss.IndexIVFRaBitQ_get_distance_computer(self) - __swig_destroy__ = _swigfaiss.delete_IndexIVFRaBitQ - -# Register IndexIVFRaBitQ in _swigfaiss: -_swigfaiss.IndexIVFRaBitQ_swigregister(IndexIVFRaBitQ) -class IndexIVFRaBitQFastScan(IndexIVFFastScan): - r""" - Fast-scan version of IndexIVFRaBitQ that processes vectors in batches - using SIMD operations. Combines the inverted file structure of IVF - with RaBitQ's bit-level quantization and FastScan's batch processing. - - Key features: - - Inherits from IndexIVFFastScan for IVF structure and search algorithms - - Processes 32 database vectors at a time using SIMD - - Separates factors from quantized bits for efficient processing - - Supports both L2 and inner product metrics - - Maintains compatibility with existing IVF search parameters - - Implementation details: - - Batch size (bbs) is typically 32 for optimal SIMD performance - - Factors are stored separately from packed codes for cache efficiency - - Query factors are computed once per search and reused across lists - - Uses specialized result handlers for RaBitQ distance corrections - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - rabitq = property(_swigfaiss.IndexIVFRaBitQFastScan_rabitq_get, _swigfaiss.IndexIVFRaBitQFastScan_rabitq_set) - qb = property(_swigfaiss.IndexIVFRaBitQFastScan_qb_get, _swigfaiss.IndexIVFRaBitQFastScan_qb_set, doc=r"""Default number of bits to quantize a query with""") - centered = property(_swigfaiss.IndexIVFRaBitQFastScan_centered_get, _swigfaiss.IndexIVFRaBitQFastScan_centered_set, doc=r"""Use zero-centered scalar quantizer for queries""") - - def __init__(self, *args): - r""" - *Overload 1:* - Build from an existing IndexIVFRaBitQ - - | - - *Overload 2:* - Build from an existing IndexIVFRaBitQ - """ - _swigfaiss.IndexIVFRaBitQFastScan_swiginit(self, _swigfaiss.new_IndexIVFRaBitQFastScan(*args)) - - def train_encoder(self, n, x, assign): - return _swigfaiss.IndexIVFRaBitQFastScan_train_encoder(self, n, x, assign) - - def encode_vectors(self, n, x, list_nos, codes, include_listnos=False): - return _swigfaiss.IndexIVFRaBitQFastScan_encode_vectors(self, n, x, list_nos, codes, include_listnos) - - def fast_scan_code_size(self): - r""" - Packed code size: (d + 7) / 8 bytes (1-bit-per-dimension sign bits, - excluding factors) - """ - return _swigfaiss.IndexIVFRaBitQFastScan_fast_scan_code_size(self) - - def get_CodePacker(self): - r"""Return CodePackerRaBitQ with enlarged block size""" - return _swigfaiss.IndexIVFRaBitQFastScan_get_CodePacker(self) - - def postprocess_packed_codes(self, list_no, list_offset, n_added, flat_codes): - r"""Write per-vector auxiliary data into block auxiliary region""" - return _swigfaiss.IndexIVFRaBitQFastScan_postprocess_packed_codes(self, list_no, list_offset, n_added, flat_codes) - - def reconstruct_from_offset(self, list_no, offset, recons): - r"""Reconstruct a single vector from an inverted list""" - return _swigfaiss.IndexIVFRaBitQFastScan_reconstruct_from_offset(self, list_no, offset, recons) - - def sa_decode(self, n, bytes, x): - r"""Override sa_decode to handle RaBitQ reconstruction""" - return _swigfaiss.IndexIVFRaBitQFastScan_sa_decode(self, n, bytes, x) - - def compute_per_vector_storage_size(self): - r"""Compute per-vector auxiliary storage size based on nb_bits""" - return _swigfaiss.IndexIVFRaBitQFastScan_compute_per_vector_storage_size(self) - - def compute_LUT_uint8(self, n, x, cq, dis_tables, biases, normalizers, context): - r""" - Override: compute and quantize LUT per-query to avoid O(n*nprobe*M*16) - float table allocation. - """ - return _swigfaiss.IndexIVFRaBitQFastScan_compute_LUT_uint8(self, n, x, cq, dis_tables, biases, normalizers, context) - - def compute_residual_LUT(self, query, centroid_id, query_factors, lut_out, qb_param, centered_param, rotated_q, centroid_buf): - r"""Compute residual, query factors, and float LUT in two passes over d.""" - return _swigfaiss.IndexIVFRaBitQFastScan_compute_residual_LUT(self, query, centroid_id, query_factors, lut_out, qb_param, centered_param, rotated_q, centroid_buf) - - def lookup_table_is_3d(self): - r"""Implementation methods for IVFRaBitQFastScan specialization""" - return _swigfaiss.IndexIVFRaBitQFastScan_lookup_table_is_3d(self) - - def compute_LUT(self, n, x, cq, dis_tables, biases, context): - return _swigfaiss.IndexIVFRaBitQFastScan_compute_LUT(self, n, x, cq, dis_tables, biases, context) - - def search_preassigned(self, n, x, k, assign, centroid_dis, distances, labels, store_pairs, params=None, stats=None): - return _swigfaiss.IndexIVFRaBitQFastScan_search_preassigned(self, n, x, k, assign, centroid_dis, distances, labels, store_pairs, params, stats) - - def get_InvertedListScanner(self, store_pairs=False, sel=None, params=None): - r""" - Get an InvertedListScanner for single-query scanning. - This provides compatibility with the standard IVF search interface - """ - return _swigfaiss.IndexIVFRaBitQFastScan_get_InvertedListScanner(self, store_pairs, sel, params) - __swig_destroy__ = _swigfaiss.delete_IndexIVFRaBitQFastScan - -# Register IndexIVFRaBitQFastScan in _swigfaiss: -_swigfaiss.IndexIVFRaBitQFastScan_swigregister(IndexIVFRaBitQFastScan) -class RangeSearchResult(object): - r""" - The objective is to have a simple result structure while - minimizing the number of mem copies in the result. The method - do_allocation can be overloaded to allocate the result tables in - the matrix type of a scripting language like Lua or Python. - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - nq = property(_swigfaiss.RangeSearchResult_nq_get, _swigfaiss.RangeSearchResult_nq_set, doc=r"""nb of queries""") - lims = property(_swigfaiss.RangeSearchResult_lims_get, _swigfaiss.RangeSearchResult_lims_set, doc=r"""size (nq + 1)""") - labels = property(_swigfaiss.RangeSearchResult_labels_get, _swigfaiss.RangeSearchResult_labels_set, doc=r"""result for query i is labels[lims[i]:lims[i+1]]""") - distances = property(_swigfaiss.RangeSearchResult_distances_get, _swigfaiss.RangeSearchResult_distances_set, doc=r"""corresponding distances (not sorted)""") - buffer_size = property(_swigfaiss.RangeSearchResult_buffer_size_get, _swigfaiss.RangeSearchResult_buffer_size_set, doc=r"""size of the result buffers used""") - - def __init__(self, nq, alloc_lims=True): - r"""lims must be allocated on input to range_search.""" - _swigfaiss.RangeSearchResult_swiginit(self, _swigfaiss.new_RangeSearchResult(nq, alloc_lims)) - - def do_allocation(self): - r""" - called when lims contains the nb of elements result entries - for each query - """ - return _swigfaiss.RangeSearchResult_do_allocation(self) - __swig_destroy__ = _swigfaiss.delete_RangeSearchResult - -# Register RangeSearchResult in _swigfaiss: -_swigfaiss.RangeSearchResult_swigregister(RangeSearchResult) -class BufferList(object): - r""" - List of temporary buffers used to store results before they are - copied to the RangeSearchResult object. - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - buffer_size = property(_swigfaiss.BufferList_buffer_size_get, _swigfaiss.BufferList_buffer_size_set) - buffers = property(_swigfaiss.BufferList_buffers_get, _swigfaiss.BufferList_buffers_set) - wp = property(_swigfaiss.BufferList_wp_get, _swigfaiss.BufferList_wp_set, doc=r"""write pointer in the last buffer.""") - - def __init__(self, buffer_size): - _swigfaiss.BufferList_swiginit(self, _swigfaiss.new_BufferList(buffer_size)) - __swig_destroy__ = _swigfaiss.delete_BufferList - - def append_buffer(self): - r"""create a new buffer""" - return _swigfaiss.BufferList_append_buffer(self) - - def add(self, id, dis): - r"""add one result, possibly appending a new buffer if needed""" - return _swigfaiss.BufferList_add(self, id, dis) - - def copy_range(self, ofs, n, dest_ids, dest_dis): - r""" - copy elements ofs:ofs+n-1 seen as linear data in the buffers to - tables dest_ids, dest_dis - """ - return _swigfaiss.BufferList_copy_range(self, ofs, n, dest_ids, dest_dis) - -# Register BufferList in _swigfaiss: -_swigfaiss.BufferList_swigregister(BufferList) -class RangeQueryResult(object): - r"""result structure for a single query""" - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - qno = property(_swigfaiss.RangeQueryResult_qno_get, _swigfaiss.RangeQueryResult_qno_set) - nres = property(_swigfaiss.RangeQueryResult_nres_get, _swigfaiss.RangeQueryResult_nres_set) - pres = property(_swigfaiss.RangeQueryResult_pres_get, _swigfaiss.RangeQueryResult_pres_set) - stats = property(_swigfaiss.RangeQueryResult_stats_get, _swigfaiss.RangeQueryResult_stats_set) - - def add(self, dis, id): - r"""called by search function to report a new result""" - return _swigfaiss.RangeQueryResult_add(self, dis, id) - - def __init__(self): - _swigfaiss.RangeQueryResult_swiginit(self, _swigfaiss.new_RangeQueryResult()) - __swig_destroy__ = _swigfaiss.delete_RangeQueryResult - -# Register RangeQueryResult in _swigfaiss: -_swigfaiss.RangeQueryResult_swigregister(RangeQueryResult) -class RangeSearchPartialResult(BufferList): - r"""the entries in the buffers are split per query""" - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - res = property(_swigfaiss.RangeSearchPartialResult_res_get, _swigfaiss.RangeSearchPartialResult_res_set) - - def __init__(self, res_in): - r"""eventually the result will be stored in res_in""" - _swigfaiss.RangeSearchPartialResult_swiginit(self, _swigfaiss.new_RangeSearchPartialResult(res_in)) - queries = property(_swigfaiss.RangeSearchPartialResult_queries_get, _swigfaiss.RangeSearchPartialResult_queries_set, doc=r"""query ids + nb of results per query.""") - - def new_result(self, qno): - r"""begin a new result""" - return _swigfaiss.RangeSearchPartialResult_new_result(self, qno) - - def finalize(self): - return _swigfaiss.RangeSearchPartialResult_finalize(self) - - def set_lims(self): - r"""called by range_search before do_allocation""" - return _swigfaiss.RangeSearchPartialResult_set_lims(self) - - def copy_result(self, incremental=False): - r"""called by range_search after do_allocation""" - return _swigfaiss.RangeSearchPartialResult_copy_result(self, incremental) - - @staticmethod - def merge(partial_results, do_delete=True): - r""" - merge a set of PartialResult's into one RangeSearchResult - on output the partialresults are empty! - """ - return _swigfaiss.RangeSearchPartialResult_merge(partial_results, do_delete) - __swig_destroy__ = _swigfaiss.delete_RangeSearchPartialResult - -# Register RangeSearchPartialResult in _swigfaiss: -_swigfaiss.RangeSearchPartialResult_swigregister(RangeSearchPartialResult) -class InterruptCallback(object): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - - def __init__(self, *args, **kwargs): - raise AttributeError("No constructor defined - class is abstract") - __repr__ = _swig_repr - - def want_interrupt(self): - return _swigfaiss.InterruptCallback_want_interrupt(self) - __swig_destroy__ = _swigfaiss.delete_InterruptCallback - - @staticmethod - def clear_instance(): - return _swigfaiss.InterruptCallback_clear_instance() - - @staticmethod - def check(): - r""" - check if: - - an interrupt callback is set - - the callback returns true - if this is the case, then throw an exception. Should not be called - from multiple threads. - """ - return _swigfaiss.InterruptCallback_check() - - @staticmethod - def is_interrupted(): - r""" - same as check() but return true if is interrupted instead of - throwing. Can be called from multiple threads. - """ - return _swigfaiss.InterruptCallback_is_interrupted() - - @staticmethod - def get_period_hint(flops): - r""" - assuming each iteration takes a certain number of flops, what - is a reasonable interval to check for interrupts? - """ - return _swigfaiss.InterruptCallback_get_period_hint(flops) - -# Register InterruptCallback in _swigfaiss: -_swigfaiss.InterruptCallback_swigregister(InterruptCallback) -class TimeoutCallback(InterruptCallback): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - start = property(_swigfaiss.TimeoutCallback_start_get, _swigfaiss.TimeoutCallback_start_set) - timeout = property(_swigfaiss.TimeoutCallback_timeout_get, _swigfaiss.TimeoutCallback_timeout_set) - - def want_interrupt(self): - return _swigfaiss.TimeoutCallback_want_interrupt(self) - - def set_timeout(self, timeout_in_seconds): - return _swigfaiss.TimeoutCallback_set_timeout(self, timeout_in_seconds) - - @staticmethod - def reset(timeout_in_seconds): - return _swigfaiss.TimeoutCallback_reset(timeout_in_seconds) - - def __init__(self): - _swigfaiss.TimeoutCallback_swiginit(self, _swigfaiss.new_TimeoutCallback()) - __swig_destroy__ = _swigfaiss.delete_TimeoutCallback - -# Register TimeoutCallback in _swigfaiss: -_swigfaiss.TimeoutCallback_swigregister(TimeoutCallback) -class VisitedTable(object): - r""" - Abstract base class for a fast, reusable Visited Set for graph search - algorithms. - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - - def __init__(self, *args, **kwargs): - raise AttributeError("No constructor defined - class is abstract") - __repr__ = _swig_repr - __swig_destroy__ = _swigfaiss.delete_VisitedTable - - def set(self, no): - r"""set flag #no to true, return whether this changed it.""" - return _swigfaiss.VisitedTable_set(self, no) - - def get(self, no): - r"""get flag #no""" - return _swigfaiss.VisitedTable_get(self, no) - - def prefetch(self, no): - r"""prefetch flag #no""" - return _swigfaiss.VisitedTable_prefetch(self, no) - - def reserve(self, arg2): - r"""pre-allocate bucket space to avoid rehashing during repeated set() calls""" - return _swigfaiss.VisitedTable_reserve(self, arg2) - - def advance(self): - r"""reset all flags to false""" - return _swigfaiss.VisitedTable_advance(self) - - @staticmethod - def get_reusable(*args): - r""" - Returns a thread-local, reusable table sized for at least `size` and - reset to a clean state. Unlike create(), it does not allocate on each - call: the O(size) versioned array is allocated once per thread and - reused across searches, avoiding a per-search alloc+zero of the whole - array when a static index is searched repeatedly. - - The returned reference is owned by thread-local storage: do not delete - it and do not use it beyond the current search on the calling thread. - """ - return _swigfaiss.VisitedTable_get_reusable(*args) - -# Register VisitedTable in _swigfaiss: -_swigfaiss.VisitedTable_swigregister(VisitedTable) -class VisitedTableSet(VisitedTable): - r""" - Set-based implementation using unordered_set. - O(1) to construct and O(visits) to advance. - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - visited_set = property(_swigfaiss.VisitedTableSet_visited_set_get, _swigfaiss.VisitedTableSet_visited_set_set) - - def __init__(self): - _swigfaiss.VisitedTableSet_swiginit(self, _swigfaiss.new_VisitedTableSet()) - - def set(self, no): - return _swigfaiss.VisitedTableSet_set(self, no) - - def get(self, no): - return _swigfaiss.VisitedTableSet_get(self, no) - - def prefetch(self, arg2): - return _swigfaiss.VisitedTableSet_prefetch(self, arg2) - - def reserve(self, n): - return _swigfaiss.VisitedTableSet_reserve(self, n) - - def advance(self): - return _swigfaiss.VisitedTableSet_advance(self) - __swig_destroy__ = _swigfaiss.delete_VisitedTableSet - -# Register VisitedTableSet in _swigfaiss: -_swigfaiss.VisitedTableSet_swigregister(VisitedTableSet) -class VisitedTableVector(VisitedTable): - r""" - Vector-based implementation using a versioned byte array. - Faster for get()/set(), but O(size) to initialize. - advance() is O(1) except every 250 calls, which are O(size). - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - visited = property(_swigfaiss.VisitedTableVector_visited_get, _swigfaiss.VisitedTableVector_visited_set) - visno = property(_swigfaiss.VisitedTableVector_visno_get, _swigfaiss.VisitedTableVector_visno_set) - - def __init__(self, size): - _swigfaiss.VisitedTableVector_swiginit(self, _swigfaiss.new_VisitedTableVector(size)) - - def ensure_size(self, size): - r""" - Grow so indices in [0, size) are valid; new slots read as unvisited. - Never shrinks, so capacity is retained when the table is reused. - """ - return _swigfaiss.VisitedTableVector_ensure_size(self, size) - - def set(self, no): - return _swigfaiss.VisitedTableVector_set(self, no) - - def get(self, no): - return _swigfaiss.VisitedTableVector_get(self, no) - - def prefetch(self, no): - return _swigfaiss.VisitedTableVector_prefetch(self, no) - - def advance(self): - return _swigfaiss.VisitedTableVector_advance(self) - __swig_destroy__ = _swigfaiss.delete_VisitedTableVector - -# Register VisitedTableVector in _swigfaiss: -_swigfaiss.VisitedTableVector_swigregister(VisitedTableVector) -class IDSelector(object): - r"""Encapsulates a set of ids to handle.""" - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - - def __init__(self, *args, **kwargs): - raise AttributeError("No constructor defined - class is abstract") - __repr__ = _swig_repr - - def is_member(self, id): - return _swigfaiss.IDSelector_is_member(self, id) - __swig_destroy__ = _swigfaiss.delete_IDSelector - -# Register IDSelector in _swigfaiss: -_swigfaiss.IDSelector_swigregister(IDSelector) -class IDSelectorRange(IDSelector): - r"""ids between [imin, imax)""" - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - imin = property(_swigfaiss.IDSelectorRange_imin_get, _swigfaiss.IDSelectorRange_imin_set) - imax = property(_swigfaiss.IDSelectorRange_imax_get, _swigfaiss.IDSelectorRange_imax_set) - assume_sorted = property(_swigfaiss.IDSelectorRange_assume_sorted_get, _swigfaiss.IDSelectorRange_assume_sorted_set, doc=r""" - Assume that the ids to handle are sorted. In some cases this can speed - up processing - """) - - def __init__(self, imin, imax, assume_sorted=False): - _swigfaiss.IDSelectorRange_swiginit(self, _swigfaiss.new_IDSelectorRange(imin, imax, assume_sorted)) - - def is_member(self, id): - return _swigfaiss.IDSelectorRange_is_member(self, id) - - def find_sorted_ids_bounds(self, list_size, ids, jmin, jmax): - r""" - for sorted ids, find the range of list indices where the valid ids are - stored - """ - return _swigfaiss.IDSelectorRange_find_sorted_ids_bounds(self, list_size, ids, jmin, jmax) - __swig_destroy__ = _swigfaiss.delete_IDSelectorRange - -# Register IDSelectorRange in _swigfaiss: -_swigfaiss.IDSelectorRange_swigregister(IDSelectorRange) -class IDSelectorArray(IDSelector): - r""" - Simple array of elements - - is_member calls are very inefficient, but some operations can use the ids - directly. - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - n = property(_swigfaiss.IDSelectorArray_n_get, _swigfaiss.IDSelectorArray_n_set) - ids = property(_swigfaiss.IDSelectorArray_ids_get, _swigfaiss.IDSelectorArray_ids_set) - - def __init__(self, n, ids): - r""" - Construct with an array of ids to process - - :type n: int - :param n: number of ids to store - :type ids: int - :param ids: elements to store. The pointer should remain valid during - IDSelectorArray's lifetime - """ - _swigfaiss.IDSelectorArray_swiginit(self, _swigfaiss.new_IDSelectorArray(n, ids)) - - def is_member(self, id): - return _swigfaiss.IDSelectorArray_is_member(self, id) - __swig_destroy__ = _swigfaiss.delete_IDSelectorArray - -# Register IDSelectorArray in _swigfaiss: -_swigfaiss.IDSelectorArray_swigregister(IDSelectorArray) -class IDSelectorBatch(IDSelector): - r""" - Ids from a set. - - Repetitions of ids in the indices set passed to the constructor does not hurt - performance. - - The hash function used for the bloom filter and GCC's implementation of - unordered_set are just the least significant bits of the id. This works fine - for random ids or ids in sequences but will produce many hash collisions if - lsb's are always the same - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - nbits = property(_swigfaiss.IDSelectorBatch_nbits_get, _swigfaiss.IDSelectorBatch_nbits_set) - mask = property(_swigfaiss.IDSelectorBatch_mask_get, _swigfaiss.IDSelectorBatch_mask_set) - - def __init__(self, n, indices): - r""" - Construct with an array of ids to process - - :type n: int - :param n: number of ids to store - :param ids: elements to store. The pointer can be released after - construction - """ - _swigfaiss.IDSelectorBatch_swiginit(self, _swigfaiss.new_IDSelectorBatch(n, indices)) - - def is_member(self, id): - return _swigfaiss.IDSelectorBatch_is_member(self, id) - __swig_destroy__ = _swigfaiss.delete_IDSelectorBatch - -# Register IDSelectorBatch in _swigfaiss: -_swigfaiss.IDSelectorBatch_swigregister(IDSelectorBatch) -class IDSelectorBitmap(IDSelector): - r"""One bit per element. Constructed with a bitmap, size ceil(n / 8).""" - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - n = property(_swigfaiss.IDSelectorBitmap_n_get, _swigfaiss.IDSelectorBitmap_n_set) - bitmap = property(_swigfaiss.IDSelectorBitmap_bitmap_get, _swigfaiss.IDSelectorBitmap_bitmap_set) - - def __init__(self, n, bitmap): - r""" - Construct with a binary mask - - :type n: int - :param n: size of the bitmap array - :type bitmap: uint8_t - :param bitmap: id will be selected iff id / 8 < n and bit number - (i%8) of bitmap[floor(i / 8)] is 1. - """ - _swigfaiss.IDSelectorBitmap_swiginit(self, _swigfaiss.new_IDSelectorBitmap(n, bitmap)) - - def is_member(self, id): - return _swigfaiss.IDSelectorBitmap_is_member(self, id) - __swig_destroy__ = _swigfaiss.delete_IDSelectorBitmap - -# Register IDSelectorBitmap in _swigfaiss: -_swigfaiss.IDSelectorBitmap_swigregister(IDSelectorBitmap) -class IDSelectorNot(IDSelector): - r"""reverts the membership test of another selector""" - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - sel = property(_swigfaiss.IDSelectorNot_sel_get, _swigfaiss.IDSelectorNot_sel_set) - - def __init__(self, sel_): - _swigfaiss.IDSelectorNot_swiginit(self, _swigfaiss.new_IDSelectorNot(sel_)) - - def is_member(self, id): - return _swigfaiss.IDSelectorNot_is_member(self, id) - __swig_destroy__ = _swigfaiss.delete_IDSelectorNot - -# Register IDSelectorNot in _swigfaiss: -_swigfaiss.IDSelectorNot_swigregister(IDSelectorNot) -class IDSelectorAll(IDSelector): - r"""selects all entries (useful for benchmarking)""" - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - - def is_member(self, arg2): - return _swigfaiss.IDSelectorAll_is_member(self, arg2) - __swig_destroy__ = _swigfaiss.delete_IDSelectorAll - - def __init__(self): - _swigfaiss.IDSelectorAll_swiginit(self, _swigfaiss.new_IDSelectorAll()) - -# Register IDSelectorAll in _swigfaiss: -_swigfaiss.IDSelectorAll_swigregister(IDSelectorAll) -class IDSelectorAnd(IDSelector): - r""" - does an AND operation on the two given IDSelector's is_membership - results. - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - lhs = property(_swigfaiss.IDSelectorAnd_lhs_get, _swigfaiss.IDSelectorAnd_lhs_set) - rhs = property(_swigfaiss.IDSelectorAnd_rhs_get, _swigfaiss.IDSelectorAnd_rhs_set) - - def __init__(self, lhs_, rhs_): - _swigfaiss.IDSelectorAnd_swiginit(self, _swigfaiss.new_IDSelectorAnd(lhs_, rhs_)) - - def is_member(self, id): - return _swigfaiss.IDSelectorAnd_is_member(self, id) - __swig_destroy__ = _swigfaiss.delete_IDSelectorAnd - -# Register IDSelectorAnd in _swigfaiss: -_swigfaiss.IDSelectorAnd_swigregister(IDSelectorAnd) -class IDSelectorOr(IDSelector): - r""" - does an OR operation on the two given IDSelector's is_membership - results. - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - lhs = property(_swigfaiss.IDSelectorOr_lhs_get, _swigfaiss.IDSelectorOr_lhs_set) - rhs = property(_swigfaiss.IDSelectorOr_rhs_get, _swigfaiss.IDSelectorOr_rhs_set) - - def __init__(self, lhs_, rhs_): - _swigfaiss.IDSelectorOr_swiginit(self, _swigfaiss.new_IDSelectorOr(lhs_, rhs_)) - - def is_member(self, id): - return _swigfaiss.IDSelectorOr_is_member(self, id) - __swig_destroy__ = _swigfaiss.delete_IDSelectorOr - -# Register IDSelectorOr in _swigfaiss: -_swigfaiss.IDSelectorOr_swigregister(IDSelectorOr) -class IDSelectorXOr(IDSelector): - r""" - does an XOR operation on the two given IDSelector's is_membership - results. - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - lhs = property(_swigfaiss.IDSelectorXOr_lhs_get, _swigfaiss.IDSelectorXOr_lhs_set) - rhs = property(_swigfaiss.IDSelectorXOr_rhs_get, _swigfaiss.IDSelectorXOr_rhs_set) - - def __init__(self, lhs_, rhs_): - _swigfaiss.IDSelectorXOr_swiginit(self, _swigfaiss.new_IDSelectorXOr(lhs_, rhs_)) - - def is_member(self, id): - return _swigfaiss.IDSelectorXOr_is_member(self, id) - __swig_destroy__ = _swigfaiss.delete_IDSelectorXOr - -# Register IDSelectorXOr in _swigfaiss: -_swigfaiss.IDSelectorXOr_swigregister(IDSelectorXOr) -class IDSelectorTranslated(IDSelector): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - id_map = property(_swigfaiss.IDSelectorTranslated_id_map_get) - sel = property(_swigfaiss.IDSelectorTranslated_sel_get, _swigfaiss.IDSelectorTranslated_sel_set) - - def __init__(self, *args): - _swigfaiss.IDSelectorTranslated_swiginit(self, _swigfaiss.new_IDSelectorTranslated(*args)) - - def is_member(self, id): - return _swigfaiss.IDSelectorTranslated_is_member(self, id) - __swig_destroy__ = _swigfaiss.delete_IDSelectorTranslated - -# Register IDSelectorTranslated in _swigfaiss: -_swigfaiss.IDSelectorTranslated_swigregister(IDSelectorTranslated) -class IndexIDMap(Index): - r"""Index that translates search results to ids""" - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - index = property(_swigfaiss.IndexIDMap_index_get, _swigfaiss.IndexIDMap_index_set) - own_fields = property(_swigfaiss.IndexIDMap_own_fields_get, _swigfaiss.IndexIDMap_own_fields_set, doc=r"""the sub-index""") - id_map = property(_swigfaiss.IndexIDMap_id_map_get, _swigfaiss.IndexIDMap_id_map_set, doc=r"""whether pointers are deleted in destructor""") - - def add_with_ids(self, n, x, xids): - r""" - :type xids: int - :param xids: if non-null, ids to store for the vectors (size n) - """ - return _swigfaiss.IndexIDMap_add_with_ids(self, n, x, xids) - - def add_with_ids_ex(self, n, x, numeric_type, xids): - return _swigfaiss.IndexIDMap_add_with_ids_ex(self, n, x, numeric_type, xids) - - def add(self, n, x): - r"""this will fail. Use add_with_ids""" - return _swigfaiss.IndexIDMap_add(self, n, x) - - def add_ex(self, n, x, numeric_type): - return _swigfaiss.IndexIDMap_add_ex(self, n, x, numeric_type) - - def search(self, n, x, k, distances, labels, params=None): - return _swigfaiss.IndexIDMap_search(self, n, x, k, distances, labels, params) - - def search_ex(self, n, x, numeric_type, k, distances, labels, params=None): - return _swigfaiss.IndexIDMap_search_ex(self, n, x, numeric_type, k, distances, labels, params) - - def train(self, n, x): - return _swigfaiss.IndexIDMap_train(self, n, x) - - def train_ex(self, n, x, numeric_type): - return _swigfaiss.IndexIDMap_train_ex(self, n, x, numeric_type) - - def reset(self): - return _swigfaiss.IndexIDMap_reset(self) - - def remove_ids(self, sel): - r"""remove ids adapted to IndexFlat""" - return _swigfaiss.IndexIDMap_remove_ids(self, sel) - - def range_search(self, n, x, radius, result, params=None): - return _swigfaiss.IndexIDMap_range_search(self, n, x, radius, result, params) - - def merge_from(self, otherIndex, add_id=0): - return _swigfaiss.IndexIDMap_merge_from(self, otherIndex, add_id) - - def check_compatible_for_merge(self, otherIndex): - return _swigfaiss.IndexIDMap_check_compatible_for_merge(self, otherIndex) - - def sa_code_size(self): - return _swigfaiss.IndexIDMap_sa_code_size(self) - - def add_sa_codes(self, n, x, xids): - return _swigfaiss.IndexIDMap_add_sa_codes(self, n, x, xids) - __swig_destroy__ = _swigfaiss.delete_IndexIDMap - - def __init__(self, *args): - _swigfaiss.IndexIDMap_swiginit(self, _swigfaiss.new_IndexIDMap(*args)) - -# Register IndexIDMap in _swigfaiss: -_swigfaiss.IndexIDMap_swigregister(IndexIDMap) -class IndexBinaryIDMap(IndexBinary): - r"""Index that translates search results to ids""" - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - index = property(_swigfaiss.IndexBinaryIDMap_index_get, _swigfaiss.IndexBinaryIDMap_index_set) - own_fields = property(_swigfaiss.IndexBinaryIDMap_own_fields_get, _swigfaiss.IndexBinaryIDMap_own_fields_set, doc=r"""the sub-index""") - id_map = property(_swigfaiss.IndexBinaryIDMap_id_map_get, _swigfaiss.IndexBinaryIDMap_id_map_set, doc=r"""whether pointers are deleted in destructor""") - - def add_with_ids(self, n, x, xids): - r""" - :type xids: int - :param xids: if non-null, ids to store for the vectors (size n) - """ - return _swigfaiss.IndexBinaryIDMap_add_with_ids(self, n, x, xids) - - def add_with_ids_ex(self, n, x, numeric_type, xids): - return _swigfaiss.IndexBinaryIDMap_add_with_ids_ex(self, n, x, numeric_type, xids) - - def add(self, n, x): - r"""this will fail. Use add_with_ids""" - return _swigfaiss.IndexBinaryIDMap_add(self, n, x) - - def add_ex(self, n, x, numeric_type): - return _swigfaiss.IndexBinaryIDMap_add_ex(self, n, x, numeric_type) - - def search(self, n, x, k, distances, labels, params=None): - return _swigfaiss.IndexBinaryIDMap_search(self, n, x, k, distances, labels, params) - - def search_ex(self, n, x, numeric_type, k, distances, labels, params=None): - return _swigfaiss.IndexBinaryIDMap_search_ex(self, n, x, numeric_type, k, distances, labels, params) - - def train(self, n, x): - return _swigfaiss.IndexBinaryIDMap_train(self, n, x) - - def train_ex(self, n, x, numeric_type): - return _swigfaiss.IndexBinaryIDMap_train_ex(self, n, x, numeric_type) - - def reset(self): - return _swigfaiss.IndexBinaryIDMap_reset(self) - - def remove_ids(self, sel): - r"""remove ids adapted to IndexFlat""" - return _swigfaiss.IndexBinaryIDMap_remove_ids(self, sel) - - def range_search(self, n, x, radius, result, params=None): - return _swigfaiss.IndexBinaryIDMap_range_search(self, n, x, radius, result, params) - - def merge_from(self, otherIndex, add_id=0): - return _swigfaiss.IndexBinaryIDMap_merge_from(self, otherIndex, add_id) - - def check_compatible_for_merge(self, otherIndex): - return _swigfaiss.IndexBinaryIDMap_check_compatible_for_merge(self, otherIndex) - - def sa_code_size(self): - return _swigfaiss.IndexBinaryIDMap_sa_code_size(self) - - def add_sa_codes(self, n, x, xids): - return _swigfaiss.IndexBinaryIDMap_add_sa_codes(self, n, x, xids) - __swig_destroy__ = _swigfaiss.delete_IndexBinaryIDMap - - def __init__(self, *args): - _swigfaiss.IndexBinaryIDMap_swiginit(self, _swigfaiss.new_IndexBinaryIDMap(*args)) - -# Register IndexBinaryIDMap in _swigfaiss: -_swigfaiss.IndexBinaryIDMap_swigregister(IndexBinaryIDMap) -class IndexIDMap2(IndexIDMap): - r""" - same as IndexIDMap but also provides an efficient reconstruction - implementation via a 2-way index - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - rev_map = property(_swigfaiss.IndexIDMap2_rev_map_get, _swigfaiss.IndexIDMap2_rev_map_set) - - def construct_rev_map(self): - r"""make the rev_map from scratch""" - return _swigfaiss.IndexIDMap2_construct_rev_map(self) - - def add_with_ids(self, n, x, xids): - return _swigfaiss.IndexIDMap2_add_with_ids(self, n, x, xids) - - def add_with_ids_ex(self, n, x, numeric_type, xids): - return _swigfaiss.IndexIDMap2_add_with_ids_ex(self, n, x, numeric_type, xids) - - def add_sa_codes(self, n, x, xids): - return _swigfaiss.IndexIDMap2_add_sa_codes(self, n, x, xids) - - def remove_ids(self, sel): - return _swigfaiss.IndexIDMap2_remove_ids(self, sel) - - def reconstruct(self, key, recons): - return _swigfaiss.IndexIDMap2_reconstruct(self, key, recons) - - def check_consistency(self): - r"""check that the rev_map and the id_map are in sync""" - return _swigfaiss.IndexIDMap2_check_consistency(self) - - def merge_from(self, otherIndex, add_id=0): - return _swigfaiss.IndexIDMap2_merge_from(self, otherIndex, add_id) - __swig_destroy__ = _swigfaiss.delete_IndexIDMap2 - - def __init__(self, *args): - _swigfaiss.IndexIDMap2_swiginit(self, _swigfaiss.new_IndexIDMap2(*args)) - -# Register IndexIDMap2 in _swigfaiss: -_swigfaiss.IndexIDMap2_swigregister(IndexIDMap2) -class IndexBinaryIDMap2(IndexBinaryIDMap): - r""" - same as IndexIDMap but also provides an efficient reconstruction - implementation via a 2-way index - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - rev_map = property(_swigfaiss.IndexBinaryIDMap2_rev_map_get, _swigfaiss.IndexBinaryIDMap2_rev_map_set) - - def construct_rev_map(self): - r"""make the rev_map from scratch""" - return _swigfaiss.IndexBinaryIDMap2_construct_rev_map(self) - - def add_with_ids(self, n, x, xids): - return _swigfaiss.IndexBinaryIDMap2_add_with_ids(self, n, x, xids) - - def add_with_ids_ex(self, n, x, numeric_type, xids): - return _swigfaiss.IndexBinaryIDMap2_add_with_ids_ex(self, n, x, numeric_type, xids) - - def add_sa_codes(self, n, x, xids): - return _swigfaiss.IndexBinaryIDMap2_add_sa_codes(self, n, x, xids) - - def remove_ids(self, sel): - return _swigfaiss.IndexBinaryIDMap2_remove_ids(self, sel) - - def reconstruct(self, key, recons): - return _swigfaiss.IndexBinaryIDMap2_reconstruct(self, key, recons) - - def check_consistency(self): - r"""check that the rev_map and the id_map are in sync""" - return _swigfaiss.IndexBinaryIDMap2_check_consistency(self) - - def merge_from(self, otherIndex, add_id=0): - return _swigfaiss.IndexBinaryIDMap2_merge_from(self, otherIndex, add_id) - __swig_destroy__ = _swigfaiss.delete_IndexBinaryIDMap2 - - def __init__(self, *args): - _swigfaiss.IndexBinaryIDMap2_swiginit(self, _swigfaiss.new_IndexBinaryIDMap2(*args)) - -# Register IndexBinaryIDMap2 in _swigfaiss: -_swigfaiss.IndexBinaryIDMap2_swigregister(IndexBinaryIDMap2) -EXACT_TOPK = _swigfaiss.EXACT_TOPK -APPROX_TOPK_BUCKETS_B32_D2 = _swigfaiss.APPROX_TOPK_BUCKETS_B32_D2 -APPROX_TOPK_BUCKETS_B8_D3 = _swigfaiss.APPROX_TOPK_BUCKETS_B8_D3 -APPROX_TOPK_BUCKETS_B16_D2 = _swigfaiss.APPROX_TOPK_BUCKETS_B16_D2 -APPROX_TOPK_BUCKETS_B8_D2 = _swigfaiss.APPROX_TOPK_BUCKETS_B8_D2 - -def approx_topk_by_mode(mode, beam_size, n_per_beam, distances, k, bh_val, bh_ids): - return _swigfaiss.approx_topk_by_mode(mode, beam_size, n_per_beam, distances, k, bh_val, bh_ids) - -def downcast_index(index): - return _swigfaiss.downcast_index(index) - -def downcast_VectorTransform(vt): - return _swigfaiss.downcast_VectorTransform(vt) - -def downcast_IndexBinary(index): - return _swigfaiss.downcast_IndexBinary(index) - -def downcast_InvertedLists(il): - return _swigfaiss.downcast_InvertedLists(il) - -def downcast_AdditiveQuantizer(aq): - return _swigfaiss.downcast_AdditiveQuantizer(aq) - -def downcast_Quantizer(aq): - return _swigfaiss.downcast_Quantizer(aq) - -def write_index(*args): - return _swigfaiss.write_index(*args) - -def write_index_binary(*args): - return _swigfaiss.write_index_binary(*args) - -def read_index(*args): - return _swigfaiss.read_index(*args) - -def read_index_binary(*args): - return _swigfaiss.read_index_binary(*args) - -def write_VectorTransform(*args): - return _swigfaiss.write_VectorTransform(*args) - -def read_VectorTransform(*args): - return _swigfaiss.read_VectorTransform(*args) - -def read_ProductQuantizer(*args): - return _swigfaiss.read_ProductQuantizer(*args) - -def write_ProductQuantizer(*args): - return _swigfaiss.write_ProductQuantizer(*args) - -def write_InvertedLists(ils, f): - return _swigfaiss.write_InvertedLists(ils, f) - -def read_InvertedLists(reader, io_flags=0): - return _swigfaiss.read_InvertedLists(reader, io_flags) - -def get_deserialization_loop_limit(): - return _swigfaiss.get_deserialization_loop_limit() - -def set_deserialization_loop_limit(value): - return _swigfaiss.set_deserialization_loop_limit(value) - -def get_deserialization_vector_byte_limit(): - return _swigfaiss.get_deserialization_vector_byte_limit() - -def set_deserialization_vector_byte_limit(value): - return _swigfaiss.set_deserialization_vector_byte_limit(value) - -def get_deserialization_lattice_r2_limit(): - return _swigfaiss.get_deserialization_lattice_r2_limit() - -def set_deserialization_lattice_r2_limit(value): - return _swigfaiss.set_deserialization_lattice_r2_limit(value) - -def clone_index(arg1): - return _swigfaiss.clone_index(arg1) -class Cloner(object): - r""" - Cloner class, useful to override classes with other cloning - functions. The cloning function above just calls - Cloner::clone_Index. - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - - def clone_VectorTransform(self, arg2): - return _swigfaiss.Cloner_clone_VectorTransform(self, arg2) - - def clone_Index(self, arg2): - return _swigfaiss.Cloner_clone_Index(self, arg2) - - def clone_IndexIVF(self, arg2): - return _swigfaiss.Cloner_clone_IndexIVF(self, arg2) - __swig_destroy__ = _swigfaiss.delete_Cloner - - def __init__(self): - _swigfaiss.Cloner_swiginit(self, _swigfaiss.new_Cloner()) - -# Register Cloner in _swigfaiss: -_swigfaiss.Cloner_swigregister(Cloner) -IO_FLAG_SKIP_STORAGE = cvar.IO_FLAG_SKIP_STORAGE -IO_FLAG_READ_ONLY = cvar.IO_FLAG_READ_ONLY -IO_FLAG_ONDISK_SAME_DIR = cvar.IO_FLAG_ONDISK_SAME_DIR -IO_FLAG_SKIP_IVF_DATA = cvar.IO_FLAG_SKIP_IVF_DATA -IO_FLAG_SKIP_PRECOMPUTE_TABLE = cvar.IO_FLAG_SKIP_PRECOMPUTE_TABLE -IO_FLAG_PQ_SKIP_SDC_TABLE = cvar.IO_FLAG_PQ_SKIP_SDC_TABLE -IO_FLAG_MMAP = cvar.IO_FLAG_MMAP -IO_FLAG_MMAP_IFC = cvar.IO_FLAG_MMAP_IFC - - -def clone_Quantizer(quant): - return _swigfaiss.clone_Quantizer(quant) - -def clone_binary_index(index): - return _swigfaiss.clone_binary_index(index) -class AutoTuneCriterion(object): - r""" - Evaluation criterion. Returns a performance measure in [0,1], - higher is better. - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - - def __init__(self, *args, **kwargs): - raise AttributeError("No constructor defined - class is abstract") - __repr__ = _swig_repr - nq = property(_swigfaiss.AutoTuneCriterion_nq_get, _swigfaiss.AutoTuneCriterion_nq_set, doc=r"""nb of queries this criterion is evaluated on""") - nnn = property(_swigfaiss.AutoTuneCriterion_nnn_get, _swigfaiss.AutoTuneCriterion_nnn_set, doc=r"""nb of NNs that the query should request""") - gt_nnn = property(_swigfaiss.AutoTuneCriterion_gt_nnn_get, _swigfaiss.AutoTuneCriterion_gt_nnn_set, doc=r"""nb of GT NNs required to evaluate criterion""") - gt_D = property(_swigfaiss.AutoTuneCriterion_gt_D_get, _swigfaiss.AutoTuneCriterion_gt_D_set, doc=r"""Ground-truth distances (size nq * gt_nnn)""") - gt_I = property(_swigfaiss.AutoTuneCriterion_gt_I_get, _swigfaiss.AutoTuneCriterion_gt_I_set, doc=r"""Ground-truth indexes (size nq * gt_nnn)""") - - def set_groundtruth(self, gt_nnn, gt_D_in, gt_I_in): - r""" - Initializes the gt_D and gt_I vectors. Must be called before evaluating - - :type gt_D_in: float - :param gt_D_in: size nq * gt_nnn - :type gt_I_in: int - :param gt_I_in: size nq * gt_nnn - """ - return _swigfaiss.AutoTuneCriterion_set_groundtruth(self, gt_nnn, gt_D_in, gt_I_in) - - def evaluate(self, D, I): - r""" - Evaluate the criterion. - - :type D: float - :param D: size nq * nnn - :type I: int - :param I: size nq * nnn - :rtype: float - :return: the criterion, between 0 and 1. Larger is better. - """ - return _swigfaiss.AutoTuneCriterion_evaluate(self, D, I) - __swig_destroy__ = _swigfaiss.delete_AutoTuneCriterion - -# Register AutoTuneCriterion in _swigfaiss: -_swigfaiss.AutoTuneCriterion_swigregister(AutoTuneCriterion) -class OneRecallAtRCriterion(AutoTuneCriterion): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - R = property(_swigfaiss.OneRecallAtRCriterion_R_get, _swigfaiss.OneRecallAtRCriterion_R_set) - - def __init__(self, nq, R): - _swigfaiss.OneRecallAtRCriterion_swiginit(self, _swigfaiss.new_OneRecallAtRCriterion(nq, R)) - - def evaluate(self, D, I): - return _swigfaiss.OneRecallAtRCriterion_evaluate(self, D, I) - __swig_destroy__ = _swigfaiss.delete_OneRecallAtRCriterion - -# Register OneRecallAtRCriterion in _swigfaiss: -_swigfaiss.OneRecallAtRCriterion_swigregister(OneRecallAtRCriterion) -class IntersectionCriterion(AutoTuneCriterion): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - R = property(_swigfaiss.IntersectionCriterion_R_get, _swigfaiss.IntersectionCriterion_R_set) - - def __init__(self, nq, R): - _swigfaiss.IntersectionCriterion_swiginit(self, _swigfaiss.new_IntersectionCriterion(nq, R)) - - def evaluate(self, D, I): - return _swigfaiss.IntersectionCriterion_evaluate(self, D, I) - __swig_destroy__ = _swigfaiss.delete_IntersectionCriterion - -# Register IntersectionCriterion in _swigfaiss: -_swigfaiss.IntersectionCriterion_swigregister(IntersectionCriterion) -class OperatingPoint(object): - r""" - Maintains a list of experimental results. Each operating point is a - (perf, t, key) triplet, where higher perf and lower t is - better. The key field is an arbitrary identifier for the operating point. - - Includes primitives to extract the Pareto-optimal operating points in the - (perf, t) space. - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - perf = property(_swigfaiss.OperatingPoint_perf_get, _swigfaiss.OperatingPoint_perf_set, doc=r"""performance measure (output of a Criterion)""") - t = property(_swigfaiss.OperatingPoint_t_get, _swigfaiss.OperatingPoint_t_set, doc=r"""corresponding execution time (ms)""") - key = property(_swigfaiss.OperatingPoint_key_get, _swigfaiss.OperatingPoint_key_set, doc=r"""key that identifies this op pt""") - cno = property(_swigfaiss.OperatingPoint_cno_get, _swigfaiss.OperatingPoint_cno_set, doc=r"""integer identifier""") - - def __init__(self): - _swigfaiss.OperatingPoint_swiginit(self, _swigfaiss.new_OperatingPoint()) - __swig_destroy__ = _swigfaiss.delete_OperatingPoint - -# Register OperatingPoint in _swigfaiss: -_swigfaiss.OperatingPoint_swigregister(OperatingPoint) -class OperatingPoints(object): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - all_pts = property(_swigfaiss.OperatingPoints_all_pts_get, _swigfaiss.OperatingPoints_all_pts_set, doc=r"""all operating points""") - optimal_pts = property(_swigfaiss.OperatingPoints_optimal_pts_get, _swigfaiss.OperatingPoints_optimal_pts_set, doc=r"""optimal operating points, sorted by perf""") - - def __init__(self): - _swigfaiss.OperatingPoints_swiginit(self, _swigfaiss.new_OperatingPoints()) - - def merge_with(self, *args): - r"""add operating points from other to this, with a prefix to the keys""" - return _swigfaiss.OperatingPoints_merge_with(self, *args) - - def clear(self): - return _swigfaiss.OperatingPoints_clear(self) - - def add(self, perf, t, key, cno=0): - r"""add a performance measure. Return whether it is an optimal point""" - return _swigfaiss.OperatingPoints_add(self, perf, t, key, cno) - - def t_for_perf(self, perf): - r"""get time required to obtain a given performance measure""" - return _swigfaiss.OperatingPoints_t_for_perf(self, perf) - - def display(self, only_optimal=True): - r"""easy-to-read output""" - return _swigfaiss.OperatingPoints_display(self, only_optimal) - - def all_to_gnuplot(self, fname): - r"""output to a format easy to digest by gnuplot""" - return _swigfaiss.OperatingPoints_all_to_gnuplot(self, fname) - - def optimal_to_gnuplot(self, fname): - return _swigfaiss.OperatingPoints_optimal_to_gnuplot(self, fname) - __swig_destroy__ = _swigfaiss.delete_OperatingPoints - -# Register OperatingPoints in _swigfaiss: -_swigfaiss.OperatingPoints_swigregister(OperatingPoints) -class ParameterRange(object): - r"""possible values of a parameter, sorted from least to most expensive/accurate""" - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - name = property(_swigfaiss.ParameterRange_name_get, _swigfaiss.ParameterRange_name_set) - values = property(_swigfaiss.ParameterRange_values_get, _swigfaiss.ParameterRange_values_set) - - def __init__(self): - _swigfaiss.ParameterRange_swiginit(self, _swigfaiss.new_ParameterRange()) - __swig_destroy__ = _swigfaiss.delete_ParameterRange - -# Register ParameterRange in _swigfaiss: -_swigfaiss.ParameterRange_swigregister(ParameterRange) -class ParameterSpace(object): - r"""Uses a-priori knowledge on the Faiss indexes to extract tunable parameters.""" - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - parameter_ranges = property(_swigfaiss.ParameterSpace_parameter_ranges_get, _swigfaiss.ParameterSpace_parameter_ranges_set, doc=r"""all tunable parameters""") - verbose = property(_swigfaiss.ParameterSpace_verbose_get, _swigfaiss.ParameterSpace_verbose_set, doc=r"""verbosity during exploration""") - n_experiments = property(_swigfaiss.ParameterSpace_n_experiments_get, _swigfaiss.ParameterSpace_n_experiments_set, doc=r"""nb of experiments during optimization (0 = try all combinations)""") - batchsize = property(_swigfaiss.ParameterSpace_batchsize_get, _swigfaiss.ParameterSpace_batchsize_set, doc=r"""maximum number of queries to submit at a time.""") - thread_over_batches = property(_swigfaiss.ParameterSpace_thread_over_batches_get, _swigfaiss.ParameterSpace_thread_over_batches_set, doc=r""" - use multithreading over batches (useful to benchmark - independent single-searches) - """) - min_test_duration = property(_swigfaiss.ParameterSpace_min_test_duration_get, _swigfaiss.ParameterSpace_min_test_duration_set, doc=r""" - run tests several times until they reach at least this - duration (to avoid jittering in MT mode) - """) - - def __init__(self): - _swigfaiss.ParameterSpace_swiginit(self, _swigfaiss.new_ParameterSpace()) - - def n_combinations(self): - r"""nb of combinations, = product of values sizes""" - return _swigfaiss.ParameterSpace_n_combinations(self) - - def combination_ge(self, c1, c2): - r"""returns whether combinations c1 >= c2 in the tuple sense""" - return _swigfaiss.ParameterSpace_combination_ge(self, c1, c2) - - def combination_name(self, cno): - r"""get string representation of the combination""" - return _swigfaiss.ParameterSpace_combination_name(self, cno) - - def display(self): - r"""print a description on stdout""" - return _swigfaiss.ParameterSpace_display(self) - - def add_range(self, name): - r"""add a new parameter (or return it if it exists)""" - return _swigfaiss.ParameterSpace_add_range(self, name) - - def initialize(self, index): - r"""initialize with reasonable parameters for the index""" - return _swigfaiss.ParameterSpace_initialize(self, index) - - def set_index_parameters(self, *args): - r""" - *Overload 1:* - set a combination of parameters on an index - - | - - *Overload 2:* - set a combination of parameters described by a string - - | - - *Overload 3:* - set a combination of parameters on a binary index - - | - - *Overload 4:* - set a combination of parameters described by a string on a binary index - """ - return _swigfaiss.ParameterSpace_set_index_parameters(self, *args) - - def set_index_parameter(self, *args): - r""" - *Overload 1:* - set one of the parameters - - | - - *Overload 2:* - set one of the parameters on a binary index - """ - return _swigfaiss.ParameterSpace_set_index_parameter(self, *args) - - def update_bounds(self, cno, op, upper_bound_perf, lower_bound_t): - r""" - find an upper bound on the performance and a lower bound on t - for configuration cno given another operating point op - """ - return _swigfaiss.ParameterSpace_update_bounds(self, cno, op, upper_bound_perf, lower_bound_t) - - def explore(self, index, nq, xq, crit, ops): - r""" - explore operating points - :type index: :py:class:`Index` - :param index: index to run on - :type xq: float - :param xq: query vectors (size nq * index.d) - :type crit: :py:class:`AutoTuneCriterion` - :param crit: selection criterion - :type ops: :py:class:`OperatingPoints` - :param ops: resulting operating points - """ - return _swigfaiss.ParameterSpace_explore(self, index, nq, xq, crit, ops) - __swig_destroy__ = _swigfaiss.delete_ParameterSpace - -# Register ParameterSpace in _swigfaiss: -_swigfaiss.ParameterSpace_swigregister(ParameterSpace) - -def index_factory(*args): - r""" - Build an index with the sequence of processing steps described in - the string. - """ - return _swigfaiss.index_factory(*args) - -def index_binary_factory(d, description, own_invlists=True): - return _swigfaiss.index_binary_factory(d, description, own_invlists) -class MatrixStats(object): - r""" - Reports some statistics on a dataset and comments on them. - - It is a class rather than a function so that all stats can also be - accessed from code - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - - def __init__(self, n, d, x): - _swigfaiss.MatrixStats_swiginit(self, _swigfaiss.new_MatrixStats(n, d, x)) - comments = property(_swigfaiss.MatrixStats_comments_get, _swigfaiss.MatrixStats_comments_set) - n = property(_swigfaiss.MatrixStats_n_get, _swigfaiss.MatrixStats_n_set) - d = property(_swigfaiss.MatrixStats_d_get, _swigfaiss.MatrixStats_d_set) - n_collision = property(_swigfaiss.MatrixStats_n_collision_get, _swigfaiss.MatrixStats_n_collision_set) - n_valid = property(_swigfaiss.MatrixStats_n_valid_get, _swigfaiss.MatrixStats_n_valid_set) - n0 = property(_swigfaiss.MatrixStats_n0_get, _swigfaiss.MatrixStats_n0_set) - min_norm2 = property(_swigfaiss.MatrixStats_min_norm2_get, _swigfaiss.MatrixStats_min_norm2_set) - max_norm2 = property(_swigfaiss.MatrixStats_max_norm2_get, _swigfaiss.MatrixStats_max_norm2_set) - hash_value = property(_swigfaiss.MatrixStats_hash_value_get, _swigfaiss.MatrixStats_hash_value_set) - per_dim_stats = property(_swigfaiss.MatrixStats_per_dim_stats_get, _swigfaiss.MatrixStats_per_dim_stats_set) - occurrences = property(_swigfaiss.MatrixStats_occurrences_get, _swigfaiss.MatrixStats_occurrences_set) - buf = property(_swigfaiss.MatrixStats_buf_get, _swigfaiss.MatrixStats_buf_set) - nbuf = property(_swigfaiss.MatrixStats_nbuf_get, _swigfaiss.MatrixStats_nbuf_set) - - def do_comment(self, fmt): - return _swigfaiss.MatrixStats_do_comment(self, fmt) - __swig_destroy__ = _swigfaiss.delete_MatrixStats - -# Register MatrixStats in _swigfaiss: -_swigfaiss.MatrixStats_swigregister(MatrixStats) -class PyCallbackIOWriter(IOWriter): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - callback = property(_swigfaiss.PyCallbackIOWriter_callback_get, _swigfaiss.PyCallbackIOWriter_callback_set) - bs = property(_swigfaiss.PyCallbackIOWriter_bs_get, _swigfaiss.PyCallbackIOWriter_bs_set) - - def __init__(self, *args): - r""" - Callback: Python function that takes a bytes object and - returns the number of bytes successfully written. - """ - _swigfaiss.PyCallbackIOWriter_swiginit(self, _swigfaiss.new_PyCallbackIOWriter(*args)) - - def __call__(self, ptrv, size, nitems): - return _swigfaiss.PyCallbackIOWriter___call__(self, ptrv, size, nitems) - __swig_destroy__ = _swigfaiss.delete_PyCallbackIOWriter - -# Register PyCallbackIOWriter in _swigfaiss: -_swigfaiss.PyCallbackIOWriter_swigregister(PyCallbackIOWriter) -class PyCallbackIOReader(IOReader): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - callback = property(_swigfaiss.PyCallbackIOReader_callback_get, _swigfaiss.PyCallbackIOReader_callback_set) - bs = property(_swigfaiss.PyCallbackIOReader_bs_get, _swigfaiss.PyCallbackIOReader_bs_set) - - def __init__(self, *args): - r""" - Callback: Python function that takes a size and returns a - bytes object with the resulting read - """ - _swigfaiss.PyCallbackIOReader_swiginit(self, _swigfaiss.new_PyCallbackIOReader(*args)) - - def __call__(self, ptrv, size, nitems): - return _swigfaiss.PyCallbackIOReader___call__(self, ptrv, size, nitems) - __swig_destroy__ = _swigfaiss.delete_PyCallbackIOReader - -# Register PyCallbackIOReader in _swigfaiss: -_swigfaiss.PyCallbackIOReader_swigregister(PyCallbackIOReader) -class PyCallbackIDSelector(IDSelector): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - callback = property(_swigfaiss.PyCallbackIDSelector_callback_get, _swigfaiss.PyCallbackIDSelector_callback_set) - - def __init__(self, callback): - _swigfaiss.PyCallbackIDSelector_swiginit(self, _swigfaiss.new_PyCallbackIDSelector(callback)) - - def is_member(self, id): - return _swigfaiss.PyCallbackIDSelector_is_member(self, id) - __swig_destroy__ = _swigfaiss.delete_PyCallbackIDSelector - -# Register PyCallbackIDSelector in _swigfaiss: -_swigfaiss.PyCallbackIDSelector_swigregister(PyCallbackIDSelector) -class PyCallbackShardingFunction(ShardingFunction): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - callback = property(_swigfaiss.PyCallbackShardingFunction_callback_get, _swigfaiss.PyCallbackShardingFunction_callback_set) - - def __call__(self, i, shard_count): - return _swigfaiss.PyCallbackShardingFunction___call__(self, i, shard_count) - __swig_destroy__ = _swigfaiss.delete_PyCallbackShardingFunction - - def __init__(self, *args): - _swigfaiss.PyCallbackShardingFunction_swiginit(self, _swigfaiss.new_PyCallbackShardingFunction(*args)) - -# Register PyCallbackShardingFunction in _swigfaiss: -_swigfaiss.PyCallbackShardingFunction_swigregister(PyCallbackShardingFunction) -class float_minheap_array_t(object): - r""" - a template structure for a set of [min|max]-heaps it is tailored - so that the actual data of the heaps can just live in compact - arrays. - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - nh = property(_swigfaiss.float_minheap_array_t_nh_get, _swigfaiss.float_minheap_array_t_nh_set, doc=r"""number of heaps""") - k = property(_swigfaiss.float_minheap_array_t_k_get, _swigfaiss.float_minheap_array_t_k_set, doc=r"""allocated size per heap""") - ids = property(_swigfaiss.float_minheap_array_t_ids_get, _swigfaiss.float_minheap_array_t_ids_set, doc=r"""identifiers (size nh * k)""") - val = property(_swigfaiss.float_minheap_array_t_val_get, _swigfaiss.float_minheap_array_t_val_set, doc=r"""values (distances or similarities), size nh * k""") - - def get_val(self, key): - r"""Return the list of values for a heap""" - return _swigfaiss.float_minheap_array_t_get_val(self, key) - - def get_ids(self, key): - r"""Corresponding identifiers""" - return _swigfaiss.float_minheap_array_t_get_ids(self, key) - - def heapify(self): - r"""prepare all the heaps before adding""" - return _swigfaiss.float_minheap_array_t_heapify(self) - - def addn(self, nj, vin, j0=0, i0=0, ni=-1): - r""" - add nj elements to heaps i0:i0+ni, with sequential ids - - :type nj: int - :param nj: nb of elements to add to each heap - :type vin: float - :param vin: elements to add, size ni * nj - :type j0: int, optional - :param j0: add this to the ids that are added - :type i0: int, optional - :param i0: first heap to update - :type ni: int, optional - :param ni: nb of elements to update (-1 = use nh) - """ - return _swigfaiss.float_minheap_array_t_addn(self, nj, vin, j0, i0, ni) - - def addn_with_ids(self, nj, vin, id_in=None, id_stride=0, i0=0, ni=-1): - r""" - same as addn - - :type id_in: int, optional - :param id_in: ids of the elements to add, size ni * nj - :type id_stride: int, optional - :param id_stride: stride for id_in - """ - return _swigfaiss.float_minheap_array_t_addn_with_ids(self, nj, vin, id_in, id_stride, i0, ni) - - def addn_query_subset_with_ids(self, nsubset, subset, nj, vin, id_in=None, id_stride=0): - r""" - same as addn_with_ids, but for just a subset of queries - - :type nsubset: int - :param nsubset: number of query entries to update - :type subset: int - :param subset: indexes of queries to update, in 0..nh-1, size nsubset - """ - return _swigfaiss.float_minheap_array_t_addn_query_subset_with_ids(self, nsubset, subset, nj, vin, id_in, id_stride) - - def reorder(self): - r"""reorder all the heaps""" - return _swigfaiss.float_minheap_array_t_reorder(self) - - def per_line_extrema(self, vals_out, idx_out): - r""" - this is not really a heap function. It just finds the per-line - extrema of each line of array D - :type vals_out: float - :param vals_out: extreme value of each line (size nh, or NULL) - :type idx_out: int - :param idx_out: index of extreme value (size nh or NULL) - """ - return _swigfaiss.float_minheap_array_t_per_line_extrema(self, vals_out, idx_out) - - def __init__(self): - _swigfaiss.float_minheap_array_t_swiginit(self, _swigfaiss.new_float_minheap_array_t()) - __swig_destroy__ = _swigfaiss.delete_float_minheap_array_t - -# Register float_minheap_array_t in _swigfaiss: -_swigfaiss.float_minheap_array_t_swigregister(float_minheap_array_t) -class int_minheap_array_t(object): - r""" - a template structure for a set of [min|max]-heaps it is tailored - so that the actual data of the heaps can just live in compact - arrays. - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - nh = property(_swigfaiss.int_minheap_array_t_nh_get, _swigfaiss.int_minheap_array_t_nh_set, doc=r"""number of heaps""") - k = property(_swigfaiss.int_minheap_array_t_k_get, _swigfaiss.int_minheap_array_t_k_set, doc=r"""allocated size per heap""") - ids = property(_swigfaiss.int_minheap_array_t_ids_get, _swigfaiss.int_minheap_array_t_ids_set, doc=r"""identifiers (size nh * k)""") - val = property(_swigfaiss.int_minheap_array_t_val_get, _swigfaiss.int_minheap_array_t_val_set, doc=r"""values (distances or similarities), size nh * k""") - - def get_val(self, key): - r"""Return the list of values for a heap""" - return _swigfaiss.int_minheap_array_t_get_val(self, key) - - def get_ids(self, key): - r"""Corresponding identifiers""" - return _swigfaiss.int_minheap_array_t_get_ids(self, key) - - def heapify(self): - r"""prepare all the heaps before adding""" - return _swigfaiss.int_minheap_array_t_heapify(self) - - def addn(self, nj, vin, j0=0, i0=0, ni=-1): - r""" - add nj elements to heaps i0:i0+ni, with sequential ids - - :type nj: int - :param nj: nb of elements to add to each heap - :type vin: int - :param vin: elements to add, size ni * nj - :type j0: int, optional - :param j0: add this to the ids that are added - :type i0: int, optional - :param i0: first heap to update - :type ni: int, optional - :param ni: nb of elements to update (-1 = use nh) - """ - return _swigfaiss.int_minheap_array_t_addn(self, nj, vin, j0, i0, ni) - - def addn_with_ids(self, nj, vin, id_in=None, id_stride=0, i0=0, ni=-1): - r""" - same as addn - - :type id_in: int, optional - :param id_in: ids of the elements to add, size ni * nj - :type id_stride: int, optional - :param id_stride: stride for id_in - """ - return _swigfaiss.int_minheap_array_t_addn_with_ids(self, nj, vin, id_in, id_stride, i0, ni) - - def addn_query_subset_with_ids(self, nsubset, subset, nj, vin, id_in=None, id_stride=0): - r""" - same as addn_with_ids, but for just a subset of queries - - :type nsubset: int - :param nsubset: number of query entries to update - :type subset: int - :param subset: indexes of queries to update, in 0..nh-1, size nsubset - """ - return _swigfaiss.int_minheap_array_t_addn_query_subset_with_ids(self, nsubset, subset, nj, vin, id_in, id_stride) - - def reorder(self): - r"""reorder all the heaps""" - return _swigfaiss.int_minheap_array_t_reorder(self) - - def per_line_extrema(self, vals_out, idx_out): - r""" - this is not really a heap function. It just finds the per-line - extrema of each line of array D - :type vals_out: int - :param vals_out: extreme value of each line (size nh, or NULL) - :type idx_out: int - :param idx_out: index of extreme value (size nh or NULL) - """ - return _swigfaiss.int_minheap_array_t_per_line_extrema(self, vals_out, idx_out) - - def __init__(self): - _swigfaiss.int_minheap_array_t_swiginit(self, _swigfaiss.new_int_minheap_array_t()) - __swig_destroy__ = _swigfaiss.delete_int_minheap_array_t - -# Register int_minheap_array_t in _swigfaiss: -_swigfaiss.int_minheap_array_t_swigregister(int_minheap_array_t) -class float_maxheap_array_t(object): - r""" - a template structure for a set of [min|max]-heaps it is tailored - so that the actual data of the heaps can just live in compact - arrays. - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - nh = property(_swigfaiss.float_maxheap_array_t_nh_get, _swigfaiss.float_maxheap_array_t_nh_set, doc=r"""number of heaps""") - k = property(_swigfaiss.float_maxheap_array_t_k_get, _swigfaiss.float_maxheap_array_t_k_set, doc=r"""allocated size per heap""") - ids = property(_swigfaiss.float_maxheap_array_t_ids_get, _swigfaiss.float_maxheap_array_t_ids_set, doc=r"""identifiers (size nh * k)""") - val = property(_swigfaiss.float_maxheap_array_t_val_get, _swigfaiss.float_maxheap_array_t_val_set, doc=r"""values (distances or similarities), size nh * k""") - - def get_val(self, key): - r"""Return the list of values for a heap""" - return _swigfaiss.float_maxheap_array_t_get_val(self, key) - - def get_ids(self, key): - r"""Corresponding identifiers""" - return _swigfaiss.float_maxheap_array_t_get_ids(self, key) - - def heapify(self): - r"""prepare all the heaps before adding""" - return _swigfaiss.float_maxheap_array_t_heapify(self) - - def addn(self, nj, vin, j0=0, i0=0, ni=-1): - r""" - add nj elements to heaps i0:i0+ni, with sequential ids - - :type nj: int - :param nj: nb of elements to add to each heap - :type vin: float - :param vin: elements to add, size ni * nj - :type j0: int, optional - :param j0: add this to the ids that are added - :type i0: int, optional - :param i0: first heap to update - :type ni: int, optional - :param ni: nb of elements to update (-1 = use nh) - """ - return _swigfaiss.float_maxheap_array_t_addn(self, nj, vin, j0, i0, ni) - - def addn_with_ids(self, nj, vin, id_in=None, id_stride=0, i0=0, ni=-1): - r""" - same as addn - - :type id_in: int, optional - :param id_in: ids of the elements to add, size ni * nj - :type id_stride: int, optional - :param id_stride: stride for id_in - """ - return _swigfaiss.float_maxheap_array_t_addn_with_ids(self, nj, vin, id_in, id_stride, i0, ni) - - def addn_query_subset_with_ids(self, nsubset, subset, nj, vin, id_in=None, id_stride=0): - r""" - same as addn_with_ids, but for just a subset of queries - - :type nsubset: int - :param nsubset: number of query entries to update - :type subset: int - :param subset: indexes of queries to update, in 0..nh-1, size nsubset - """ - return _swigfaiss.float_maxheap_array_t_addn_query_subset_with_ids(self, nsubset, subset, nj, vin, id_in, id_stride) - - def reorder(self): - r"""reorder all the heaps""" - return _swigfaiss.float_maxheap_array_t_reorder(self) - - def per_line_extrema(self, vals_out, idx_out): - r""" - this is not really a heap function. It just finds the per-line - extrema of each line of array D - :type vals_out: float - :param vals_out: extreme value of each line (size nh, or NULL) - :type idx_out: int - :param idx_out: index of extreme value (size nh or NULL) - """ - return _swigfaiss.float_maxheap_array_t_per_line_extrema(self, vals_out, idx_out) - - def __init__(self): - _swigfaiss.float_maxheap_array_t_swiginit(self, _swigfaiss.new_float_maxheap_array_t()) - __swig_destroy__ = _swigfaiss.delete_float_maxheap_array_t - -# Register float_maxheap_array_t in _swigfaiss: -_swigfaiss.float_maxheap_array_t_swigregister(float_maxheap_array_t) -class int_maxheap_array_t(object): - r""" - a template structure for a set of [min|max]-heaps it is tailored - so that the actual data of the heaps can just live in compact - arrays. - """ - - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - nh = property(_swigfaiss.int_maxheap_array_t_nh_get, _swigfaiss.int_maxheap_array_t_nh_set, doc=r"""number of heaps""") - k = property(_swigfaiss.int_maxheap_array_t_k_get, _swigfaiss.int_maxheap_array_t_k_set, doc=r"""allocated size per heap""") - ids = property(_swigfaiss.int_maxheap_array_t_ids_get, _swigfaiss.int_maxheap_array_t_ids_set, doc=r"""identifiers (size nh * k)""") - val = property(_swigfaiss.int_maxheap_array_t_val_get, _swigfaiss.int_maxheap_array_t_val_set, doc=r"""values (distances or similarities), size nh * k""") - - def get_val(self, key): - r"""Return the list of values for a heap""" - return _swigfaiss.int_maxheap_array_t_get_val(self, key) - - def get_ids(self, key): - r"""Corresponding identifiers""" - return _swigfaiss.int_maxheap_array_t_get_ids(self, key) - - def heapify(self): - r"""prepare all the heaps before adding""" - return _swigfaiss.int_maxheap_array_t_heapify(self) - - def addn(self, nj, vin, j0=0, i0=0, ni=-1): - r""" - add nj elements to heaps i0:i0+ni, with sequential ids - - :type nj: int - :param nj: nb of elements to add to each heap - :type vin: int - :param vin: elements to add, size ni * nj - :type j0: int, optional - :param j0: add this to the ids that are added - :type i0: int, optional - :param i0: first heap to update - :type ni: int, optional - :param ni: nb of elements to update (-1 = use nh) - """ - return _swigfaiss.int_maxheap_array_t_addn(self, nj, vin, j0, i0, ni) - - def addn_with_ids(self, nj, vin, id_in=None, id_stride=0, i0=0, ni=-1): - r""" - same as addn - - :type id_in: int, optional - :param id_in: ids of the elements to add, size ni * nj - :type id_stride: int, optional - :param id_stride: stride for id_in - """ - return _swigfaiss.int_maxheap_array_t_addn_with_ids(self, nj, vin, id_in, id_stride, i0, ni) - - def addn_query_subset_with_ids(self, nsubset, subset, nj, vin, id_in=None, id_stride=0): - r""" - same as addn_with_ids, but for just a subset of queries - - :type nsubset: int - :param nsubset: number of query entries to update - :type subset: int - :param subset: indexes of queries to update, in 0..nh-1, size nsubset - """ - return _swigfaiss.int_maxheap_array_t_addn_query_subset_with_ids(self, nsubset, subset, nj, vin, id_in, id_stride) - - def reorder(self): - r"""reorder all the heaps""" - return _swigfaiss.int_maxheap_array_t_reorder(self) - - def per_line_extrema(self, vals_out, idx_out): - r""" - this is not really a heap function. It just finds the per-line - extrema of each line of array D - :type vals_out: int - :param vals_out: extreme value of each line (size nh, or NULL) - :type idx_out: int - :param idx_out: index of extreme value (size nh or NULL) - """ - return _swigfaiss.int_maxheap_array_t_per_line_extrema(self, vals_out, idx_out) - - def __init__(self): - _swigfaiss.int_maxheap_array_t_swiginit(self, _swigfaiss.new_int_maxheap_array_t()) - __swig_destroy__ = _swigfaiss.delete_int_maxheap_array_t - -# Register int_maxheap_array_t in _swigfaiss: -_swigfaiss.int_maxheap_array_t_swigregister(int_maxheap_array_t) - -def CMin_float_partition_fuzzy(vals, ids, n, q_min, q_max, q_out): - r""" - partitions the table into 0:q and q:n where all elements above q are >= all - elements below q (for C = CMax, for CMin comparisons are reversed) - - Returns the partition threshold. The elements q:n are destroyed on output. - """ - return _swigfaiss.CMin_float_partition_fuzzy(vals, ids, n, q_min, q_max, q_out) - -def CMax_float_partition_fuzzy(vals, ids, n, q_min, q_max, q_out): - r""" - partitions the table into 0:q and q:n where all elements above q are >= all - elements below q (for C = CMax, for CMin comparisons are reversed) - - Returns the partition threshold. The elements q:n are destroyed on output. - """ - return _swigfaiss.CMax_float_partition_fuzzy(vals, ids, n, q_min, q_max, q_out) -class AlignedTableUint8(object): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - tab = property(_swigfaiss.AlignedTableUint8_tab_get, _swigfaiss.AlignedTableUint8_tab_set) - numel = property(_swigfaiss.AlignedTableUint8_numel_get, _swigfaiss.AlignedTableUint8_numel_set) - - @staticmethod - def round_capacity(n): - return _swigfaiss.AlignedTableUint8_round_capacity(n) - - def __init__(self, *args): - _swigfaiss.AlignedTableUint8_swiginit(self, _swigfaiss.new_AlignedTableUint8(*args)) - - def itemsize(self): - return _swigfaiss.AlignedTableUint8_itemsize(self) - - def resize(self, n): - return _swigfaiss.AlignedTableUint8_resize(self, n) - - def clear(self): - return _swigfaiss.AlignedTableUint8_clear(self) - - def size(self): - return _swigfaiss.AlignedTableUint8_size(self) - - def nbytes(self): - return _swigfaiss.AlignedTableUint8_nbytes(self) - - def get(self, *args): - return _swigfaiss.AlignedTableUint8_get(self, *args) - - def data(self, *args): - return _swigfaiss.AlignedTableUint8_data(self, *args) - __swig_destroy__ = _swigfaiss.delete_AlignedTableUint8 - -# Register AlignedTableUint8 in _swigfaiss: -_swigfaiss.AlignedTableUint8_swigregister(AlignedTableUint8) -class AlignedTableUint16(object): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - tab = property(_swigfaiss.AlignedTableUint16_tab_get, _swigfaiss.AlignedTableUint16_tab_set) - numel = property(_swigfaiss.AlignedTableUint16_numel_get, _swigfaiss.AlignedTableUint16_numel_set) - - @staticmethod - def round_capacity(n): - return _swigfaiss.AlignedTableUint16_round_capacity(n) - - def __init__(self, *args): - _swigfaiss.AlignedTableUint16_swiginit(self, _swigfaiss.new_AlignedTableUint16(*args)) - - def itemsize(self): - return _swigfaiss.AlignedTableUint16_itemsize(self) - - def resize(self, n): - return _swigfaiss.AlignedTableUint16_resize(self, n) - - def clear(self): - return _swigfaiss.AlignedTableUint16_clear(self) - - def size(self): - return _swigfaiss.AlignedTableUint16_size(self) - - def nbytes(self): - return _swigfaiss.AlignedTableUint16_nbytes(self) - - def get(self, *args): - return _swigfaiss.AlignedTableUint16_get(self, *args) - - def data(self, *args): - return _swigfaiss.AlignedTableUint16_data(self, *args) - __swig_destroy__ = _swigfaiss.delete_AlignedTableUint16 - -# Register AlignedTableUint16 in _swigfaiss: -_swigfaiss.AlignedTableUint16_swigregister(AlignedTableUint16) -class AlignedTableFloat32(object): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - tab = property(_swigfaiss.AlignedTableFloat32_tab_get, _swigfaiss.AlignedTableFloat32_tab_set) - numel = property(_swigfaiss.AlignedTableFloat32_numel_get, _swigfaiss.AlignedTableFloat32_numel_set) - - @staticmethod - def round_capacity(n): - return _swigfaiss.AlignedTableFloat32_round_capacity(n) - - def __init__(self, *args): - _swigfaiss.AlignedTableFloat32_swiginit(self, _swigfaiss.new_AlignedTableFloat32(*args)) - - def itemsize(self): - return _swigfaiss.AlignedTableFloat32_itemsize(self) - - def resize(self, n): - return _swigfaiss.AlignedTableFloat32_resize(self, n) - - def clear(self): - return _swigfaiss.AlignedTableFloat32_clear(self) - - def size(self): - return _swigfaiss.AlignedTableFloat32_size(self) - - def nbytes(self): - return _swigfaiss.AlignedTableFloat32_nbytes(self) - - def get(self, *args): - return _swigfaiss.AlignedTableFloat32_get(self, *args) - - def data(self, *args): - return _swigfaiss.AlignedTableFloat32_data(self, *args) - __swig_destroy__ = _swigfaiss.delete_AlignedTableFloat32 - -# Register AlignedTableFloat32 in _swigfaiss: -_swigfaiss.AlignedTableFloat32_swigregister(AlignedTableFloat32) -class MaybeOwnedVectorUInt8(object): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - is_owned = property(_swigfaiss.MaybeOwnedVectorUInt8_is_owned_get, _swigfaiss.MaybeOwnedVectorUInt8_is_owned_set) - owned_data = property(_swigfaiss.MaybeOwnedVectorUInt8_owned_data_get, _swigfaiss.MaybeOwnedVectorUInt8_owned_data_set) - view_data = property(_swigfaiss.MaybeOwnedVectorUInt8_view_data_get, _swigfaiss.MaybeOwnedVectorUInt8_view_data_set) - view_size = property(_swigfaiss.MaybeOwnedVectorUInt8_view_size_get, _swigfaiss.MaybeOwnedVectorUInt8_view_size_set) - owner = property(_swigfaiss.MaybeOwnedVectorUInt8_owner_get, _swigfaiss.MaybeOwnedVectorUInt8_owner_set) - c_ptr = property(_swigfaiss.MaybeOwnedVectorUInt8_c_ptr_get, _swigfaiss.MaybeOwnedVectorUInt8_c_ptr_set) - c_size = property(_swigfaiss.MaybeOwnedVectorUInt8_c_size_get, _swigfaiss.MaybeOwnedVectorUInt8_c_size_set) - - def __init__(self, *args): - _swigfaiss.MaybeOwnedVectorUInt8_swiginit(self, _swigfaiss.new_MaybeOwnedVectorUInt8(*args)) - - @staticmethod - def create_view(address, n_elements, owner): - return _swigfaiss.MaybeOwnedVectorUInt8_create_view(address, n_elements, owner) - - def data(self, *args): - return _swigfaiss.MaybeOwnedVectorUInt8_data(self, *args) - - def size(self): - return _swigfaiss.MaybeOwnedVectorUInt8_size(self) - - def byte_size(self): - return _swigfaiss.MaybeOwnedVectorUInt8_byte_size(self) - - def at(self, *args): - return _swigfaiss.MaybeOwnedVectorUInt8_at(self, *args) - - def begin(self, *args): - return _swigfaiss.MaybeOwnedVectorUInt8_begin(self, *args) - - def end(self, *args): - return _swigfaiss.MaybeOwnedVectorUInt8_end(self, *args) - - def erase(self, begin, end): - return _swigfaiss.MaybeOwnedVectorUInt8_erase(self, begin, end) - - def clear(self): - return _swigfaiss.MaybeOwnedVectorUInt8_clear(self) - - def resize(self, *args): - return _swigfaiss.MaybeOwnedVectorUInt8_resize(self, *args) - __swig_destroy__ = _swigfaiss.delete_MaybeOwnedVectorUInt8 - -# Register MaybeOwnedVectorUInt8 in _swigfaiss: -_swigfaiss.MaybeOwnedVectorUInt8_swigregister(MaybeOwnedVectorUInt8) -class MaybeOwnedVectorInt32(object): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - is_owned = property(_swigfaiss.MaybeOwnedVectorInt32_is_owned_get, _swigfaiss.MaybeOwnedVectorInt32_is_owned_set) - owned_data = property(_swigfaiss.MaybeOwnedVectorInt32_owned_data_get, _swigfaiss.MaybeOwnedVectorInt32_owned_data_set) - view_data = property(_swigfaiss.MaybeOwnedVectorInt32_view_data_get, _swigfaiss.MaybeOwnedVectorInt32_view_data_set) - view_size = property(_swigfaiss.MaybeOwnedVectorInt32_view_size_get, _swigfaiss.MaybeOwnedVectorInt32_view_size_set) - owner = property(_swigfaiss.MaybeOwnedVectorInt32_owner_get, _swigfaiss.MaybeOwnedVectorInt32_owner_set) - c_ptr = property(_swigfaiss.MaybeOwnedVectorInt32_c_ptr_get, _swigfaiss.MaybeOwnedVectorInt32_c_ptr_set) - c_size = property(_swigfaiss.MaybeOwnedVectorInt32_c_size_get, _swigfaiss.MaybeOwnedVectorInt32_c_size_set) - - def __init__(self, *args): - _swigfaiss.MaybeOwnedVectorInt32_swiginit(self, _swigfaiss.new_MaybeOwnedVectorInt32(*args)) - - @staticmethod - def create_view(address, n_elements, owner): - return _swigfaiss.MaybeOwnedVectorInt32_create_view(address, n_elements, owner) - - def data(self, *args): - return _swigfaiss.MaybeOwnedVectorInt32_data(self, *args) - - def size(self): - return _swigfaiss.MaybeOwnedVectorInt32_size(self) - - def byte_size(self): - return _swigfaiss.MaybeOwnedVectorInt32_byte_size(self) - - def at(self, *args): - return _swigfaiss.MaybeOwnedVectorInt32_at(self, *args) - - def begin(self, *args): - return _swigfaiss.MaybeOwnedVectorInt32_begin(self, *args) - - def end(self, *args): - return _swigfaiss.MaybeOwnedVectorInt32_end(self, *args) - - def erase(self, begin, end): - return _swigfaiss.MaybeOwnedVectorInt32_erase(self, begin, end) - - def clear(self): - return _swigfaiss.MaybeOwnedVectorInt32_clear(self) - - def resize(self, *args): - return _swigfaiss.MaybeOwnedVectorInt32_resize(self, *args) - __swig_destroy__ = _swigfaiss.delete_MaybeOwnedVectorInt32 - -# Register MaybeOwnedVectorInt32 in _swigfaiss: -_swigfaiss.MaybeOwnedVectorInt32_swigregister(MaybeOwnedVectorInt32) -class MaybeOwnedVectorFloat32(object): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - is_owned = property(_swigfaiss.MaybeOwnedVectorFloat32_is_owned_get, _swigfaiss.MaybeOwnedVectorFloat32_is_owned_set) - owned_data = property(_swigfaiss.MaybeOwnedVectorFloat32_owned_data_get, _swigfaiss.MaybeOwnedVectorFloat32_owned_data_set) - view_data = property(_swigfaiss.MaybeOwnedVectorFloat32_view_data_get, _swigfaiss.MaybeOwnedVectorFloat32_view_data_set) - view_size = property(_swigfaiss.MaybeOwnedVectorFloat32_view_size_get, _swigfaiss.MaybeOwnedVectorFloat32_view_size_set) - owner = property(_swigfaiss.MaybeOwnedVectorFloat32_owner_get, _swigfaiss.MaybeOwnedVectorFloat32_owner_set) - c_ptr = property(_swigfaiss.MaybeOwnedVectorFloat32_c_ptr_get, _swigfaiss.MaybeOwnedVectorFloat32_c_ptr_set) - c_size = property(_swigfaiss.MaybeOwnedVectorFloat32_c_size_get, _swigfaiss.MaybeOwnedVectorFloat32_c_size_set) - - def __init__(self, *args): - _swigfaiss.MaybeOwnedVectorFloat32_swiginit(self, _swigfaiss.new_MaybeOwnedVectorFloat32(*args)) - - @staticmethod - def create_view(address, n_elements, owner): - return _swigfaiss.MaybeOwnedVectorFloat32_create_view(address, n_elements, owner) - - def data(self, *args): - return _swigfaiss.MaybeOwnedVectorFloat32_data(self, *args) - - def size(self): - return _swigfaiss.MaybeOwnedVectorFloat32_size(self) - - def byte_size(self): - return _swigfaiss.MaybeOwnedVectorFloat32_byte_size(self) - - def at(self, *args): - return _swigfaiss.MaybeOwnedVectorFloat32_at(self, *args) - - def begin(self, *args): - return _swigfaiss.MaybeOwnedVectorFloat32_begin(self, *args) - - def end(self, *args): - return _swigfaiss.MaybeOwnedVectorFloat32_end(self, *args) - - def erase(self, begin, end): - return _swigfaiss.MaybeOwnedVectorFloat32_erase(self, begin, end) - - def clear(self): - return _swigfaiss.MaybeOwnedVectorFloat32_clear(self) - - def resize(self, *args): - return _swigfaiss.MaybeOwnedVectorFloat32_resize(self, *args) - __swig_destroy__ = _swigfaiss.delete_MaybeOwnedVectorFloat32 - -# Register MaybeOwnedVectorFloat32 in _swigfaiss: -_swigfaiss.MaybeOwnedVectorFloat32_swigregister(MaybeOwnedVectorFloat32) - -def CMin_uint16_partition_fuzzy(*args): - return _swigfaiss.CMin_uint16_partition_fuzzy(*args) - -def CMax_uint16_partition_fuzzy(*args): - return _swigfaiss.CMax_uint16_partition_fuzzy(*args) - -def merge_knn_results_CMin(*args): - return _swigfaiss.merge_knn_results_CMin(*args) - -def merge_knn_results_CMax(*args): - return _swigfaiss.merge_knn_results_CMax(*args) -class MapLong2Long(object): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - map = property(_swigfaiss.MapLong2Long_map_get, _swigfaiss.MapLong2Long_map_set) - - def add(self, n, keys, vals): - return _swigfaiss.MapLong2Long_add(self, n, keys, vals) - - def search(self, key): - return _swigfaiss.MapLong2Long_search(self, key) - - def search_multiple(self, n, keys, vals): - return _swigfaiss.MapLong2Long_search_multiple(self, n, keys, vals) - - def __init__(self): - _swigfaiss.MapLong2Long_swiginit(self, _swigfaiss.new_MapLong2Long()) - __swig_destroy__ = _swigfaiss.delete_MapLong2Long - -# Register MapLong2Long in _swigfaiss: -_swigfaiss.MapLong2Long_swigregister(MapLong2Long) - -def omp_set_num_threads(num_threads): - return _swigfaiss.omp_set_num_threads(num_threads) - -def omp_get_max_threads(): - return _swigfaiss.omp_get_max_threads() - -def memcpy(dest, src, n): - return _swigfaiss.memcpy(dest, src, n) -class PythonInterruptCallback(InterruptCallback): - thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag") - __repr__ = _swig_repr - - def want_interrupt(self): - return _swigfaiss.PythonInterruptCallback_want_interrupt(self) - - @staticmethod - def reset(): - return _swigfaiss.PythonInterruptCallback_reset() - - def __init__(self): - _swigfaiss.PythonInterruptCallback_swiginit(self, _swigfaiss.new_PythonInterruptCallback()) - __swig_destroy__ = _swigfaiss.delete_PythonInterruptCallback - -# Register PythonInterruptCallback in _swigfaiss: -_swigfaiss.PythonInterruptCallback_swigregister(PythonInterruptCallback) - -def swig_ptr(a): - return _swigfaiss.swig_ptr(a) - -def rev_swig_ptr(*args): - return _swigfaiss.rev_swig_ptr(*args) - -def cast_integer_to_uint8_ptr(x): - return _swigfaiss.cast_integer_to_uint8_ptr(x) - -def cast_integer_to_float_ptr(x): - return _swigfaiss.cast_integer_to_float_ptr(x) - -def cast_integer_to_idx_t_ptr(x): - return _swigfaiss.cast_integer_to_idx_t_ptr(x) - -def cast_integer_to_int_ptr(x): - return _swigfaiss.cast_integer_to_int_ptr(x) - -def cast_integer_to_void_ptr(x): - return _swigfaiss.cast_integer_to_void_ptr(x) - -def swig_version(): - return _swigfaiss.swig_version() - diff --git a/bundle/python-cpu/Lib/site-packages/faiss_cpu-1.15.0.dist-info/DELVEWHEEL b/bundle/python-cpu/Lib/site-packages/faiss_cpu-1.15.0.dist-info/DELVEWHEEL deleted file mode 100644 index c0f4d26fb619814fc17f5b02fe06b058cd462c1d..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/faiss_cpu-1.15.0.dist-info/DELVEWHEEL +++ /dev/null @@ -1,2 +0,0 @@ -Version: 1.13.0 -Arguments: ['C:\\Users\\runneradmin\\AppData\\Local\\Temp\\cibw-run-fm8v1x01\\cp310-win_amd64\\build\\venv\\Scripts\\delvewheel', 'repair', '-w', 'C:\\Users\\runneradmin\\AppData\\Local\\Temp\\cibw-run-fm8v1x01\\cp310-win_amd64\\repaired_wheel', 'C:\\Users\\runneradmin\\AppData\\Local\\Temp\\cibw-run-fm8v1x01\\cp310-win_amd64\\built_wheel\\faiss_cpu-1.15.0-cp310-cp310-win_amd64.whl', '--add-path', 'C:/openblas/bin', '--ignore-in-wheel'] diff --git a/bundle/python-cpu/Lib/site-packages/faiss_cpu-1.15.0.dist-info/INSTALLER b/bundle/python-cpu/Lib/site-packages/faiss_cpu-1.15.0.dist-info/INSTALLER deleted file mode 100644 index a1b589e38a32041e49332e5e81c2d363dc418d68..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/faiss_cpu-1.15.0.dist-info/INSTALLER +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/bundle/python-cpu/Lib/site-packages/faiss_cpu-1.15.0.dist-info/METADATA b/bundle/python-cpu/Lib/site-packages/faiss_cpu-1.15.0.dist-info/METADATA deleted file mode 100644 index f66dea23bff9ff6d129443e0e42eddda31e96244..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/faiss_cpu-1.15.0.dist-info/METADATA +++ /dev/null @@ -1,124 +0,0 @@ -Metadata-Version: 2.4 -Name: faiss-cpu -Version: 1.15.0 -Summary: A library for efficient similarity search and clustering of dense vectors. -Keywords: search,nearest-neighbors,clustering,vectors,similarity -Author: Meta AI Research -License-Expression: MIT -License-File: LICENSE -License-File: THIRD_PARTY_NOTICES -Classifier: Development Status :: 5 - Production/Stable -Classifier: Intended Audience :: Developers -Classifier: Intended Audience :: Science/Research -Classifier: Operating System :: MacOS :: MacOS X -Classifier: Operating System :: Microsoft :: Windows -Classifier: Operating System :: POSIX :: Linux -Classifier: Programming Language :: C++ -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3.11 -Classifier: Programming Language :: Python :: 3.12 -Classifier: Programming Language :: Python :: 3.13 -Classifier: Programming Language :: Python :: 3.14 -Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence -Project-URL: Homepage, https://github.com/facebookresearch/faiss -Project-URL: Documentation, https://github.com/facebookresearch/faiss/wiki -Project-URL: Repository, https://github.com/facebookresearch/faiss -Project-URL: Issues, https://github.com/facebookresearch/faiss/issues -Requires-Python: >=3.10 -Requires-Dist: numpy>=1.25 -Requires-Dist: packaging -Description-Content-Type: text/markdown - -# Faiss - -Faiss is a library for efficient similarity search and clustering of dense vectors. It contains algorithms that search in sets of vectors of any size, up to ones that possibly do not fit in RAM. It also contains supporting code for evaluation and parameter tuning. Faiss is written in C++ with complete wrappers for Python/numpy. Some of the most useful algorithms are implemented on the GPU. It is developed primarily at Meta's [Fundamental AI Research](https://ai.facebook.com/) group. - -## News - -See [CHANGELOG.md](CHANGELOG.md) for detailed information about latest features. - -## Introduction - -Faiss contains several methods for similarity search. It assumes that the instances are represented as vectors and are identified by an integer, and that the vectors can be compared with L2 (Euclidean) distances or dot products. Vectors that are similar to a query vector are those that have the lowest L2 distance or the highest dot product with the query vector. It also supports cosine similarity, since this is a dot product on normalized vectors. - -Some of the methods, like those based on binary vectors and compact quantization codes, solely use a compressed representation of the vectors and do not require to keep the original vectors. This generally comes at the cost of a less precise search but these methods can scale to billions of vectors in main memory on a single server. Other methods, like HNSW and NSG add an indexing structure on top of the raw vectors to make searching more efficient. - -The GPU implementation can accept input from either CPU or GPU memory. On a server with GPUs, the GPU indexes can be used a drop-in replacement for the CPU indexes (e.g., replace `IndexFlatL2` with `GpuIndexFlatL2`) and copies to/from GPU memory are handled automatically. Results will be faster however if both input and output remain resident on the GPU. Both single and multi-GPU usage is supported. - -## Installing - -Faiss comes with precompiled libraries for Anaconda in Python, see [faiss-cpu](https://anaconda.org/pytorch/faiss-cpu), [faiss-gpu](https://anaconda.org/pytorch/faiss-gpu) and [faiss-gpu-cuvs](https://anaconda.org/pytorch/faiss-gpu-cuvs). The library is mostly implemented in C++, the only dependency is a [BLAS](https://en.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms) implementation. Optional GPU support is provided via CUDA or AMD ROCm, and the Python interface is also optional. The backend GPU implementations of NVIDIA [cuVS](https://github.com/rapidsai/cuvs) can also be enabled optionally. It compiles with cmake. See [INSTALL.md](INSTALL.md) for details. - -## How Faiss works - -Faiss is built around an index type that stores a set of vectors, and provides a function to search in them with L2 and/or dot product vector comparison. Some index types are simple baselines, such as exact search. Most of the available indexing structures correspond to various trade-offs with respect to - -- search time -- search quality -- memory used per index vector -- training time -- adding time -- need for external data for unsupervised training - -The optional GPU implementation provides what is likely (as of March 2017) the fastest exact and approximate (compressed-domain) nearest neighbor search implementation for high-dimensional vectors, fastest Lloyd's k-means, and fastest small k-selection algorithm known. [The implementation is detailed here](https://arxiv.org/abs/1702.08734). - -## Full documentation of Faiss - -The following are entry points for documentation: - -- the full documentation can be found on the [wiki page](https://github.com/facebookresearch/faiss/wiki), including a [tutorial](https://github.com/facebookresearch/faiss/wiki/Getting-started), a [FAQ](https://github.com/facebookresearch/faiss/wiki/FAQ) and a [troubleshooting section](https://github.com/facebookresearch/faiss/wiki/Troubleshooting) -- the [doxygen documentation](https://faiss.ai/) gives per-class information extracted from code comments -- to reproduce results from our research papers, [Polysemous codes](https://arxiv.org/abs/1609.01882) and [Billion-scale similarity search with GPUs](https://arxiv.org/abs/1702.08734), refer to the [benchmarks README](benchs/README.md). For [ -Link and code: Fast indexing with graphs and compact regression codes](https://arxiv.org/abs/1804.09996), see the [link_and_code README](benchs/link_and_code) - -## Authors - -The main authors of Faiss are: -- [Hervé Jégou](https://github.com/jegou) initiated the Faiss project and wrote its first implementation -- [Matthijs Douze](https://github.com/mdouze) implemented most of the CPU Faiss -- [Jeff Johnson](https://github.com/wickedfoo) implemented all of the GPU Faiss -- [Lucas Hosseini](https://github.com/beauby) implemented the binary indexes and the build system -- [Chengqi Deng](https://github.com/KinglittleQ) implemented NSG, NNdescent and much of the additive quantization code. -- [Alexandr Guzhva](https://github.com/alexanderguzhva) many optimizations: SIMD, memory allocation and layout, fast decoding kernels for vector codecs, etc. -- [Gergely Szilvasy](https://github.com/algoriddle) build system, benchmarking framework. - -## Reference - -References to cite when you use Faiss in a research paper: -``` -@article{douze2024faiss, - title={The Faiss library}, - author={Matthijs Douze and Alexandr Guzhva and Chengqi Deng and Jeff Johnson and Gergely Szilvasy and Pierre-Emmanuel Mazaré and Maria Lomeli and Lucas Hosseini and Hervé Jégou}, - year={2024}, - eprint={2401.08281}, - archivePrefix={arXiv}, - primaryClass={cs.LG} -} -``` -For the GPU version of Faiss, please cite: -``` -@article{johnson2019billion, - title={Billion-scale similarity search with {GPUs}}, - author={Johnson, Jeff and Douze, Matthijs and J{\'e}gou, Herv{\'e}}, - journal={IEEE Transactions on Big Data}, - volume={7}, - number={3}, - pages={535--547}, - year={2019}, - publisher={IEEE} -} -``` - -## Join the Faiss community - -For public discussion of Faiss or for questions, visit https://github.com/facebookresearch/faiss/discussions. - -We monitor the [issues page](https://github.com/facebookresearch/faiss/issues) of the repository. -You can report bugs, ask questions, etc. - -## Legal - -Faiss is MIT-licensed, refer to the [LICENSE file](https://github.com/facebookresearch/faiss/blob/main/LICENSE) in the top level directory. - -Copyright © Meta Platforms, Inc. diff --git a/bundle/python-cpu/Lib/site-packages/faiss_cpu-1.15.0.dist-info/RECORD b/bundle/python-cpu/Lib/site-packages/faiss_cpu-1.15.0.dist-info/RECORD deleted file mode 100644 index 18483778f5424ddda09f9bc444351b0a2fd8952e..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/faiss_cpu-1.15.0.dist-info/RECORD +++ /dev/null @@ -1,64 +0,0 @@ -faiss/__init__.py,sha256=wZrkF7fk6Ha-tz-lcuWdIL95lPJ5Qdg5InA1ZIb28yA,21606 -faiss/__init__.pyi,sha256=LKajJAT1Mc1iVj2Z4Ne63HwY_9AFF0ExvbfWOxU8fsY,153231 -faiss/__pycache__/__init__.cpython-310.pyc,, -faiss/__pycache__/array_conversions.cpython-310.pyc,, -faiss/__pycache__/class_wrappers.cpython-310.pyc,, -faiss/__pycache__/extra_wrappers.cpython-310.pyc,, -faiss/__pycache__/gpu_wrappers.cpython-310.pyc,, -faiss/__pycache__/loader.cpython-310.pyc,, -faiss/__pycache__/swigfaiss.cpython-310.pyc,, -faiss/_swigfaiss.pyd,sha256=Y2lul2uzYKAbAbdHWz7UEPaTMWni2DByJXpXKNq1wSA,5585920 -faiss/array_conversions.py,sha256=z62k0IUN5KRkWlY1V6veS9N9loAzCxISZjk-jczeMy0,6057 -faiss/class_wrappers.py,sha256=LZMddaM_AgjTYt8rHTmDkq0_0lcepCfz6NU2IazEAOk,56980 -faiss/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -faiss/contrib/__pycache__/__init__.cpython-310.pyc,, -faiss/contrib/__pycache__/big_batch_search.cpython-310.pyc,, -faiss/contrib/__pycache__/client_server.cpython-310.pyc,, -faiss/contrib/__pycache__/clustering.cpython-310.pyc,, -faiss/contrib/__pycache__/datasets.cpython-310.pyc,, -faiss/contrib/__pycache__/evaluation.cpython-310.pyc,, -faiss/contrib/__pycache__/exhaustive_search.cpython-310.pyc,, -faiss/contrib/__pycache__/factory_tools.cpython-310.pyc,, -faiss/contrib/__pycache__/inspect_tools.cpython-310.pyc,, -faiss/contrib/__pycache__/ivf_tools.cpython-310.pyc,, -faiss/contrib/__pycache__/ondisk.cpython-310.pyc,, -faiss/contrib/__pycache__/rpc.cpython-310.pyc,, -faiss/contrib/__pycache__/torch_utils.cpython-310.pyc,, -faiss/contrib/__pycache__/vecs_io.cpython-310.pyc,, -faiss/contrib/big_batch_search.py,sha256=gfN4CdJdCzLb9Zc23A9XtXvl9FBWyVUJmeRKPv4QUFg,18657 -faiss/contrib/client_server.py,sha256=yLg5cCBsoyGrD4a3hu2TTp8L_44yBnSe2ALtLrjK6mo,2776 -faiss/contrib/clustering.py,sha256=3OO7x8ArPxVSW3PqjTitZW3sDQd8nahllKNzCUWQvmw,16451 -faiss/contrib/datasets.py,sha256=XuDvIxPkCCZeVAntozaVBEHVaN4W08abQqGUb6CPHdY,17865 -faiss/contrib/evaluation.py,sha256=se3-wu_Fu09HmHb_4Lx4x-pTpPiJLuHnXBBViNs1vWo,15433 -faiss/contrib/exhaustive_search.py,sha256=SLa7UjPlpjJxuIqrDZLJd27ud5y7N1TVSFHLyqBIpsE,12899 -faiss/contrib/factory_tools.py,sha256=xoQUH6CB_a4MAYvCkH60tfDg41l_r2dgApylL72_aNk,7054 -faiss/contrib/inspect_tools.py,sha256=2y01Uhb4-w4_77VdBJur_zK_BBqIkF9vQ7tMLtRMQSQ,3787 -faiss/contrib/ivf_tools.py,sha256=NrYKr_sFv4mgCVaNSFIqzvNb7HAnixp1pM2IuvgWALU,4986 -faiss/contrib/ondisk.py,sha256=0birRO7TNgtC4_1vYBFMIhoDqlv6qJ3bC6lpwUIfyy8,2160 -faiss/contrib/rpc.py,sha256=9Th07LYKO8duE-mtAOi00Y0UYO39tyYYbNEqHmXX-Jo,7647 -faiss/contrib/torch/README.md,sha256=vF49uS9H9pGeDefHK-YrMM5gmRs3vqo4VlV2xlNRJZw,218 -faiss/contrib/torch/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -faiss/contrib/torch/__pycache__/__init__.cpython-310.pyc,, -faiss/contrib/torch/__pycache__/clustering.cpython-310.pyc,, -faiss/contrib/torch/__pycache__/quantization.cpython-310.pyc,, -faiss/contrib/torch/clustering.py,sha256=dODq1Oe4lbycNbXGWtZ3_ecCB4edqqwjq39-FCbYMJw,1735 -faiss/contrib/torch/quantization.py,sha256=7Jqz_GvSAXCPQIAFItxuVcZzBu8iigTWDD9zW298l00,2893 -faiss/contrib/torch_utils.py,sha256=FnkWPE_YjoatkVR0q-dCpmC2iVDBmKszCU-HEybF6dc,29739 -faiss/contrib/vecs_io.py,sha256=gGCGQvuaHg912LzWJVFUpsxAcOiR48e0hnMZ0sJMPZ8,5697 -faiss/extra_wrappers.py,sha256=zlvrVDF3sXJ6Ti8M5I67pV0yv7s5fEI5zAS1JHSsrQk,24351 -faiss/faiss.dll,sha256=7kapTdGqyWfBAJGiOF2TNAYRqJzuLH4o5YGFh2K3OUM,7428608 -faiss/gpu_wrappers.py,sha256=DQv-oO3vbH63QhQe-liTZOduNnzh8MQKv6oATxd2e_g,9563 -faiss/loader.py,sha256=o-9WTRHz0OkEv_WTy99TkhljYaRfvSZBnBObuYQSpck,8632 -faiss/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -faiss/swigfaiss.py,sha256=q_LKOsvhMPvKj55u19HRd8fsCSxnEyCY7X-gsOOtQGE,671346 -faiss_cpu-1.15.0.dist-info/DELVEWHEEL,sha256=uWkITleavrRf42UvFkpWLaESYG3duCgZVOiabHntYrc,457 -faiss_cpu-1.15.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -faiss_cpu-1.15.0.dist-info/METADATA,sha256=MFkMJeZsHYx2v2M79Yb-8Yg1T7Iq4ksQveaj9TpqzNw,7785 -faiss_cpu-1.15.0.dist-info/RECORD,, -faiss_cpu-1.15.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -faiss_cpu-1.15.0.dist-info/WHEEL,sha256=dLsqnLqoa03X-KKRvIZetJerE-pAfZT9U_wzO7zFOgQ,105 -faiss_cpu-1.15.0.dist-info/licenses/LICENSE,sha256=8IqUv7C9wdfxy1m62vD4xVGxDbhxGFYi2_H9A2r_qcs,1107 -faiss_cpu-1.15.0.dist-info/licenses/THIRD_PARTY_NOTICES,sha256=xZTQJum-hkwSSD99Fj9lsADyOQnTOzKc3-_Vqc9T1fY,22241 -faiss_cpu.libs/libopenblas.dll,sha256=6CTPn8IuWUmAfOmVoy5BOjRfuX5j5tEM-_QaqGOCGTw,51076488 -faiss_cpu.libs/msvcp140.dll,sha256=pMIim9wqKmMKzcCVtNhgCOXD47x3cxdDVPPaT1vrnN4,575056 -faiss_cpu.libs/vcomp140.dll,sha256=-W86FNiNiEbzHzqzikkDBM59bk9w-uQwTGPlnHrqLTA,213072 diff --git a/bundle/python-cpu/Lib/site-packages/faiss_cpu-1.15.0.dist-info/REQUESTED b/bundle/python-cpu/Lib/site-packages/faiss_cpu-1.15.0.dist-info/REQUESTED deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/bundle/python-cpu/Lib/site-packages/faiss_cpu-1.15.0.dist-info/WHEEL b/bundle/python-cpu/Lib/site-packages/faiss_cpu-1.15.0.dist-info/WHEEL deleted file mode 100644 index 1b26578e474ada8147cf896584d64b24f79eea22..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/faiss_cpu-1.15.0.dist-info/WHEEL +++ /dev/null @@ -1,5 +0,0 @@ -Wheel-Version: 1.0 -Generator: scikit-build-core 1.0.3 -Root-Is-Purelib: false -Tag: cp310-cp310-win_amd64 - diff --git a/bundle/python-cpu/Lib/site-packages/faiss_cpu-1.15.0.dist-info/licenses/LICENSE b/bundle/python-cpu/Lib/site-packages/faiss_cpu-1.15.0.dist-info/licenses/LICENSE deleted file mode 100644 index a5d83a84b7140fd65fe29238b11c559d317ed460..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/faiss_cpu-1.15.0.dist-info/licenses/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) Facebook, Inc. and its affiliates. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/bundle/python-cpu/Lib/site-packages/faiss_cpu-1.15.0.dist-info/licenses/THIRD_PARTY_NOTICES b/bundle/python-cpu/Lib/site-packages/faiss_cpu-1.15.0.dist-info/licenses/THIRD_PARTY_NOTICES deleted file mode 100644 index 93ddde874eeb6cb115d6e1900fbdf6b11afd88cc..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/faiss_cpu-1.15.0.dist-info/licenses/THIRD_PARTY_NOTICES +++ /dev/null @@ -1,410 +0,0 @@ -Third-Party Notices for faiss pip wheels -======================================== - -The faiss pip wheels bundle the following third-party libraries as binary -dependencies. Their licenses are reproduced below. - - -1. OpenBLAS (Linux, Windows wheels) -------------------------------------------- - -Copyright (c) 2011-2014, The OpenBLAS Project -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - 3. Neither the name of the OpenBLAS project nor the names of - its contributors may be used to endorse or promote products - derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -License: BSD-3-Clause -Source: https://github.com/OpenMathLib/OpenBLAS - - -2. LLVM OpenMP Runtime (libomp) (macOS wheels) ------------------------------------------------ - -============================================================================== -The LLVM Project is under the Apache License v2.0 with LLVM Exceptions: -============================================================================== - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - ----- LLVM Exceptions to the Apache 2.0 License ---- - -As an exception, if, as a result of your compiling your source code, portions -of this Software are embedded into an Object form of such source code, you -may redistribute such embedded portions in such Object form without complying -with the conditions of Sections 4(a), 4(b) and 4(d) of the License. - -In addition, if you combine or link compiled forms of this Software with -software that is licensed under the GPLv2 ("Combined Software") and if a -court of competent jurisdiction determines that the patent provision (Section -3), the indemnity provision (Section 9) or other Section of the License -conflicts with the conditions of the GPLv2, you may retroactively and -prospectively choose to deem waived or otherwise exclude such Section(s) of -the License, but only in their entirety and only with respect to the Combined -Software. - -============================================================================== -Software from third parties included in the LLVM Project: -============================================================================== -The LLVM Project contains third party software which is under different license -terms. All such code will be identified clearly using at least one of two -mechanisms: -1) It will be in a separate directory tree with its own `LICENSE.txt` or - `LICENSE` file at the top containing the specific license and restrictions - which apply to that software, or -2) It will contain specific license and restriction terms at the top of every - file. - -============================================================================== -Legacy LLVM License (https://llvm.org/docs/DeveloperPolicy.html#legacy): -============================================================================== - -The software contained in this directory tree is dual licensed under both the -University of Illinois "BSD-Like" license and the MIT license. As a user of -this code you may choose to use it under either license. As a contributor, -you agree to allow your code to be used under both. The full text of the -relevant licenses is included below. - -In addition, a license agreement from the copyright/patent holders of the -software contained in this directory tree is included below. - -============================================================================== - -University of Illinois/NCSA -Open Source License - -Copyright (c) 1997-2019 Intel Corporation - -All rights reserved. - -Developed by: - OpenMP Runtime Team - Intel Corporation - http://www.openmprtl.org - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal with -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimers. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimers in the - documentation and/or other materials provided with the distribution. - - * Neither the names of Intel Corporation OpenMP Runtime Team nor the - names of its contributors may be used to endorse or promote products - derived from this Software without specific prior written permission. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE -SOFTWARE. - -============================================================================== - -Copyright (c) 1997-2019 Intel Corporation - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -============================================================================== - -Intel Corporation - -Software Grant License Agreement ("Agreement") - -Except for the license granted herein to you, Intel Corporation ("Intel") reserves -all right, title, and interest in and to the Software (defined below). - -Definition - -"Software" means the code and documentation as well as any original work of -authorship, including any modifications or additions to an existing work, that -is intentionally submitted by Intel to llvm.org (http://llvm.org) ("LLVM") for -inclusion in, or documentation of, any of the products owned or managed by LLVM -(the "Work"). For the purposes of this definition, "submitted" means any form of -electronic, verbal, or written communication sent to LLVM or its -representatives, including but not limited to communication on electronic -mailing lists, source code control systems, and issue tracking systems that are -managed by, or on behalf of, LLVM for the purpose of discussing and improving -the Work, but excluding communication that is conspicuously marked otherwise. - -1. Grant of Copyright License. Subject to the terms and conditions of this - Agreement, Intel hereby grants to you and to recipients of the Software - distributed by LLVM a perpetual, worldwide, non-exclusive, no-charge, - royalty-free, irrevocable copyright license to reproduce, prepare derivative - works of, publicly display, publicly perform, sublicense, and distribute the - Software and such derivative works. - -2. Grant of Patent License. Subject to the terms and conditions of this - Agreement, Intel hereby grants you and to recipients of the Software - distributed by LLVM a perpetual, worldwide, non-exclusive, no-charge, - royalty-free, irrevocable (except as stated in this section) patent license - to make, have made, use, offer to sell, sell, import, and otherwise transfer - the Work, where such license applies only to those patent claims licensable - by Intel that are necessarily infringed by Intel's Software alone or by - combination of the Software with the Work to which such Software was - submitted. If any entity institutes patent litigation against Intel or any - other entity (including a cross-claim or counterclaim in a lawsuit) alleging - that Intel's Software, or the Work to which Intel has contributed constitutes - direct or contributory patent infringement, then any patent licenses granted - to that entity under this Agreement for the Software or Work shall terminate - as of the date such litigation is filed. - -Unless required by applicable law or agreed to in writing, the software is -provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, -either express or implied, including, without limitation, any warranties or -conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A -PARTICULAR PURPOSE. - -============================================================================== -License: Apache-2.0 WITH LLVM-exception -Source: https://github.com/llvm/llvm-project diff --git a/bundle/python-cpu/Lib/site-packages/faiss_cpu.libs/libopenblas.dll b/bundle/python-cpu/Lib/site-packages/faiss_cpu.libs/libopenblas.dll deleted file mode 100644 index 5ec205e59ce6c6043edc9039da018f47020a1406..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/faiss_cpu.libs/libopenblas.dll +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e824cf9fc22e5949807ce995a32e413a345fb97e63e6d10cfbf41aa86382193c -size 51076488 diff --git a/bundle/python-cpu/Lib/site-packages/faiss_cpu.libs/msvcp140.dll b/bundle/python-cpu/Lib/site-packages/faiss_cpu.libs/msvcp140.dll deleted file mode 100644 index e71a456c461eebca84058e6f2f8b5002f689dd08..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/faiss_cpu.libs/msvcp140.dll +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a4c2229bdc2a2a630acdc095b4d86008e5c3e3bc7773174354f3da4f5beb9cde -size 575056 diff --git a/bundle/python-cpu/Lib/site-packages/faiss_cpu.libs/vcomp140.dll b/bundle/python-cpu/Lib/site-packages/faiss_cpu.libs/vcomp140.dll deleted file mode 100644 index 87f5e96904482931c93deddd53ca96f7d03f3e2b..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/faiss_cpu.libs/vcomp140.dll +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f96f3a14d88d8846f31f3ab38a490304ce7d6e4f70fae4304c63e59c7aea2d30 -size 213072 diff --git a/bundle/python-cpu/Lib/site-packages/fastapi-0.141.1.dist-info/INSTALLER b/bundle/python-cpu/Lib/site-packages/fastapi-0.141.1.dist-info/INSTALLER deleted file mode 100644 index 5c69047b2eb8235994febeeae1da4a82365a240a..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/fastapi-0.141.1.dist-info/INSTALLER +++ /dev/null @@ -1 +0,0 @@ -uv \ No newline at end of file diff --git a/bundle/python-cpu/Lib/site-packages/fastapi-0.141.1.dist-info/METADATA b/bundle/python-cpu/Lib/site-packages/fastapi-0.141.1.dist-info/METADATA deleted file mode 100644 index 8bffeff5e31968851d860a97c45a0cc59d372aa4..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/fastapi-0.141.1.dist-info/METADATA +++ /dev/null @@ -1,617 +0,0 @@ -Metadata-Version: 2.4 -Name: fastapi -Version: 0.141.1 -Summary: FastAPI framework, high performance, easy to learn, fast to code, ready for production -Author-Email: =?utf-8?q?Sebasti=C3=A1n_Ram=C3=ADrez?=-License-Expression: MIT -License-File: LICENSE -Classifier: Intended Audience :: Information Technology -Classifier: Intended Audience :: System Administrators -Classifier: Operating System :: OS Independent -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python -Classifier: Topic :: Internet -Classifier: Topic :: Software Development :: Libraries :: Application Frameworks -Classifier: Topic :: Software Development :: Libraries :: Python Modules -Classifier: Topic :: Software Development :: Libraries -Classifier: Topic :: Software Development -Classifier: Typing :: Typed -Classifier: Development Status :: 4 - Beta -Classifier: Environment :: Web Environment -Classifier: Framework :: AsyncIO -Classifier: Framework :: FastAPI -Classifier: Framework :: Pydantic -Classifier: Framework :: Pydantic :: 2 -Classifier: Intended Audience :: Developers -Classifier: Programming Language :: Python :: 3 :: Only -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: 3.11 -Classifier: Programming Language :: Python :: 3.12 -Classifier: Programming Language :: Python :: 3.13 -Classifier: Programming Language :: Python :: 3.14 -Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers -Classifier: Topic :: Internet :: WWW/HTTP -Project-URL: Homepage, https://github.com/fastapi/fastapi -Project-URL: Documentation, https://fastapi.tiangolo.com/ -Project-URL: Repository, https://github.com/fastapi/fastapi -Project-URL: Issues, https://github.com/fastapi/fastapi/issues -Project-URL: Changelog, https://fastapi.tiangolo.com/release-notes/ -Requires-Python: >=3.10 -Requires-Dist: starlette>=0.46.0 -Requires-Dist: pydantic>=2.9.0 -Requires-Dist: typing-extensions>=4.8.0 -Requires-Dist: typing-inspection>=0.4.2 -Requires-Dist: annotated-doc>=0.0.2 -Provides-Extra: standard -Requires-Dist: fastapi-cli[standard]>=0.0.32; extra == "standard" -Requires-Dist: fastar>=0.9.0; extra == "standard" -Requires-Dist: httpx<1.0.0,>=0.23.0; extra == "standard" -Requires-Dist: jinja2>=3.1.5; extra == "standard" -Requires-Dist: python-multipart>=0.0.18; extra == "standard" -Requires-Dist: email-validator>=2.0.0; extra == "standard" -Requires-Dist: uvicorn[standard]>=0.12.0; extra == "standard" -Requires-Dist: pydantic-settings>=2.0.0; extra == "standard" -Requires-Dist: pydantic-extra-types>=2.0.0; extra == "standard" -Provides-Extra: standard-no-fastapi-cloud-cli -Requires-Dist: fastapi-cli[standard-no-fastapi-cloud-cli]>=0.0.32; extra == "standard-no-fastapi-cloud-cli" -Requires-Dist: httpx<1.0.0,>=0.23.0; extra == "standard-no-fastapi-cloud-cli" -Requires-Dist: jinja2>=3.1.5; extra == "standard-no-fastapi-cloud-cli" -Requires-Dist: python-multipart>=0.0.18; extra == "standard-no-fastapi-cloud-cli" -Requires-Dist: email-validator>=2.0.0; extra == "standard-no-fastapi-cloud-cli" -Requires-Dist: uvicorn[standard]>=0.12.0; extra == "standard-no-fastapi-cloud-cli" -Requires-Dist: pydantic-settings>=2.0.0; extra == "standard-no-fastapi-cloud-cli" -Requires-Dist: pydantic-extra-types>=2.0.0; extra == "standard-no-fastapi-cloud-cli" -Provides-Extra: all -Requires-Dist: fastapi-cli[standard]>=0.0.32; extra == "all" -Requires-Dist: httpx<1.0.0,>=0.23.0; extra == "all" -Requires-Dist: jinja2>=3.1.5; extra == "all" -Requires-Dist: python-multipart>=0.0.18; extra == "all" -Requires-Dist: itsdangerous>=1.1.0; extra == "all" -Requires-Dist: pyyaml>=5.3.1; extra == "all" -Requires-Dist: email-validator>=2.0.0; extra == "all" -Requires-Dist: uvicorn[standard]>=0.12.0; extra == "all" -Requires-Dist: pydantic-settings>=2.0.0; extra == "all" -Requires-Dist: pydantic-extra-types>=2.0.0; extra == "all" -Description-Content-Type: text/markdown - - - - FastAPI framework, high performance, easy to learn, fast to code, ready for production -
- - ---- - -**Documentation**: [https://fastapi.tiangolo.com](https://fastapi.tiangolo.com) - -**Source Code**: [https://github.com/fastapi/fastapi](https://github.com/fastapi/fastapi) - ---- - -FastAPI is a modern, fast (high-performance), web framework for building APIs with Python based on standard Python type hints. - -The key features are: - -* **Fast**: Very high performance, on par with **NodeJS** and **Go** (thanks to Starlette and Pydantic). [One of the fastest Python frameworks available](#performance). -* **Fast to code**: Increase the speed to develop features by about 200% to 300%. * -* **Fewer bugs**: Reduce about 40% of human (developer) induced errors. * -* **Intuitive**: Great editor support. Completion everywhere. Less time debugging. -* **Easy**: Designed to be easy to use and learn. Less time reading docs. -* **Short**: Minimize code duplication. Multiple features from each parameter declaration. Fewer bugs. -* **Robust**: Get production-ready code. With automatic interactive documentation. -* **Standards-based**: Based on (and fully compatible with) the open standards for APIs: [OpenAPI](https://github.com/OAI/OpenAPI-Specification) (previously known as Swagger) and [JSON Schema](https://json-schema.org/). - -* estimation based on tests conducted by an internal development team, building production applications. - -## Sponsors - - -### Keystone Sponsor - -- -### Gold Sponsors - -
-
-
-
-
-
-
-
- -### Silver Sponsors - -
-
-
-
-
-
- - - -[Other sponsors](https://fastapi.tiangolo.com/fastapi-people/#sponsors) - -## Opinions - - - -
- -"_[...] I'm using **FastAPI** a ton these days. [...] I'm actually planning to use it for all of my team's **ML services at Microsoft**. Some of them are getting integrated into the core **Windows** product and some **Office** products._" - -- -## FastAPI Conf - -[**FastAPI Conf '26**](https://fastapiconf.com) is happening on **October 28, 2026** in **Amsterdam, NL**. All about FastAPI, right from the source. 🎤 - -Kabir Khan - Microsoft (ref)- ---- - -"_We adopted the **FastAPI** library to spawn a **REST** server that can be queried to obtain **predictions**. [for Ludwig]_" - -Piero Molino, Yaroslav Dudin, and Sai Sumanth Miryala - Uber (ref)- ---- - -"_**Netflix** is pleased to announce the open-source release of our **crisis management** orchestration framework: **Dispatch**! [built with **FastAPI**]_" - -Kevin Glisson, Marc Vilanova, Forest Monsen - Netflix (ref)- ---- - -"_If anyone is looking to build a production Python API, I would highly recommend **FastAPI**. It is **beautifully designed**, **simple to use** and **highly scalable**, it has become a **key component** in our API first development strategy and is driving many automations and services such as our Virtual TAC Engineer._" - -Deon Pillsbury - Cisco (ref)- ---- - -- -## FastAPI mini documentary - -There's a [FastAPI mini documentary](https://www.youtube.com/watch?v=mpR8ngthqiE) released at the end of 2025, you can watch it online: - -
- -## **Typer**, the FastAPI of CLIs - -
- -If you are building a CLI app to be used in the terminal instead of a web API, check out [**Typer**](https://typer.tiangolo.com/). - -**Typer** is FastAPI's little sibling. And it's intended to be the **FastAPI of CLIs**. ⌨️ 🚀 - -## Requirements - -FastAPI stands on the shoulders of giants: - -* [Starlette](https://starlette.dev/) for the web parts. -* [Pydantic](https://pydantic.dev/docs/) for the data parts. - -## Installation - -First, [install `uv`](https://docs.astral.sh/uv/getting-started/installation/), and then add FastAPI to your project: - -
- -```console -$ uv add "fastapi[standard]" - ----> 100% -``` - -- -**Note**: Make sure you put `"fastapi[standard]"` in quotes to ensure it works in all terminals. - -If you prefer to use `pip`, install `fastapi[standard]` inside a virtual environment. See the [installation guide](tutorial/#install-fastapi) for the alternative steps. - -## Example - -### Create it - -Create a file `main.py` with: - -```Python -from fastapi import FastAPI - -app = FastAPI() - - -@app.get("/") -def read_root(): - return {"Hello": "World"} - - -@app.get("/items/{item_id}") -def read_item(item_id: int, q: str | None = None): - return {"item_id": item_id, "q": q} -``` - --- -### Run it - -Run the server with: - -Or use
- -If your code uses `async` / `await`, use `async def`: - -```Python hl_lines="7 12" -from fastapi import FastAPI - -app = FastAPI() - - -@app.get("/") -async def read_root(): - return {"Hello": "World"} - - -@app.get("/items/{item_id}") -async def read_item(item_id: int, q: str | None = None): - return {"item_id": item_id, "q": q} -``` - -**Note**: - -If you don't know, check the _"In a hurry?"_ section about [`async` and `await` in the docs](https://fastapi.tiangolo.com/async/#in-a-hurry). - -async def...- -```console -$ uv run fastapi dev - - ╭────────── FastAPI CLI - Development mode ───────────╮ - │ │ - │ Serving at: http://127.0.0.1:8000 │ - │ │ - │ API docs: http://127.0.0.1:8000/docs │ - │ │ - │ Running in development mode, for production use: │ - │ │ - │ fastapi run │ - │ │ - ╰─────────────────────────────────────────────────────╯ - -INFO: Will watch for changes in these directories: ['/home/user/code/awesomeapp'] -INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) -INFO: Started reloader process [2248755] using WatchFiles -INFO: Started server process [2248757] -INFO: Waiting for application startup. -INFO: Application startup complete. -``` - -- --- -### Check it - -Open your browser at [http://127.0.0.1:8000/items/5?q=somequery](http://127.0.0.1:8000/items/5?q=somequery). - -You will see the JSON response as: - -```JSON -{"item_id": 5, "q": "somequery"} -``` - -You already created an API that: - -* Receives HTTP requests in the _paths_ `/` and `/items/{item_id}`. -* Both _paths_ take `GET` operations (also known as HTTP _methods_). -* The _path_ `/items/{item_id}` has a _path parameter_ `item_id` that should be an `int`. -* The _path_ `/items/{item_id}` has an optional `str` _query parameter_ `q`. - -### Interactive API docs - -Now go to [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs). - -You will see the automatic interactive API documentation (provided by [Swagger UI](https://github.com/swagger-api/swagger-ui)): - - - -### Alternative API docs - -And now, go to [http://127.0.0.1:8000/redoc](http://127.0.0.1:8000/redoc). - -You will see the alternative automatic documentation (provided by [ReDoc](https://github.com/Redocly/redoc)): - - - -## Example upgrade - -Now modify the file `main.py` to receive a body from a `PUT` request. - -Declare the body using standard Python types, thanks to Pydantic. - -```Python hl_lines="2 7-10 23-25" -from fastapi import FastAPI -from pydantic import BaseModel - -app = FastAPI() - - -class Item(BaseModel): - name: str - price: float - is_offer: bool | None = None - - -@app.get("/") -def read_root(): - return {"Hello": "World"} - - -@app.get("/items/{item_id}") -def read_item(item_id: int, q: str | None = None): - return {"item_id": item_id, "q": q} - - -@app.put("/items/{item_id}") -def update_item(item_id: int, item: Item): - return {"item_name": item.name, "item_id": item_id} -``` - -The `fastapi dev` server should reload automatically. - -### Interactive API docs upgrade - -Now go to [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs). - -* The interactive API documentation will be automatically updated, including the new body: - - - -* Click on the button "Try it out", it allows you to fill the parameters and directly interact with the API: - - - -* Then click on the "Execute" button, the user interface will communicate with your API, send the parameters, get the results and show them on the screen: - - - -### Alternative API docs upgrade - -And now, go to [http://127.0.0.1:8000/redoc](http://127.0.0.1:8000/redoc). - -* The alternative documentation will also reflect the new query parameter and body: - - - -### Recap - -In summary, you declare **once** the types of parameters, body, etc. as function parameters. - -You do that with standard modern Python types. - -You don't have to learn a new syntax, the methods or classes of a specific library, etc. - -Just standard **Python**. - -For example, for an `int`: - -```Python -item_id: int -``` - -or for a more complex `Item` model: - -```Python -item: Item -``` - -...and with that single declaration you get: - -* Editor support, including: - * Completion. - * Type checks. -* Validation of data: - * Automatic and clear errors when the data is invalid. - * Validation even for deeply nested JSON objects. -* Conversion of input data: coming from the network to Python data and types. Reading from: - * JSON. - * Path parameters. - * Query parameters. - * Cookies. - * Headers. - * Forms. - * Files. -* Conversion of output data: converting from Python data and types to network data (as JSON): - * Convert Python types (`str`, `int`, `float`, `bool`, `list`, etc). - * `datetime` objects. - * `UUID` objects. - * Database models. - * ...and many more. -* Automatic interactive API documentation, including 2 alternative user interfaces: - * Swagger UI. - * ReDoc. - ---- - -Coming back to the previous code example, **FastAPI** will: - -* Validate that there is an `item_id` in the path for `GET` and `PUT` requests. -* Validate that the `item_id` is of type `int` for `GET` and `PUT` requests. - * If it is not, the client will see a useful, clear error. -* Check if there is an optional query parameter named `q` (as in `http://127.0.0.1:8000/items/foo?q=somequery`) for `GET` requests. - * As the `q` parameter is declared with `= None`, it is optional. - * Without the `None` it would be required (as is the body in the case with `PUT`). -* For `PUT` requests to `/items/{item_id}`, read the body as JSON: - * Check that it has a required attribute `name` that should be a `str`. - * Check that it has a required attribute `price` that has to be a `float`. - * Check that it has an optional attribute `is_offer`, that should be a `bool`, if present. - * All this would also work for deeply nested JSON objects. -* Convert from and to JSON automatically. -* Document everything with OpenAPI, that can be used by: - * Interactive documentation systems. - * Automatic client code generation systems, for many languages. -* Provide 2 interactive documentation web interfaces directly. - ---- - -We just scratched the surface, but you already get the idea of how it all works. - -Try changing the line with: - -```Python - return {"item_name": item.name, "item_id": item_id} -``` - -...from: - -```Python - ... "item_name": item.name ... -``` - -...to: - -```Python - ... "item_price": item.price ... -``` - -...and see how your editor will auto-complete the attributes and know their types: - - - -For a more complete example including more features, see the Tutorial - User Guide. - -**Spoiler alert**: the tutorial - user guide includes: - -* Declaration of **parameters** from other different places such as: **headers**, **cookies**, **form fields** and **files**. -* How to set **validation constraints** such as `maximum_length` or `regex`. -* A very powerful and easy to use **Dependency Injection** system. -* Security and authentication, including support for **OAuth2** with **JWT tokens** and **HTTP Basic** auth. -* More advanced (but equally easy) techniques for declaring **deeply nested JSON models** (thanks to Pydantic). -* **GraphQL** integration with [Strawberry](https://strawberry.rocks) and other libraries. -* Many extra features (thanks to Starlette) such as: - * **WebSockets** - * extremely easy tests based on HTTPX and `pytest` - * **CORS** - * **Cookie Sessions** - * ...and more. - -### Deploy your app (optional) - -You can optionally deploy your FastAPI app to [FastAPI Cloud](https://fastapicloud.com) with a single command. 🚀 - -About the command
- -The command `fastapi dev` reads your `main.py` file automatically, detects the **FastAPI** app in it, and starts a server using [Uvicorn](https://uvicorn.dev). - -By default, `fastapi dev` will start with auto-reload enabled for local development. - -You can read more about it in the [FastAPI CLI docs](https://fastapi.tiangolo.com/fastapi-cli/). - -fastapi dev...- -```console -$ uv run fastapi deploy - -Deploying to FastAPI Cloud... - -✅ Deployment successful! - -🐔 Ready the chicken! Your app is ready at https://myapp.fastapicloud.dev -``` - -- -The CLI will automatically detect your FastAPI application and deploy it to the cloud. If you are not logged in, your browser will open to complete the authentication process. - -That's it! Now you can access your app at that URL. ✨ - -#### About FastAPI Cloud - -**[FastAPI Cloud](https://fastapicloud.com)** is built by the same author and team behind **FastAPI**. - -It streamlines the process of **building**, **deploying**, and **accessing** an API with minimal effort. - -It brings the same **developer experience** of building apps with FastAPI to **deploying** them to the cloud. 🎉 - -FastAPI Cloud is the primary sponsor and funding provider for the *FastAPI and friends* open source projects. ✨ - -#### Deploy to other cloud providers - -FastAPI is open source and based on standards. You can deploy FastAPI apps to any cloud provider you choose. - -Follow your cloud provider's guides to deploy FastAPI apps with them. 🤓 - -## Performance - -Independent TechEmpower benchmarks show **FastAPI** applications running under Uvicorn as [one of the fastest Python frameworks available](https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7), only below Starlette and Uvicorn themselves (used internally by FastAPI). (*) - -To understand more about it, see the section [Benchmarks](https://fastapi.tiangolo.com/benchmarks/). - -## Dependencies - -FastAPI depends on Pydantic and Starlette. - -### `standard` Dependencies - -When you install FastAPI with `uv add "fastapi[standard]"` it comes with the `standard` group of optional dependencies: - -Used by Pydantic: - -* [`email-validator`](https://github.com/JoshData/python-email-validator) - for email validation. - -Used by Starlette: - -* [`httpx`](https://www.python-httpx.org) - Required if you want to use the `TestClient`. -* [`jinja2`](https://jinja.palletsprojects.com) - Required if you want to use the default template configuration. -* [`python-multipart`](https://github.com/Kludex/python-multipart) - Required if you want to support form "parsing", with `request.form()`. - -Used by FastAPI: - -* [`uvicorn`](https://uvicorn.dev) - for the server that loads and serves your application. This includes `uvicorn[standard]`, which includes some dependencies (e.g. `uvloop`) needed for high performance serving. -* `fastapi-cli[standard]` - to provide the `fastapi` command. - * This includes `fastapi-cloud-cli`, which allows you to deploy your FastAPI application to [FastAPI Cloud](https://fastapicloud.com). - -### Without `standard` Dependencies - -If you don't want to include the `standard` optional dependencies, you can install with `uv add fastapi` instead of `uv add "fastapi[standard]"`. - -### Without `fastapi-cloud-cli` - -If you want to install FastAPI with the standard dependencies but without the `fastapi-cloud-cli`, you can install with `uv add "fastapi[standard-no-fastapi-cloud-cli]"`. - -### Additional Optional Dependencies - -There are some additional dependencies you might want to install. - -Additional optional Pydantic dependencies: - -* [`pydantic-settings`](https://pydantic.dev/docs/validation/latest/concepts/pydantic_settings/) - for settings management. -* [`pydantic-extra-types`](https://github.com/pydantic/pydantic-extra-types) - for extra types to be used with Pydantic. - -Additional optional FastAPI dependencies: - -* [`orjson`](https://github.com/ijl/orjson) - Required if you want to use `ORJSONResponse`. -* [`ujson`](https://github.com/ultrajson/ultrajson) - Required if you want to use `UJSONResponse`. - -## License - -This project is licensed under the terms of the MIT license. diff --git a/bundle/python-cpu/Lib/site-packages/fastapi-0.141.1.dist-info/RECORD b/bundle/python-cpu/Lib/site-packages/fastapi-0.141.1.dist-info/RECORD deleted file mode 100644 index b9bff9646af1c91e9ca7599b7ea4bcce5f461c85..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/fastapi-0.141.1.dist-info/RECORD +++ /dev/null @@ -1,64 +0,0 @@ -../../Scripts/fastapi.exe,sha256=PTYuF1w1y-RUqjyl5MJyhWNpL1Sx9uf1yr2oId1l7Po,46080 -fastapi-0.141.1.dist-info/INSTALLER,sha256=5hhM4Q4mYTT9z6QB6PGpUAW81PGNFrYrdXMj4oM_6ak,2 -fastapi-0.141.1.dist-info/METADATA,sha256=EBDClUe0AmvbPNHEBuBXC515u0SLWmH6TVu1pesLdSw,27029 -fastapi-0.141.1.dist-info/RECORD,, -fastapi-0.141.1.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -fastapi-0.141.1.dist-info/WHEEL,sha256=VP-D4TPS230sME9Z3vb3INXvo1yt0924YRm5AOsk_dE,90 -fastapi-0.141.1.dist-info/entry_points.txt,sha256=GCf-WbIZxyGT4MUmrPGj1cOHYZoGsNPHAvNkT6hnGeA,61 -fastapi-0.141.1.dist-info/licenses/LICENSE,sha256=Tsif_IFIW5f-xYSy1KlhAy7v_oNEU4lP2cEnSQbMdE4,1086 -fastapi/.agents/skills/fastapi/SKILL.md,sha256=mJ5RNq0BXBdcyihmnQUb_vLiDa0TqDhTg4hWSGB_XrY,10111 -fastapi/.agents/skills/fastapi/references/dependencies.md,sha256=i2txoD-hRoCQWoH1PxiDuQwqt6xl7vp3wmZMLQON5Gk,3268 -fastapi/.agents/skills/fastapi/references/other-tools.md,sha256=oskZlYkCdGgezS9mIfqW5kImCGtOsgPUa46Sd81H-P0,1527 -fastapi/.agents/skills/fastapi/references/path-operations.md,sha256=7Y0qIRI7z2PdHpqmHMjk4zqHjLvx0JSYpVakIDAplco,1583 -fastapi/.agents/skills/fastapi/references/pydantic.md,sha256=hAq5YnOYYa7S6neAXcRpecmpar2PwAQ_GXs71dY46Es,1844 -fastapi/.agents/skills/fastapi/references/responses.md,sha256=fJIVCLvQk2lzAcqWEgOJds-1tlvcLcQqDALigJ02Uqc,1856 -fastapi/.agents/skills/fastapi/references/streaming.md,sha256=bHaIKnwbTkd7TUVQm_uxapUnAlEG4rdvALV9koD5ypI,2581 -fastapi/__init__.py,sha256=A2QG2fYV0hWsknlMOMeZ7ua0mJNWWc4DNd6_1HgV17k,1081 -fastapi/__main__.py,sha256=bKePXLdO4SsVSM6r9SVoLickJDcR2c0cTOxZRKq26YQ,37 -fastapi/_compat/__init__.py,sha256=PYOR-8vJ5va4Qjl810FcQmJbqmpyyeQMoZ9R86CeE2U,2095 -fastapi/_compat/shared.py,sha256=lv0zlY5SSt8gx-TDpHL9NNGy9Qf16RBEK3-OXc7_LOQ,7323 -fastapi/_compat/v2.py,sha256=sDGyi1iKSFW9LuJ7n4B61-1yrQI1NHRSwsFRRLuFJ8k,17601 -fastapi/applications.py,sha256=ONzLGbKgsLmEyNdUEmOEKVSjfAh8-WtEY66heHPGGDw,183840 -fastapi/background.py,sha256=TADzAethOAaqpVvckYuTT3c4O9N1HaFQysFCPt0MsgU,1820 -fastapi/cli.py,sha256=OYhZb0NR_deuT5ofyPF2NoNBzZDNOP8Salef2nk-HqA,418 -fastapi/concurrency.py,sha256=xHGDEOQAA6cvFEDX46oq3r2t1Zd4sVvreaRgdIE4juM,1489 -fastapi/datastructures.py,sha256=XPugnojHc4N07eF5Xp1TTndP2gMv1fG4k-0L4Vdr7Kc,5321 -fastapi/dependencies/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -fastapi/dependencies/models.py,sha256=3EpGqAA2d885jr1ENd-Pj8e1b80uGYPtMiYjnUHbp3c,8092 -fastapi/dependencies/utils.py,sha256=E2kzdauV4yQk5UNMIfkoRjY0r17hJhzz4EAxOBvfR9k,39180 -fastapi/encoders.py,sha256=TMCSMOymQ1iS9rwlohheIU2-3-mU1RA_62OtJpE3yq0,11713 -fastapi/exception_handlers.py,sha256=YVcT8Zy021VYYeecgdyh5YEUjEIHKcLspbkSf4OfbJI,1275 -fastapi/exceptions.py,sha256=fUNOBRdIsULU0TnO8aNBg3HoJeyJxXp9UV6D8wYu9lI,7453 -fastapi/logger.py,sha256=I9NNi3ov8AcqbsbC9wl1X-hdItKgYt2XTrx1f99Zpl4,54 -fastapi/middleware/__init__.py,sha256=oQDxiFVcc1fYJUOIFvphnK7pTT5kktmfL32QXpBFvvo,58 -fastapi/middleware/asyncexitstack.py,sha256=RKGlQpGzg3GLosqVhrxBy_NCZ9qJS7zQeNHt5Y3x-00,637 -fastapi/middleware/cors.py,sha256=ynwjWQZoc_vbhzZ3_ZXceoaSrslHFHPdoM52rXr0WUU,79 -fastapi/middleware/gzip.py,sha256=xM5PcsH8QlAimZw4VDvcmTnqQamslThsfe3CVN2voa0,79 -fastapi/middleware/httpsredirect.py,sha256=rL8eXMnmLijwVkH7_400zHri1AekfeBd6D6qs8ix950,115 -fastapi/middleware/trustedhost.py,sha256=eE5XGRxGa7c5zPnMJDGp3BxaL25k5iVQlhnv-Pk0Pss,109 -fastapi/middleware/wsgi.py,sha256=a_FMDoeTwcdig9wdAGumIH82oDFfuj4pxtQxLbAw2Ns,107 -fastapi/openapi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -fastapi/openapi/constants.py,sha256=adGzmis1L1HJRTE3kJ5fmHS_Noq6tIY6pWv_SFzoFDU,153 -fastapi/openapi/docs.py,sha256=PcjH0Sn-yp97O0exXincG8epsY7ATyJC5662bK1DRao,12425 -fastapi/openapi/models.py,sha256=twjJWGf6lcKRJZgaZCcnQ0Ten1hDhcyCLgbr7tXIP30,14608 -fastapi/openapi/utils.py,sha256=gdzqK4eEuxpoQmyZyVJfRGNLWDkWqJSjx9kkpyiG9Sc,29347 -fastapi/param_functions.py,sha256=4fTCVlvEDbAQr7gvWYkOX8hktdl2Iwk-kv4FaTz7P8w,69596 -fastapi/params.py,sha256=1fNNSK5J7PM5Fw-F5_9uOysA2NgC-61mb3LlrBWpqJM,26205 -fastapi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -fastapi/requests.py,sha256=zayepKFcienBllv3snmWI20Gk0oHNVLU4DDhqXBb4LU,142 -fastapi/responses.py,sha256=BM7JtiZ_G4j2Z7QvHUzV1KtZPnjOoCfX35RqYXlZDh0,4144 -fastapi/routing.py,sha256=ex72X7ayCURdxDvgcKIzJLeHmu-ca59j5paCNLdyO1U,255632 -fastapi/security/__init__.py,sha256=bO8pNmxqVRXUjfl2mOKiVZLn0FpBQ61VUYVjmppnbJw,881 -fastapi/security/api_key.py,sha256=4CNLNVAStOsMhytH9C5EOUEOZrtLg_IpMQS_HcRDP4M,9793 -fastapi/security/base.py,sha256=dl4pvbC-RxjfbWgPtCWd8MVU-7CB2SZ22rJDXVCXO6c,141 -fastapi/security/http.py,sha256=Z0xALDqwgJZRAaDs40Sa68rAnjFzEL99UEmO5PJzTKA,13410 -fastapi/security/oauth2.py,sha256=sSqW4tbvoHaWNld46TYatta5rgFfjod4LhxmedXzkI8,24178 -fastapi/security/open_id_connect_url.py,sha256=V8WLPEsEq_WJlIjPwJO2vCoJWGLu-VTt1-N2H7aV-D4,3136 -fastapi/security/utils.py,sha256=E9YIoez-H2k1oBLEdxqJEi8sV1umunJYKjQHvZG3FRY,261 -fastapi/sse.py,sha256=27Z0q8AO7ExKQWKQOEpTg94isE_NVcuHA33-YL9-Pr0,7083 -fastapi/staticfiles.py,sha256=iirGIt3sdY2QZXd36ijs3Cj-T0FuGFda3cd90kM9Ikw,69 -fastapi/templating.py,sha256=4zsuTWgcjcEainMJFAlW6-gnslm6AgOS1SiiDWfmQxk,76 -fastapi/testclient.py,sha256=nBvaAmX66YldReJNZXPOk1sfuo2Q6hs8bOvIaCep6LQ,66 -fastapi/types.py,sha256=g2tD842BUHC2C3_P8P06albQ4MhCb9RybrSmp5rODgU,438 -fastapi/utils.py,sha256=DX0VrnMwfVsZxRz8IitQ42c2---fDzmFZkeRMZR2UMo,4341 -fastapi/websockets.py,sha256=419uncYObEKZG0YcrXscfQQYLSWoE10jqxVMetGdR98,222 diff --git a/bundle/python-cpu/Lib/site-packages/fastapi-0.141.1.dist-info/REQUESTED b/bundle/python-cpu/Lib/site-packages/fastapi-0.141.1.dist-info/REQUESTED deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/bundle/python-cpu/Lib/site-packages/fastapi-0.141.1.dist-info/WHEEL b/bundle/python-cpu/Lib/site-packages/fastapi-0.141.1.dist-info/WHEEL deleted file mode 100644 index e651d8efb5fb543a06227b0ebfab1007f9e19326..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/fastapi-0.141.1.dist-info/WHEEL +++ /dev/null @@ -1,4 +0,0 @@ -Wheel-Version: 1.0 -Generator: pdm-backend (2.4.9) -Root-Is-Purelib: true -Tag: py3-none-any diff --git a/bundle/python-cpu/Lib/site-packages/fastapi-0.141.1.dist-info/entry_points.txt b/bundle/python-cpu/Lib/site-packages/fastapi-0.141.1.dist-info/entry_points.txt deleted file mode 100644 index b81849e1ef82b793f6f81bb970cdc3cb791f5776..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/fastapi-0.141.1.dist-info/entry_points.txt +++ /dev/null @@ -1,5 +0,0 @@ -[console_scripts] -fastapi = fastapi.cli:main - -[gui_scripts] - diff --git a/bundle/python-cpu/Lib/site-packages/fastapi-0.141.1.dist-info/licenses/LICENSE b/bundle/python-cpu/Lib/site-packages/fastapi-0.141.1.dist-info/licenses/LICENSE deleted file mode 100644 index 3e92463e6bd522a2a21e5f0a80d8089d6c4be20d..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/fastapi-0.141.1.dist-info/licenses/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2018 Sebastián Ramírez - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/bundle/python-cpu/Lib/site-packages/fastapi/.agents/skills/fastapi/SKILL.md b/bundle/python-cpu/Lib/site-packages/fastapi/.agents/skills/fastapi/SKILL.md deleted file mode 100644 index fc35b97ed9dc2ec0db51dee69c4ba358c5c8f3b8..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/fastapi/.agents/skills/fastapi/SKILL.md +++ /dev/null @@ -1,321 +0,0 @@ ---- -name: fastapi -description: FastAPI best practices and conventions. Use when working with FastAPI APIs, Pydantic models, dependencies, streaming responses including Server-Sent Events (SSE), and serving frontend apps. Keeps FastAPI code clean and up to date with the latest features and patterns. ---- - -# FastAPI - -Official FastAPI skill to write code with best practices, keeping up to date with new versions and features. - -## Quick Reference - -* Serve frontend apps: use `app.frontend()` or `router.frontend()` for built frontend assets; see [Serve Frontend Apps](#serve-frontend-apps). -* Server-Sent Events (SSE): use `response_class=EventSourceResponse` and `yield`; see [Streaming](#streaming-json-lines-sse-bytes) and [the streaming reference](references/streaming.md). -* JSON Lines and byte streaming: see [the streaming reference](references/streaming.md). -* Dependencies: use `Annotated[..., Depends(...)]`; see [Dependency Injection](#dependency-injection) and [the dependency injection reference](references/dependencies.md) for `yield`, scopes, and class dependencies. -* Response models: prefer return types; use `response_model` when the public response schema differs from the internal return value; see [the response reference](references/responses.md). -* Pydantic models: do not use ellipsis or `RootModel`; see [the Pydantic reference](references/pydantic.md). -* Routing: declare router-level prefix, tags, and shared dependencies on the `APIRouter`; see [the path operation reference](references/path-operations.md). -* Tooling and related libraries: use uv, Ruff, ty, Asyncer, SQLModel, and HTTPX when applicable; see [the other tools reference](references/other-tools.md). - -## Use the `fastapi` CLI - -Run the development server on localhost with reload: - -```bash -fastapi dev -``` - -Run the production server: - -```bash -fastapi run -``` - -Prefer declaring the entrypoint in `pyproject.toml`: - -```toml -[tool.fastapi] -entrypoint = "my_app.main:app" -``` - -When adding the entrypoint is not possible, or the user explicitly asks not to, pass the app file path: - -```bash -fastapi dev my_app/main.py -``` - -## Use `Annotated` - -Always prefer the `Annotated` style for parameter and dependency declarations. It keeps function signatures working in other contexts, respects the types, and allows reusability. - -Use `Annotated` for parameter declarations, including `Path`, `Query`, `Header`, etc.: - -```python -from typing import Annotated - -from fastapi import FastAPI, Path, Query - -app = FastAPI() - - -@app.get("/items/{item_id}") -async def read_item( - item_id: Annotated[int, Path(ge=1, description="The item ID")], - q: Annotated[str | None, Query(max_length=50)] = None, -): - return {"message": "Hello World"} -``` - -Use `Annotated` for dependencies with `Depends()`. Unless asked not to, create a new type alias for the dependency to allow reusing it: - -```python -from typing import Annotated - -from fastapi import Depends, FastAPI - -app = FastAPI() - - -def get_current_user(): - return {"username": "johndoe"} - - -CurrentUserDep = Annotated[dict, Depends(get_current_user)] - - -@app.get("/items/") -async def read_item(current_user: CurrentUserDep): - return {"message": "Hello World"} -``` - -## Do not use Ellipsis for *path operations* or Pydantic models - -Do not use `...` as a default value for required parameters or model fields. It's not needed and not recommended. - -```python -from typing import Annotated - -from fastapi import FastAPI, Query -from pydantic import BaseModel, Field - -app = FastAPI() - - -class Item(BaseModel): - name: str - description: str | None = None - price: float = Field(gt=0) - - -@app.post("/items/") -async def create_item(item: Item, project_id: Annotated[int, Query()]): - return item -``` - -See [the Pydantic reference](references/pydantic.md) for more details. - -## Return Type or Response Model - -When possible, include a return type. It will be used to validate, filter, document, and serialize the response. - -```python -from fastapi import FastAPI -from pydantic import BaseModel - -app = FastAPI() - - -class Item(BaseModel): - name: str - description: str | None = None - - -@app.get("/items/me") -async def get_item() -> Item: - return Item(name="Plumbus", description="All-purpose home device") -``` - -Return types or response models filter data to avoid exposing sensitive information, and they let Pydantic serialize the data on the Rust side for performance. - -Use `response_model` when the type you return is not the same as the public schema you want to validate, filter, document, and serialize. See [the response reference](references/responses.md). - -## Performance - -Do not use `ORJSONResponse` or `UJSONResponse`, they are deprecated. - -Instead, declare a return type or response model. Pydantic will handle the data serialization on the Rust side. - -## Including Routers - -When declaring routers, prefer to add router-level parameters like prefix, tags, and shared dependencies to the router itself instead of in `include_router()`. - -```python -from fastapi import APIRouter, Depends, FastAPI - -app = FastAPI() - - -def get_current_user(): - return {"username": "johndoe"} - - -router = APIRouter( - prefix="/items", - tags=["items"], - dependencies=[Depends(get_current_user)], -) - - -@router.get("/") -async def list_items(): - return [] - - -app.include_router(router) -``` - -See [the path operation reference](references/path-operations.md) for more routing patterns. - -## Serve Frontend Apps - -Use `app.frontend()` to serve a built static frontend app, for example a directory generated by Vite, Astro, Angular, Svelte, Vue, or a similar tool. - -```python -from fastapi import FastAPI - -app = FastAPI() - -app.frontend("/", directory="dist") -``` - -Use `router.frontend()` when the frontend belongs to an `APIRouter`; normal router prefix behavior applies when the router is included. - -```python -from fastapi import APIRouter, FastAPI - -app = FastAPI() -router = APIRouter(prefix="/admin") - -router.frontend("/", directory="admin-dist") -app.include_router(router) -``` - -`app.frontend()` and `router.frontend()` are low-priority routes: regular API routes are matched first, then frontend files and client-side routing fallbacks. Use this for single-page apps and built frontend assets instead of mounting `StaticFiles` manually. - -## Dependency Injection - -Use dependencies when the logic can't be declared in Pydantic validation, depends on external resources, needs cleanup with `yield`, or is shared across endpoints. - -Apply shared dependencies at the router level via `dependencies=[Depends(...)]`. - -See [the dependency injection reference](references/dependencies.md) for detailed patterns including `yield` with `scope`, and class dependencies. - -## Async vs Sync *path operations* - -Use `async` *path operations* only when fully certain that the logic called inside is compatible with async and await, and that it doesn't block. - -```python -from fastapi import FastAPI - -app = FastAPI() - - -@app.get("/async-items/") -async def read_async_items(): - data = await some_async_library.fetch_items() - return data - - -@app.get("/items/") -def read_items(): - data = some_blocking_library.fetch_items() - return data -``` - -In case of doubt, or by default, use regular `def` functions. They will be run in a threadpool so they don't block the event loop. The same rules apply to dependencies. - -Make sure blocking code is not run inside of `async` functions. The logic will work, but will damage performance heavily. - -When needing to mix blocking and async code, see Asyncer in [the other tools reference](references/other-tools.md). - -## Streaming (JSON Lines, SSE, bytes) - -To stream Server-Sent Events, use `response_class=EventSourceResponse` and `yield` items from the endpoint. - -```python -from collections.abc import AsyncIterable - -from fastapi import FastAPI -from fastapi.sse import EventSourceResponse, ServerSentEvent - -app = FastAPI() - - -@app.get("/events", response_class=EventSourceResponse) -async def stream_events() -> AsyncIterable[ServerSentEvent]: - yield ServerSentEvent(data={"status": "started"}, event="status", id="1") -``` - -Plain objects are automatically JSON-serialized as `data:` fields. Use `ServerSentEvent` for full control over SSE fields (`event`, `id`, `retry`, `comment`) and `raw_data` for pre-formatted strings. - -See [the streaming reference](references/streaming.md) for JSON Lines, Server-Sent Events (`EventSourceResponse`, `ServerSentEvent`), and byte streaming (`StreamingResponse`) patterns. - -## Tooling - -See [the other tools reference](references/other-tools.md) for details on uv, Ruff, ty for package management, linting, type checking, formatting, etc. - -## Other Libraries - -See [the other tools reference](references/other-tools.md) for details on other libraries: - -* Asyncer for handling async and await, concurrency, mixing async and blocking code, prefer it over AnyIO or asyncio. -* SQLModel for working with SQL databases, prefer it over SQLAlchemy. -* HTTPX for interacting with HTTP (other APIs), prefer it over Requests. - -## Do not use Pydantic RootModels - -Do not use Pydantic `RootModel`; instead use regular type annotations with `Annotated` and Pydantic validation utilities. - -```python -from typing import Annotated - -from fastapi import Body, FastAPI -from pydantic import Field - -app = FastAPI() - - -@app.post("/items/") -async def create_items(items: Annotated[list[int], Field(min_length=1), Body()]): - return items -``` - -FastAPI supports these type annotations and will create a Pydantic `TypeAdapter` for them, so types work normally without custom wrapper models. See [the Pydantic reference](references/pydantic.md). - -## Use one HTTP operation per function - -Don't mix HTTP operations in a single function. Having one function per HTTP operation helps separate concerns and organize the code. - -```python -from fastapi import FastAPI -from pydantic import BaseModel - -app = FastAPI() - - -class Item(BaseModel): - name: str - - -@app.get("/items/") -async def list_items(): - return [] - - -@app.post("/items/") -async def create_item(item: Item): - return item -``` - -See [the path operation reference](references/path-operations.md) for more examples. diff --git a/bundle/python-cpu/Lib/site-packages/fastapi/.agents/skills/fastapi/references/dependencies.md b/bundle/python-cpu/Lib/site-packages/fastapi/.agents/skills/fastapi/references/dependencies.md deleted file mode 100644 index a562dd9469851c085b4591ce748ca6689864a1d3..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/fastapi/.agents/skills/fastapi/references/dependencies.md +++ /dev/null @@ -1,142 +0,0 @@ -# Dependency Injection - -Use dependencies when: - -* They can't be declared in Pydantic validation and require additional logic -* The logic depends on external resources or could block in any other way -* Other dependencies need their results (it's a sub-dependency) -* The logic can be shared by multiple endpoints to do things like error early, handle authentication, etc. -* They need to handle cleanup (e.g., DB sessions, file handles), using dependencies with `yield` -* Their logic needs input data from the request, like headers, query parameters, etc. - -## Dependencies with `yield` and `scope` - -When using dependencies with `yield`, they can have a `scope` that defines when the exit code is run. - -Use the default scope `"request"` to run the exit code after the response is sent back. - -```python -from typing import Annotated - -from fastapi import Depends, FastAPI - -app = FastAPI() - - -def get_db(): - db = DBSession() - try: - yield db - finally: - db.close() - - -DBDep = Annotated[DBSession, Depends(get_db)] - - -@app.get("/items/") -async def read_items(db: DBDep): - return db.query(Item).all() -``` - -Use the scope `"function"` when they should run the exit code after the response data is generated but before the response is sent back to the client. - -```python -from typing import Annotated - -from fastapi import Depends, FastAPI - -app = FastAPI() - - -def get_username(): - try: - yield "Rick" - finally: - print("Clean up before response is sent") - -UserNameDep = Annotated[str, Depends(get_username, scope="function")] - -@app.get("/users/me") -def get_user_me(username: UserNameDep): - return username -``` - -## Class Dependencies - -Avoid creating class dependencies when possible. - -If a class is needed, instead create a regular function dependency that returns a class instance. - -Do this: - -```python -from dataclasses import dataclass -from typing import Annotated - -from fastapi import Depends, FastAPI - -app = FastAPI() - - -@dataclass -class DatabasePaginator: - offset: int = 0 - limit: int = 100 - q: str | None = None - - def get_page(self) -> dict: - # Simulate a page of data - return { - "offset": self.offset, - "limit": self.limit, - "q": self.q, - "items": [], - } - - -def get_db_paginator( - offset: int = 0, limit: int = 100, q: str | None = None -) -> DatabasePaginator: - return DatabasePaginator(offset=offset, limit=limit, q=q) - - -PaginatorDep = Annotated[DatabasePaginator, Depends(get_db_paginator)] - - -@app.get("/items/") -async def read_items(paginator: PaginatorDep): - return paginator.get_page() -``` - -instead of this: - -```python -# DO NOT DO THIS -from typing import Annotated - -from fastapi import Depends, FastAPI - -app = FastAPI() - - -class DatabasePaginator: - def __init__(self, offset: int = 0, limit: int = 100, q: str | None = None): - self.offset = offset - self.limit = limit - self.q = q - - def get_page(self) -> dict: - # Simulate a page of data - return { - "offset": self.offset, - "limit": self.limit, - "q": self.q, - "items": [], - } - - -@app.get("/items/") -async def read_items(paginator: Annotated[DatabasePaginator, Depends()]): - return paginator.get_page() -``` diff --git a/bundle/python-cpu/Lib/site-packages/fastapi/.agents/skills/fastapi/references/other-tools.md b/bundle/python-cpu/Lib/site-packages/fastapi/.agents/skills/fastapi/references/other-tools.md deleted file mode 100644 index b5b58cfd62e330e738b25399175f9e5c921cd09d..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/fastapi/.agents/skills/fastapi/references/other-tools.md +++ /dev/null @@ -1,76 +0,0 @@ -# Other Tools - -## uv - -If uv is available, use it to manage dependencies. - -## Ruff - -If Ruff is available, use it to lint and format the code. Consider enabling the FastAPI rules. - -## ty - -If ty is available, use it to check types. - -## Asyncer - -When needing to run blocking code inside of async functions, or async code inside of blocking functions, suggest using Asyncer. - -Prefer it over AnyIO or asyncio. - -Install: - -```bash -uv add asyncer -``` - -Run blocking sync code inside of async with `asyncify()`: - -```python -from asyncer import asyncify -from fastapi import FastAPI - -app = FastAPI() - - -def do_blocking_work(name: str) -> str: - # Some blocking I/O operation - return f"Hello {name}" - - -@app.get("/items/") -async def read_items(): - result = await asyncify(do_blocking_work)(name="World") - return {"message": result} -``` - -And run async code inside of blocking sync code with `syncify()`: - -```python -from asyncer import syncify -from fastapi import FastAPI - -app = FastAPI() - - -async def do_async_work(name: str) -> str: - return f"Hello {name}" - - -@app.get("/items/") -def read_items(): - result = syncify(do_async_work)(name="World") - return {"message": result} -``` - -## SQLModel for SQL databases - -When working with SQL databases, prefer using SQLModel as it is integrated with Pydantic and will allow declaring data validation with the same models. - -Prefer it over SQLAlchemy. - -## HTTPX - -Use HTTPX for handling HTTP communication (e.g. with other APIs). It supports sync and async usage. - -Prefer it over Requests. diff --git a/bundle/python-cpu/Lib/site-packages/fastapi/.agents/skills/fastapi/references/path-operations.md b/bundle/python-cpu/Lib/site-packages/fastapi/.agents/skills/fastapi/references/path-operations.md deleted file mode 100644 index 1292c17742536ea255813563d4757502bf209b2d..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/fastapi/.agents/skills/fastapi/references/path-operations.md +++ /dev/null @@ -1,93 +0,0 @@ -# Path Operations and Routing - -## Including Routers - -When declaring routers, prefer to add router-level parameters like prefix, tags, and shared dependencies to the router itself instead of in `include_router()`. - -Do this: - -```python -from fastapi import APIRouter, FastAPI - -app = FastAPI() - -router = APIRouter(prefix="/items", tags=["items"]) - - -@router.get("/") -async def list_items(): - return [] - - -app.include_router(router) -``` - -Instead of: - -```python -# DO NOT DO THIS -from fastapi import APIRouter, FastAPI - -app = FastAPI() - -router = APIRouter() - - -@router.get("/") -async def list_items(): - return [] - - -app.include_router(router, prefix="/items", tags=["items"]) -``` - -There could be exceptions, but try to follow this convention. - -Apply shared dependencies at the router level via `dependencies=[Depends(...)]`. - -## Use one HTTP operation per function - -Don't mix HTTP operations in a single function. Having one function per HTTP operation helps separate concerns and organize the code. - -Do this: - -```python -from fastapi import FastAPI -from pydantic import BaseModel - -app = FastAPI() - - -class Item(BaseModel): - name: str - - -@app.get("/items/") -async def list_items(): - return [] - - -@app.post("/items/") -async def create_item(item: Item): - return item -``` - -Instead of: - -```python -# DO NOT DO THIS -from fastapi import FastAPI, Request -from pydantic import BaseModel - -app = FastAPI() - - -class Item(BaseModel): - name: str - - -@app.api_route("/items/", methods=["GET", "POST"]) -async def handle_items(request: Request): - if request.method == "GET": - return [] -``` diff --git a/bundle/python-cpu/Lib/site-packages/fastapi/.agents/skills/fastapi/references/pydantic.md b/bundle/python-cpu/Lib/site-packages/fastapi/.agents/skills/fastapi/references/pydantic.md deleted file mode 100644 index fadf99c1a9d52110d2039cc03b0ab80a95875e82..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/fastapi/.agents/skills/fastapi/references/pydantic.md +++ /dev/null @@ -1,93 +0,0 @@ -# Pydantic - -## Do not use Ellipsis - -Do not use `...` as a default value for required parameters or model fields. It's not needed and not recommended. - -Do this, without Ellipsis (`...`): - -```python -from typing import Annotated - -from fastapi import FastAPI, Query -from pydantic import BaseModel, Field - -app = FastAPI() - - -class Item(BaseModel): - name: str - description: str | None = None - price: float = Field(gt=0) - - -@app.post("/items/") -async def create_item(item: Item, project_id: Annotated[int, Query()]): - return item -``` - -Instead of: - -```python -# DO NOT DO THIS -from typing import Annotated - -from fastapi import FastAPI, Query -from pydantic import BaseModel, Field - -app = FastAPI() - - -class Item(BaseModel): - name: str = ... - description: str | None = None - price: float = Field(..., gt=0) - - -@app.post("/items/") -async def create_item(item: Item, project_id: Annotated[int, Query(...)]): - return item -``` - -## Do not use Pydantic RootModels - -Do not use Pydantic `RootModel`; instead use regular type annotations with `Annotated` and Pydantic validation utilities. - -For example, for a list with validations: - -```python -from typing import Annotated - -from fastapi import Body, FastAPI -from pydantic import Field - -app = FastAPI() - - -@app.post("/items/") -async def create_items(items: Annotated[list[int], Field(min_length=1), Body()]): - return items -``` - -Instead of: - -```python -# DO NOT DO THIS -from typing import Annotated - -from fastapi import FastAPI -from pydantic import Field, RootModel - -app = FastAPI() - - -class ItemList(RootModel[Annotated[list[int], Field(min_length=1)]]): - pass - - -@app.post("/items/") -async def create_items(items: ItemList): - return items -``` - -FastAPI supports these type annotations and will create a Pydantic `TypeAdapter` for them, so types work normally without custom wrapper models. diff --git a/bundle/python-cpu/Lib/site-packages/fastapi/.agents/skills/fastapi/references/responses.md b/bundle/python-cpu/Lib/site-packages/fastapi/.agents/skills/fastapi/references/responses.md deleted file mode 100644 index 09081236a0ac06a15cc08d1eb25b01e00f69e564..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/fastapi/.agents/skills/fastapi/references/responses.md +++ /dev/null @@ -1,79 +0,0 @@ -# Responses - -## Return Type or Response Model - -When possible, include a return type. It will be used to validate, filter, document, and serialize the response. - -```python -from fastapi import FastAPI -from pydantic import BaseModel - -app = FastAPI() - - -class Item(BaseModel): - name: str - description: str | None = None - - -@app.get("/items/me") -async def get_item() -> Item: - return Item(name="Plumbus", description="All-purpose home device") -``` - -Return types or response models filter data to avoid exposing sensitive information. They also let Pydantic serialize data on the Rust side for performance. - -The return type doesn't have to be a Pydantic model. It can be a different type, like a list of integers, a dict, etc. - -## When to use `response_model` - -If the return type is not the same as the type that you want to use to validate, filter, or serialize, use the `response_model` parameter on the decorator. - -```python -from typing import Any - -from fastapi import FastAPI -from pydantic import BaseModel - -app = FastAPI() - - -class Item(BaseModel): - name: str - description: str | None = None - - -@app.get("/items/me", response_model=Item) -async def get_item() -> Any: - return {"name": "Foo", "description": "A very nice Item"} -``` - -This is particularly useful when filtering data to expose only the public fields and avoid exposing sensitive information. - -```python -from typing import Any - -from fastapi import FastAPI -from pydantic import BaseModel - -app = FastAPI() - - -class InternalItem(BaseModel): - name: str - description: str | None = None - secret_key: str - - -class Item(BaseModel): - name: str - description: str | None = None - - -@app.get("/items/me", response_model=Item) -async def get_item() -> Any: - item = InternalItem( - name="Foo", description="A very nice Item", secret_key="supersecret" - ) - return item -``` diff --git a/bundle/python-cpu/Lib/site-packages/fastapi/.agents/skills/fastapi/references/streaming.md b/bundle/python-cpu/Lib/site-packages/fastapi/.agents/skills/fastapi/references/streaming.md deleted file mode 100644 index 0832eedcb92b747444e4fcc406c845ed51fa21bd..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/fastapi/.agents/skills/fastapi/references/streaming.md +++ /dev/null @@ -1,105 +0,0 @@ -# Streaming - -## Stream JSON Lines - -To stream JSON Lines, declare the return type and use `yield` to return the data. - -```python -@app.get("/items/stream") -async def stream_items() -> AsyncIterable[Item]: - for item in items: - yield item -``` - -## Server-Sent Events (SSE) - -To stream Server-Sent Events, use `response_class=EventSourceResponse` and `yield` items from the endpoint. - -Plain objects are automatically JSON-serialized as `data:` fields, declare the return type so the serialization is done by Pydantic: - -```python -from collections.abc import AsyncIterable - -from fastapi import FastAPI -from fastapi.sse import EventSourceResponse -from pydantic import BaseModel - -app = FastAPI() - - -class Item(BaseModel): - name: str - price: float - - -@app.get("/items/stream", response_class=EventSourceResponse) -async def stream_items() -> AsyncIterable[Item]: - yield Item(name="Plumbus", price=32.99) - yield Item(name="Portal Gun", price=999.99) -``` - -For full control over SSE fields (`event`, `id`, `retry`, `comment`), yield `ServerSentEvent` instances: - -```python -from collections.abc import AsyncIterable - -from fastapi import FastAPI -from fastapi.sse import EventSourceResponse, ServerSentEvent - -app = FastAPI() - - -@app.get("/events", response_class=EventSourceResponse) -async def stream_events() -> AsyncIterable[ServerSentEvent]: - yield ServerSentEvent(data={"status": "started"}, event="status", id="1") - yield ServerSentEvent(data={"progress": 50}, event="progress", id="2") -``` - -Use `raw_data` instead of `data` to send pre-formatted strings without JSON encoding: - -```python -yield ServerSentEvent(raw_data="plain text line", event="log") -``` - -## Stream bytes - -To stream bytes, declare a `response_class=` of `StreamingResponse` or a sub-class, and use `yield` to return the data. - -```python -from fastapi import FastAPI -from fastapi.responses import StreamingResponse -from app.utils import read_image - -app = FastAPI() - - -class PNGStreamingResponse(StreamingResponse): - media_type = "image/png" - -@app.get("/image", response_class=PNGStreamingResponse) -def stream_image_no_async_no_annotation(): - with read_image() as image_file: - yield from image_file -``` - -prefer this over returning a `StreamingResponse` directly: - -```python -# DO NOT DO THIS - -import anyio -from fastapi import FastAPI -from fastapi.responses import StreamingResponse -from app.utils import read_image - -app = FastAPI() - - -class PNGStreamingResponse(StreamingResponse): - media_type = "image/png" - - -@app.get("/") -async def main(): - return PNGStreamingResponse(read_image()) -``` diff --git a/bundle/python-cpu/Lib/site-packages/fastapi/__init__.py b/bundle/python-cpu/Lib/site-packages/fastapi/__init__.py deleted file mode 100644 index 1ca29aa85e498ee348e860504c5f50b117e82221..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/fastapi/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -"""FastAPI framework, high performance, easy to learn, fast to code, ready for production""" - -__version__ = "0.141.1" - -from starlette import status as status - -from .applications import FastAPI as FastAPI -from .background import BackgroundTasks as BackgroundTasks -from .datastructures import UploadFile as UploadFile -from .exceptions import HTTPException as HTTPException -from .exceptions import WebSocketException as WebSocketException -from .param_functions import Body as Body -from .param_functions import Cookie as Cookie -from .param_functions import Depends as Depends -from .param_functions import File as File -from .param_functions import Form as Form -from .param_functions import Header as Header -from .param_functions import Path as Path -from .param_functions import Query as Query -from .param_functions import Security as Security -from .requests import Request as Request -from .responses import Response as Response -from .routing import APIRouter as APIRouter -from .websockets import WebSocket as WebSocket -from .websockets import WebSocketDisconnect as WebSocketDisconnect diff --git a/bundle/python-cpu/Lib/site-packages/fastapi/__main__.py b/bundle/python-cpu/Lib/site-packages/fastapi/__main__.py deleted file mode 100644 index fc36465f5f40701bf333de8811d76d3484f211e6..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/fastapi/__main__.py +++ /dev/null @@ -1,3 +0,0 @@ -from fastapi.cli import main - -main() diff --git a/bundle/python-cpu/Lib/site-packages/fastapi/_compat/__init__.py b/bundle/python-cpu/Lib/site-packages/fastapi/_compat/__init__.py deleted file mode 100644 index 4581c38c88ede0d70f9c40a67fbc9ee79529cffd..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/fastapi/_compat/__init__.py +++ /dev/null @@ -1,40 +0,0 @@ -from .shared import PYDANTIC_VERSION_MINOR_TUPLE as PYDANTIC_VERSION_MINOR_TUPLE -from .shared import annotation_is_pydantic_v1 as annotation_is_pydantic_v1 -from .shared import field_annotation_is_scalar as field_annotation_is_scalar -from .shared import ( - field_annotation_is_scalar_sequence as field_annotation_is_scalar_sequence, -) -from .shared import field_annotation_is_sequence as field_annotation_is_sequence -from .shared import ( - is_bytes_or_nonable_bytes_annotation as is_bytes_or_nonable_bytes_annotation, -) -from .shared import is_bytes_sequence_annotation as is_bytes_sequence_annotation -from .shared import is_pydantic_v1_model_instance as is_pydantic_v1_model_instance -from .shared import ( - is_uploadfile_or_nonable_uploadfile_annotation as is_uploadfile_or_nonable_uploadfile_annotation, -) -from .shared import ( - is_uploadfile_sequence_annotation as is_uploadfile_sequence_annotation, -) -from .shared import lenient_issubclass as lenient_issubclass -from .shared import sequence_types as sequence_types -from .shared import value_is_sequence as value_is_sequence -from .v2 import ModelField as ModelField -from .v2 import PydanticSchemaGenerationError as PydanticSchemaGenerationError -from .v2 import RequiredParam as RequiredParam -from .v2 import Undefined as Undefined -from .v2 import Url as Url -from .v2 import copy_field_info as copy_field_info -from .v2 import create_body_model as create_body_model -from .v2 import evaluate_forwardref as evaluate_forwardref -from .v2 import get_cached_model_fields as get_cached_model_fields -from .v2 import get_definitions as get_definitions -from .v2 import get_flat_models_from_fields as get_flat_models_from_fields -from .v2 import get_missing_field_error as get_missing_field_error -from .v2 import get_model_name_map as get_model_name_map -from .v2 import get_schema_from_model_field as get_schema_from_model_field -from .v2 import is_scalar_field as is_scalar_field -from .v2 import serialize_sequence_value as serialize_sequence_value -from .v2 import ( - with_info_plain_validator_function as with_info_plain_validator_function, -) diff --git a/bundle/python-cpu/Lib/site-packages/fastapi/_compat/shared.py b/bundle/python-cpu/Lib/site-packages/fastapi/_compat/shared.py deleted file mode 100644 index 8d4720a2ed3a31531efaf3e0bc3cf4b2a3763ac5..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/fastapi/_compat/shared.py +++ /dev/null @@ -1,222 +0,0 @@ -import types -import typing -import warnings -from collections import deque -from collections.abc import Mapping, Sequence -from dataclasses import is_dataclass -from typing import ( - Annotated, - Any, - TypeGuard, - TypeVar, - Union, - get_args, - get_origin, -) - -from fastapi.types import UnionType -from pydantic import BaseModel -from pydantic.version import VERSION as PYDANTIC_VERSION -from starlette.datastructures import UploadFile - -_T = TypeVar("_T") - -# Copy from Pydantic: pydantic/_internal/_typing_extra.py -WithArgsTypes: tuple[Any, ...] = ( - typing._GenericAlias, # type: ignore[attr-defined] # ty: ignore[unresolved-attribute] - types.GenericAlias, - types.UnionType, -) # pyright: ignore[reportAttributeAccessIssue] - -PYDANTIC_VERSION_MINOR_TUPLE = tuple(int(x) for x in PYDANTIC_VERSION.split(".")[:2]) - - -sequence_annotation_to_type = { - Sequence: list, - list: list, - tuple: tuple, - set: set, - frozenset: frozenset, - deque: deque, -} - -sequence_types: tuple[type[Any], ...] = tuple(sequence_annotation_to_type.keys()) - - -# Copy of Pydantic: pydantic/_internal/_utils.py with added TypeGuard -def lenient_issubclass( - cls: Any, class_or_tuple: type[_T] | tuple[type[_T], ...] | None -) -> TypeGuard[type[_T]]: - try: - return isinstance(cls, type) and issubclass(cls, class_or_tuple) # type: ignore[arg-type] # ty: ignore[invalid-argument-type] - except TypeError: # pragma: no cover - if isinstance(cls, WithArgsTypes): - return False - raise # pragma: no cover - - -def _annotation_is_sequence(annotation: type[Any] | None) -> bool: - if lenient_issubclass(annotation, (str, bytes)): - return False - return lenient_issubclass(annotation, sequence_types) - - -def field_annotation_is_sequence(annotation: type[Any] | None) -> bool: - origin = get_origin(annotation) - - if origin is Annotated: - return field_annotation_is_sequence(get_args(annotation)[0]) - - if origin is Union or origin is UnionType: - for arg in get_args(annotation): - if field_annotation_is_sequence(arg): - return True - return False - return _annotation_is_sequence(annotation) or _annotation_is_sequence( - get_origin(annotation) - ) - - -def value_is_sequence(value: Any) -> bool: - return isinstance(value, sequence_types) and not isinstance(value, (str, bytes)) - - -def _annotation_is_complex(annotation: type[Any] | None) -> bool: - return ( - lenient_issubclass(annotation, (BaseModel, Mapping, UploadFile)) - or _annotation_is_sequence(annotation) - or is_dataclass(annotation) - ) - - -def field_annotation_is_complex(annotation: type[Any] | None) -> bool: - origin = get_origin(annotation) - if origin is Union or origin is UnionType: - return any(field_annotation_is_complex(arg) for arg in get_args(annotation)) - - if origin is Annotated: - return field_annotation_is_complex(get_args(annotation)[0]) - - return ( - _annotation_is_complex(annotation) - or _annotation_is_complex(origin) - or hasattr(origin, "__pydantic_core_schema__") - or hasattr(origin, "__get_pydantic_core_schema__") - ) - - -def field_annotation_is_scalar(annotation: Any) -> bool: - # handle Ellipsis here to make tuple[int, ...] work nicely - return annotation is Ellipsis or not field_annotation_is_complex(annotation) - - -def field_annotation_is_scalar_sequence(annotation: type[Any] | None) -> bool: - origin = get_origin(annotation) - - if origin is Annotated: - return field_annotation_is_scalar_sequence(get_args(annotation)[0]) - - if origin is Union or origin is UnionType: - at_least_one_scalar_sequence = False - for arg in get_args(annotation): - if field_annotation_is_scalar_sequence(arg): - at_least_one_scalar_sequence = True - continue - elif not field_annotation_is_scalar(arg): - return False - return at_least_one_scalar_sequence - return field_annotation_is_sequence(annotation) and all( - field_annotation_is_scalar(sub_annotation) - for sub_annotation in get_args(annotation) - ) - - -def is_bytes_or_nonable_bytes_annotation(annotation: Any) -> bool: - if lenient_issubclass(annotation, bytes): - return True - origin = get_origin(annotation) - if origin is Union or origin is UnionType: - for arg in get_args(annotation): - if lenient_issubclass(arg, bytes): - return True - return False - - -def is_uploadfile_or_nonable_uploadfile_annotation(annotation: Any) -> bool: - if lenient_issubclass(annotation, UploadFile): - return True - origin = get_origin(annotation) - if origin is Union or origin is UnionType: - for arg in get_args(annotation): - if lenient_issubclass(arg, UploadFile): - return True - return False - - -def is_bytes_sequence_annotation(annotation: Any) -> bool: - origin = get_origin(annotation) - if origin is Union or origin is UnionType: - at_least_one = False - for arg in get_args(annotation): - if is_bytes_sequence_annotation(arg): - at_least_one = True - continue - return at_least_one - return field_annotation_is_sequence(annotation) and all( - is_bytes_or_nonable_bytes_annotation(sub_annotation) - for sub_annotation in get_args(annotation) - ) - - -def is_uploadfile_sequence_annotation(annotation: Any) -> bool: - origin = get_origin(annotation) - if origin is Union or origin is UnionType: - at_least_one = False - for arg in get_args(annotation): - if is_uploadfile_sequence_annotation(arg): - at_least_one = True - continue - return at_least_one - return field_annotation_is_sequence(annotation) and all( - is_uploadfile_or_nonable_uploadfile_annotation(sub_annotation) - for sub_annotation in get_args(annotation) - ) - - -def is_pydantic_v1_model_instance(obj: Any) -> bool: - # TODO: remove this function once the required version of Pydantic fully - # removes pydantic.v1 - try: - with warnings.catch_warnings(): - warnings.simplefilter("ignore", UserWarning) - from pydantic import v1 - except ImportError: # pragma: no cover - return False - return isinstance(obj, v1.BaseModel) - - -def is_pydantic_v1_model_class(cls: Any) -> bool: - # TODO: remove this function once the required version of Pydantic fully - # removes pydantic.v1 - try: - with warnings.catch_warnings(): - warnings.simplefilter("ignore", UserWarning) - from pydantic import v1 - except ImportError: # pragma: no cover - return False - return lenient_issubclass(cls, v1.BaseModel) - - -def annotation_is_pydantic_v1(annotation: Any) -> bool: - if is_pydantic_v1_model_class(annotation): - return True - origin = get_origin(annotation) - if origin is Union or origin is UnionType: - for arg in get_args(annotation): - if is_pydantic_v1_model_class(arg): - return True - if field_annotation_is_sequence(annotation): - for sub_annotation in get_args(annotation): - if annotation_is_pydantic_v1(sub_annotation): - return True - return False diff --git a/bundle/python-cpu/Lib/site-packages/fastapi/_compat/v2.py b/bundle/python-cpu/Lib/site-packages/fastapi/_compat/v2.py deleted file mode 100644 index 7be686d8655a9e7720ff0d751f82283cac20db98..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/fastapi/_compat/v2.py +++ /dev/null @@ -1,493 +0,0 @@ -import re -import warnings -from collections.abc import Sequence -from copy import copy -from dataclasses import dataclass, is_dataclass -from enum import Enum -from functools import lru_cache -from typing import ( - Annotated, - Any, - Literal, - Union, - cast, - get_args, - get_origin, -) - -from fastapi._compat import lenient_issubclass, shared -from fastapi.openapi.constants import REF_TEMPLATE -from fastapi.types import IncEx, ModelNameMap, UnionType -from pydantic import BaseModel, ConfigDict, Field, TypeAdapter, create_model -from pydantic import PydanticSchemaGenerationError as PydanticSchemaGenerationError -from pydantic import PydanticUndefinedAnnotation as PydanticUndefinedAnnotation -from pydantic import ValidationError as ValidationError -from pydantic._internal import _typing_extra as _pydantic_typing_extra -from pydantic._internal._schema_generation_shared import ( # type: ignore[attr-defined] - GetJsonSchemaHandler as GetJsonSchemaHandler, -) -from pydantic.fields import FieldInfo as FieldInfo -from pydantic.json_schema import GenerateJsonSchema as _GenerateJsonSchema -from pydantic.json_schema import JsonSchemaValue as JsonSchemaValue -from pydantic_core import CoreSchema as CoreSchema -from pydantic_core import PydanticUndefined -from pydantic_core import Url as Url -from pydantic_core.core_schema import ( - with_info_plain_validator_function as with_info_plain_validator_function, -) - -RequiredParam = PydanticUndefined -Undefined = PydanticUndefined - - -def evaluate_forwardref( - value: Any, - globalns: dict[str, Any] | None = None, - localns: dict[str, Any] | None = None, -) -> Any: - # eval_type_lenient has been deprecated since Pydantic v2.10.0b1 (PR #10530) - try_eval_type = getattr(_pydantic_typing_extra, "try_eval_type", None) - if try_eval_type is not None: - return try_eval_type(value, globalns, localns)[0] - return _pydantic_typing_extra.eval_type_lenient( # ty: ignore[deprecated] - value, globalns, localns - ) - - -class GenerateJsonSchema(_GenerateJsonSchema): - # TODO: remove when this is merged (or equivalent): https://github.com/pydantic/pydantic/pull/12841 - # and dropping support for any version of Pydantic before that one (so, in a very long time) - def bytes_schema(self, schema: CoreSchema) -> JsonSchemaValue: - json_schema = {"type": "string", "contentMediaType": "application/octet-stream"} - bytes_mode = ( - self._config.ser_json_bytes - if self.mode == "serialization" - else self._config.val_json_bytes - ) - if bytes_mode == "base64": - json_schema["contentEncoding"] = "base64" - self.update_with_validations(json_schema, schema, self.ValidationsMapping.bytes) - return json_schema - - -# TODO: remove when dropping support for Pydantic < v2.12.3 -_Attrs = { - "default": ..., - "default_factory": None, - "alias": None, - "alias_priority": None, - "validation_alias": None, - "serialization_alias": None, - "title": None, - "field_title_generator": None, - "description": None, - "examples": None, - "exclude": None, - "exclude_if": None, - "discriminator": None, - "deprecated": None, - "json_schema_extra": None, - "frozen": None, - "validate_default": None, - "repr": True, - "init": None, - "init_var": None, - "kw_only": None, -} - - -# TODO: remove when dropping support for Pydantic < v2.12.3 -def asdict(field_info: FieldInfo) -> dict[str, Any]: - attributes = {} - for attr in _Attrs: - value = getattr(field_info, attr, Undefined) - if value is not Undefined: - attributes[attr] = value - return { - "annotation": field_info.annotation, - "metadata": field_info.metadata, - "attributes": attributes, - } - - -@dataclass -class ModelField: - field_info: FieldInfo - name: str - mode: Literal["validation", "serialization"] = "validation" - config: ConfigDict | None = None - - @property - def alias(self) -> str: - a = self.field_info.alias - return a if a is not None else self.name - - @property - def validation_alias(self) -> str | None: - va = self.field_info.validation_alias - if isinstance(va, str) and va: - return va - return None - - @property - def serialization_alias(self) -> str | None: - sa = self.field_info.serialization_alias - return sa or None - - @property - def default(self) -> Any: - return self.get_default() - - def __post_init__(self) -> None: - with warnings.catch_warnings(): - # Pydantic >= 2.12.0 warns about field specific metadata that is unused - # (e.g. `TypeAdapter(Annotated[int, Field(alias='b')])`). In some cases, we - # end up building the type adapter from a model field annotation so we - # need to ignore the warning: - if shared.PYDANTIC_VERSION_MINOR_TUPLE >= (2, 12): - from pydantic.warnings import UnsupportedFieldAttributeWarning - - warnings.simplefilter( - "ignore", category=UnsupportedFieldAttributeWarning - ) - # TODO: remove after setting the min Pydantic to v2.12.3 - # that adds asdict(), and use self.field_info.asdict() instead - field_dict = asdict(self.field_info) - annotated_args = ( - field_dict["annotation"], - *field_dict["metadata"], - # this FieldInfo needs to be created again so that it doesn't include - # the old field info metadata and only the rest of the attributes - Field(**field_dict["attributes"]), - ) - self._type_adapter: TypeAdapter[Any] = TypeAdapter( - Annotated[annotated_args], # ty: ignore[invalid-type-form] - config=self.config, - ) - - def get_default(self) -> Any: - if self.field_info.is_required(): - return Undefined - return self.field_info.get_default(call_default_factory=True) - - def validate( - self, - value: Any, - values: dict[str, Any] = {}, # noqa: B006 - *, - loc: tuple[int | str, ...] = (), - ) -> tuple[Any, list[dict[str, Any]]]: - try: - return ( - self._type_adapter.validate_python(value, from_attributes=True), - [], - ) - except ValidationError as exc: - return None, _regenerate_error_with_loc( - errors=exc.errors(include_url=False), loc_prefix=loc - ) - - def serialize( - self, - value: Any, - *, - mode: Literal["json", "python"] = "json", - include: IncEx | None = None, - exclude: IncEx | None = None, - by_alias: bool = True, - exclude_unset: bool = False, - exclude_defaults: bool = False, - exclude_none: bool = False, - ) -> Any: - # What calls this code passes a value that already called - # self._type_adapter.validate_python(value) - return self._type_adapter.dump_python( - value, - mode=mode, - include=include, - exclude=exclude, - by_alias=by_alias, - exclude_unset=exclude_unset, - exclude_defaults=exclude_defaults, - exclude_none=exclude_none, - ) - - def serialize_json( - self, - value: Any, - *, - include: IncEx | None = None, - exclude: IncEx | None = None, - by_alias: bool = True, - exclude_unset: bool = False, - exclude_defaults: bool = False, - exclude_none: bool = False, - ) -> bytes: - # What calls this code passes a value that already called - # self._type_adapter.validate_python(value) - # This uses Pydantic's dump_json() which serializes directly to JSON - # bytes in one pass (via Rust), avoiding the intermediate Python dict - # step of dump_python(mode="json") + json.dumps(). - return self._type_adapter.dump_json( - value, - include=include, - exclude=exclude, - by_alias=by_alias, - exclude_unset=exclude_unset, - exclude_defaults=exclude_defaults, - exclude_none=exclude_none, - ) - - def __hash__(self) -> int: - # Each ModelField is unique for our purposes, to allow making a dict from - # ModelField to its JSON Schema. - return id(self) - - -def _has_computed_fields(field: ModelField) -> bool: - computed_fields = field._type_adapter.core_schema.get("schema", {}).get( - "computed_fields", [] - ) - return len(computed_fields) > 0 - - -def get_schema_from_model_field( - *, - field: ModelField, - model_name_map: ModelNameMap, - field_mapping: dict[ - tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue - ], - separate_input_output_schemas: bool = True, -) -> dict[str, Any]: - override_mode: Literal["validation"] | None = ( - None - if (separate_input_output_schemas or _has_computed_fields(field)) - else "validation" - ) - field_alias = ( - (field.validation_alias or field.alias) - if field.mode == "validation" - else (field.serialization_alias or field.alias) - ) - - # This expects that GenerateJsonSchema was already used to generate the definitions - json_schema = field_mapping[(field, override_mode or field.mode)] - if "$ref" not in json_schema: - # TODO remove when deprecating Pydantic v1 - # Ref: https://github.com/pydantic/pydantic/blob/d61792cc42c80b13b23e3ffa74bc37ec7c77f7d1/pydantic/schema.py#L207 - json_schema["title"] = field.field_info.title or field_alias.title().replace( - "_", " " - ) - return json_schema - - -def get_definitions( - *, - fields: Sequence[ModelField], - model_name_map: ModelNameMap, - separate_input_output_schemas: bool = True, -) -> tuple[ - dict[tuple[ModelField, Literal["validation", "serialization"]], JsonSchemaValue], - dict[str, dict[str, Any]], -]: - schema_generator = GenerateJsonSchema(ref_template=REF_TEMPLATE) - validation_fields = [field for field in fields if field.mode == "validation"] - serialization_fields = [field for field in fields if field.mode == "serialization"] - flat_validation_models = get_flat_models_from_fields( - validation_fields, known_models=set() - ) - flat_serialization_models = get_flat_models_from_fields( - serialization_fields, known_models=set() - ) - flat_validation_model_fields = [ - ModelField( - field_info=FieldInfo(annotation=model), - name=model.__name__, - mode="validation", - ) - for model in flat_validation_models - ] - flat_serialization_model_fields = [ - ModelField( - field_info=FieldInfo(annotation=model), - name=model.__name__, - mode="serialization", - ) - for model in flat_serialization_models - ] - flat_model_fields = flat_validation_model_fields + flat_serialization_model_fields - input_types = {f.field_info.annotation for f in fields} - unique_flat_model_fields = { - f for f in flat_model_fields if f.field_info.annotation not in input_types - } - inputs = [ - ( - field, - ( - field.mode - if (separate_input_output_schemas or _has_computed_fields(field)) - else "validation" - ), - field._type_adapter.core_schema, - ) - for field in list(fields) + list(unique_flat_model_fields) - ] - field_mapping, definitions = schema_generator.generate_definitions(inputs=inputs) - for item_def in cast(dict[str, dict[str, Any]], definitions).values(): - if "description" in item_def: - item_description = cast(str, item_def["description"]).split("\f")[0] - item_def["description"] = item_description - # definitions: dict[DefsRef, dict[str, Any]] - # but mypy complains about general str in other places that are not declared as - # DefsRef, although DefsRef is just str: - # DefsRef = NewType('DefsRef', str) - # So, a cast to simplify the types here - return field_mapping, cast(dict[str, dict[str, Any]], definitions) - - -def is_scalar_field(field: ModelField) -> bool: - from fastapi import params - - return shared.field_annotation_is_scalar( - field.field_info.annotation - ) and not isinstance(field.field_info, params.Body) - - -def copy_field_info(*, field_info: FieldInfo, annotation: Any) -> FieldInfo: - cls = type(field_info) - merged_field_info = cls.from_annotation(annotation) - new_field_info = copy(field_info) - new_field_info.metadata = merged_field_info.metadata - new_field_info.annotation = merged_field_info.annotation - return new_field_info - - -def serialize_sequence_value(*, field: ModelField, value: Any) -> Sequence[Any]: - origin_type = get_origin(field.field_info.annotation) or field.field_info.annotation - if origin_type is Union or origin_type is UnionType: # Handle optional sequences - union_args = get_args(field.field_info.annotation) - for union_arg in union_args: - if union_arg is type(None): - continue - origin_type = get_origin(union_arg) or union_arg - break - assert issubclass(origin_type, shared.sequence_types) # type: ignore[arg-type] # ty: ignore[invalid-argument-type] - return shared.sequence_annotation_to_type[origin_type](value) # type: ignore[no-any-return,index] # ty: ignore[invalid-return-type] - - -def get_missing_field_error(loc: tuple[int | str, ...]) -> dict[str, Any]: - error = ValidationError.from_exception_data( - "Field required", [{"type": "missing", "loc": loc, "input": {}}] - ).errors(include_url=False)[0] - error["input"] = None - return error # type: ignore[return-value] # ty: ignore[invalid-return-type] - - -def create_body_model( - *, fields: Sequence[ModelField], model_name: str -) -> type[BaseModel]: - field_params = {f.name: (f.field_info.annotation, f.field_info) for f in fields} - BodyModel: type[BaseModel] = create_model(model_name, **field_params) # type: ignore[call-overload] # ty: ignore[no-matching-overload] - return BodyModel - - -def get_model_fields(model: type[BaseModel]) -> list[ModelField]: - model_fields: list[ModelField] = [] - for name, field_info in model.model_fields.items(): - type_ = field_info.annotation - if lenient_issubclass(type_, (BaseModel, dict)) or is_dataclass(type_): - model_config = None - else: - model_config = model.model_config - model_fields.append( - ModelField( - field_info=field_info, - name=name, - config=model_config, - ) - ) - return model_fields - - -@lru_cache -def get_cached_model_fields(model: type[BaseModel]) -> list[ModelField]: - return get_model_fields(model) - - -# Duplicate of several schema functions from Pydantic v1 to make them compatible with -# Pydantic v2 and allow mixing the models - -TypeModelOrEnum = type["BaseModel"] | type[Enum] -TypeModelSet = set[TypeModelOrEnum] - - -def normalize_name(name: str) -> str: - return re.sub(r"[^a-zA-Z0-9.\-_]", "_", name) - - -def get_model_name_map(unique_models: TypeModelSet) -> dict[TypeModelOrEnum, str]: - name_model_map = {} - for model in unique_models: - model_name = normalize_name(model.__name__) - name_model_map[model_name] = model - return {v: k for k, v in name_model_map.items()} - - -def get_flat_models_from_model( - model: type["BaseModel"], known_models: TypeModelSet | None = None -) -> TypeModelSet: - known_models = known_models or set() - fields = get_model_fields(model) - get_flat_models_from_fields(fields, known_models=known_models) - return known_models - - -def get_flat_models_from_annotation( - annotation: Any, known_models: TypeModelSet -) -> TypeModelSet: - origin = get_origin(annotation) - if origin is not None: - for arg in get_args(annotation): - if lenient_issubclass(arg, (BaseModel, Enum)): - if arg not in known_models: - known_models.add(arg) # type: ignore[arg-type] - if lenient_issubclass(arg, BaseModel): - get_flat_models_from_model(arg, known_models=known_models) - else: - get_flat_models_from_annotation(arg, known_models=known_models) - return known_models - - -def get_flat_models_from_field( - field: ModelField, known_models: TypeModelSet -) -> TypeModelSet: - field_type = field.field_info.annotation - if lenient_issubclass(field_type, BaseModel): - if field_type in known_models: - return known_models - known_models.add(field_type) - get_flat_models_from_model(field_type, known_models=known_models) - elif lenient_issubclass(field_type, Enum): - known_models.add(field_type) - else: - get_flat_models_from_annotation(field_type, known_models=known_models) - return known_models - - -def get_flat_models_from_fields( - fields: Sequence[ModelField], known_models: TypeModelSet -) -> TypeModelSet: - for field in fields: - get_flat_models_from_field(field, known_models=known_models) - return known_models - - -def _regenerate_error_with_loc( - *, errors: Sequence[Any], loc_prefix: tuple[str | int, ...] -) -> list[dict[str, Any]]: - updated_loc_errors: list[Any] = [ - {**err, "loc": loc_prefix + err.get("loc", ())} for err in errors - ] - - return updated_loc_errors diff --git a/bundle/python-cpu/Lib/site-packages/fastapi/applications.py b/bundle/python-cpu/Lib/site-packages/fastapi/applications.py deleted file mode 100644 index b5fc76d1607622648ccc0eff63a6b08e65d42afa..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/fastapi/applications.py +++ /dev/null @@ -1,4774 +0,0 @@ -import os -from collections.abc import Awaitable, Callable, Coroutine, Sequence -from enum import Enum -from typing import Annotated, Any, Literal, TypeVar - -from annotated_doc import Doc -from fastapi import routing -from fastapi.datastructures import Default, DefaultPlaceholder -from fastapi.exception_handlers import ( - http_exception_handler, - request_validation_exception_handler, - websocket_request_validation_exception_handler, -) -from fastapi.exceptions import RequestValidationError, WebSocketRequestValidationError -from fastapi.logger import logger -from fastapi.middleware.asyncexitstack import AsyncExitStackMiddleware -from fastapi.openapi.docs import ( - get_redoc_html, - get_swagger_ui_html, - get_swagger_ui_oauth2_redirect_html, -) -from fastapi.openapi.utils import get_openapi -from fastapi.params import Depends -from fastapi.types import DecoratedCallable, IncEx -from fastapi.utils import generate_unique_id -from starlette.applications import Starlette -from starlette.datastructures import State -from starlette.exceptions import HTTPException -from starlette.middleware import Middleware -from starlette.middleware.base import BaseHTTPMiddleware -from starlette.middleware.errors import ServerErrorMiddleware -from starlette.middleware.exceptions import ExceptionMiddleware -from starlette.requests import Request -from starlette.responses import HTMLResponse, JSONResponse, Response -from starlette.routing import BaseRoute -from starlette.types import ASGIApp, ExceptionHandler, Lifespan, Receive, Scope, Send -from typing_extensions import deprecated - -AppType = TypeVar("AppType", bound="FastAPI") - - -class FastAPI(Starlette): - """ - `FastAPI` app class, the main entrypoint to use FastAPI. - - Read more in the - [FastAPI docs for First Steps](https://fastapi.tiangolo.com/tutorial/first-steps/). - - ## Example - - ```python - from fastapi import FastAPI - - app = FastAPI() - ``` - """ - - def __init__( - self: AppType, - *, - debug: Annotated[ - bool, - Doc( - """ - Boolean indicating if debug tracebacks should be returned on server - errors. - - Read more in the - [Starlette docs for Applications](https://starlette.dev/applications/#starlette.applications.Starlette). - """ - ), - ] = False, - routes: Annotated[ - list[BaseRoute] | None, - Doc( - """ - **Note**: you probably shouldn't use this parameter, it is inherited - from Starlette and supported for compatibility. - - --- - - A list of routes to serve incoming HTTP and WebSocket requests. - """ - ), - deprecated( - """ - You normally wouldn't use this parameter with FastAPI, it is inherited - from Starlette and supported for compatibility. - - In FastAPI, you normally would use the *path operation methods*, - like `app.get()`, `app.post()`, etc. - """ - ), - ] = None, - title: Annotated[ - str, - Doc( - """ - The title of the API. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more in the - [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-api). - - **Example** - - ```python - from fastapi import FastAPI - - app = FastAPI(title="ChimichangApp") - ``` - """ - ), - ] = "FastAPI", - summary: Annotated[ - str | None, - Doc( - """ - A short summary of the API. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more in the - [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-api). - - **Example** - - ```python - from fastapi import FastAPI - - app = FastAPI(summary="Deadpond's favorite app. Nuff said.") - ``` - """ - ), - ] = None, - description: Annotated[ - str, - Doc( - ''' - A description of the API. Supports Markdown (using - [CommonMark syntax](https://commonmark.org/)). - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more in the - [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-api). - - **Example** - - ```python - from fastapi import FastAPI - - app = FastAPI( - description=""" - ChimichangApp API helps you do awesome stuff. 🚀 - - ## Items - - You can **read items**. - - ## Users - - You will be able to: - - * **Create users** (_not implemented_). - * **Read users** (_not implemented_). - - """ - ) - ``` - ''' - ), - ] = "", - version: Annotated[ - str, - Doc( - """ - The version of the API. - - **Note** This is the version of your application, not the version of - the OpenAPI specification nor the version of FastAPI being used. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more in the - [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-api). - - **Example** - - ```python - from fastapi import FastAPI - - app = FastAPI(version="0.0.1") - ``` - """ - ), - ] = "0.1.0", - openapi_url: Annotated[ - str | None, - Doc( - """ - The URL where the OpenAPI schema will be served from. - - If you set it to `None`, no OpenAPI schema will be served publicly, and - the default automatic endpoints `/docs` and `/redoc` will also be - disabled. - - Read more in the - [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#openapi-url). - - **Example** - - ```python - from fastapi import FastAPI - - app = FastAPI(openapi_url="/api/v1/openapi.json") - ``` - """ - ), - ] = "/openapi.json", - openapi_tags: Annotated[ - list[dict[str, Any]] | None, - Doc( - """ - A list of tags used by OpenAPI, these are the same `tags` you can set - in the *path operations*, like: - - * `@app.get("/users/", tags=["users"])` - * `@app.get("/items/", tags=["items"])` - - The order of the tags can be used to specify the order shown in - tools like Swagger UI, used in the automatic path `/docs`. - - It's not required to specify all the tags used. - - The tags that are not declared MAY be organized randomly or based - on the tools' logic. Each tag name in the list MUST be unique. - - The value of each item is a `dict` containing: - - * `name`: The name of the tag. - * `description`: A short description of the tag. - [CommonMark syntax](https://commonmark.org/) MAY be used for rich - text representation. - * `externalDocs`: Additional external documentation for this tag. If - provided, it would contain a `dict` with: - * `description`: A short description of the target documentation. - [CommonMark syntax](https://commonmark.org/) MAY be used for - rich text representation. - * `url`: The URL for the target documentation. Value MUST be in - the form of a URL. - - Read more in the - [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-tags). - - **Example** - - ```python - from fastapi import FastAPI - - tags_metadata = [ - { - "name": "users", - "description": "Operations with users. The **login** logic is also here.", - }, - { - "name": "items", - "description": "Manage items. So _fancy_ they have their own docs.", - "externalDocs": { - "description": "Items external docs", - "url": "https://fastapi.tiangolo.com/", - }, - }, - ] - - app = FastAPI(openapi_tags=tags_metadata) - ``` - """ - ), - ] = None, - servers: Annotated[ - list[dict[str, str | Any]] | None, - Doc( - """ - A `list` of `dict`s with connectivity information to a target server. - - You would use it, for example, if your application is served from - different domains and you want to use the same Swagger UI in the - browser to interact with each of them (instead of having multiple - browser tabs open). Or if you want to leave fixed the possible URLs. - - If the servers `list` is not provided, or is an empty `list`, the - `servers` property in the generated OpenAPI will be: - - * a `dict` with a `url` value of the application's mounting point - (`root_path`) if it's different from `/`. - * otherwise, the `servers` property will be omitted from the OpenAPI - schema. - - Each item in the `list` is a `dict` containing: - - * `url`: A URL to the target host. This URL supports Server Variables - and MAY be relative, to indicate that the host location is relative - to the location where the OpenAPI document is being served. Variable - substitutions will be made when a variable is named in `{`brackets`}`. - * `description`: An optional string describing the host designated by - the URL. [CommonMark syntax](https://commonmark.org/) MAY be used for - rich text representation. - * `variables`: A `dict` between a variable name and its value. The value - is used for substitution in the server's URL template. - - Read more in the - [FastAPI docs for Behind a Proxy](https://fastapi.tiangolo.com/advanced/behind-a-proxy/#additional-servers). - - **Example** - - ```python - from fastapi import FastAPI - - app = FastAPI( - servers=[ - {"url": "https://stag.example.com", "description": "Staging environment"}, - {"url": "https://prod.example.com", "description": "Production environment"}, - ] - ) - ``` - """ - ), - ] = None, - dependencies: Annotated[ - Sequence[Depends] | None, - Doc( - """ - A list of global dependencies, they will be applied to each - *path operation*, including in sub-routers. - - Read more about it in the - [FastAPI docs for Global Dependencies](https://fastapi.tiangolo.com/tutorial/dependencies/global-dependencies/). - - **Example** - - ```python - from fastapi import Depends, FastAPI - - from .dependencies import func_dep_1, func_dep_2 - - app = FastAPI(dependencies=[Depends(func_dep_1), Depends(func_dep_2)]) - ``` - """ - ), - ] = None, - default_response_class: Annotated[ - type[Response], - Doc( - """ - The default response class to be used. - - Read more in the - [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#default-response-class). - - **Example** - - ```python - from fastapi import FastAPI - from fastapi.responses import ORJSONResponse - - app = FastAPI(default_response_class=ORJSONResponse) - ``` - """ - ), - ] = Default(JSONResponse), - redirect_slashes: Annotated[ - bool, - Doc( - """ - Whether to detect and redirect slashes in URLs when the client doesn't - use the same format. - - **Example** - - ```python - from fastapi import FastAPI - - app = FastAPI(redirect_slashes=True) # the default - - @app.get("/items/") - async def read_items(): - return [{"item_id": "Foo"}] - ``` - - With this app, if a client goes to `/items` (without a trailing slash), - they will be automatically redirected with an HTTP status code of 307 - to `/items/`. - """ - ), - ] = True, - docs_url: Annotated[ - str | None, - Doc( - """ - The path to the automatic interactive API documentation. - It is handled in the browser by Swagger UI. - - The default URL is `/docs`. You can disable it by setting it to `None`. - - If `openapi_url` is set to `None`, this will be automatically disabled. - - Read more in the - [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#docs-urls). - - **Example** - - ```python - from fastapi import FastAPI - - app = FastAPI(docs_url="/documentation", redoc_url=None) - ``` - """ - ), - ] = "/docs", - redoc_url: Annotated[ - str | None, - Doc( - """ - The path to the alternative automatic interactive API documentation - provided by ReDoc. - - The default URL is `/redoc`. You can disable it by setting it to `None`. - - If `openapi_url` is set to `None`, this will be automatically disabled. - - Read more in the - [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#docs-urls). - - **Example** - - ```python - from fastapi import FastAPI - - app = FastAPI(docs_url="/documentation", redoc_url="redocumentation") - ``` - """ - ), - ] = "/redoc", - swagger_ui_oauth2_redirect_url: Annotated[ - str | None, - Doc( - """ - The OAuth2 redirect endpoint for the Swagger UI. - - By default it is `/docs/oauth2-redirect`. - - This is only used if you use OAuth2 (with the "Authorize" button) - with Swagger UI. - """ - ), - ] = "/docs/oauth2-redirect", - swagger_ui_init_oauth: Annotated[ - dict[str, Any] | None, - Doc( - """ - OAuth2 configuration for the Swagger UI, by default shown at `/docs`. - - Read more about the available configuration options in the - [Swagger UI docs](https://swagger.io/docs/open-source-tools/swagger-ui/usage/oauth2/). - """ - ), - ] = None, - middleware: Annotated[ - Sequence[Middleware] | None, - Doc( - """ - List of middleware to be added when creating the application. - - In FastAPI you would normally do this with `app.add_middleware()` - instead. - - Read more in the - [FastAPI docs for Middleware](https://fastapi.tiangolo.com/tutorial/middleware/). - """ - ), - ] = None, - exception_handlers: Annotated[ - dict[ - int | type[Exception], - Callable[[Request, Any], Coroutine[Any, Any, Response]], - ] - | None, - Doc( - """ - A dictionary with handlers for exceptions. - - In FastAPI, you would normally use the decorator - `@app.exception_handler()`. - - Read more in the - [FastAPI docs for Handling Errors](https://fastapi.tiangolo.com/tutorial/handling-errors/). - """ - ), - ] = None, - on_startup: Annotated[ - Sequence[Callable[[], Any]] | None, - Doc( - """ - A list of startup event handler functions. - - You should instead use the `lifespan` handlers. - - Read more in the [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/). - """ - ), - ] = None, - on_shutdown: Annotated[ - Sequence[Callable[[], Any]] | None, - Doc( - """ - A list of shutdown event handler functions. - - You should instead use the `lifespan` handlers. - - Read more in the - [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/). - """ - ), - ] = None, - lifespan: Annotated[ - Lifespan[AppType] | None, - Doc( - """ - A `Lifespan` context manager handler. This replaces `startup` and - `shutdown` functions with a single context manager. - - Read more in the - [FastAPI docs for `lifespan`](https://fastapi.tiangolo.com/advanced/events/). - """ - ), - ] = None, - terms_of_service: Annotated[ - str | None, - Doc( - """ - A URL to the Terms of Service for your API. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more at the - [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-api). - - **Example** - - ```python - app = FastAPI(terms_of_service="http://example.com/terms/") - ``` - """ - ), - ] = None, - contact: Annotated[ - dict[str, str | Any] | None, - Doc( - """ - A dictionary with the contact information for the exposed API. - - It can contain several fields. - - * `name`: (`str`) The name of the contact person/organization. - * `url`: (`str`) A URL pointing to the contact information. MUST be in - the format of a URL. - * `email`: (`str`) The email address of the contact person/organization. - MUST be in the format of an email address. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more at the - [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-api). - - **Example** - - ```python - app = FastAPI( - contact={ - "name": "Deadpoolio the Amazing", - "url": "http://x-force.example.com/contact/", - "email": "dp@x-force.example.com", - } - ) - ``` - """ - ), - ] = None, - license_info: Annotated[ - dict[str, str | Any] | None, - Doc( - """ - A dictionary with the license information for the exposed API. - - It can contain several fields. - - * `name`: (`str`) **REQUIRED** (if a `license_info` is set). The - license name used for the API. - * `identifier`: (`str`) An [SPDX](https://spdx.dev/) license expression - for the API. The `identifier` field is mutually exclusive of the `url` - field. Available since OpenAPI 3.1.0, FastAPI 0.99.0. - * `url`: (`str`) A URL to the license used for the API. This MUST be - the format of a URL. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more at the - [FastAPI docs for Metadata and Docs URLs](https://fastapi.tiangolo.com/tutorial/metadata/#metadata-for-api). - - **Example** - - ```python - app = FastAPI( - license_info={ - "name": "Apache 2.0", - "url": "https://www.apache.org/licenses/LICENSE-2.0.html", - } - ) - ``` - """ - ), - ] = None, - openapi_prefix: Annotated[ - str, - Doc( - """ - A URL prefix for the OpenAPI URL. - """ - ), - deprecated( - """ - "openapi_prefix" has been deprecated in favor of "root_path", which - follows more closely the ASGI standard, is simpler, and more - automatic. - """ - ), - ] = "", - root_path: Annotated[ - str, - Doc( - """ - A path prefix handled by a proxy that is not seen by the application - but is seen by external clients, which affects things like Swagger UI. - - Read more about it at the - [FastAPI docs for Behind a Proxy](https://fastapi.tiangolo.com/advanced/behind-a-proxy/). - - **Example** - - ```python - from fastapi import FastAPI - - app = FastAPI(root_path="/api/v1") - ``` - """ - ), - ] = "", - root_path_in_servers: Annotated[ - bool, - Doc( - """ - To disable automatically generating the URLs in the `servers` field - in the autogenerated OpenAPI using the `root_path`. - - Read more about it in the - [FastAPI docs for Behind a Proxy](https://fastapi.tiangolo.com/advanced/behind-a-proxy/#disable-automatic-server-from-root-path). - - **Example** - - ```python - from fastapi import FastAPI - - app = FastAPI(root_path_in_servers=False) - ``` - """ - ), - ] = True, - responses: Annotated[ - dict[int | str, dict[str, Any]] | None, - Doc( - """ - Additional responses to be shown in OpenAPI. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for Additional Responses in OpenAPI](https://fastapi.tiangolo.com/advanced/additional-responses/). - - And in the - [FastAPI docs for Bigger Applications](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies). - """ - ), - ] = None, - callbacks: Annotated[ - list[BaseRoute] | None, - Doc( - """ - OpenAPI callbacks that should apply to all *path operations*. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/). - """ - ), - ] = None, - webhooks: Annotated[ - routing.APIRouter | None, - Doc( - """ - Add OpenAPI webhooks. This is similar to `callbacks` but it doesn't - depend on specific *path operations*. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - **Note**: This is available since OpenAPI 3.1.0, FastAPI 0.99.0. - - Read more about it in the - [FastAPI docs for OpenAPI Webhooks](https://fastapi.tiangolo.com/advanced/openapi-webhooks/). - """ - ), - ] = None, - deprecated: Annotated[ - bool | None, - Doc( - """ - Mark all *path operations* as deprecated. You probably don't need it, - but it's available. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#deprecate-a-path-operation). - """ - ), - ] = None, - include_in_schema: Annotated[ - bool, - Doc( - """ - To include (or not) all the *path operations* in the generated OpenAPI. - You probably don't need it, but it's available. - - This affects the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-parameters-from-openapi). - """ - ), - ] = True, - swagger_ui_parameters: Annotated[ - dict[str, Any] | None, - Doc( - """ - Parameters to configure Swagger UI, the autogenerated interactive API - documentation (by default at `/docs`). - - Read more about it in the - [FastAPI docs about how to Configure Swagger UI](https://fastapi.tiangolo.com/how-to/configure-swagger-ui/). - """ - ), - ] = None, - generate_unique_id_function: Annotated[ - Callable[[routing.APIRoute], str], - Doc( - """ - Customize the function used to generate unique IDs for the *path - operations* shown in the generated OpenAPI. - - This is particularly useful when automatically generating clients or - SDKs for your API. - - Read more about it in the - [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). - """ - ), - ] = Default(generate_unique_id), - separate_input_output_schemas: Annotated[ - bool, - Doc( - """ - Whether to generate separate OpenAPI schemas for request body and - response body when the results would be more precise. - - This is particularly useful when automatically generating clients. - - For example, if you have a model like: - - ```python - from pydantic import BaseModel - - class Item(BaseModel): - name: str - tags: list[str] = [] - ``` - - When `Item` is used for input, a request body, `tags` is not required, - the client doesn't have to provide it. - - But when using `Item` for output, for a response body, `tags` is always - available because it has a default value, even if it's just an empty - list. So, the client should be able to always expect it. - - In this case, there would be two different schemas, one for input and - another one for output. - - Read more about it in the - [FastAPI docs about how to separate schemas for input and output](https://fastapi.tiangolo.com/how-to/separate-openapi-schemas) - """ - ), - ] = True, - openapi_external_docs: Annotated[ - dict[str, Any] | None, - Doc( - """ - This field allows you to provide additional external documentation links. - If provided, it must be a dictionary containing: - - * `description`: A brief description of the external documentation. - * `url`: The URL pointing to the external documentation. The value **MUST** - be a valid URL format. - - **Example**: - - ```python - from fastapi import FastAPI - - external_docs = { - "description": "Detailed API Reference", - "url": "https://example.com/api-docs", - } - - app = FastAPI(openapi_external_docs=external_docs) - ``` - """ - ), - ] = None, - strict_content_type: Annotated[ - bool, - Doc( - """ - Enable strict checking for request Content-Type headers. - - When `True` (the default), requests with a body that do not include - a `Content-Type` header will **not** be parsed as JSON. - - This prevents potential cross-site request forgery (CSRF) attacks - that exploit the browser's ability to send requests without a - Content-Type header, bypassing CORS preflight checks. In particular - applicable for apps that need to be run locally (in localhost). - - When `False`, requests without a `Content-Type` header will have - their body parsed as JSON, which maintains compatibility with - certain clients that don't send `Content-Type` headers. - - Read more about it in the - [FastAPI docs for Strict Content-Type](https://fastapi.tiangolo.com/advanced/strict-content-type/). - """ - ), - ] = True, - **extra: Annotated[ - Any, - Doc( - """ - Extra keyword arguments to be stored in the app, not used by FastAPI - anywhere. - """ - ), - ], - ) -> None: - self.debug = debug - self.title = title - self.summary = summary - self.description = description - self.version = version - self.terms_of_service = terms_of_service - self.contact = contact - self.license_info = license_info - self.openapi_url = openapi_url - self.openapi_tags = openapi_tags - self.root_path_in_servers = root_path_in_servers - self.docs_url = docs_url - self.redoc_url = redoc_url - self.swagger_ui_oauth2_redirect_url = swagger_ui_oauth2_redirect_url - self.swagger_ui_init_oauth = swagger_ui_init_oauth - self.swagger_ui_parameters = swagger_ui_parameters - self.servers = servers or [] - self.separate_input_output_schemas = separate_input_output_schemas - self.openapi_external_docs = openapi_external_docs - self.extra = extra - self.openapi_version: Annotated[ - str, - Doc( - """ - The version string of OpenAPI. - - FastAPI will generate OpenAPI version 3.1.0, and will output that as - the OpenAPI version. But some tools, even though they might be - compatible with OpenAPI 3.1.0, might not recognize it as a valid. - - So you could override this value to trick those tools into using - the generated OpenAPI. Have in mind that this is a hack. But if you - avoid using features added in OpenAPI 3.1.0, it might work for your - use case. - - This is not passed as a parameter to the `FastAPI` class to avoid - giving the false idea that FastAPI would generate a different OpenAPI - schema. It is only available as an attribute. - - **Example** - - ```python - from fastapi import FastAPI - - app = FastAPI() - - app.openapi_version = "3.0.2" - ``` - """ - ), - ] = "3.1.0" - self.openapi_schema: dict[str, Any] | None = None - self._openapi_routes_version: int | None = None - if self.openapi_url: - assert self.title, "A title must be provided for OpenAPI, e.g.: 'My API'" - assert self.version, "A version must be provided for OpenAPI, e.g.: '2.1.0'" - # TODO: remove when discarding the openapi_prefix parameter - if openapi_prefix: - logger.warning( - '"openapi_prefix" has been deprecated in favor of "root_path", which ' - "follows more closely the ASGI standard, is simpler, and more " - "automatic. Check the docs at " - "https://fastapi.tiangolo.com/advanced/sub-applications/" - ) - self.webhooks: Annotated[ - routing.APIRouter, - Doc( - """ - The `app.webhooks` attribute is an `APIRouter` with the *path - operations* that will be used just for documentation of webhooks. - - Read more about it in the - [FastAPI docs for OpenAPI Webhooks](https://fastapi.tiangolo.com/advanced/openapi-webhooks/). - """ - ), - ] = webhooks or routing.APIRouter() - self.root_path = root_path or openapi_prefix - self.state: Annotated[ - State, - Doc( - """ - A state object for the application. This is the same object for the - entire application, it doesn't change from request to request. - - You normally wouldn't use this in FastAPI, for most of the cases you - would instead use FastAPI dependencies. - - This is simply inherited from Starlette. - - Read more about it in the - [Starlette docs for Applications](https://starlette.dev/applications/#storing-state-on-the-app-instance). - """ - ), - ] = State() - self.dependency_overrides: Annotated[ - dict[Callable[..., Any], Callable[..., Any]], - Doc( - """ - A dictionary with overrides for the dependencies. - - Each key is the original dependency callable, and the value is the - actual dependency that should be called. - - This is for testing, to replace expensive dependencies with testing - versions. - - Read more about it in the - [FastAPI docs for Testing Dependencies with Overrides](https://fastapi.tiangolo.com/advanced/testing-dependencies/). - """ - ), - ] = {} - self.router: routing.APIRouter = routing.APIRouter( - routes=routes, - redirect_slashes=redirect_slashes, - dependency_overrides_provider=self, - on_startup=on_startup, - on_shutdown=on_shutdown, - lifespan=lifespan, - default_response_class=default_response_class, - dependencies=dependencies, - callbacks=callbacks, - deprecated=deprecated, - include_in_schema=include_in_schema, - responses=responses, - generate_unique_id_function=generate_unique_id_function, - strict_content_type=strict_content_type, - ) - self.exception_handlers: dict[ - Any, Callable[[Request, Any], Response | Awaitable[Response]] - ] = {} if exception_handlers is None else dict(exception_handlers) - self.exception_handlers.setdefault(HTTPException, http_exception_handler) - self.exception_handlers.setdefault( - RequestValidationError, request_validation_exception_handler - ) - - # Starlette still has incorrect type specification for the handlers - self.exception_handlers.setdefault( - WebSocketRequestValidationError, - websocket_request_validation_exception_handler, # type: ignore[arg-type] - ) # ty: ignore[no-matching-overload] - - self.user_middleware: list[Middleware] = ( - [] if middleware is None else list(middleware) - ) - self.middleware_stack: ASGIApp | None = None - self.setup() - - def build_middleware_stack(self) -> ASGIApp: - # Duplicate/override from Starlette to add AsyncExitStackMiddleware - # inside of ExceptionMiddleware, inside of custom user middlewares - debug = self.debug - error_handler = None - exception_handlers: dict[Any, ExceptionHandler] = {} - - for key, value in self.exception_handlers.items(): - if key in (500, Exception): - error_handler = value - else: - exception_handlers[key] = value - - middleware = ( - [Middleware(ServerErrorMiddleware, handler=error_handler, debug=debug)] - + self.user_middleware - + [ - Middleware( - ExceptionMiddleware, - handlers=exception_handlers, - debug=debug, - ), - # Add FastAPI-specific AsyncExitStackMiddleware for closing files. - # Before this was also used for closing dependencies with yield but - # those now have their own AsyncExitStack, to properly support - # streaming responses while keeping compatibility with the previous - # versions (as of writing 0.117.1) that allowed doing - # except HTTPException inside a dependency with yield. - # This needs to happen after user middlewares because those create a - # new contextvars context copy by using a new AnyIO task group. - # This AsyncExitStack preserves the context for contextvars, not - # strictly necessary for closing files but it was one of the original - # intentions. - # If the AsyncExitStack lived outside of the custom middlewares and - # contextvars were set, for example in a dependency with 'yield' - # in that internal contextvars context, the values would not be - # available in the outer context of the AsyncExitStack. - # By placing the middleware and the AsyncExitStack here, inside all - # user middlewares, the same context is used. - # This is currently not needed, only for closing files, but used to be - # important when dependencies with yield were closed here. - Middleware(AsyncExitStackMiddleware), - ] - ) - - app = self.router - for cls, args, kwargs in reversed(middleware): - app = cls(app, *args, **kwargs) - return app - - def openapi(self) -> dict[str, Any]: - """ - Generate the OpenAPI schema of the application. This is called by FastAPI - internally. - - The first time it is called it stores the result in the attribute - `app.openapi_schema`, and next times it is called, it just returns that same - result. To avoid the cost of generating the schema every time. - - If you need to modify the generated OpenAPI schema, you could modify it. - - Read more in the - [FastAPI docs for OpenAPI](https://fastapi.tiangolo.com/how-to/extending-openapi/). - """ - routes_version = self.router._get_routes_version() - if not self.openapi_schema or self._openapi_routes_version != routes_version: - self.openapi_schema = get_openapi( - title=self.title, - version=self.version, - openapi_version=self.openapi_version, - summary=self.summary, - description=self.description, - terms_of_service=self.terms_of_service, - contact=self.contact, - license_info=self.license_info, - routes=self.routes, - webhooks=self.webhooks.routes, - tags=self.openapi_tags, - servers=self.servers, - separate_input_output_schemas=self.separate_input_output_schemas, - external_docs=self.openapi_external_docs, - ) - self._openapi_routes_version = routes_version - return self.openapi_schema - - def setup(self) -> None: - if self.openapi_url: - - async def openapi(req: Request) -> JSONResponse: - root_path = req.scope.get("root_path", "").rstrip("/") - schema = self.openapi() - if root_path and self.root_path_in_servers: - server_urls = {s.get("url") for s in schema.get("servers", [])} - if root_path not in server_urls: - schema = dict(schema) - schema["servers"] = [{"url": root_path}] + schema.get( - "servers", [] - ) - return JSONResponse(schema) - - self.add_route(self.openapi_url, openapi, include_in_schema=False) - if self.openapi_url and self.docs_url: - - async def swagger_ui_html(req: Request) -> HTMLResponse: - root_path = req.scope.get("root_path", "").rstrip("/") - openapi_url = root_path + self.openapi_url - oauth2_redirect_url = self.swagger_ui_oauth2_redirect_url - if oauth2_redirect_url: - oauth2_redirect_url = root_path + oauth2_redirect_url - return get_swagger_ui_html( - openapi_url=openapi_url, - title=f"{self.title} - Swagger UI", - oauth2_redirect_url=oauth2_redirect_url, - init_oauth=self.swagger_ui_init_oauth, - swagger_ui_parameters=self.swagger_ui_parameters, - ) - - self.add_route(self.docs_url, swagger_ui_html, include_in_schema=False) - - if self.swagger_ui_oauth2_redirect_url: - - async def swagger_ui_redirect(req: Request) -> HTMLResponse: - return get_swagger_ui_oauth2_redirect_html() - - self.add_route( - self.swagger_ui_oauth2_redirect_url, - swagger_ui_redirect, - include_in_schema=False, - ) - if self.openapi_url and self.redoc_url: - - async def redoc_html(req: Request) -> HTMLResponse: - root_path = req.scope.get("root_path", "").rstrip("/") - openapi_url = root_path + self.openapi_url - return get_redoc_html( - openapi_url=openapi_url, title=f"{self.title} - ReDoc" - ) - - self.add_route(self.redoc_url, redoc_html, include_in_schema=False) - - async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: - if self.root_path: - scope["root_path"] = self.root_path - await super().__call__(scope, receive, send) - - def add_api_route( - self, - path: str, - endpoint: Callable[..., Any], - *, - response_model: Any = Default(None), - status_code: int | None = None, - tags: list[str | Enum] | None = None, - dependencies: Sequence[Depends] | None = None, - summary: str | None = None, - description: str | None = None, - response_description: str = "Successful Response", - responses: dict[int | str, dict[str, Any]] | None = None, - deprecated: bool | None = None, - methods: list[str] | None = None, - operation_id: str | None = None, - response_model_include: IncEx | None = None, - response_model_exclude: IncEx | None = None, - response_model_by_alias: bool = True, - response_model_exclude_unset: bool = False, - response_model_exclude_defaults: bool = False, - response_model_exclude_none: bool = False, - include_in_schema: bool = True, - response_class: type[Response] | DefaultPlaceholder = Default(JSONResponse), - name: str | None = None, - openapi_extra: dict[str, Any] | None = None, - generate_unique_id_function: Callable[[routing.APIRoute], str] = Default( - generate_unique_id - ), - ) -> None: - self.router.add_api_route( - path, - endpoint=endpoint, - response_model=response_model, - status_code=status_code, - tags=tags, - dependencies=dependencies, - summary=summary, - description=description, - response_description=response_description, - responses=responses, - deprecated=deprecated, - methods=methods, - operation_id=operation_id, - response_model_include=response_model_include, - response_model_exclude=response_model_exclude, - response_model_by_alias=response_model_by_alias, - response_model_exclude_unset=response_model_exclude_unset, - response_model_exclude_defaults=response_model_exclude_defaults, - response_model_exclude_none=response_model_exclude_none, - include_in_schema=include_in_schema, - response_class=response_class, - name=name, - openapi_extra=openapi_extra, - generate_unique_id_function=generate_unique_id_function, - ) - - def frontend( - self, - path: Annotated[ - str, - Doc( - """ - The URL path prefix where the frontend build should be served. - """ - ), - ], - *, - directory: Annotated[ - str | os.PathLike[str], - Doc( - """ - The directory containing the static frontend build output. - """ - ), - ], - fallback: Annotated[ - Literal["auto", "index.html", "404.html"] | None, - Doc( - """ - The fallback file behavior for missing frontend paths. - """ - ), - ] = "auto", - check_dir: Annotated[ - bool | Literal["auto"], - Doc( - """ - Check that the frontend directory exists when the app is created. When - set to `"auto"`, skip the check with a warning when `FASTAPI_ENV` is - `"development"`, and check it otherwise. The `fastapi dev` command - sets `FASTAPI_ENV` to `"development"` if it is not already set. - """ - ), - ] = "auto", - ) -> None: - """ - Serve a static frontend build as low-priority routes. - - Use this for frontend tools that build static files into a directory, - such as `dist`. **FastAPI** path operations are checked first, and - the frontend files are checked only if no normal route matched. - - A typical project could look like this: - - ```text - . - ├── pyproject.toml - ├── app - │ ├── __init__.py - │ └── main.py - └── dist - ├── index.html - └── assets - └── app.js - ``` - - Then in `app/main.py`: - - ```python - from fastapi import FastAPI - - app = FastAPI() - app.frontend("/", directory="dist") - ``` - """ - check_dir = routing._resolve_frontend_check_dir( - directory=directory, check_dir=check_dir - ) - self.router.frontend( - path, - directory=directory, - fallback=fallback, - check_dir=check_dir, - ) - - def api_route( - self, - path: str, - *, - response_model: Any = Default(None), - status_code: int | None = None, - tags: list[str | Enum] | None = None, - dependencies: Sequence[Depends] | None = None, - summary: str | None = None, - description: str | None = None, - response_description: str = "Successful Response", - responses: dict[int | str, dict[str, Any]] | None = None, - deprecated: bool | None = None, - methods: list[str] | None = None, - operation_id: str | None = None, - response_model_include: IncEx | None = None, - response_model_exclude: IncEx | None = None, - response_model_by_alias: bool = True, - response_model_exclude_unset: bool = False, - response_model_exclude_defaults: bool = False, - response_model_exclude_none: bool = False, - include_in_schema: bool = True, - response_class: type[Response] = Default(JSONResponse), - name: str | None = None, - openapi_extra: dict[str, Any] | None = None, - generate_unique_id_function: Callable[[routing.APIRoute], str] = Default( - generate_unique_id - ), - ) -> Callable[[DecoratedCallable], DecoratedCallable]: - def decorator(func: DecoratedCallable) -> DecoratedCallable: - self.router.add_api_route( - path, - func, - response_model=response_model, - status_code=status_code, - tags=tags, - dependencies=dependencies, - summary=summary, - description=description, - response_description=response_description, - responses=responses, - deprecated=deprecated, - methods=methods, - operation_id=operation_id, - response_model_include=response_model_include, - response_model_exclude=response_model_exclude, - response_model_by_alias=response_model_by_alias, - response_model_exclude_unset=response_model_exclude_unset, - response_model_exclude_defaults=response_model_exclude_defaults, - response_model_exclude_none=response_model_exclude_none, - include_in_schema=include_in_schema, - response_class=response_class, - name=name, - openapi_extra=openapi_extra, - generate_unique_id_function=generate_unique_id_function, - ) - return func - - return decorator - - def add_api_websocket_route( - self, - path: str, - endpoint: Callable[..., Any], - name: str | None = None, - *, - dependencies: Sequence[Depends] | None = None, - ) -> None: - self.router.add_api_websocket_route( - path, - endpoint, - name=name, - dependencies=dependencies, - ) - - def websocket( - self, - path: Annotated[ - str, - Doc( - """ - WebSocket path. - """ - ), - ], - name: Annotated[ - str | None, - Doc( - """ - A name for the WebSocket. Only used internally. - """ - ), - ] = None, - *, - dependencies: Annotated[ - Sequence[Depends] | None, - Doc( - """ - A list of dependencies (using `Depends()`) to be used for this - WebSocket. - - Read more about it in the - [FastAPI docs for WebSockets](https://fastapi.tiangolo.com/advanced/websockets/). - """ - ), - ] = None, - ) -> Callable[[DecoratedCallable], DecoratedCallable]: - """ - Decorate a WebSocket function. - - Read more about it in the - [FastAPI docs for WebSockets](https://fastapi.tiangolo.com/advanced/websockets/). - - **Example** - - ```python - from fastapi import FastAPI, WebSocket - - app = FastAPI() - - @app.websocket("/ws") - async def websocket_endpoint(websocket: WebSocket): - await websocket.accept() - while True: - data = await websocket.receive_text() - await websocket.send_text(f"Message text was: {data}") - ``` - """ - - def decorator(func: DecoratedCallable) -> DecoratedCallable: - self.add_api_websocket_route( - path, - func, - name=name, - dependencies=dependencies, - ) - return func - - return decorator - - def include_router( - self, - router: Annotated[routing.APIRouter, Doc("The `APIRouter` to include.")], - *, - prefix: Annotated[str, Doc("An optional path prefix for the router.")] = "", - tags: Annotated[ - list[str | Enum] | None, - Doc( - """ - A list of tags to be applied to all the *path operations* in this - router. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). - """ - ), - ] = None, - dependencies: Annotated[ - Sequence[Depends] | None, - Doc( - """ - A list of dependencies (using `Depends()`) to be applied to all the - *path operations* in this router. - - Read more about it in the - [FastAPI docs for Bigger Applications - Multiple Files](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies). - - **Example** - - ```python - from fastapi import Depends, FastAPI - - from .dependencies import get_token_header - from .internal import admin - - app = FastAPI() - - app.include_router( - admin.router, - dependencies=[Depends(get_token_header)], - ) - ``` - """ - ), - ] = None, - responses: Annotated[ - dict[int | str, dict[str, Any]] | None, - Doc( - """ - Additional responses to be shown in OpenAPI. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for Additional Responses in OpenAPI](https://fastapi.tiangolo.com/advanced/additional-responses/). - - And in the - [FastAPI docs for Bigger Applications](https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-with-a-custom-prefix-tags-responses-and-dependencies). - """ - ), - ] = None, - deprecated: Annotated[ - bool | None, - Doc( - """ - Mark all the *path operations* in this router as deprecated. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - **Example** - - ```python - from fastapi import FastAPI - - from .internal import old_api - - app = FastAPI() - - app.include_router( - old_api.router, - deprecated=True, - ) - ``` - """ - ), - ] = None, - include_in_schema: Annotated[ - bool, - Doc( - """ - Include (or not) all the *path operations* in this router in the - generated OpenAPI schema. - - This affects the generated OpenAPI (e.g. visible at `/docs`). - - **Example** - - ```python - from fastapi import FastAPI - - from .internal import old_api - - app = FastAPI() - - app.include_router( - old_api.router, - include_in_schema=False, - ) - ``` - """ - ), - ] = True, - default_response_class: Annotated[ - type[Response], - Doc( - """ - Default response class to be used for the *path operations* in this - router. - - Read more in the - [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#default-response-class). - - **Example** - - ```python - from fastapi import FastAPI - from fastapi.responses import ORJSONResponse - - from .internal import old_api - - app = FastAPI() - - app.include_router( - old_api.router, - default_response_class=ORJSONResponse, - ) - ``` - """ - ), - ] = Default(JSONResponse), - callbacks: Annotated[ - list[BaseRoute] | None, - Doc( - """ - List of *path operations* that will be used as OpenAPI callbacks. - - This is only for OpenAPI documentation, the callbacks won't be used - directly. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/). - """ - ), - ] = None, - generate_unique_id_function: Annotated[ - Callable[[routing.APIRoute], str], - Doc( - """ - Customize the function used to generate unique IDs for the *path - operations* shown in the generated OpenAPI. - - This is particularly useful when automatically generating clients or - SDKs for your API. - - Read more about it in the - [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). - """ - ), - ] = Default(generate_unique_id), - ) -> None: - """ - Include an `APIRouter` in the same app. - - Read more about it in the - [FastAPI docs for Bigger Applications](https://fastapi.tiangolo.com/tutorial/bigger-applications/). - - ## Example - - ```python - from fastapi import FastAPI - - from .users import users_router - - app = FastAPI() - - app.include_router(users_router) - ``` - """ - self.router.include_router( - router, - prefix=prefix, - tags=tags, - dependencies=dependencies, - responses=responses, - deprecated=deprecated, - include_in_schema=include_in_schema, - default_response_class=default_response_class, - callbacks=callbacks, - generate_unique_id_function=generate_unique_id_function, - ) - - def get( - self, - path: Annotated[ - str, - Doc( - """ - The URL path to be used for this *path operation*. - - For example, in `http://example.com/items`, the path is `/items`. - """ - ), - ], - *, - response_model: Annotated[ - Any, - Doc( - """ - The type to use for the response. - - It could be any valid Pydantic *field* type. So, it doesn't have to - be a Pydantic model, it could be other things, like a `list`, `dict`, - etc. - - It will be used for: - - * Documentation: the generated OpenAPI (and the UI at `/docs`) will - show it as the response (JSON Schema). - * Serialization: you could return an arbitrary object and the - `response_model` would be used to serialize that object into the - corresponding JSON. - * Filtering: the JSON sent to the client will only contain the data - (fields) defined in the `response_model`. If you returned an object - that contains an attribute `password` but the `response_model` does - not include that field, the JSON sent to the client would not have - that `password`. - * Validation: whatever you return will be serialized with the - `response_model`, converting any data as necessary to generate the - corresponding JSON. But if the data in the object returned is not - valid, that would mean a violation of the contract with the client, - so it's an error from the API developer. So, FastAPI will raise an - error and return a 500 error code (Internal Server Error). - - Read more about it in the - [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/). - """ - ), - ] = Default(None), - status_code: Annotated[ - int | None, - Doc( - """ - The default status code to be used for the response. - - You could override the status code by returning a response directly. - - Read more about it in the - [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/). - """ - ), - ] = None, - tags: Annotated[ - list[str | Enum] | None, - Doc( - """ - A list of tags to be applied to the *path operation*. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags). - """ - ), - ] = None, - dependencies: Annotated[ - Sequence[Depends] | None, - Doc( - """ - A list of dependencies (using `Depends()`) to be applied to the - *path operation*. - - Read more about it in the - [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/). - """ - ), - ] = None, - summary: Annotated[ - str | None, - Doc( - """ - A summary for the *path operation*. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). - """ - ), - ] = None, - description: Annotated[ - str | None, - Doc( - """ - A description for the *path operation*. - - If not provided, it will be extracted automatically from the docstring - of the *path operation function*. - - It can contain Markdown. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). - """ - ), - ] = None, - response_description: Annotated[ - str, - Doc( - """ - The description for the default response. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - """ - ), - ] = "Successful Response", - responses: Annotated[ - dict[int | str, dict[str, Any]] | None, - Doc( - """ - Additional responses that could be returned by this *path operation*. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - """ - ), - ] = None, - deprecated: Annotated[ - bool | None, - Doc( - """ - Mark this *path operation* as deprecated. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - """ - ), - ] = None, - operation_id: Annotated[ - str | None, - Doc( - """ - Custom operation ID to be used by this *path operation*. - - By default, it is generated automatically. - - If you provide a custom operation ID, you need to make sure it is - unique for the whole API. - - You can customize the - operation ID generation with the parameter - `generate_unique_id_function` in the `FastAPI` class. - - Read more about it in the - [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). - """ - ), - ] = None, - response_model_include: Annotated[ - IncEx | None, - Doc( - """ - Configuration passed to Pydantic to include only certain fields in the - response data. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ - ), - ] = None, - response_model_exclude: Annotated[ - IncEx | None, - Doc( - """ - Configuration passed to Pydantic to exclude certain fields in the - response data. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ - ), - ] = None, - response_model_by_alias: Annotated[ - bool, - Doc( - """ - Configuration passed to Pydantic to define if the response model - should be serialized by alias when an alias is used. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ - ), - ] = True, - response_model_exclude_unset: Annotated[ - bool, - Doc( - """ - Configuration passed to Pydantic to define if the response data - should have all the fields, including the ones that were not set and - have their default values. This is different from - `response_model_exclude_defaults` in that if the fields are set, - they will be included in the response, even if the value is the same - as the default. - - When `True`, default values are omitted from the response. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). - """ - ), - ] = False, - response_model_exclude_defaults: Annotated[ - bool, - Doc( - """ - Configuration passed to Pydantic to define if the response data - should have all the fields, including the ones that have the same value - as the default. This is different from `response_model_exclude_unset` - in that if the fields are set but contain the same default values, - they will be excluded from the response. - - When `True`, default values are omitted from the response. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). - """ - ), - ] = False, - response_model_exclude_none: Annotated[ - bool, - Doc( - """ - Configuration passed to Pydantic to define if the response data should - exclude fields set to `None`. - - This is much simpler (less smart) than `response_model_exclude_unset` - and `response_model_exclude_defaults`. You probably want to use one of - those two instead of this one, as those allow returning `None` values - when it makes sense. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none). - """ - ), - ] = False, - include_in_schema: Annotated[ - bool, - Doc( - """ - Include this *path operation* in the generated OpenAPI schema. - - This affects the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-parameters-from-openapi). - """ - ), - ] = True, - response_class: Annotated[ - type[Response], - Doc( - """ - Response class to be used for this *path operation*. - - This will not be used if you return a response directly. - - Read more about it in the - [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse). - """ - ), - ] = Default(JSONResponse), - name: Annotated[ - str | None, - Doc( - """ - Name for this *path operation*. Only used internally. - """ - ), - ] = None, - callbacks: Annotated[ - list[BaseRoute] | None, - Doc( - """ - List of *path operations* that will be used as OpenAPI callbacks. - - This is only for OpenAPI documentation, the callbacks won't be used - directly. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/). - """ - ), - ] = None, - openapi_extra: Annotated[ - dict[str, Any] | None, - Doc( - """ - Extra metadata to be included in the OpenAPI schema for this *path - operation*. - - Read more about it in the - [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema). - """ - ), - ] = None, - generate_unique_id_function: Annotated[ - Callable[[routing.APIRoute], str], - Doc( - """ - Customize the function used to generate unique IDs for the *path - operations* shown in the generated OpenAPI. - - This is particularly useful when automatically generating clients or - SDKs for your API. - - Read more about it in the - [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). - """ - ), - ] = Default(generate_unique_id), - ) -> Callable[[DecoratedCallable], DecoratedCallable]: - """ - Add a *path operation* using an HTTP GET operation. - - ## Example - - ```python - from fastapi import FastAPI - - app = FastAPI() - - @app.get("/items/") - def read_items(): - return [{"name": "Empanada"}, {"name": "Arepa"}] - ``` - """ - return self.router.get( - path, - response_model=response_model, - status_code=status_code, - tags=tags, - dependencies=dependencies, - summary=summary, - description=description, - response_description=response_description, - responses=responses, - deprecated=deprecated, - operation_id=operation_id, - response_model_include=response_model_include, - response_model_exclude=response_model_exclude, - response_model_by_alias=response_model_by_alias, - response_model_exclude_unset=response_model_exclude_unset, - response_model_exclude_defaults=response_model_exclude_defaults, - response_model_exclude_none=response_model_exclude_none, - include_in_schema=include_in_schema, - response_class=response_class, - name=name, - callbacks=callbacks, - openapi_extra=openapi_extra, - generate_unique_id_function=generate_unique_id_function, - ) - - def put( - self, - path: Annotated[ - str, - Doc( - """ - The URL path to be used for this *path operation*. - - For example, in `http://example.com/items`, the path is `/items`. - """ - ), - ], - *, - response_model: Annotated[ - Any, - Doc( - """ - The type to use for the response. - - It could be any valid Pydantic *field* type. So, it doesn't have to - be a Pydantic model, it could be other things, like a `list`, `dict`, - etc. - - It will be used for: - - * Documentation: the generated OpenAPI (and the UI at `/docs`) will - show it as the response (JSON Schema). - * Serialization: you could return an arbitrary object and the - `response_model` would be used to serialize that object into the - corresponding JSON. - * Filtering: the JSON sent to the client will only contain the data - (fields) defined in the `response_model`. If you returned an object - that contains an attribute `password` but the `response_model` does - not include that field, the JSON sent to the client would not have - that `password`. - * Validation: whatever you return will be serialized with the - `response_model`, converting any data as necessary to generate the - corresponding JSON. But if the data in the object returned is not - valid, that would mean a violation of the contract with the client, - so it's an error from the API developer. So, FastAPI will raise an - error and return a 500 error code (Internal Server Error). - - Read more about it in the - [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/). - """ - ), - ] = Default(None), - status_code: Annotated[ - int | None, - Doc( - """ - The default status code to be used for the response. - - You could override the status code by returning a response directly. - - Read more about it in the - [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/). - """ - ), - ] = None, - tags: Annotated[ - list[str | Enum] | None, - Doc( - """ - A list of tags to be applied to the *path operation*. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags). - """ - ), - ] = None, - dependencies: Annotated[ - Sequence[Depends] | None, - Doc( - """ - A list of dependencies (using `Depends()`) to be applied to the - *path operation*. - - Read more about it in the - [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/). - """ - ), - ] = None, - summary: Annotated[ - str | None, - Doc( - """ - A summary for the *path operation*. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). - """ - ), - ] = None, - description: Annotated[ - str | None, - Doc( - """ - A description for the *path operation*. - - If not provided, it will be extracted automatically from the docstring - of the *path operation function*. - - It can contain Markdown. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). - """ - ), - ] = None, - response_description: Annotated[ - str, - Doc( - """ - The description for the default response. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - """ - ), - ] = "Successful Response", - responses: Annotated[ - dict[int | str, dict[str, Any]] | None, - Doc( - """ - Additional responses that could be returned by this *path operation*. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - """ - ), - ] = None, - deprecated: Annotated[ - bool | None, - Doc( - """ - Mark this *path operation* as deprecated. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - """ - ), - ] = None, - operation_id: Annotated[ - str | None, - Doc( - """ - Custom operation ID to be used by this *path operation*. - - By default, it is generated automatically. - - If you provide a custom operation ID, you need to make sure it is - unique for the whole API. - - You can customize the - operation ID generation with the parameter - `generate_unique_id_function` in the `FastAPI` class. - - Read more about it in the - [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). - """ - ), - ] = None, - response_model_include: Annotated[ - IncEx | None, - Doc( - """ - Configuration passed to Pydantic to include only certain fields in the - response data. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ - ), - ] = None, - response_model_exclude: Annotated[ - IncEx | None, - Doc( - """ - Configuration passed to Pydantic to exclude certain fields in the - response data. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ - ), - ] = None, - response_model_by_alias: Annotated[ - bool, - Doc( - """ - Configuration passed to Pydantic to define if the response model - should be serialized by alias when an alias is used. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ - ), - ] = True, - response_model_exclude_unset: Annotated[ - bool, - Doc( - """ - Configuration passed to Pydantic to define if the response data - should have all the fields, including the ones that were not set and - have their default values. This is different from - `response_model_exclude_defaults` in that if the fields are set, - they will be included in the response, even if the value is the same - as the default. - - When `True`, default values are omitted from the response. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). - """ - ), - ] = False, - response_model_exclude_defaults: Annotated[ - bool, - Doc( - """ - Configuration passed to Pydantic to define if the response data - should have all the fields, including the ones that have the same value - as the default. This is different from `response_model_exclude_unset` - in that if the fields are set but contain the same default values, - they will be excluded from the response. - - When `True`, default values are omitted from the response. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). - """ - ), - ] = False, - response_model_exclude_none: Annotated[ - bool, - Doc( - """ - Configuration passed to Pydantic to define if the response data should - exclude fields set to `None`. - - This is much simpler (less smart) than `response_model_exclude_unset` - and `response_model_exclude_defaults`. You probably want to use one of - those two instead of this one, as those allow returning `None` values - when it makes sense. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none). - """ - ), - ] = False, - include_in_schema: Annotated[ - bool, - Doc( - """ - Include this *path operation* in the generated OpenAPI schema. - - This affects the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-parameters-from-openapi). - """ - ), - ] = True, - response_class: Annotated[ - type[Response], - Doc( - """ - Response class to be used for this *path operation*. - - This will not be used if you return a response directly. - - Read more about it in the - [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse). - """ - ), - ] = Default(JSONResponse), - name: Annotated[ - str | None, - Doc( - """ - Name for this *path operation*. Only used internally. - """ - ), - ] = None, - callbacks: Annotated[ - list[BaseRoute] | None, - Doc( - """ - List of *path operations* that will be used as OpenAPI callbacks. - - This is only for OpenAPI documentation, the callbacks won't be used - directly. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/). - """ - ), - ] = None, - openapi_extra: Annotated[ - dict[str, Any] | None, - Doc( - """ - Extra metadata to be included in the OpenAPI schema for this *path - operation*. - - Read more about it in the - [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema). - """ - ), - ] = None, - generate_unique_id_function: Annotated[ - Callable[[routing.APIRoute], str], - Doc( - """ - Customize the function used to generate unique IDs for the *path - operations* shown in the generated OpenAPI. - - This is particularly useful when automatically generating clients or - SDKs for your API. - - Read more about it in the - [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). - """ - ), - ] = Default(generate_unique_id), - ) -> Callable[[DecoratedCallable], DecoratedCallable]: - """ - Add a *path operation* using an HTTP PUT operation. - - ## Example - - ```python - from fastapi import FastAPI - from pydantic import BaseModel - - class Item(BaseModel): - name: str - description: str | None = None - - app = FastAPI() - - @app.put("/items/{item_id}") - def replace_item(item_id: str, item: Item): - return {"message": "Item replaced", "id": item_id} - ``` - """ - return self.router.put( - path, - response_model=response_model, - status_code=status_code, - tags=tags, - dependencies=dependencies, - summary=summary, - description=description, - response_description=response_description, - responses=responses, - deprecated=deprecated, - operation_id=operation_id, - response_model_include=response_model_include, - response_model_exclude=response_model_exclude, - response_model_by_alias=response_model_by_alias, - response_model_exclude_unset=response_model_exclude_unset, - response_model_exclude_defaults=response_model_exclude_defaults, - response_model_exclude_none=response_model_exclude_none, - include_in_schema=include_in_schema, - response_class=response_class, - name=name, - callbacks=callbacks, - openapi_extra=openapi_extra, - generate_unique_id_function=generate_unique_id_function, - ) - - def post( - self, - path: Annotated[ - str, - Doc( - """ - The URL path to be used for this *path operation*. - - For example, in `http://example.com/items`, the path is `/items`. - """ - ), - ], - *, - response_model: Annotated[ - Any, - Doc( - """ - The type to use for the response. - - It could be any valid Pydantic *field* type. So, it doesn't have to - be a Pydantic model, it could be other things, like a `list`, `dict`, - etc. - - It will be used for: - - * Documentation: the generated OpenAPI (and the UI at `/docs`) will - show it as the response (JSON Schema). - * Serialization: you could return an arbitrary object and the - `response_model` would be used to serialize that object into the - corresponding JSON. - * Filtering: the JSON sent to the client will only contain the data - (fields) defined in the `response_model`. If you returned an object - that contains an attribute `password` but the `response_model` does - not include that field, the JSON sent to the client would not have - that `password`. - * Validation: whatever you return will be serialized with the - `response_model`, converting any data as necessary to generate the - corresponding JSON. But if the data in the object returned is not - valid, that would mean a violation of the contract with the client, - so it's an error from the API developer. So, FastAPI will raise an - error and return a 500 error code (Internal Server Error). - - Read more about it in the - [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/). - """ - ), - ] = Default(None), - status_code: Annotated[ - int | None, - Doc( - """ - The default status code to be used for the response. - - You could override the status code by returning a response directly. - - Read more about it in the - [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/). - """ - ), - ] = None, - tags: Annotated[ - list[str | Enum] | None, - Doc( - """ - A list of tags to be applied to the *path operation*. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags). - """ - ), - ] = None, - dependencies: Annotated[ - Sequence[Depends] | None, - Doc( - """ - A list of dependencies (using `Depends()`) to be applied to the - *path operation*. - - Read more about it in the - [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/). - """ - ), - ] = None, - summary: Annotated[ - str | None, - Doc( - """ - A summary for the *path operation*. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). - """ - ), - ] = None, - description: Annotated[ - str | None, - Doc( - """ - A description for the *path operation*. - - If not provided, it will be extracted automatically from the docstring - of the *path operation function*. - - It can contain Markdown. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). - """ - ), - ] = None, - response_description: Annotated[ - str, - Doc( - """ - The description for the default response. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - """ - ), - ] = "Successful Response", - responses: Annotated[ - dict[int | str, dict[str, Any]] | None, - Doc( - """ - Additional responses that could be returned by this *path operation*. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - """ - ), - ] = None, - deprecated: Annotated[ - bool | None, - Doc( - """ - Mark this *path operation* as deprecated. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - """ - ), - ] = None, - operation_id: Annotated[ - str | None, - Doc( - """ - Custom operation ID to be used by this *path operation*. - - By default, it is generated automatically. - - If you provide a custom operation ID, you need to make sure it is - unique for the whole API. - - You can customize the - operation ID generation with the parameter - `generate_unique_id_function` in the `FastAPI` class. - - Read more about it in the - [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). - """ - ), - ] = None, - response_model_include: Annotated[ - IncEx | None, - Doc( - """ - Configuration passed to Pydantic to include only certain fields in the - response data. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ - ), - ] = None, - response_model_exclude: Annotated[ - IncEx | None, - Doc( - """ - Configuration passed to Pydantic to exclude certain fields in the - response data. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ - ), - ] = None, - response_model_by_alias: Annotated[ - bool, - Doc( - """ - Configuration passed to Pydantic to define if the response model - should be serialized by alias when an alias is used. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ - ), - ] = True, - response_model_exclude_unset: Annotated[ - bool, - Doc( - """ - Configuration passed to Pydantic to define if the response data - should have all the fields, including the ones that were not set and - have their default values. This is different from - `response_model_exclude_defaults` in that if the fields are set, - they will be included in the response, even if the value is the same - as the default. - - When `True`, default values are omitted from the response. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). - """ - ), - ] = False, - response_model_exclude_defaults: Annotated[ - bool, - Doc( - """ - Configuration passed to Pydantic to define if the response data - should have all the fields, including the ones that have the same value - as the default. This is different from `response_model_exclude_unset` - in that if the fields are set but contain the same default values, - they will be excluded from the response. - - When `True`, default values are omitted from the response. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). - """ - ), - ] = False, - response_model_exclude_none: Annotated[ - bool, - Doc( - """ - Configuration passed to Pydantic to define if the response data should - exclude fields set to `None`. - - This is much simpler (less smart) than `response_model_exclude_unset` - and `response_model_exclude_defaults`. You probably want to use one of - those two instead of this one, as those allow returning `None` values - when it makes sense. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none). - """ - ), - ] = False, - include_in_schema: Annotated[ - bool, - Doc( - """ - Include this *path operation* in the generated OpenAPI schema. - - This affects the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-parameters-from-openapi). - """ - ), - ] = True, - response_class: Annotated[ - type[Response], - Doc( - """ - Response class to be used for this *path operation*. - - This will not be used if you return a response directly. - - Read more about it in the - [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse). - """ - ), - ] = Default(JSONResponse), - name: Annotated[ - str | None, - Doc( - """ - Name for this *path operation*. Only used internally. - """ - ), - ] = None, - callbacks: Annotated[ - list[BaseRoute] | None, - Doc( - """ - List of *path operations* that will be used as OpenAPI callbacks. - - This is only for OpenAPI documentation, the callbacks won't be used - directly. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/). - """ - ), - ] = None, - openapi_extra: Annotated[ - dict[str, Any] | None, - Doc( - """ - Extra metadata to be included in the OpenAPI schema for this *path - operation*. - - Read more about it in the - [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema). - """ - ), - ] = None, - generate_unique_id_function: Annotated[ - Callable[[routing.APIRoute], str], - Doc( - """ - Customize the function used to generate unique IDs for the *path - operations* shown in the generated OpenAPI. - - This is particularly useful when automatically generating clients or - SDKs for your API. - - Read more about it in the - [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). - """ - ), - ] = Default(generate_unique_id), - ) -> Callable[[DecoratedCallable], DecoratedCallable]: - """ - Add a *path operation* using an HTTP POST operation. - - ## Example - - ```python - from fastapi import FastAPI - from pydantic import BaseModel - - class Item(BaseModel): - name: str - description: str | None = None - - app = FastAPI() - - @app.post("/items/") - def create_item(item: Item): - return {"message": "Item created"} - ``` - """ - return self.router.post( - path, - response_model=response_model, - status_code=status_code, - tags=tags, - dependencies=dependencies, - summary=summary, - description=description, - response_description=response_description, - responses=responses, - deprecated=deprecated, - operation_id=operation_id, - response_model_include=response_model_include, - response_model_exclude=response_model_exclude, - response_model_by_alias=response_model_by_alias, - response_model_exclude_unset=response_model_exclude_unset, - response_model_exclude_defaults=response_model_exclude_defaults, - response_model_exclude_none=response_model_exclude_none, - include_in_schema=include_in_schema, - response_class=response_class, - name=name, - callbacks=callbacks, - openapi_extra=openapi_extra, - generate_unique_id_function=generate_unique_id_function, - ) - - def delete( - self, - path: Annotated[ - str, - Doc( - """ - The URL path to be used for this *path operation*. - - For example, in `http://example.com/items`, the path is `/items`. - """ - ), - ], - *, - response_model: Annotated[ - Any, - Doc( - """ - The type to use for the response. - - It could be any valid Pydantic *field* type. So, it doesn't have to - be a Pydantic model, it could be other things, like a `list`, `dict`, - etc. - - It will be used for: - - * Documentation: the generated OpenAPI (and the UI at `/docs`) will - show it as the response (JSON Schema). - * Serialization: you could return an arbitrary object and the - `response_model` would be used to serialize that object into the - corresponding JSON. - * Filtering: the JSON sent to the client will only contain the data - (fields) defined in the `response_model`. If you returned an object - that contains an attribute `password` but the `response_model` does - not include that field, the JSON sent to the client would not have - that `password`. - * Validation: whatever you return will be serialized with the - `response_model`, converting any data as necessary to generate the - corresponding JSON. But if the data in the object returned is not - valid, that would mean a violation of the contract with the client, - so it's an error from the API developer. So, FastAPI will raise an - error and return a 500 error code (Internal Server Error). - - Read more about it in the - [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/). - """ - ), - ] = Default(None), - status_code: Annotated[ - int | None, - Doc( - """ - The default status code to be used for the response. - - You could override the status code by returning a response directly. - - Read more about it in the - [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/). - """ - ), - ] = None, - tags: Annotated[ - list[str | Enum] | None, - Doc( - """ - A list of tags to be applied to the *path operation*. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags). - """ - ), - ] = None, - dependencies: Annotated[ - Sequence[Depends] | None, - Doc( - """ - A list of dependencies (using `Depends()`) to be applied to the - *path operation*. - - Read more about it in the - [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/). - """ - ), - ] = None, - summary: Annotated[ - str | None, - Doc( - """ - A summary for the *path operation*. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). - """ - ), - ] = None, - description: Annotated[ - str | None, - Doc( - """ - A description for the *path operation*. - - If not provided, it will be extracted automatically from the docstring - of the *path operation function*. - - It can contain Markdown. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). - """ - ), - ] = None, - response_description: Annotated[ - str, - Doc( - """ - The description for the default response. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - """ - ), - ] = "Successful Response", - responses: Annotated[ - dict[int | str, dict[str, Any]] | None, - Doc( - """ - Additional responses that could be returned by this *path operation*. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - """ - ), - ] = None, - deprecated: Annotated[ - bool | None, - Doc( - """ - Mark this *path operation* as deprecated. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - """ - ), - ] = None, - operation_id: Annotated[ - str | None, - Doc( - """ - Custom operation ID to be used by this *path operation*. - - By default, it is generated automatically. - - If you provide a custom operation ID, you need to make sure it is - unique for the whole API. - - You can customize the - operation ID generation with the parameter - `generate_unique_id_function` in the `FastAPI` class. - - Read more about it in the - [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). - """ - ), - ] = None, - response_model_include: Annotated[ - IncEx | None, - Doc( - """ - Configuration passed to Pydantic to include only certain fields in the - response data. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ - ), - ] = None, - response_model_exclude: Annotated[ - IncEx | None, - Doc( - """ - Configuration passed to Pydantic to exclude certain fields in the - response data. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ - ), - ] = None, - response_model_by_alias: Annotated[ - bool, - Doc( - """ - Configuration passed to Pydantic to define if the response model - should be serialized by alias when an alias is used. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ - ), - ] = True, - response_model_exclude_unset: Annotated[ - bool, - Doc( - """ - Configuration passed to Pydantic to define if the response data - should have all the fields, including the ones that were not set and - have their default values. This is different from - `response_model_exclude_defaults` in that if the fields are set, - they will be included in the response, even if the value is the same - as the default. - - When `True`, default values are omitted from the response. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). - """ - ), - ] = False, - response_model_exclude_defaults: Annotated[ - bool, - Doc( - """ - Configuration passed to Pydantic to define if the response data - should have all the fields, including the ones that have the same value - as the default. This is different from `response_model_exclude_unset` - in that if the fields are set but contain the same default values, - they will be excluded from the response. - - When `True`, default values are omitted from the response. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). - """ - ), - ] = False, - response_model_exclude_none: Annotated[ - bool, - Doc( - """ - Configuration passed to Pydantic to define if the response data should - exclude fields set to `None`. - - This is much simpler (less smart) than `response_model_exclude_unset` - and `response_model_exclude_defaults`. You probably want to use one of - those two instead of this one, as those allow returning `None` values - when it makes sense. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none). - """ - ), - ] = False, - include_in_schema: Annotated[ - bool, - Doc( - """ - Include this *path operation* in the generated OpenAPI schema. - - This affects the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-parameters-from-openapi). - """ - ), - ] = True, - response_class: Annotated[ - type[Response], - Doc( - """ - Response class to be used for this *path operation*. - - This will not be used if you return a response directly. - - Read more about it in the - [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse). - """ - ), - ] = Default(JSONResponse), - name: Annotated[ - str | None, - Doc( - """ - Name for this *path operation*. Only used internally. - """ - ), - ] = None, - callbacks: Annotated[ - list[BaseRoute] | None, - Doc( - """ - List of *path operations* that will be used as OpenAPI callbacks. - - This is only for OpenAPI documentation, the callbacks won't be used - directly. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/). - """ - ), - ] = None, - openapi_extra: Annotated[ - dict[str, Any] | None, - Doc( - """ - Extra metadata to be included in the OpenAPI schema for this *path - operation*. - - Read more about it in the - [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema). - """ - ), - ] = None, - generate_unique_id_function: Annotated[ - Callable[[routing.APIRoute], str], - Doc( - """ - Customize the function used to generate unique IDs for the *path - operations* shown in the generated OpenAPI. - - This is particularly useful when automatically generating clients or - SDKs for your API. - - Read more about it in the - [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). - """ - ), - ] = Default(generate_unique_id), - ) -> Callable[[DecoratedCallable], DecoratedCallable]: - """ - Add a *path operation* using an HTTP DELETE operation. - - ## Example - - ```python - from fastapi import FastAPI - - app = FastAPI() - - @app.delete("/items/{item_id}") - def delete_item(item_id: str): - return {"message": "Item deleted"} - ``` - """ - return self.router.delete( - path, - response_model=response_model, - status_code=status_code, - tags=tags, - dependencies=dependencies, - summary=summary, - description=description, - response_description=response_description, - responses=responses, - deprecated=deprecated, - operation_id=operation_id, - response_model_include=response_model_include, - response_model_exclude=response_model_exclude, - response_model_by_alias=response_model_by_alias, - response_model_exclude_unset=response_model_exclude_unset, - response_model_exclude_defaults=response_model_exclude_defaults, - response_model_exclude_none=response_model_exclude_none, - include_in_schema=include_in_schema, - response_class=response_class, - name=name, - callbacks=callbacks, - openapi_extra=openapi_extra, - generate_unique_id_function=generate_unique_id_function, - ) - - def options( - self, - path: Annotated[ - str, - Doc( - """ - The URL path to be used for this *path operation*. - - For example, in `http://example.com/items`, the path is `/items`. - """ - ), - ], - *, - response_model: Annotated[ - Any, - Doc( - """ - The type to use for the response. - - It could be any valid Pydantic *field* type. So, it doesn't have to - be a Pydantic model, it could be other things, like a `list`, `dict`, - etc. - - It will be used for: - - * Documentation: the generated OpenAPI (and the UI at `/docs`) will - show it as the response (JSON Schema). - * Serialization: you could return an arbitrary object and the - `response_model` would be used to serialize that object into the - corresponding JSON. - * Filtering: the JSON sent to the client will only contain the data - (fields) defined in the `response_model`. If you returned an object - that contains an attribute `password` but the `response_model` does - not include that field, the JSON sent to the client would not have - that `password`. - * Validation: whatever you return will be serialized with the - `response_model`, converting any data as necessary to generate the - corresponding JSON. But if the data in the object returned is not - valid, that would mean a violation of the contract with the client, - so it's an error from the API developer. So, FastAPI will raise an - error and return a 500 error code (Internal Server Error). - - Read more about it in the - [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/). - """ - ), - ] = Default(None), - status_code: Annotated[ - int | None, - Doc( - """ - The default status code to be used for the response. - - You could override the status code by returning a response directly. - - Read more about it in the - [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/). - """ - ), - ] = None, - tags: Annotated[ - list[str | Enum] | None, - Doc( - """ - A list of tags to be applied to the *path operation*. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags). - """ - ), - ] = None, - dependencies: Annotated[ - Sequence[Depends] | None, - Doc( - """ - A list of dependencies (using `Depends()`) to be applied to the - *path operation*. - - Read more about it in the - [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/). - """ - ), - ] = None, - summary: Annotated[ - str | None, - Doc( - """ - A summary for the *path operation*. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). - """ - ), - ] = None, - description: Annotated[ - str | None, - Doc( - """ - A description for the *path operation*. - - If not provided, it will be extracted automatically from the docstring - of the *path operation function*. - - It can contain Markdown. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). - """ - ), - ] = None, - response_description: Annotated[ - str, - Doc( - """ - The description for the default response. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - """ - ), - ] = "Successful Response", - responses: Annotated[ - dict[int | str, dict[str, Any]] | None, - Doc( - """ - Additional responses that could be returned by this *path operation*. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - """ - ), - ] = None, - deprecated: Annotated[ - bool | None, - Doc( - """ - Mark this *path operation* as deprecated. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - """ - ), - ] = None, - operation_id: Annotated[ - str | None, - Doc( - """ - Custom operation ID to be used by this *path operation*. - - By default, it is generated automatically. - - If you provide a custom operation ID, you need to make sure it is - unique for the whole API. - - You can customize the - operation ID generation with the parameter - `generate_unique_id_function` in the `FastAPI` class. - - Read more about it in the - [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). - """ - ), - ] = None, - response_model_include: Annotated[ - IncEx | None, - Doc( - """ - Configuration passed to Pydantic to include only certain fields in the - response data. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ - ), - ] = None, - response_model_exclude: Annotated[ - IncEx | None, - Doc( - """ - Configuration passed to Pydantic to exclude certain fields in the - response data. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ - ), - ] = None, - response_model_by_alias: Annotated[ - bool, - Doc( - """ - Configuration passed to Pydantic to define if the response model - should be serialized by alias when an alias is used. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ - ), - ] = True, - response_model_exclude_unset: Annotated[ - bool, - Doc( - """ - Configuration passed to Pydantic to define if the response data - should have all the fields, including the ones that were not set and - have their default values. This is different from - `response_model_exclude_defaults` in that if the fields are set, - they will be included in the response, even if the value is the same - as the default. - - When `True`, default values are omitted from the response. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). - """ - ), - ] = False, - response_model_exclude_defaults: Annotated[ - bool, - Doc( - """ - Configuration passed to Pydantic to define if the response data - should have all the fields, including the ones that have the same value - as the default. This is different from `response_model_exclude_unset` - in that if the fields are set but contain the same default values, - they will be excluded from the response. - - When `True`, default values are omitted from the response. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). - """ - ), - ] = False, - response_model_exclude_none: Annotated[ - bool, - Doc( - """ - Configuration passed to Pydantic to define if the response data should - exclude fields set to `None`. - - This is much simpler (less smart) than `response_model_exclude_unset` - and `response_model_exclude_defaults`. You probably want to use one of - those two instead of this one, as those allow returning `None` values - when it makes sense. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none). - """ - ), - ] = False, - include_in_schema: Annotated[ - bool, - Doc( - """ - Include this *path operation* in the generated OpenAPI schema. - - This affects the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-parameters-from-openapi). - """ - ), - ] = True, - response_class: Annotated[ - type[Response], - Doc( - """ - Response class to be used for this *path operation*. - - This will not be used if you return a response directly. - - Read more about it in the - [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse). - """ - ), - ] = Default(JSONResponse), - name: Annotated[ - str | None, - Doc( - """ - Name for this *path operation*. Only used internally. - """ - ), - ] = None, - callbacks: Annotated[ - list[BaseRoute] | None, - Doc( - """ - List of *path operations* that will be used as OpenAPI callbacks. - - This is only for OpenAPI documentation, the callbacks won't be used - directly. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/). - """ - ), - ] = None, - openapi_extra: Annotated[ - dict[str, Any] | None, - Doc( - """ - Extra metadata to be included in the OpenAPI schema for this *path - operation*. - - Read more about it in the - [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema). - """ - ), - ] = None, - generate_unique_id_function: Annotated[ - Callable[[routing.APIRoute], str], - Doc( - """ - Customize the function used to generate unique IDs for the *path - operations* shown in the generated OpenAPI. - - This is particularly useful when automatically generating clients or - SDKs for your API. - - Read more about it in the - [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). - """ - ), - ] = Default(generate_unique_id), - ) -> Callable[[DecoratedCallable], DecoratedCallable]: - """ - Add a *path operation* using an HTTP OPTIONS operation. - - ## Example - - ```python - from fastapi import FastAPI - - app = FastAPI() - - @app.options("/items/") - def get_item_options(): - return {"additions": ["Aji", "Guacamole"]} - ``` - """ - return self.router.options( - path, - response_model=response_model, - status_code=status_code, - tags=tags, - dependencies=dependencies, - summary=summary, - description=description, - response_description=response_description, - responses=responses, - deprecated=deprecated, - operation_id=operation_id, - response_model_include=response_model_include, - response_model_exclude=response_model_exclude, - response_model_by_alias=response_model_by_alias, - response_model_exclude_unset=response_model_exclude_unset, - response_model_exclude_defaults=response_model_exclude_defaults, - response_model_exclude_none=response_model_exclude_none, - include_in_schema=include_in_schema, - response_class=response_class, - name=name, - callbacks=callbacks, - openapi_extra=openapi_extra, - generate_unique_id_function=generate_unique_id_function, - ) - - def head( - self, - path: Annotated[ - str, - Doc( - """ - The URL path to be used for this *path operation*. - - For example, in `http://example.com/items`, the path is `/items`. - """ - ), - ], - *, - response_model: Annotated[ - Any, - Doc( - """ - The type to use for the response. - - It could be any valid Pydantic *field* type. So, it doesn't have to - be a Pydantic model, it could be other things, like a `list`, `dict`, - etc. - - It will be used for: - - * Documentation: the generated OpenAPI (and the UI at `/docs`) will - show it as the response (JSON Schema). - * Serialization: you could return an arbitrary object and the - `response_model` would be used to serialize that object into the - corresponding JSON. - * Filtering: the JSON sent to the client will only contain the data - (fields) defined in the `response_model`. If you returned an object - that contains an attribute `password` but the `response_model` does - not include that field, the JSON sent to the client would not have - that `password`. - * Validation: whatever you return will be serialized with the - `response_model`, converting any data as necessary to generate the - corresponding JSON. But if the data in the object returned is not - valid, that would mean a violation of the contract with the client, - so it's an error from the API developer. So, FastAPI will raise an - error and return a 500 error code (Internal Server Error). - - Read more about it in the - [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/). - """ - ), - ] = Default(None), - status_code: Annotated[ - int | None, - Doc( - """ - The default status code to be used for the response. - - You could override the status code by returning a response directly. - - Read more about it in the - [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/). - """ - ), - ] = None, - tags: Annotated[ - list[str | Enum] | None, - Doc( - """ - A list of tags to be applied to the *path operation*. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags). - """ - ), - ] = None, - dependencies: Annotated[ - Sequence[Depends] | None, - Doc( - """ - A list of dependencies (using `Depends()`) to be applied to the - *path operation*. - - Read more about it in the - [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/). - """ - ), - ] = None, - summary: Annotated[ - str | None, - Doc( - """ - A summary for the *path operation*. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). - """ - ), - ] = None, - description: Annotated[ - str | None, - Doc( - """ - A description for the *path operation*. - - If not provided, it will be extracted automatically from the docstring - of the *path operation function*. - - It can contain Markdown. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). - """ - ), - ] = None, - response_description: Annotated[ - str, - Doc( - """ - The description for the default response. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - """ - ), - ] = "Successful Response", - responses: Annotated[ - dict[int | str, dict[str, Any]] | None, - Doc( - """ - Additional responses that could be returned by this *path operation*. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - """ - ), - ] = None, - deprecated: Annotated[ - bool | None, - Doc( - """ - Mark this *path operation* as deprecated. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - """ - ), - ] = None, - operation_id: Annotated[ - str | None, - Doc( - """ - Custom operation ID to be used by this *path operation*. - - By default, it is generated automatically. - - If you provide a custom operation ID, you need to make sure it is - unique for the whole API. - - You can customize the - operation ID generation with the parameter - `generate_unique_id_function` in the `FastAPI` class. - - Read more about it in the - [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). - """ - ), - ] = None, - response_model_include: Annotated[ - IncEx | None, - Doc( - """ - Configuration passed to Pydantic to include only certain fields in the - response data. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ - ), - ] = None, - response_model_exclude: Annotated[ - IncEx | None, - Doc( - """ - Configuration passed to Pydantic to exclude certain fields in the - response data. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ - ), - ] = None, - response_model_by_alias: Annotated[ - bool, - Doc( - """ - Configuration passed to Pydantic to define if the response model - should be serialized by alias when an alias is used. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ - ), - ] = True, - response_model_exclude_unset: Annotated[ - bool, - Doc( - """ - Configuration passed to Pydantic to define if the response data - should have all the fields, including the ones that were not set and - have their default values. This is different from - `response_model_exclude_defaults` in that if the fields are set, - they will be included in the response, even if the value is the same - as the default. - - When `True`, default values are omitted from the response. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). - """ - ), - ] = False, - response_model_exclude_defaults: Annotated[ - bool, - Doc( - """ - Configuration passed to Pydantic to define if the response data - should have all the fields, including the ones that have the same value - as the default. This is different from `response_model_exclude_unset` - in that if the fields are set but contain the same default values, - they will be excluded from the response. - - When `True`, default values are omitted from the response. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). - """ - ), - ] = False, - response_model_exclude_none: Annotated[ - bool, - Doc( - """ - Configuration passed to Pydantic to define if the response data should - exclude fields set to `None`. - - This is much simpler (less smart) than `response_model_exclude_unset` - and `response_model_exclude_defaults`. You probably want to use one of - those two instead of this one, as those allow returning `None` values - when it makes sense. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none). - """ - ), - ] = False, - include_in_schema: Annotated[ - bool, - Doc( - """ - Include this *path operation* in the generated OpenAPI schema. - - This affects the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-parameters-from-openapi). - """ - ), - ] = True, - response_class: Annotated[ - type[Response], - Doc( - """ - Response class to be used for this *path operation*. - - This will not be used if you return a response directly. - - Read more about it in the - [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse). - """ - ), - ] = Default(JSONResponse), - name: Annotated[ - str | None, - Doc( - """ - Name for this *path operation*. Only used internally. - """ - ), - ] = None, - callbacks: Annotated[ - list[BaseRoute] | None, - Doc( - """ - List of *path operations* that will be used as OpenAPI callbacks. - - This is only for OpenAPI documentation, the callbacks won't be used - directly. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/). - """ - ), - ] = None, - openapi_extra: Annotated[ - dict[str, Any] | None, - Doc( - """ - Extra metadata to be included in the OpenAPI schema for this *path - operation*. - - Read more about it in the - [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema). - """ - ), - ] = None, - generate_unique_id_function: Annotated[ - Callable[[routing.APIRoute], str], - Doc( - """ - Customize the function used to generate unique IDs for the *path - operations* shown in the generated OpenAPI. - - This is particularly useful when automatically generating clients or - SDKs for your API. - - Read more about it in the - [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). - """ - ), - ] = Default(generate_unique_id), - ) -> Callable[[DecoratedCallable], DecoratedCallable]: - """ - Add a *path operation* using an HTTP HEAD operation. - - ## Example - - ```python - from fastapi import FastAPI, Response - - app = FastAPI() - - @app.head("/items/", status_code=204) - def get_items_headers(response: Response): - response.headers["X-Cat-Dog"] = "Alone in the world" - ``` - """ - return self.router.head( - path, - response_model=response_model, - status_code=status_code, - tags=tags, - dependencies=dependencies, - summary=summary, - description=description, - response_description=response_description, - responses=responses, - deprecated=deprecated, - operation_id=operation_id, - response_model_include=response_model_include, - response_model_exclude=response_model_exclude, - response_model_by_alias=response_model_by_alias, - response_model_exclude_unset=response_model_exclude_unset, - response_model_exclude_defaults=response_model_exclude_defaults, - response_model_exclude_none=response_model_exclude_none, - include_in_schema=include_in_schema, - response_class=response_class, - name=name, - callbacks=callbacks, - openapi_extra=openapi_extra, - generate_unique_id_function=generate_unique_id_function, - ) - - def patch( - self, - path: Annotated[ - str, - Doc( - """ - The URL path to be used for this *path operation*. - - For example, in `http://example.com/items`, the path is `/items`. - """ - ), - ], - *, - response_model: Annotated[ - Any, - Doc( - """ - The type to use for the response. - - It could be any valid Pydantic *field* type. So, it doesn't have to - be a Pydantic model, it could be other things, like a `list`, `dict`, - etc. - - It will be used for: - - * Documentation: the generated OpenAPI (and the UI at `/docs`) will - show it as the response (JSON Schema). - * Serialization: you could return an arbitrary object and the - `response_model` would be used to serialize that object into the - corresponding JSON. - * Filtering: the JSON sent to the client will only contain the data - (fields) defined in the `response_model`. If you returned an object - that contains an attribute `password` but the `response_model` does - not include that field, the JSON sent to the client would not have - that `password`. - * Validation: whatever you return will be serialized with the - `response_model`, converting any data as necessary to generate the - corresponding JSON. But if the data in the object returned is not - valid, that would mean a violation of the contract with the client, - so it's an error from the API developer. So, FastAPI will raise an - error and return a 500 error code (Internal Server Error). - - Read more about it in the - [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/). - """ - ), - ] = Default(None), - status_code: Annotated[ - int | None, - Doc( - """ - The default status code to be used for the response. - - You could override the status code by returning a response directly. - - Read more about it in the - [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/). - """ - ), - ] = None, - tags: Annotated[ - list[str | Enum] | None, - Doc( - """ - A list of tags to be applied to the *path operation*. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags). - """ - ), - ] = None, - dependencies: Annotated[ - Sequence[Depends] | None, - Doc( - """ - A list of dependencies (using `Depends()`) to be applied to the - *path operation*. - - Read more about it in the - [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/). - """ - ), - ] = None, - summary: Annotated[ - str | None, - Doc( - """ - A summary for the *path operation*. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). - """ - ), - ] = None, - description: Annotated[ - str | None, - Doc( - """ - A description for the *path operation*. - - If not provided, it will be extracted automatically from the docstring - of the *path operation function*. - - It can contain Markdown. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). - """ - ), - ] = None, - response_description: Annotated[ - str, - Doc( - """ - The description for the default response. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - """ - ), - ] = "Successful Response", - responses: Annotated[ - dict[int | str, dict[str, Any]] | None, - Doc( - """ - Additional responses that could be returned by this *path operation*. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - """ - ), - ] = None, - deprecated: Annotated[ - bool | None, - Doc( - """ - Mark this *path operation* as deprecated. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - """ - ), - ] = None, - operation_id: Annotated[ - str | None, - Doc( - """ - Custom operation ID to be used by this *path operation*. - - By default, it is generated automatically. - - If you provide a custom operation ID, you need to make sure it is - unique for the whole API. - - You can customize the - operation ID generation with the parameter - `generate_unique_id_function` in the `FastAPI` class. - - Read more about it in the - [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). - """ - ), - ] = None, - response_model_include: Annotated[ - IncEx | None, - Doc( - """ - Configuration passed to Pydantic to include only certain fields in the - response data. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ - ), - ] = None, - response_model_exclude: Annotated[ - IncEx | None, - Doc( - """ - Configuration passed to Pydantic to exclude certain fields in the - response data. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ - ), - ] = None, - response_model_by_alias: Annotated[ - bool, - Doc( - """ - Configuration passed to Pydantic to define if the response model - should be serialized by alias when an alias is used. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ - ), - ] = True, - response_model_exclude_unset: Annotated[ - bool, - Doc( - """ - Configuration passed to Pydantic to define if the response data - should have all the fields, including the ones that were not set and - have their default values. This is different from - `response_model_exclude_defaults` in that if the fields are set, - they will be included in the response, even if the value is the same - as the default. - - When `True`, default values are omitted from the response. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). - """ - ), - ] = False, - response_model_exclude_defaults: Annotated[ - bool, - Doc( - """ - Configuration passed to Pydantic to define if the response data - should have all the fields, including the ones that have the same value - as the default. This is different from `response_model_exclude_unset` - in that if the fields are set but contain the same default values, - they will be excluded from the response. - - When `True`, default values are omitted from the response. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). - """ - ), - ] = False, - response_model_exclude_none: Annotated[ - bool, - Doc( - """ - Configuration passed to Pydantic to define if the response data should - exclude fields set to `None`. - - This is much simpler (less smart) than `response_model_exclude_unset` - and `response_model_exclude_defaults`. You probably want to use one of - those two instead of this one, as those allow returning `None` values - when it makes sense. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none). - """ - ), - ] = False, - include_in_schema: Annotated[ - bool, - Doc( - """ - Include this *path operation* in the generated OpenAPI schema. - - This affects the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-parameters-from-openapi). - """ - ), - ] = True, - response_class: Annotated[ - type[Response], - Doc( - """ - Response class to be used for this *path operation*. - - This will not be used if you return a response directly. - - Read more about it in the - [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse). - """ - ), - ] = Default(JSONResponse), - name: Annotated[ - str | None, - Doc( - """ - Name for this *path operation*. Only used internally. - """ - ), - ] = None, - callbacks: Annotated[ - list[BaseRoute] | None, - Doc( - """ - List of *path operations* that will be used as OpenAPI callbacks. - - This is only for OpenAPI documentation, the callbacks won't be used - directly. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/). - """ - ), - ] = None, - openapi_extra: Annotated[ - dict[str, Any] | None, - Doc( - """ - Extra metadata to be included in the OpenAPI schema for this *path - operation*. - - Read more about it in the - [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema). - """ - ), - ] = None, - generate_unique_id_function: Annotated[ - Callable[[routing.APIRoute], str], - Doc( - """ - Customize the function used to generate unique IDs for the *path - operations* shown in the generated OpenAPI. - - This is particularly useful when automatically generating clients or - SDKs for your API. - - Read more about it in the - [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). - """ - ), - ] = Default(generate_unique_id), - ) -> Callable[[DecoratedCallable], DecoratedCallable]: - """ - Add a *path operation* using an HTTP PATCH operation. - - ## Example - - ```python - from fastapi import FastAPI - from pydantic import BaseModel - - class Item(BaseModel): - name: str - description: str | None = None - - app = FastAPI() - - @app.patch("/items/") - def update_item(item: Item): - return {"message": "Item updated in place"} - ``` - """ - return self.router.patch( - path, - response_model=response_model, - status_code=status_code, - tags=tags, - dependencies=dependencies, - summary=summary, - description=description, - response_description=response_description, - responses=responses, - deprecated=deprecated, - operation_id=operation_id, - response_model_include=response_model_include, - response_model_exclude=response_model_exclude, - response_model_by_alias=response_model_by_alias, - response_model_exclude_unset=response_model_exclude_unset, - response_model_exclude_defaults=response_model_exclude_defaults, - response_model_exclude_none=response_model_exclude_none, - include_in_schema=include_in_schema, - response_class=response_class, - name=name, - callbacks=callbacks, - openapi_extra=openapi_extra, - generate_unique_id_function=generate_unique_id_function, - ) - - def trace( - self, - path: Annotated[ - str, - Doc( - """ - The URL path to be used for this *path operation*. - - For example, in `http://example.com/items`, the path is `/items`. - """ - ), - ], - *, - response_model: Annotated[ - Any, - Doc( - """ - The type to use for the response. - - It could be any valid Pydantic *field* type. So, it doesn't have to - be a Pydantic model, it could be other things, like a `list`, `dict`, - etc. - - It will be used for: - - * Documentation: the generated OpenAPI (and the UI at `/docs`) will - show it as the response (JSON Schema). - * Serialization: you could return an arbitrary object and the - `response_model` would be used to serialize that object into the - corresponding JSON. - * Filtering: the JSON sent to the client will only contain the data - (fields) defined in the `response_model`. If you returned an object - that contains an attribute `password` but the `response_model` does - not include that field, the JSON sent to the client would not have - that `password`. - * Validation: whatever you return will be serialized with the - `response_model`, converting any data as necessary to generate the - corresponding JSON. But if the data in the object returned is not - valid, that would mean a violation of the contract with the client, - so it's an error from the API developer. So, FastAPI will raise an - error and return a 500 error code (Internal Server Error). - - Read more about it in the - [FastAPI docs for Response Model](https://fastapi.tiangolo.com/tutorial/response-model/). - """ - ), - ] = Default(None), - status_code: Annotated[ - int | None, - Doc( - """ - The default status code to be used for the response. - - You could override the status code by returning a response directly. - - Read more about it in the - [FastAPI docs for Response Status Code](https://fastapi.tiangolo.com/tutorial/response-status-code/). - """ - ), - ] = None, - tags: Annotated[ - list[str | Enum] | None, - Doc( - """ - A list of tags to be applied to the *path operation*. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/#tags). - """ - ), - ] = None, - dependencies: Annotated[ - Sequence[Depends] | None, - Doc( - """ - A list of dependencies (using `Depends()`) to be applied to the - *path operation*. - - Read more about it in the - [FastAPI docs for Dependencies in path operation decorators](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/). - """ - ), - ] = None, - summary: Annotated[ - str | None, - Doc( - """ - A summary for the *path operation*. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). - """ - ), - ] = None, - description: Annotated[ - str | None, - Doc( - """ - A description for the *path operation*. - - If not provided, it will be extracted automatically from the docstring - of the *path operation function*. - - It can contain Markdown. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for Path Operation Configuration](https://fastapi.tiangolo.com/tutorial/path-operation-configuration/). - """ - ), - ] = None, - response_description: Annotated[ - str, - Doc( - """ - The description for the default response. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - """ - ), - ] = "Successful Response", - responses: Annotated[ - dict[int | str, dict[str, Any]] | None, - Doc( - """ - Additional responses that could be returned by this *path operation*. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - """ - ), - ] = None, - deprecated: Annotated[ - bool | None, - Doc( - """ - Mark this *path operation* as deprecated. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - """ - ), - ] = None, - operation_id: Annotated[ - str | None, - Doc( - """ - Custom operation ID to be used by this *path operation*. - - By default, it is generated automatically. - - If you provide a custom operation ID, you need to make sure it is - unique for the whole API. - - You can customize the - operation ID generation with the parameter - `generate_unique_id_function` in the `FastAPI` class. - - Read more about it in the - [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). - """ - ), - ] = None, - response_model_include: Annotated[ - IncEx | None, - Doc( - """ - Configuration passed to Pydantic to include only certain fields in the - response data. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ - ), - ] = None, - response_model_exclude: Annotated[ - IncEx | None, - Doc( - """ - Configuration passed to Pydantic to exclude certain fields in the - response data. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ - ), - ] = None, - response_model_by_alias: Annotated[ - bool, - Doc( - """ - Configuration passed to Pydantic to define if the response model - should be serialized by alias when an alias is used. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_include-and-response_model_exclude). - """ - ), - ] = True, - response_model_exclude_unset: Annotated[ - bool, - Doc( - """ - Configuration passed to Pydantic to define if the response data - should have all the fields, including the ones that were not set and - have their default values. This is different from - `response_model_exclude_defaults` in that if the fields are set, - they will be included in the response, even if the value is the same - as the default. - - When `True`, default values are omitted from the response. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). - """ - ), - ] = False, - response_model_exclude_defaults: Annotated[ - bool, - Doc( - """ - Configuration passed to Pydantic to define if the response data - should have all the fields, including the ones that have the same value - as the default. This is different from `response_model_exclude_unset` - in that if the fields are set but contain the same default values, - they will be excluded from the response. - - When `True`, default values are omitted from the response. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#use-the-response_model_exclude_unset-parameter). - """ - ), - ] = False, - response_model_exclude_none: Annotated[ - bool, - Doc( - """ - Configuration passed to Pydantic to define if the response data should - exclude fields set to `None`. - - This is much simpler (less smart) than `response_model_exclude_unset` - and `response_model_exclude_defaults`. You probably want to use one of - those two instead of this one, as those allow returning `None` values - when it makes sense. - - Read more about it in the - [FastAPI docs for Response Model - Return Type](https://fastapi.tiangolo.com/tutorial/response-model/#response_model_exclude_none). - """ - ), - ] = False, - include_in_schema: Annotated[ - bool, - Doc( - """ - Include this *path operation* in the generated OpenAPI schema. - - This affects the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#exclude-parameters-from-openapi). - """ - ), - ] = True, - response_class: Annotated[ - type[Response], - Doc( - """ - Response class to be used for this *path operation*. - - This will not be used if you return a response directly. - - Read more about it in the - [FastAPI docs for Custom Response - HTML, Stream, File, others](https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse). - """ - ), - ] = Default(JSONResponse), - name: Annotated[ - str | None, - Doc( - """ - Name for this *path operation*. Only used internally. - """ - ), - ] = None, - callbacks: Annotated[ - list[BaseRoute] | None, - Doc( - """ - List of *path operations* that will be used as OpenAPI callbacks. - - This is only for OpenAPI documentation, the callbacks won't be used - directly. - - It will be added to the generated OpenAPI (e.g. visible at `/docs`). - - Read more about it in the - [FastAPI docs for OpenAPI Callbacks](https://fastapi.tiangolo.com/advanced/openapi-callbacks/). - """ - ), - ] = None, - openapi_extra: Annotated[ - dict[str, Any] | None, - Doc( - """ - Extra metadata to be included in the OpenAPI schema for this *path - operation*. - - Read more about it in the - [FastAPI docs for Path Operation Advanced Configuration](https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#custom-openapi-path-operation-schema). - """ - ), - ] = None, - generate_unique_id_function: Annotated[ - Callable[[routing.APIRoute], str], - Doc( - """ - Customize the function used to generate unique IDs for the *path - operations* shown in the generated OpenAPI. - - This is particularly useful when automatically generating clients or - SDKs for your API. - - Read more about it in the - [FastAPI docs about how to Generate Clients](https://fastapi.tiangolo.com/advanced/generate-clients/#custom-generate-unique-id-function). - """ - ), - ] = Default(generate_unique_id), - ) -> Callable[[DecoratedCallable], DecoratedCallable]: - """ - Add a *path operation* using an HTTP TRACE operation. - - ## Example - - ```python - from fastapi import FastAPI - - app = FastAPI() - - @app.trace("/items/{item_id}") - def trace_item(item_id: str): - return None - ``` - """ - return self.router.trace( - path, - response_model=response_model, - status_code=status_code, - tags=tags, - dependencies=dependencies, - summary=summary, - description=description, - response_description=response_description, - responses=responses, - deprecated=deprecated, - operation_id=operation_id, - response_model_include=response_model_include, - response_model_exclude=response_model_exclude, - response_model_by_alias=response_model_by_alias, - response_model_exclude_unset=response_model_exclude_unset, - response_model_exclude_defaults=response_model_exclude_defaults, - response_model_exclude_none=response_model_exclude_none, - include_in_schema=include_in_schema, - response_class=response_class, - name=name, - callbacks=callbacks, - openapi_extra=openapi_extra, - generate_unique_id_function=generate_unique_id_function, - ) - - def websocket_route( - self, path: str, name: str | None = None - ) -> Callable[[DecoratedCallable], DecoratedCallable]: - def decorator(func: DecoratedCallable) -> DecoratedCallable: - self.router.add_websocket_route(path, func, name=name) - return func - - return decorator - - @deprecated( - """ - on_event is deprecated, use lifespan event handlers instead. - - Read more about it in the - [FastAPI docs for Lifespan Events](https://fastapi.tiangolo.com/advanced/events/). - """ - ) - def on_event( - self, - event_type: Annotated[ - str, - Doc( - """ - The type of event. `startup` or `shutdown`. - """ - ), - ], - ) -> Callable[[DecoratedCallable], DecoratedCallable]: - """ - Add an event handler for the application. - - `on_event` is deprecated, use `lifespan` event handlers instead. - - Read more about it in the - [FastAPI docs for Lifespan Events](https://fastapi.tiangolo.com/advanced/events/#alternative-events-deprecated). - """ - return self.router.on_event(event_type) # ty: ignore[deprecated] - - def middleware( - self, - middleware_type: Annotated[ - str, - Doc( - """ - The type of middleware. Currently only supports `http`. - """ - ), - ], - ) -> Callable[[DecoratedCallable], DecoratedCallable]: - """ - Add a middleware to the application. - - Read more about it in the - [FastAPI docs for Middleware](https://fastapi.tiangolo.com/tutorial/middleware/). - - ## Example - - ```python - import time - from typing import Awaitable, Callable - - from fastapi import FastAPI, Request, Response - - app = FastAPI() - - - @app.middleware("http") - async def add_process_time_header( - request: Request, call_next: Callable[[Request], Awaitable[Response]] - ) -> Response: - start_time = time.time() - response = await call_next(request) - process_time = time.time() - start_time - response.headers["X-Process-Time"] = str(process_time) - return response - ``` - """ - - def decorator(func: DecoratedCallable) -> DecoratedCallable: - self.add_middleware(BaseHTTPMiddleware, dispatch=func) - return func - - return decorator - - def exception_handler( - self, - exc_class_or_status_code: Annotated[ - int | type[Exception], - Doc( - """ - The Exception class this would handle, or a status code. - """ - ), - ], - ) -> Callable[[DecoratedCallable], DecoratedCallable]: - """ - Add an exception handler to the app. - - Read more about it in the - [FastAPI docs for Handling Errors](https://fastapi.tiangolo.com/tutorial/handling-errors/). - - ## Example - - ```python - from fastapi import FastAPI, Request - from fastapi.responses import JSONResponse - - - class UnicornException(Exception): - def __init__(self, name: str): - self.name = name - - - app = FastAPI() - - - @app.exception_handler(UnicornException) - async def unicorn_exception_handler(request: Request, exc: UnicornException): - return JSONResponse( - status_code=418, - content={"message": f"Oops! {exc.name} did something. There goes a rainbow..."}, - ) - ``` - """ - - def decorator(func: DecoratedCallable) -> DecoratedCallable: - self.add_exception_handler(exc_class_or_status_code, func) - return func - - return decorator diff --git a/bundle/python-cpu/Lib/site-packages/fastapi/background.py b/bundle/python-cpu/Lib/site-packages/fastapi/background.py deleted file mode 100644 index 7677058c438105d599233d441e8e7de81225a697..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/fastapi/background.py +++ /dev/null @@ -1,61 +0,0 @@ -from collections.abc import Callable -from typing import Annotated, Any - -from annotated_doc import Doc -from starlette.background import BackgroundTasks as StarletteBackgroundTasks -from typing_extensions import ParamSpec - -P = ParamSpec("P") - - -class BackgroundTasks(StarletteBackgroundTasks): - """ - A collection of background tasks that will be called after a response has been - sent to the client. - - Read more about it in the - [FastAPI docs for Background Tasks](https://fastapi.tiangolo.com/tutorial/background-tasks/). - - ## Example - - ```python - from fastapi import BackgroundTasks, FastAPI - - app = FastAPI() - - - def write_notification(email: str, message=""): - with open("log.txt", mode="w") as email_file: - content = f"notification for {email}: {message}" - email_file.write(content) - - - @app.post("/send-notification/{email}") - async def send_notification(email: str, background_tasks: BackgroundTasks): - background_tasks.add_task(write_notification, email, message="some notification") - return {"message": "Notification sent in the background"} - ``` - """ - - def add_task( - self, - func: Annotated[ - Callable[P, Any], - Doc( - """ - The function to call after the response is sent. - - It can be a regular `def` function or an `async def` function. - """ - ), - ], - *args: P.args, - **kwargs: P.kwargs, - ) -> None: - """ - Add a function to be called in the background after the response is sent. - - Read more about it in the - [FastAPI docs for Background Tasks](https://fastapi.tiangolo.com/tutorial/background-tasks/). - """ - return super().add_task(func, *args, **kwargs) diff --git a/bundle/python-cpu/Lib/site-packages/fastapi/cli.py b/bundle/python-cpu/Lib/site-packages/fastapi/cli.py deleted file mode 100644 index 8d3301e9daf73b474162d712f4b87f54ccd97a16..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/fastapi/cli.py +++ /dev/null @@ -1,13 +0,0 @@ -try: - from fastapi_cli.cli import main as cli_main - -except ImportError: # pragma: no cover - cli_main = None # type: ignore - - -def main() -> None: - if not cli_main: # type: ignore[truthy-function] - message = 'To use the fastapi command, please install "fastapi[standard]":\n\n\tpip install "fastapi[standard]"\n' - print(message) - raise RuntimeError(message) # noqa: B904 - cli_main() diff --git a/bundle/python-cpu/Lib/site-packages/fastapi/concurrency.py b/bundle/python-cpu/Lib/site-packages/fastapi/concurrency.py deleted file mode 100644 index 76a5a2eb128bc8c22d61d986ab2cdc434178dd24..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/fastapi/concurrency.py +++ /dev/null @@ -1,41 +0,0 @@ -from collections.abc import AsyncGenerator -from contextlib import AbstractContextManager -from contextlib import asynccontextmanager as asynccontextmanager -from typing import TypeVar - -import anyio.to_thread -from anyio import CapacityLimiter -from starlette.concurrency import iterate_in_threadpool as iterate_in_threadpool # noqa -from starlette.concurrency import run_in_threadpool as run_in_threadpool # noqa -from starlette.concurrency import ( # noqa - run_until_first_complete as run_until_first_complete, -) - -_T = TypeVar("_T") - - -@asynccontextmanager -async def contextmanager_in_threadpool( - cm: AbstractContextManager[_T], -) -> AsyncGenerator[_T, None]: - # blocking __exit__ from running waiting on a free thread - # can create race conditions/deadlocks if the context manager itself - # has its own internal pool (e.g. a database connection pool) - # to avoid this we let __exit__ run without a capacity limit - # since we're creating a new limiter for each call, any non-zero limit - # works (1 is arbitrary) - exit_limiter = CapacityLimiter(1) - try: - yield await run_in_threadpool(cm.__enter__) - except Exception as e: - ok = bool( - await anyio.to_thread.run_sync( - cm.__exit__, type(e), e, e.__traceback__, limiter=exit_limiter - ) - ) - if not ok: - raise e - else: - await anyio.to_thread.run_sync( - cm.__exit__, None, None, None, limiter=exit_limiter - ) diff --git a/bundle/python-cpu/Lib/site-packages/fastapi/datastructures.py b/bundle/python-cpu/Lib/site-packages/fastapi/datastructures.py deleted file mode 100644 index 1da784cf0927ed55ec6abeb051d89a6ce1e90630..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/fastapi/datastructures.py +++ /dev/null @@ -1,186 +0,0 @@ -from collections.abc import Callable, Mapping -from typing import ( - Annotated, - Any, - BinaryIO, - TypeVar, - cast, -) - -from annotated_doc import Doc -from pydantic import GetJsonSchemaHandler -from starlette.datastructures import URL as URL # noqa: F401 -from starlette.datastructures import Address as Address # noqa: F401 -from starlette.datastructures import FormData as FormData # noqa: F401 -from starlette.datastructures import Headers as Headers # noqa: F401 -from starlette.datastructures import QueryParams as QueryParams # noqa: F401 -from starlette.datastructures import State as State # noqa: F401 -from starlette.datastructures import UploadFile as StarletteUploadFile - - -class UploadFile(StarletteUploadFile): - """ - A file uploaded in a request. - - Define it as a *path operation function* (or dependency) parameter. - - If you are using a regular `def` function, you can use the `upload_file.file` - attribute to access the raw standard Python file (blocking, not async), useful and - needed for non-async code. - - Read more about it in the - [FastAPI docs for Request Files](https://fastapi.tiangolo.com/tutorial/request-files/). - - ## Example - - ```python - from typing import Annotated - - from fastapi import FastAPI, File, UploadFile - - app = FastAPI() - - - @app.post("/files/") - async def create_file(file: Annotated[bytes, File()]): - return {"file_size": len(file)} - - - @app.post("/uploadfile/") - async def create_upload_file(file: UploadFile): - return {"filename": file.filename} - ``` - """ - - file: Annotated[ - BinaryIO, - Doc("The standard Python file object (non-async)."), - ] - filename: Annotated[str | None, Doc("The original file name.")] - size: Annotated[int | None, Doc("The size of the file in bytes.")] - headers: Annotated[Headers, Doc("The headers of the request.")] - content_type: Annotated[ - str | None, Doc("The content type of the request, from the headers.") - ] - - async def write( - self, - data: Annotated[ - bytes, - Doc( - """ - The bytes to write to the file. - """ - ), - ], - ) -> None: - """ - Write some bytes to the file. - - You normally wouldn't use this from a file you read in a request. - - To be awaitable, compatible with async, this is run in threadpool. - """ - return await super().write(data) - - async def read( - self, - size: Annotated[ - int, - Doc( - """ - The number of bytes to read from the file. - """ - ), - ] = -1, - ) -> bytes: - """ - Read some bytes from the file. - - To be awaitable, compatible with async, this is run in threadpool. - """ - return await super().read(size) - - async def seek( - self, - offset: Annotated[ - int, - Doc( - """ - The position in bytes to seek to in the file. - """ - ), - ], - ) -> None: - """ - Move to a position in the file. - - Any next read or write will be done from that position. - - To be awaitable, compatible with async, this is run in threadpool. - """ - return await super().seek(offset) - - async def close(self) -> None: - """ - Close the file. - - To be awaitable, compatible with async, this is run in threadpool. - """ - return await super().close() - - @classmethod - def _validate(cls, __input_value: Any, _: Any) -> "UploadFile": - if not isinstance(__input_value, StarletteUploadFile): - raise ValueError(f"Expected UploadFile, received: {type(__input_value)}") - return cast(UploadFile, __input_value) - - @classmethod - def __get_pydantic_json_schema__( - cls, core_schema: Mapping[str, Any], handler: GetJsonSchemaHandler - ) -> dict[str, Any]: - return {"type": "string", "contentMediaType": "application/octet-stream"} - - @classmethod - def __get_pydantic_core_schema__( - cls, source: type[Any], handler: Callable[[Any], Mapping[str, Any]] - ) -> Mapping[str, Any]: - from ._compat.v2 import with_info_plain_validator_function - - return with_info_plain_validator_function(cls._validate) - - -class DefaultPlaceholder: - """ - You shouldn't use this class directly. - - It's used internally to recognize when a default value has been overwritten, even - if the overridden default value was truthy. - """ - - def __init__(self, value: Any): - self.value = value - - def __bool__(self) -> bool: - return bool(self.value) - - def __eq__(self, o: object) -> bool: - return isinstance(o, DefaultPlaceholder) and o.value == self.value - - -DefaultType = TypeVar("DefaultType") - - -def Default(value: DefaultType) -> DefaultType: - """ - You shouldn't use this function directly. - - It's used internally to recognize when a default value has been overwritten, even - if the overridden default value was truthy. - """ - return DefaultPlaceholder(value) # type: ignore - - -# Sentinel for "parameter not provided" in Param/FieldInfo. -# Typed as None to satisfy ty -_Unset = Default(None) diff --git a/bundle/python-cpu/Lib/site-packages/fastapi/dependencies/__init__.py b/bundle/python-cpu/Lib/site-packages/fastapi/dependencies/__init__.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/bundle/python-cpu/Lib/site-packages/fastapi/dependencies/models.py b/bundle/python-cpu/Lib/site-packages/fastapi/dependencies/models.py deleted file mode 100644 index 5c7cbc82ba12e30d18887f170ca1704b59c8f915..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/fastapi/dependencies/models.py +++ /dev/null @@ -1,234 +0,0 @@ -import inspect -import sys -from collections.abc import Callable -from dataclasses import dataclass, field -from functools import lru_cache, partial -from typing import Any, Literal - -from fastapi._compat import ModelField -from fastapi.security.base import SecurityBase -from fastapi.types import DependencyCacheKey - -if sys.version_info >= (3, 13): # pragma: no cover - from inspect import iscoroutinefunction -else: # pragma: no cover - from asyncio import iscoroutinefunction - - -def _unwrapped_call(call: Callable[..., Any] | None) -> Any: - if call is None: - return call # pragma: no cover - unwrapped = inspect.unwrap(_impartial(call)) - return unwrapped - - -def _impartial(func: Callable[..., Any]) -> Callable[..., Any]: - while isinstance(func, partial): - func = func.func - return func - - -@dataclass(slots=True) -class Dependant: - path_params: list[ModelField] = field(default_factory=list) - query_params: list[ModelField] = field(default_factory=list) - header_params: list[ModelField] = field(default_factory=list) - cookie_params: list[ModelField] = field(default_factory=list) - body_params: list[ModelField] = field(default_factory=list) - dependencies: list["Dependant"] = field(default_factory=list) - name: str | None = None - call: Callable[..., Any] | None = None - request_param_name: str | None = None - websocket_param_name: str | None = None - http_connection_param_name: str | None = None - response_param_name: str | None = None - background_tasks_param_name: str | None = None - security_scopes_param_name: str | None = None - own_oauth_scopes: list[str] | None = None - parent_oauth_scopes: list[str] | None = None - use_cache: bool = True - path: str | None = None - scope: Literal["function", "request"] | None = None - - -_UsesScopesCache = dict[int, tuple[Dependant, bool]] -_CALLABLE_CLASSIFICATION_CACHE_SIZE = 4096 - - -class _CallIdentity: - __slots__ = ("call",) - - def __init__(self, call: Callable[..., Any]) -> None: - self.call = call - - def __hash__(self) -> int: - return id(self.call) - - def __eq__(self, other: object) -> bool: - return isinstance(other, _CallIdentity) and self.call is other.call - - -def _get_oauth_scopes(*, dependant: Dependant) -> list[str]: - scopes = ( - dependant.parent_oauth_scopes.copy() if dependant.parent_oauth_scopes else [] - ) - # This doesn't use a set to preserve order, just in case - for scope in dependant.own_oauth_scopes or []: - if scope not in scopes: - scopes.append(scope) - return scopes - - -def _get_cache_key( - *, - dependant: Dependant, - uses_scopes_cache: _UsesScopesCache | None = None, -) -> DependencyCacheKey: - scopes_for_cache = ( - tuple(sorted(set(_get_oauth_scopes(dependant=dependant)))) - if _uses_scopes(dependant=dependant, cache=uses_scopes_cache) - else () - ) - return ( - dependant.call, - scopes_for_cache, - _get_computed_scope(dependant=dependant) or "", - ) - - -def _uses_scopes( - *, dependant: Dependant, cache: _UsesScopesCache | None = None -) -> bool: - if cache is None: - cache = {} - cache_key = id(dependant) - cached = cache.get(cache_key) - if cached is not None and cached[0] is dependant: - return cached[1] - if dependant.own_oauth_scopes: - result = True - elif dependant.security_scopes_param_name is not None: - result = True - elif _is_security_scheme(dependant=dependant): - result = True - else: - result = any( - _uses_scopes(dependant=sub_dep, cache=cache) - for sub_dep in dependant.dependencies - ) - cache[cache_key] = (dependant, result) - return result - - -def _is_security_scheme(*, dependant: Dependant) -> bool: - if dependant.call is None: - return False # pragma: no cover - unwrapped = _unwrapped_call(dependant.call) - return isinstance(unwrapped, SecurityBase) - - -def _get_security_scheme(*, dependant: Dependant) -> SecurityBase: - # Mainly to get the type of SecurityBase, but it's the same dependant.call - unwrapped = _unwrapped_call(dependant.call) - assert isinstance(unwrapped, SecurityBase) - return unwrapped - - -@lru_cache(maxsize=_CALLABLE_CLASSIFICATION_CACHE_SIZE) -def _is_gen_callable_cached(call_identity: _CallIdentity) -> bool: - call = call_identity.call - if inspect.isgeneratorfunction(_impartial(call)) or inspect.isgeneratorfunction( - _unwrapped_call(call) - ): - return True - if inspect.isclass(_unwrapped_call(call)): - return False - dunder_call = getattr(_impartial(call), "__call__", None) # noqa: B004 - if dunder_call is None: - return False # pragma: no cover - if inspect.isgeneratorfunction( - _impartial(dunder_call) - ) or inspect.isgeneratorfunction(_unwrapped_call(dunder_call)): - return True - dunder_unwrapped_call = getattr(_unwrapped_call(call), "__call__", None) # noqa: B004 - if dunder_unwrapped_call is None: - return False # pragma: no cover - return inspect.isgeneratorfunction( - _impartial(dunder_unwrapped_call) - ) or inspect.isgeneratorfunction(_unwrapped_call(dunder_unwrapped_call)) - - -def _is_gen_callable(call: Callable[..., Any] | None) -> bool: - if call is None: - return False # pragma: no cover - return _is_gen_callable_cached(_CallIdentity(call)) - - -@lru_cache(maxsize=_CALLABLE_CLASSIFICATION_CACHE_SIZE) -def _is_async_gen_callable_cached(call_identity: _CallIdentity) -> bool: - call = call_identity.call - if inspect.isasyncgenfunction(_impartial(call)) or inspect.isasyncgenfunction( - _unwrapped_call(call) - ): - return True - if inspect.isclass(_unwrapped_call(call)): - return False - dunder_call = getattr(_impartial(call), "__call__", None) # noqa: B004 - if dunder_call is None: - return False # pragma: no cover - if inspect.isasyncgenfunction( - _impartial(dunder_call) - ) or inspect.isasyncgenfunction(_unwrapped_call(dunder_call)): - return True - dunder_unwrapped_call = getattr(_unwrapped_call(call), "__call__", None) # noqa: B004 - if dunder_unwrapped_call is None: - return False # pragma: no cover - return inspect.isasyncgenfunction( - _impartial(dunder_unwrapped_call) - ) or inspect.isasyncgenfunction(_unwrapped_call(dunder_unwrapped_call)) - - -def _is_async_gen_callable(call: Callable[..., Any] | None) -> bool: - if call is None: - return False # pragma: no cover - return _is_async_gen_callable_cached(_CallIdentity(call)) - - -@lru_cache(maxsize=_CALLABLE_CLASSIFICATION_CACHE_SIZE) -def _is_coroutine_callable_cached(call_identity: _CallIdentity) -> bool: - call = call_identity.call - if inspect.isroutine(_impartial(call)) and iscoroutinefunction(_impartial(call)): - return True - if inspect.isroutine(_unwrapped_call(call)) and iscoroutinefunction( - _unwrapped_call(call) - ): - return True - if inspect.isclass(_unwrapped_call(call)): - return False - dunder_call = getattr(_impartial(call), "__call__", None) # noqa: B004 - if dunder_call is None: - return False # pragma: no cover - if iscoroutinefunction(_impartial(dunder_call)) or iscoroutinefunction( - _unwrapped_call(dunder_call) - ): - return True - dunder_unwrapped_call = getattr(_unwrapped_call(call), "__call__", None) # noqa: B004 - if dunder_unwrapped_call is None: - return False # pragma: no cover - return iscoroutinefunction( - _impartial(dunder_unwrapped_call) - ) or iscoroutinefunction(_unwrapped_call(dunder_unwrapped_call)) - - -def _is_coroutine_callable(call: Callable[..., Any] | None) -> bool: - if call is None: - return False # pragma: no cover - return _is_coroutine_callable_cached(_CallIdentity(call)) - - -def _get_computed_scope(*, dependant: Dependant) -> str | None: - if dependant.scope: - return dependant.scope - if _is_gen_callable(dependant.call) or _is_async_gen_callable(dependant.call): - return "request" - return None diff --git a/bundle/python-cpu/Lib/site-packages/fastapi/dependencies/utils.py b/bundle/python-cpu/Lib/site-packages/fastapi/dependencies/utils.py deleted file mode 100644 index 01820e6a4cf477a22fffeaad1b308489d6a4a0a8..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/fastapi/dependencies/utils.py +++ /dev/null @@ -1,1053 +0,0 @@ -import dataclasses -import inspect -import sys -from collections.abc import ( - AsyncGenerator, - AsyncIterable, - AsyncIterator, - Callable, - Generator, - Iterable, - Iterator, - Mapping, - Sequence, -) -from contextlib import AsyncExitStack, contextmanager -from copy import copy, deepcopy -from dataclasses import dataclass -from typing import ( - Annotated, - Any, - ForwardRef, - Literal, - Union, - cast, - get_args, - get_origin, -) - -from fastapi import params -from fastapi._compat import ( - ModelField, - RequiredParam, - Undefined, - copy_field_info, - create_body_model, - evaluate_forwardref, - field_annotation_is_scalar, - field_annotation_is_scalar_sequence, - field_annotation_is_sequence, - get_cached_model_fields, - get_missing_field_error, - is_bytes_or_nonable_bytes_annotation, - is_bytes_sequence_annotation, - is_scalar_field, - is_uploadfile_or_nonable_uploadfile_annotation, - is_uploadfile_sequence_annotation, - lenient_issubclass, - sequence_types, - serialize_sequence_value, - value_is_sequence, -) -from fastapi.background import BackgroundTasks -from fastapi.concurrency import ( - asynccontextmanager, - contextmanager_in_threadpool, -) -from fastapi.dependencies.models import ( - Dependant, - _get_cache_key, - _get_computed_scope, - _get_oauth_scopes, - _is_async_gen_callable, - _is_coroutine_callable, - _is_gen_callable, - _UsesScopesCache, -) -from fastapi.exceptions import DependencyScopeError -from fastapi.logger import logger -from fastapi.security.oauth2 import SecurityScopes -from fastapi.types import DependencyCacheKey -from fastapi.utils import create_model_field, get_path_param_names -from pydantic import BaseModel, Json -from pydantic.fields import FieldInfo -from starlette.background import BackgroundTasks as StarletteBackgroundTasks -from starlette.concurrency import run_in_threadpool -from starlette.datastructures import ( - FormData, - Headers, - ImmutableMultiDict, - QueryParams, - UploadFile, -) -from starlette.requests import HTTPConnection, Request -from starlette.responses import Response -from starlette.websockets import WebSocket -from typing_inspection.typing_objects import is_typealiastype - -multipart_not_installed_error = ( - 'Form data requires "python-multipart" to be installed. \n' - 'You can install "python-multipart" with: \n\n' - "pip install python-multipart\n" -) -multipart_incorrect_install_error = ( - 'Form data requires "python-multipart" to be installed. ' - 'It seems you installed "multipart" instead. \n' - 'You can remove "multipart" with: \n\n' - "pip uninstall multipart\n\n" - 'And then install "python-multipart" with: \n\n' - "pip install python-multipart\n" -) - - -def ensure_multipart_is_installed() -> None: - try: - from python_multipart import __version__ - - # Import an attribute that can be mocked/deleted in testing - assert __version__ > "0.0.12" - except (ImportError, AssertionError): - try: - # __version__ is available in both multiparts, and can be mocked - from multipart import ( # type: ignore[no-redef,import-untyped] - __version__, - ) - - assert __version__ - try: - # parse_options_header is only available in the right multipart - from multipart.multipart import ( # type: ignore[import-untyped] - parse_options_header, - ) - - assert parse_options_header - except ImportError: - logger.error(multipart_incorrect_install_error) - raise RuntimeError(multipart_incorrect_install_error) from None - except ImportError: - logger.error(multipart_not_installed_error) - raise RuntimeError(multipart_not_installed_error) from None - - -def get_parameterless_sub_dependant(*, depends: params.Depends, path: str) -> Dependant: - assert callable(depends.dependency), ( - "A parameter-less dependency must have a callable dependency" - ) - own_oauth_scopes: list[str] = [] - if isinstance(depends, params.Security) and depends.scopes: - own_oauth_scopes.extend(depends.scopes) - return get_dependant( - path=path, - call=depends.dependency, - scope=depends.scope, - own_oauth_scopes=own_oauth_scopes, - ) - - -def _get_flat_body_params(dependant: Dependant) -> list[ModelField]: - body_params: list[ModelField] = [] - dependants = [dependant] - while dependants: - current_dependant = dependants.pop() - body_params.extend(current_dependant.body_params) - dependants.extend(reversed(current_dependant.dependencies)) - return body_params - - -def _get_flat_fields_from_params(fields: list[ModelField]) -> list[ModelField]: - if not fields: - return fields - first_field = fields[0] - if len(fields) == 1 and lenient_issubclass( - first_field.field_info.annotation, BaseModel - ): - fields_to_extract = get_cached_model_fields(first_field.field_info.annotation) - return fields_to_extract - return fields - - -def get_flat_params(dependant: Dependant) -> list[ModelField]: - path_params: list[ModelField] = [] - query_params: list[ModelField] = [] - header_params: list[ModelField] = [] - cookie_params: list[ModelField] = [] - visited: list[DependencyCacheKey] = [] - uses_scopes_cache: _UsesScopesCache = {} - dependants = [dependant] - while dependants: - current_dependant = dependants.pop() - cache_key = _get_cache_key( - dependant=current_dependant, - uses_scopes_cache=uses_scopes_cache, - ) - if cache_key in visited: - continue - visited.append(cache_key) - path_params.extend(current_dependant.path_params) - query_params.extend(current_dependant.query_params) - header_params.extend(current_dependant.header_params) - cookie_params.extend(current_dependant.cookie_params) - dependants.extend(reversed(current_dependant.dependencies)) - path_params = _get_flat_fields_from_params(path_params) - query_params = _get_flat_fields_from_params(query_params) - header_params = _get_flat_fields_from_params(header_params) - cookie_params = _get_flat_fields_from_params(cookie_params) - return path_params + query_params + header_params + cookie_params - - -def _get_signature(call: Callable[..., Any]) -> inspect.Signature: - try: - signature = inspect.signature(call, eval_str=True) - except NameError: - # Handle type annotations with if TYPE_CHECKING, not used by FastAPI - # e.g. dependency return types - if sys.version_info >= (3, 14): - from annotationlib import Format - - signature = inspect.signature(call, annotation_format=Format.FORWARDREF) - else: - signature = inspect.signature(call) - return signature - - -def get_typed_signature(call: Callable[..., Any]) -> inspect.Signature: - signature = _get_signature(call) - unwrapped = inspect.unwrap(call) - globalns = getattr(unwrapped, "__globals__", {}) - typed_params = [ - inspect.Parameter( - name=param.name, - kind=param.kind, - default=param.default, - annotation=get_typed_annotation(param.annotation, globalns), - ) - for param in signature.parameters.values() - ] - typed_signature = inspect.Signature(typed_params) - return typed_signature - - -def get_typed_annotation(annotation: Any, globalns: dict[str, Any]) -> Any: - if isinstance(annotation, str): - annotation = ForwardRef(annotation) - annotation = evaluate_forwardref(annotation, globalns, globalns) - if annotation is type(None): - return None - return annotation - - -def get_typed_return_annotation(call: Callable[..., Any]) -> Any: - signature = _get_signature(call) - unwrapped = inspect.unwrap(call) - annotation = signature.return_annotation - - if annotation is inspect.Signature.empty: - return None - - globalns = getattr(unwrapped, "__globals__", {}) - return get_typed_annotation(annotation, globalns) - - -_STREAM_ORIGINS = { - AsyncIterable, - AsyncIterator, - AsyncGenerator, - Iterable, - Iterator, - Generator, -} - - -def get_stream_item_type(annotation: Any) -> Any | None: - origin = get_origin(annotation) - if origin is not None and origin in _STREAM_ORIGINS: - type_args = get_args(annotation) - if type_args: - return type_args[0] - return Any - return None - - -def get_dependant( - *, - path: str, - call: Callable[..., Any], - name: str | None = None, - own_oauth_scopes: list[str] | None = None, - parent_oauth_scopes: list[str] | None = None, - use_cache: bool = True, - scope: Literal["function", "request"] | None = None, -) -> Dependant: - dependant = Dependant( - call=call, - name=name, - path=path, - use_cache=use_cache, - scope=scope, - own_oauth_scopes=own_oauth_scopes, - parent_oauth_scopes=parent_oauth_scopes, - ) - current_scopes = (parent_oauth_scopes or []) + (own_oauth_scopes or []) - path_param_names = get_path_param_names(path) - endpoint_signature = get_typed_signature(call) - signature_params = endpoint_signature.parameters - for param_name, param in signature_params.items(): - is_path_param = param_name in path_param_names - param_details = analyze_param( - param_name=param_name, - annotation=param.annotation, - value=param.default, - is_path_param=is_path_param, - ) - if param_details.depends is not None: - assert param_details.depends.dependency - if ( - ( - _is_gen_callable(dependant.call) - or _is_async_gen_callable(dependant.call) - ) - and _get_computed_scope(dependant=dependant) == "request" - and param_details.depends.scope == "function" - ): - assert dependant.call - call_name = getattr(dependant.call, "__name__", "") - raise DependencyScopeError( - f'The dependency "{call_name}" has a scope of ' - '"request", it cannot depend on dependencies with scope "function".' - ) - sub_own_oauth_scopes: list[str] = [] - if isinstance(param_details.depends, params.Security): - if param_details.depends.scopes: - sub_own_oauth_scopes = list(param_details.depends.scopes) - sub_dependant = get_dependant( - path=path, - call=param_details.depends.dependency, - name=param_name, - own_oauth_scopes=sub_own_oauth_scopes, - parent_oauth_scopes=current_scopes, - use_cache=param_details.depends.use_cache, - scope=param_details.depends.scope, - ) - dependant.dependencies.append(sub_dependant) - continue - if add_non_field_param_to_dependency( - param_name=param_name, - type_annotation=param_details.type_annotation, - dependant=dependant, - ): - assert param_details.field is None, ( - f"Cannot specify multiple FastAPI annotations for {param_name!r}" - ) - continue - assert param_details.field is not None - if isinstance(param_details.field.field_info, params.Body): - dependant.body_params.append(param_details.field) - else: - add_param_to_fields(field=param_details.field, dependant=dependant) - return dependant - - -def add_non_field_param_to_dependency( - *, param_name: str, type_annotation: Any, dependant: Dependant -) -> bool | None: - if lenient_issubclass(type_annotation, Request): - dependant.request_param_name = param_name - return True - elif lenient_issubclass(type_annotation, WebSocket): - dependant.websocket_param_name = param_name - return True - elif lenient_issubclass(type_annotation, HTTPConnection): - dependant.http_connection_param_name = param_name - return True - elif lenient_issubclass(type_annotation, Response): - dependant.response_param_name = param_name - return True - elif lenient_issubclass(type_annotation, StarletteBackgroundTasks): - dependant.background_tasks_param_name = param_name - return True - elif lenient_issubclass(type_annotation, SecurityScopes): - dependant.security_scopes_param_name = param_name - return True - return None - - -@dataclass -class ParamDetails: - type_annotation: Any - depends: params.Depends | None - field: ModelField | None - - -def analyze_param( - *, - param_name: str, - annotation: Any, - value: Any, - is_path_param: bool, -) -> ParamDetails: - field_info = None - depends = None - type_annotation: Any = Any - use_annotation: Any = Any - if is_typealiastype(annotation): - # unpack in case PEP 695 type syntax is used - annotation = annotation.__value__ - if annotation is not inspect.Signature.empty: - use_annotation = annotation - type_annotation = annotation - # Extract Annotated info - if get_origin(use_annotation) is Annotated: - annotated_args = get_args(annotation) - type_annotation = annotated_args[0] - fastapi_annotations = [ - arg - for arg in annotated_args[1:] - if isinstance(arg, (FieldInfo, params.Depends)) - ] - fastapi_specific_annotations = [ - arg - for arg in fastapi_annotations - if isinstance( - arg, - ( - params.Param, - params.Body, - params.Depends, - ), - ) - ] - if fastapi_specific_annotations: - fastapi_annotation: FieldInfo | params.Depends | None = ( - fastapi_specific_annotations[-1] - ) - else: - fastapi_annotation = None - # Set default for Annotated FieldInfo - if isinstance(fastapi_annotation, FieldInfo): - # Copy `field_info` because we mutate `field_info.default` below. - field_info = copy_field_info( - field_info=fastapi_annotation, - annotation=use_annotation, - ) - assert ( - field_info.default == Undefined or field_info.default == RequiredParam - ), ( - f"`{field_info.__class__.__name__}` default value cannot be set in" - f" `Annotated` for {param_name!r}. Set the default value with `=` instead." - ) - if value is not inspect.Signature.empty: - assert not is_path_param, "Path parameters cannot have default values" - field_info.default = value - else: - field_info.default = RequiredParam - # Get Annotated Depends - elif isinstance(fastapi_annotation, params.Depends): - depends = fastapi_annotation - # Get Depends from default value - if isinstance(value, params.Depends): - assert depends is None, ( - "Cannot specify `Depends` in `Annotated` and default value" - f" together for {param_name!r}" - ) - assert field_info is None, ( - "Cannot specify a FastAPI annotation in `Annotated` and `Depends` as a" - f" default value together for {param_name!r}" - ) - depends = value - # Get FieldInfo from default value - elif isinstance(value, FieldInfo): - assert field_info is None, ( - "Cannot specify FastAPI annotations in `Annotated` and default value" - f" together for {param_name!r}" - ) - field_info = value - if isinstance(field_info, FieldInfo): - field_info.annotation = type_annotation - - # Get Depends from type annotation - if depends is not None and depends.dependency is None: - # Copy `depends` before mutating it - depends = copy(depends) - depends = dataclasses.replace(depends, dependency=type_annotation) - - # Handle non-param type annotations like Request - # Only apply special handling when there's no explicit Depends - if there's a Depends, - # the dependency will be called and its return value used instead of the special injection - if depends is None and lenient_issubclass( - type_annotation, - ( - Request, - WebSocket, - HTTPConnection, - Response, - StarletteBackgroundTasks, - SecurityScopes, - ), - ): - assert field_info is None, ( - f"Cannot specify FastAPI annotation for type {type_annotation!r}" - ) - # Handle default assignations, neither field_info nor depends was not found in Annotated nor default value - elif field_info is None and depends is None: - default_value = value if value is not inspect.Signature.empty else RequiredParam - if is_path_param: - # We might check here that `default_value is RequiredParam`, but the fact is that the same - # parameter might sometimes be a path parameter and sometimes not. See - # `tests/test_infer_param_optionality.py` for an example. - field_info = params.Path(annotation=use_annotation) - elif is_uploadfile_or_nonable_uploadfile_annotation( - type_annotation - ) or is_uploadfile_sequence_annotation(type_annotation): - field_info = params.File(annotation=use_annotation, default=default_value) - elif not field_annotation_is_scalar(annotation=type_annotation): - field_info = params.Body(annotation=use_annotation, default=default_value) - else: - field_info = params.Query(annotation=use_annotation, default=default_value) - - field = None - # It's a field_info, not a dependency - if field_info is not None: - # Handle field_info.in_ - if is_path_param: - assert isinstance(field_info, params.Path), ( - f"Cannot use `{field_info.__class__.__name__}` for path param" - f" {param_name!r}" - ) - elif ( - isinstance(field_info, params.Param) - and getattr(field_info, "in_", None) is None - ): - field_info.in_ = params.ParamTypes.query - use_annotation_from_field_info = use_annotation - if isinstance(field_info, params.Form): - ensure_multipart_is_installed() - if not field_info.alias and getattr(field_info, "convert_underscores", None): - alias = param_name.replace("_", "-") - else: - alias = field_info.alias or param_name - field_info.alias = alias - field = create_model_field( - name=param_name, - type_=use_annotation_from_field_info, - default=field_info.default, - alias=alias, - field_info=field_info, - ) - if is_path_param: - assert is_scalar_field(field=field), ( - "Path params must be of one of the supported types" - ) - elif isinstance(field_info, params.Query): - assert ( - is_scalar_field(field) - or field_annotation_is_scalar_sequence(field.field_info.annotation) - or lenient_issubclass(field.field_info.annotation, BaseModel) - ), f"Query parameter {param_name!r} must be one of the supported types" - - return ParamDetails(type_annotation=type_annotation, depends=depends, field=field) - - -def add_param_to_fields(*, field: ModelField, dependant: Dependant) -> None: - field_info = field.field_info - field_info_in = getattr(field_info, "in_", None) - if field_info_in == params.ParamTypes.path: - dependant.path_params.append(field) - elif field_info_in == params.ParamTypes.query: - dependant.query_params.append(field) - elif field_info_in == params.ParamTypes.header: - dependant.header_params.append(field) - else: - assert field_info_in == params.ParamTypes.cookie, ( - f"non-body parameters must be in path, query, header or cookie: {field.name}" - ) - dependant.cookie_params.append(field) - - -async def _solve_generator( - *, dependant: Dependant, stack: AsyncExitStack, sub_values: dict[str, Any] -) -> Any: - assert dependant.call - if _is_async_gen_callable(dependant.call): - cm = asynccontextmanager(dependant.call)(**sub_values) - elif _is_gen_callable(dependant.call): - cm = contextmanager_in_threadpool(contextmanager(dependant.call)(**sub_values)) - return await stack.enter_async_context(cm) - - -@dataclass -class SolvedDependency: - values: dict[str, Any] - errors: list[Any] - background_tasks: StarletteBackgroundTasks | None - response: Response - dependency_cache: dict[DependencyCacheKey, Any] - - -async def solve_dependencies( - *, - request: Request | WebSocket, - dependant: Dependant, - body: dict[str, Any] | FormData | bytes | None = None, - background_tasks: StarletteBackgroundTasks | None = None, - response: Response | None = None, - dependency_overrides_provider: Any | None = None, - dependency_cache: dict[DependencyCacheKey, Any] | None = None, - # TODO: remove this parameter later, no longer used, not removing it yet as some - # people might be monkey patching this function (although that's not supported) - async_exit_stack: AsyncExitStack, - embed_body_fields: bool, - _uses_scopes_cache: _UsesScopesCache | None = None, -) -> SolvedDependency: - request_astack = request.scope.get("fastapi_inner_astack") - assert isinstance(request_astack, AsyncExitStack), ( - "fastapi_inner_astack not found in request scope" - ) - function_astack = request.scope.get("fastapi_function_astack") - assert isinstance(function_astack, AsyncExitStack), ( - "fastapi_function_astack not found in request scope" - ) - values: dict[str, Any] = {} - errors: list[Any] = [] - if response is None: - response = Response() - del response.headers["content-length"] - response.status_code = None # type: ignore - if dependency_cache is None: - dependency_cache = {} - if _uses_scopes_cache is None: - _uses_scopes_cache = {} - for sub_dependant in dependant.dependencies: - sub_dependant.call = cast(Callable[..., Any], sub_dependant.call) - call = sub_dependant.call - use_sub_dependant = sub_dependant - if ( - dependency_overrides_provider - and dependency_overrides_provider.dependency_overrides - ): - original_call = sub_dependant.call - call = getattr( - dependency_overrides_provider, "dependency_overrides", {} - ).get(original_call, original_call) - use_path: str = sub_dependant.path # type: ignore - use_sub_dependant = get_dependant( - path=use_path, - call=call, - name=sub_dependant.name, - parent_oauth_scopes=_get_oauth_scopes(dependant=sub_dependant), - scope=sub_dependant.scope, - ) - - solved_result = await solve_dependencies( - request=request, - dependant=use_sub_dependant, - body=body, - background_tasks=background_tasks, - response=response, - dependency_overrides_provider=dependency_overrides_provider, - dependency_cache=dependency_cache, - async_exit_stack=async_exit_stack, - embed_body_fields=embed_body_fields, - _uses_scopes_cache=_uses_scopes_cache, - ) - background_tasks = solved_result.background_tasks - if solved_result.errors: - errors.extend(solved_result.errors) - continue - sub_dependant_cache_key = _get_cache_key( - dependant=sub_dependant, - uses_scopes_cache=_uses_scopes_cache, - ) - if sub_dependant.use_cache and sub_dependant_cache_key in dependency_cache: - solved = dependency_cache[sub_dependant_cache_key] - elif _is_gen_callable(use_sub_dependant.call) or _is_async_gen_callable( - use_sub_dependant.call - ): - use_astack = request_astack - if sub_dependant.scope == "function": - use_astack = function_astack - solved = await _solve_generator( - dependant=use_sub_dependant, - stack=use_astack, - sub_values=solved_result.values, - ) - elif _is_coroutine_callable(use_sub_dependant.call): - solved = await call(**solved_result.values) - else: - solved = await run_in_threadpool(call, **solved_result.values) - if sub_dependant.name is not None: - values[sub_dependant.name] = solved - if sub_dependant_cache_key not in dependency_cache: - dependency_cache[sub_dependant_cache_key] = solved - path_values, path_errors = request_params_to_args( - dependant.path_params, request.path_params - ) - query_values, query_errors = request_params_to_args( - dependant.query_params, request.query_params - ) - header_values, header_errors = request_params_to_args( - dependant.header_params, request.headers - ) - cookie_values, cookie_errors = request_params_to_args( - dependant.cookie_params, request.cookies - ) - values.update(path_values) - values.update(query_values) - values.update(header_values) - values.update(cookie_values) - errors += path_errors + query_errors + header_errors + cookie_errors - if dependant.body_params: - ( - body_values, - body_errors, - ) = await request_body_to_args( # body_params checked above - body_fields=dependant.body_params, - received_body=body, - embed_body_fields=embed_body_fields, - ) - values.update(body_values) - errors.extend(body_errors) - if dependant.http_connection_param_name: - values[dependant.http_connection_param_name] = request - if dependant.request_param_name and isinstance(request, Request): - values[dependant.request_param_name] = request - elif dependant.websocket_param_name and isinstance(request, WebSocket): - values[dependant.websocket_param_name] = request - if dependant.background_tasks_param_name: - if background_tasks is None: - background_tasks = BackgroundTasks() - values[dependant.background_tasks_param_name] = background_tasks - if dependant.response_param_name: - values[dependant.response_param_name] = response - if dependant.security_scopes_param_name: - values[dependant.security_scopes_param_name] = SecurityScopes( - scopes=_get_oauth_scopes(dependant=dependant) - ) - return SolvedDependency( - values=values, - errors=errors, - background_tasks=background_tasks, - response=response, - dependency_cache=dependency_cache, - ) - - -def _validate_value_with_model_field( - *, field: ModelField, value: Any, values: dict[str, Any], loc: tuple[str, ...] -) -> tuple[Any, list[Any]]: - if value is None: - if field.field_info.is_required(): - return None, [get_missing_field_error(loc=loc)] - else: - return deepcopy(field.default), [] - return field.validate(value, values, loc=loc) - - -def _is_json_field(field: ModelField) -> bool: - return any(type(item) is Json for item in field.field_info.metadata) - - -def _get_multidict_value( - field: ModelField, values: Mapping[str, Any], alias: str | None = None -) -> Any: - alias = alias or get_validation_alias(field) - if ( - (not _is_json_field(field)) - and field_annotation_is_sequence(field.field_info.annotation) - and isinstance(values, (ImmutableMultiDict, Headers)) - ): - value = values.getlist(alias) - else: - value = values.get(alias, None) - if ( - value is None - or ( - isinstance(field.field_info, params.Form) - and isinstance(value, str) # For type checks - and value == "" - ) - or ( - field_annotation_is_sequence(field.field_info.annotation) - and len(value) == 0 - ) - ): - if field.field_info.is_required(): - return - else: - return deepcopy(field.default) - return value - - -def request_params_to_args( - fields: Sequence[ModelField], - received_params: Mapping[str, Any] | QueryParams | Headers, -) -> tuple[dict[str, Any], list[Any]]: - values: dict[str, Any] = {} - errors: list[dict[str, Any]] = [] - - if not fields: - return values, errors - - first_field = fields[0] - fields_to_extract = fields - single_not_embedded_field = False - default_convert_underscores = True - if len(fields) == 1 and lenient_issubclass( - first_field.field_info.annotation, BaseModel - ): - fields_to_extract = get_cached_model_fields(first_field.field_info.annotation) - single_not_embedded_field = True - # If headers are in a Pydantic model, the way to disable convert_underscores - # would be with Header(convert_underscores=False) at the Pydantic model level - default_convert_underscores = getattr( - first_field.field_info, "convert_underscores", True - ) - - params_to_process: dict[str, Any] = {} - - processed_keys = set() - - for field in fields_to_extract: - alias = None - if isinstance(received_params, Headers): - # Handle fields extracted from a Pydantic Model for a header, each field - # doesn't have a FieldInfo of type Header with the default convert_underscores=True - convert_underscores = getattr( - field.field_info, "convert_underscores", default_convert_underscores - ) - if convert_underscores: - alias = get_validation_alias(field) - if alias == field.name: - alias = alias.replace("_", "-") - value = _get_multidict_value(field, received_params, alias=alias) - if value is not None: - params_to_process[get_validation_alias(field)] = value - processed_keys.add(alias or get_validation_alias(field)) - # For headers with convert_underscores=True, mark both the converted - # header name and the original field alias as processed to avoid - # accepting the original alias as an extra header. - processed_keys.add(get_validation_alias(field)) - - for key in received_params.keys(): - if key not in processed_keys: - if isinstance(received_params, (ImmutableMultiDict, Headers)): - value = received_params.getlist(key) - if isinstance(value, list) and (len(value) == 1): - params_to_process[key] = value[0] - else: - params_to_process[key] = value - else: - params_to_process[key] = received_params.get(key) - - if single_not_embedded_field: - field_info = first_field.field_info - assert isinstance(field_info, params.Param), ( - "Params must be subclasses of Param" - ) - loc: tuple[str, ...] = (field_info.in_.value,) - v_, errors_ = _validate_value_with_model_field( - field=first_field, value=params_to_process, values=values, loc=loc - ) - return {first_field.name: v_}, errors_ - - for field in fields: - value = _get_multidict_value(field, received_params) - field_info = field.field_info - assert isinstance(field_info, params.Param), ( - "Params must be subclasses of Param" - ) - loc = (field_info.in_.value, get_validation_alias(field)) - v_, errors_ = _validate_value_with_model_field( - field=field, value=value, values=values, loc=loc - ) - if errors_: - errors.extend(errors_) - else: - values[field.name] = v_ - return values, errors - - -def is_union_of_base_models(field_type: Any) -> bool: - """Check if field type is a Union where all members are BaseModel subclasses.""" - from fastapi.types import UnionType - - origin = get_origin(field_type) - - # Check if it's a Union type (covers both typing.Union and types.UnionType in Python 3.10+) - if origin is not Union and origin is not UnionType: - return False - - union_args = get_args(field_type) - - for arg in union_args: - if not lenient_issubclass(arg, BaseModel): - return False - - return True - - -def _should_embed_body_fields(fields: list[ModelField]) -> bool: - if not fields: - return False - # More than one dependency could have the same field, it would show up as multiple - # fields but it's the same one, so count them by name - body_param_names_set = {field.name for field in fields} - # A top level field has to be a single field, not multiple - if len(body_param_names_set) > 1: - return True - first_field = fields[0] - # If it explicitly specifies it is embedded, it has to be embedded - if getattr(first_field.field_info, "embed", None): - return True - # If it's a Form (or File) field, it has to be a BaseModel (or a union of BaseModels) to be top level - # otherwise it has to be embedded, so that the key value pair can be extracted - if ( - isinstance(first_field.field_info, params.Form) - and not lenient_issubclass(first_field.field_info.annotation, BaseModel) - and not is_union_of_base_models(first_field.field_info.annotation) - ): - return True - return False - - -async def _extract_form_body( - body_fields: list[ModelField], - received_body: FormData, -) -> dict[str, Any]: - values = {} - - for field in body_fields: - value = _get_multidict_value(field, received_body) - field_info = field.field_info - if ( - isinstance(field_info, params.File) - and is_bytes_or_nonable_bytes_annotation(field.field_info.annotation) - and isinstance(value, UploadFile) - ): - value = await value.read() - elif ( - is_bytes_sequence_annotation(field.field_info.annotation) - and isinstance(field_info, params.File) - and value_is_sequence(value) - ): - # For types - assert isinstance(value, sequence_types) - results: list[bytes | str] = [] - for sub_value in value: - results.append(await sub_value.read()) - value = serialize_sequence_value(field=field, value=results) - if value is not None: - values[get_validation_alias(field)] = value - field_aliases = {get_validation_alias(field) for field in body_fields} - for key in received_body.keys(): - if key not in field_aliases: - param_values = received_body.getlist(key) - if len(param_values) == 1: - values[key] = param_values[0] - else: - values[key] = param_values - return values - - -async def request_body_to_args( - body_fields: list[ModelField], - received_body: dict[str, Any] | FormData | bytes | None, - embed_body_fields: bool, -) -> tuple[dict[str, Any], list[dict[str, Any]]]: - values: dict[str, Any] = {} - errors: list[dict[str, Any]] = [] - assert body_fields, "request_body_to_args() should be called with fields" - single_not_embedded_field = len(body_fields) == 1 and not embed_body_fields - first_field = body_fields[0] - body_to_process = received_body - - fields_to_extract: list[ModelField] = body_fields - - if ( - single_not_embedded_field - and lenient_issubclass(first_field.field_info.annotation, BaseModel) - and isinstance(received_body, FormData) - ): - fields_to_extract = get_cached_model_fields(first_field.field_info.annotation) - - if isinstance(received_body, FormData): - body_to_process = await _extract_form_body(fields_to_extract, received_body) - - if single_not_embedded_field: - loc: tuple[str, ...] = ("body",) - v_, errors_ = _validate_value_with_model_field( - field=first_field, value=body_to_process, values=values, loc=loc - ) - return {first_field.name: v_}, errors_ - for field in body_fields: - loc = ("body", get_validation_alias(field)) - value: Any | None = None - if body_to_process is not None and not isinstance(body_to_process, bytes): - try: - value = body_to_process.get(get_validation_alias(field)) - # If the received body is a list, not a dict - except AttributeError: - errors.append(get_missing_field_error(loc)) - continue - v_, errors_ = _validate_value_with_model_field( - field=field, value=value, values=values, loc=loc - ) - if errors_: - errors.extend(errors_) - else: - values[field.name] = v_ - return values, errors - - -def _get_body_field( - *, body_params: list[ModelField], name: str, embed_body_fields: bool -) -> ModelField | None: - """ - Get a ModelField representing the request body for a path operation, combining - all body parameters into a single field if necessary. - - Used to check if it's form data (with `isinstance(body_field, params.Form)`) - or JSON and to generate the JSON Schema for a request body. - - This is **not** used to validate/parse the request body, that's done with each - individual body parameter. - """ - if not body_params: - return None - first_param = body_params[0] - if not embed_body_fields: - return first_param - model_name = "Body_" + name - BodyModel = create_body_model(fields=body_params, model_name=model_name) - required = any(True for f in body_params if f.field_info.is_required()) - BodyFieldInfo_kwargs: dict[str, Any] = { - "annotation": BodyModel, - "alias": "body", - } - if not required: - BodyFieldInfo_kwargs["default"] = None - if any(isinstance(f.field_info, params.File) for f in body_params): - BodyFieldInfo: type[params.Body] = params.File - elif any(isinstance(f.field_info, params.Form) for f in body_params): - BodyFieldInfo = params.Form - else: - BodyFieldInfo = params.Body - - body_param_media_types = [ - f.field_info.media_type - for f in body_params - if isinstance(f.field_info, params.Body) - ] - if len(set(body_param_media_types)) == 1: - BodyFieldInfo_kwargs["media_type"] = body_param_media_types[0] - final_field = create_model_field( - name="body", - type_=BodyModel, - alias="body", - field_info=BodyFieldInfo(**BodyFieldInfo_kwargs), - ) - return final_field - - -def get_validation_alias(field: ModelField) -> str: - va = getattr(field, "validation_alias", None) - return va or field.alias diff --git a/bundle/python-cpu/Lib/site-packages/fastapi/encoders.py b/bundle/python-cpu/Lib/site-packages/fastapi/encoders.py deleted file mode 100644 index e578768dac5b33556087b42bd6a2e0782a9d5379..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/fastapi/encoders.py +++ /dev/null @@ -1,366 +0,0 @@ -import dataclasses -import datetime -from collections import defaultdict, deque -from collections.abc import Callable -from decimal import Decimal -from enum import Enum -from ipaddress import ( - IPv4Address, - IPv4Interface, - IPv4Network, - IPv6Address, - IPv6Interface, - IPv6Network, -) -from pathlib import Path, PurePath -from re import Pattern -from types import GeneratorType -from typing import Annotated, Any -from uuid import UUID - -from annotated_doc import Doc -from fastapi.exceptions import PydanticV1NotSupportedError -from fastapi.types import IncEx -from pydantic import BaseModel -from pydantic.networks import AnyUrl, NameEmail -from pydantic.types import SecretBytes, SecretStr -from pydantic_core import PydanticUndefinedType - -from ._compat import ( - Url, - is_pydantic_v1_model_instance, -) - -try: - # pydantic.color.Color is deprecated since v2.0b3, but supporting for bwd-compat - from pydantic.color import Color # ty: ignore[deprecated] -except ImportError: # pragma: no cover - - class Color: # type: ignore[no-redef] - pass - - -try: - # Supporting the new Color format for newer versions of Pydantic - from pydantic_extra_types.color import Color as PyExtraColor -except ImportError: # pragma: no cover - - class PyExtraColor: # type: ignore[no-redef] - pass - - -# Taken from Pydantic v1 as is -def isoformat(o: datetime.date | datetime.time) -> str: - return o.isoformat() - - -# Adapted from Pydantic v1 -# TODO: pv2 should this return strings instead? -def decimal_encoder(dec_value: Decimal) -> int | float: - """ - Encodes a Decimal as int if there's no exponent, otherwise float - - This is useful when we use ConstrainedDecimal to represent Numeric(x,0) - where an integer (but not int typed) is used. Encoding this as a float - results in failed round-tripping between encode and parse. - Our Id type is a prime example of this. - - >>> decimal_encoder(Decimal("1.0")) - 1.0 - - >>> decimal_encoder(Decimal("1")) - 1 - - >>> decimal_encoder(Decimal("NaN")) - nan - """ - exponent = dec_value.as_tuple().exponent - if isinstance(exponent, int) and exponent >= 0: - return int(dec_value) - else: - return float(dec_value) - - -ENCODERS_BY_TYPE: dict[type[Any], Callable[[Any], Any]] = { - bytes: lambda o: o.decode(), - Color: str, - PyExtraColor: str, - datetime.date: isoformat, - datetime.datetime: isoformat, - datetime.time: isoformat, - datetime.timedelta: lambda td: td.total_seconds(), - Decimal: decimal_encoder, - Enum: lambda o: o.value, - frozenset: list, - deque: list, - GeneratorType: list, - IPv4Address: str, - IPv4Interface: str, - IPv4Network: str, - IPv6Address: str, - IPv6Interface: str, - IPv6Network: str, - NameEmail: str, - Path: str, - Pattern: lambda o: o.pattern, - SecretBytes: str, - SecretStr: str, - set: list, - UUID: str, - Url: str, - AnyUrl: str, -} - - -def generate_encoders_by_class_tuples( - type_encoder_map: dict[Any, Callable[[Any], Any]], -) -> dict[Callable[[Any], Any], tuple[Any, ...]]: - encoders_by_class_tuples: dict[Callable[[Any], Any], tuple[Any, ...]] = defaultdict( - tuple - ) - for type_, encoder in type_encoder_map.items(): - encoders_by_class_tuples[encoder] += (type_,) - return encoders_by_class_tuples - - -encoders_by_class_tuples = generate_encoders_by_class_tuples(ENCODERS_BY_TYPE) - - -def jsonable_encoder( - obj: Annotated[ - Any, - Doc( - """ - The input object to convert to JSON. - """ - ), - ], - include: Annotated[ - IncEx | None, - Doc( - """ - Pydantic's `include` parameter, passed to Pydantic models to set the - fields to include. - """ - ), - ] = None, - exclude: Annotated[ - IncEx | None, - Doc( - """ - Pydantic's `exclude` parameter, passed to Pydantic models to set the - fields to exclude. - """ - ), - ] = None, - by_alias: Annotated[ - bool, - Doc( - """ - Pydantic's `by_alias` parameter, passed to Pydantic models to define if - the output should use the alias names (when provided) or the Python - attribute names. In an API, if you set an alias, it's probably because you - want to use it in the result, so you probably want to leave this set to - `True`. - """ - ), - ] = True, - exclude_unset: Annotated[ - bool, - Doc( - """ - Pydantic's `exclude_unset` parameter, passed to Pydantic models to define - if it should exclude from the output the fields that were not explicitly - set (and that only had their default values). - """ - ), - ] = False, - exclude_defaults: Annotated[ - bool, - Doc( - """ - Pydantic's `exclude_defaults` parameter, passed to Pydantic models to define - if it should exclude from the output the fields that had the same default - value, even when they were explicitly set. - """ - ), - ] = False, - exclude_none: Annotated[ - bool, - Doc( - """ - Pydantic's `exclude_none` parameter, passed to Pydantic models to define - if it should exclude from the output any fields that have a `None` value. - """ - ), - ] = False, - custom_encoder: Annotated[ - dict[Any, Callable[[Any], Any]] | None, - Doc( - """ - Pydantic's `custom_encoder` parameter, passed to Pydantic models to define - a custom encoder. - """ - ), - ] = None, - sqlalchemy_safe: Annotated[ - bool, - Doc( - """ - Exclude from the output any fields that start with the name `_sa`. - - This is mainly a hack for compatibility with SQLAlchemy objects, they - store internal SQLAlchemy-specific state in attributes named with `_sa`, - and those objects can't (and shouldn't be) serialized to JSON. - """ - ), - ] = True, -) -> Any: - """ - Convert any object to something that can be encoded in JSON. - - This is used internally by FastAPI to make sure anything you return can be - encoded as JSON before it is sent to the client. - - You can also use it yourself, for example to convert objects before saving them - in a database that supports only JSON. - - Read more about it in the - [FastAPI docs for JSON Compatible Encoder](https://fastapi.tiangolo.com/tutorial/encoder/). - """ - custom_encoder = custom_encoder or {} - if custom_encoder: - if type(obj) in custom_encoder: - return custom_encoder[type(obj)](obj) - else: - for encoder_type, encoder_instance in custom_encoder.items(): - if isinstance(obj, encoder_type): - return encoder_instance(obj) - if include is not None and not isinstance(include, (set, dict)): - include = set(include) # type: ignore[assignment] # ty: ignore[invalid-assignment] - if exclude is not None and not isinstance(exclude, (set, dict)): - exclude = set(exclude) # type: ignore[assignment] # ty: ignore[invalid-assignment] - if isinstance(obj, BaseModel): - obj_dict = obj.model_dump( - mode="json", - include=include, - exclude=exclude, - by_alias=by_alias, - exclude_unset=exclude_unset, - exclude_none=exclude_none, - exclude_defaults=exclude_defaults, - ) - return jsonable_encoder( - obj_dict, - exclude_none=exclude_none, - exclude_defaults=exclude_defaults, - sqlalchemy_safe=sqlalchemy_safe, - ) - if dataclasses.is_dataclass(obj): - assert not isinstance(obj, type) - obj_dict = dataclasses.asdict(obj) - return jsonable_encoder( - obj_dict, - include=include, - exclude=exclude, - by_alias=by_alias, - exclude_unset=exclude_unset, - exclude_defaults=exclude_defaults, - exclude_none=exclude_none, - custom_encoder=custom_encoder, - sqlalchemy_safe=sqlalchemy_safe, - ) - if isinstance(obj, Enum): - return obj.value - if isinstance(obj, PurePath): - return str(obj) - if isinstance(obj, (str, int, float, type(None))): - return obj - if isinstance(obj, PydanticUndefinedType): - return None - if isinstance(obj, dict): - encoded_dict = {} - allowed_keys = set(obj.keys()) - if include is not None: - allowed_keys &= set(include) - if exclude is not None: - allowed_keys -= set(exclude) - for key, value in obj.items(): - if ( - ( - not sqlalchemy_safe - or (not isinstance(key, str)) - or (not key.startswith("_sa")) - ) - and (value is not None or not exclude_none) - and key in allowed_keys - ): - encoded_key = jsonable_encoder( - key, - by_alias=by_alias, - exclude_unset=exclude_unset, - exclude_defaults=exclude_defaults, - exclude_none=exclude_none, - custom_encoder=custom_encoder, - sqlalchemy_safe=sqlalchemy_safe, - ) - encoded_value = jsonable_encoder( - value, - by_alias=by_alias, - exclude_unset=exclude_unset, - exclude_defaults=exclude_defaults, - exclude_none=exclude_none, - custom_encoder=custom_encoder, - sqlalchemy_safe=sqlalchemy_safe, - ) - encoded_dict[encoded_key] = encoded_value - return encoded_dict - if isinstance(obj, (list, set, frozenset, GeneratorType, tuple, deque)): - encoded_list = [] - for item in obj: - encoded_list.append( - jsonable_encoder( - item, - include=include, - exclude=exclude, - by_alias=by_alias, - exclude_unset=exclude_unset, - exclude_defaults=exclude_defaults, - exclude_none=exclude_none, - custom_encoder=custom_encoder, - sqlalchemy_safe=sqlalchemy_safe, - ) - ) - return encoded_list - - if type(obj) in ENCODERS_BY_TYPE: - return ENCODERS_BY_TYPE[type(obj)](obj) - for encoder, classes_tuple in encoders_by_class_tuples.items(): - if isinstance(obj, classes_tuple): - return encoder(obj) - if is_pydantic_v1_model_instance(obj): - raise PydanticV1NotSupportedError( - "pydantic.v1 models are no longer supported by FastAPI." - f" Please update the model {obj!r}." - ) - try: - data = dict(obj) - except Exception as e: - errors: list[Exception] = [] - errors.append(e) - try: - data = vars(obj) - except Exception as e: - errors.append(e) - raise ValueError(errors) from e - return jsonable_encoder( - data, - include=include, - exclude=exclude, - by_alias=by_alias, - exclude_unset=exclude_unset, - exclude_defaults=exclude_defaults, - exclude_none=exclude_none, - custom_encoder=custom_encoder, - sqlalchemy_safe=sqlalchemy_safe, - ) diff --git a/bundle/python-cpu/Lib/site-packages/fastapi/exception_handlers.py b/bundle/python-cpu/Lib/site-packages/fastapi/exception_handlers.py deleted file mode 100644 index 475dd7bdd9891a7595b6df5db97cd3840179c8fa..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/fastapi/exception_handlers.py +++ /dev/null @@ -1,34 +0,0 @@ -from fastapi.encoders import jsonable_encoder -from fastapi.exceptions import RequestValidationError, WebSocketRequestValidationError -from fastapi.utils import is_body_allowed_for_status_code -from fastapi.websockets import WebSocket -from starlette.exceptions import HTTPException -from starlette.requests import Request -from starlette.responses import JSONResponse, Response -from starlette.status import WS_1008_POLICY_VIOLATION - - -async def http_exception_handler(request: Request, exc: HTTPException) -> Response: - headers = getattr(exc, "headers", None) - if not is_body_allowed_for_status_code(exc.status_code): - return Response(status_code=exc.status_code, headers=headers) - return JSONResponse( - {"detail": exc.detail}, status_code=exc.status_code, headers=headers - ) - - -async def request_validation_exception_handler( - request: Request, exc: RequestValidationError -) -> JSONResponse: - return JSONResponse( - status_code=422, - content={"detail": jsonable_encoder(exc.errors())}, - ) - - -async def websocket_request_validation_exception_handler( - websocket: WebSocket, exc: WebSocketRequestValidationError -) -> None: - await websocket.close( - code=WS_1008_POLICY_VIOLATION, reason=jsonable_encoder(exc.errors()) - ) diff --git a/bundle/python-cpu/Lib/site-packages/fastapi/exceptions.py b/bundle/python-cpu/Lib/site-packages/fastapi/exceptions.py deleted file mode 100644 index d7065c52fe20220e12b7d20db4da7cbeadaf171a..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/fastapi/exceptions.py +++ /dev/null @@ -1,256 +0,0 @@ -from collections.abc import Mapping, Sequence -from typing import Annotated, Any, TypedDict - -from annotated_doc import Doc -from pydantic import BaseModel, create_model -from starlette.exceptions import HTTPException as StarletteHTTPException -from starlette.exceptions import WebSocketException as StarletteWebSocketException - - -class EndpointContext(TypedDict, total=False): - function: str - path: str - file: str - line: int - - -class HTTPException(StarletteHTTPException): - """ - An HTTP exception you can raise in your own code to show errors to the client. - - This is for client errors, invalid authentication, invalid data, etc. Not for server - errors in your code. - - Read more about it in the - [FastAPI docs for Handling Errors](https://fastapi.tiangolo.com/tutorial/handling-errors/). - - ## Example - - ```python - from fastapi import FastAPI, HTTPException - - app = FastAPI() - - items = {"foo": "The Foo Wrestlers"} - - - @app.get("/items/{item_id}") - async def read_item(item_id: str): - if item_id not in items: - raise HTTPException(status_code=404, detail="Item not found") - return {"item": items[item_id]} - ``` - """ - - def __init__( - self, - status_code: Annotated[ - int, - Doc( - """ - HTTP status code to send to the client. - - Read more about it in the - [FastAPI docs for Handling Errors](https://fastapi.tiangolo.com/tutorial/handling-errors/#use-httpexception) - """ - ), - ], - detail: Annotated[ - Any, - Doc( - """ - Any data to be sent to the client in the `detail` key of the JSON - response. - - Read more about it in the - [FastAPI docs for Handling Errors](https://fastapi.tiangolo.com/tutorial/handling-errors/#use-httpexception) - """ - ), - ] = None, - headers: Annotated[ - Mapping[str, str] | None, - Doc( - """ - Any headers to send to the client in the response. - - Read more about it in the - [FastAPI docs for Handling Errors](https://fastapi.tiangolo.com/tutorial/handling-errors/#add-custom-headers) - - """ - ), - ] = None, - ) -> None: - super().__init__(status_code=status_code, detail=detail, headers=headers) - - -class WebSocketException(StarletteWebSocketException): - """ - A WebSocket exception you can raise in your own code to show errors to the client. - - This is for client errors, invalid authentication, invalid data, etc. Not for server - errors in your code. - - Read more about it in the - [FastAPI docs for WebSockets](https://fastapi.tiangolo.com/advanced/websockets/). - - ## Example - - ```python - from typing import Annotated - - from fastapi import ( - Cookie, - FastAPI, - WebSocket, - WebSocketException, - status, - ) - - app = FastAPI() - - @app.websocket("/items/{item_id}/ws") - async def websocket_endpoint( - *, - websocket: WebSocket, - session: Annotated[str | None, Cookie()] = None, - item_id: str, - ): - if session is None: - raise WebSocketException(code=status.WS_1008_POLICY_VIOLATION) - await websocket.accept() - while True: - data = await websocket.receive_text() - await websocket.send_text(f"Session cookie is: {session}") - await websocket.send_text(f"Message text was: {data}, for item ID: {item_id}") - ``` - """ - - def __init__( - self, - code: Annotated[ - int, - Doc( - """ - A closing code from the - [valid codes defined in the specification](https://datatracker.ietf.org/doc/html/rfc6455#section-7.4.1). - """ - ), - ], - reason: Annotated[ - str | None, - Doc( - """ - The reason to close the WebSocket connection. - - It is UTF-8-encoded data. The interpretation of the reason is up to the - application, it is not specified by the WebSocket specification. - - It could contain text that could be human-readable or interpretable - by the client code, etc. - """ - ), - ] = None, - ) -> None: - super().__init__(code=code, reason=reason) - - -RequestErrorModel: type[BaseModel] = create_model("Request") -WebSocketErrorModel: type[BaseModel] = create_model("WebSocket") - - -class FastAPIError(RuntimeError): - """ - A generic, FastAPI-specific error. - """ - - -class DependencyScopeError(FastAPIError): - """ - A dependency declared that it depends on another dependency with an invalid - (narrower) scope. - """ - - -class ValidationException(Exception): - def __init__( - self, - errors: Sequence[Any], - *, - endpoint_ctx: EndpointContext | None = None, - ) -> None: - self._errors = errors - self.endpoint_ctx = endpoint_ctx - - ctx = endpoint_ctx or {} - self.endpoint_function = ctx.get("function") - self.endpoint_path = ctx.get("path") - self.endpoint_file = ctx.get("file") - self.endpoint_line = ctx.get("line") - - def errors(self) -> Sequence[Any]: - return self._errors - - def _format_endpoint_context(self) -> str: - if not (self.endpoint_file and self.endpoint_line and self.endpoint_function): - if self.endpoint_path: - return f"\n Endpoint: {self.endpoint_path}" - return "" - - context = f'\n File "{self.endpoint_file}", line {self.endpoint_line}, in {self.endpoint_function}' - if self.endpoint_path: - context += f"\n {self.endpoint_path}" - return context - - def __str__(self) -> str: - message = f"{len(self._errors)} validation error{'s' if len(self._errors) != 1 else ''}:\n" - for err in self._errors: - message += f" {err}\n" - message += self._format_endpoint_context() - return message.rstrip() - - -class RequestValidationError(ValidationException): - def __init__( - self, - errors: Sequence[Any], - *, - body: Any = None, - endpoint_ctx: EndpointContext | None = None, - ) -> None: - super().__init__(errors, endpoint_ctx=endpoint_ctx) - self.body = body - - -class WebSocketRequestValidationError(ValidationException): - def __init__( - self, - errors: Sequence[Any], - *, - endpoint_ctx: EndpointContext | None = None, - ) -> None: - super().__init__(errors, endpoint_ctx=endpoint_ctx) - - -class ResponseValidationError(ValidationException): - def __init__( - self, - errors: Sequence[Any], - *, - body: Any = None, - endpoint_ctx: EndpointContext | None = None, - ) -> None: - super().__init__(errors, endpoint_ctx=endpoint_ctx) - self.body = body - - -class PydanticV1NotSupportedError(FastAPIError): - """ - A pydantic.v1 model is used, which is no longer supported. - """ - - -class FastAPIDeprecationWarning(UserWarning): - """ - A custom deprecation warning as DeprecationWarning is ignored - Ref: https://sethmlarson.dev/deprecations-via-warnings-dont-work-for-python-libraries - """ diff --git a/bundle/python-cpu/Lib/site-packages/fastapi/logger.py b/bundle/python-cpu/Lib/site-packages/fastapi/logger.py deleted file mode 100644 index 5b2c4ad5250b589aa0c8f8d1cc9125b91b10edb0..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/fastapi/logger.py +++ /dev/null @@ -1,3 +0,0 @@ -import logging - -logger = logging.getLogger("fastapi") diff --git a/bundle/python-cpu/Lib/site-packages/fastapi/middleware/__init__.py b/bundle/python-cpu/Lib/site-packages/fastapi/middleware/__init__.py deleted file mode 100644 index 620296d5ad6ca2cc49eb5d0dc140bcbc3204e9b4..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/fastapi/middleware/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from starlette.middleware import Middleware as Middleware diff --git a/bundle/python-cpu/Lib/site-packages/fastapi/middleware/asyncexitstack.py b/bundle/python-cpu/Lib/site-packages/fastapi/middleware/asyncexitstack.py deleted file mode 100644 index 4ce3f5a625548a00514f872d1653194bd3669a73..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/fastapi/middleware/asyncexitstack.py +++ /dev/null @@ -1,18 +0,0 @@ -from contextlib import AsyncExitStack - -from starlette.types import ASGIApp, Receive, Scope, Send - - -# Used mainly to close files after the request is done, dependencies are closed -# in their own AsyncExitStack -class AsyncExitStackMiddleware: - def __init__( - self, app: ASGIApp, context_name: str = "fastapi_middleware_astack" - ) -> None: - self.app = app - self.context_name = context_name - - async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: - async with AsyncExitStack() as stack: - scope[self.context_name] = stack - await self.app(scope, receive, send) diff --git a/bundle/python-cpu/Lib/site-packages/fastapi/middleware/cors.py b/bundle/python-cpu/Lib/site-packages/fastapi/middleware/cors.py deleted file mode 100644 index 8dfaad0dbb3ff5300cccb2023748cd30f54bc920..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/fastapi/middleware/cors.py +++ /dev/null @@ -1 +0,0 @@ -from starlette.middleware.cors import CORSMiddleware as CORSMiddleware # noqa diff --git a/bundle/python-cpu/Lib/site-packages/fastapi/middleware/gzip.py b/bundle/python-cpu/Lib/site-packages/fastapi/middleware/gzip.py deleted file mode 100644 index bbeb2cc7861a735d6cd5c0e29aeb6dbf8457023a..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/fastapi/middleware/gzip.py +++ /dev/null @@ -1 +0,0 @@ -from starlette.middleware.gzip import GZipMiddleware as GZipMiddleware # noqa diff --git a/bundle/python-cpu/Lib/site-packages/fastapi/middleware/httpsredirect.py b/bundle/python-cpu/Lib/site-packages/fastapi/middleware/httpsredirect.py deleted file mode 100644 index b7a3d8e078574e87dc6e345d621f5a596c3bdc1e..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/fastapi/middleware/httpsredirect.py +++ /dev/null @@ -1,3 +0,0 @@ -from starlette.middleware.httpsredirect import ( # noqa - HTTPSRedirectMiddleware as HTTPSRedirectMiddleware, -) diff --git a/bundle/python-cpu/Lib/site-packages/fastapi/middleware/trustedhost.py b/bundle/python-cpu/Lib/site-packages/fastapi/middleware/trustedhost.py deleted file mode 100644 index 08d7e035315677856fd2cd0be2044689b57619bf..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/fastapi/middleware/trustedhost.py +++ /dev/null @@ -1,3 +0,0 @@ -from starlette.middleware.trustedhost import ( # noqa - TrustedHostMiddleware as TrustedHostMiddleware, -) diff --git a/bundle/python-cpu/Lib/site-packages/fastapi/middleware/wsgi.py b/bundle/python-cpu/Lib/site-packages/fastapi/middleware/wsgi.py deleted file mode 100644 index 69e4dcab96370cac0ab93039a1eb9376d1659120..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/fastapi/middleware/wsgi.py +++ /dev/null @@ -1,3 +0,0 @@ -from starlette.middleware.wsgi import ( - WSGIMiddleware as WSGIMiddleware, -) # pragma: no cover # noqa diff --git a/bundle/python-cpu/Lib/site-packages/fastapi/openapi/__init__.py b/bundle/python-cpu/Lib/site-packages/fastapi/openapi/__init__.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/bundle/python-cpu/Lib/site-packages/fastapi/openapi/constants.py b/bundle/python-cpu/Lib/site-packages/fastapi/openapi/constants.py deleted file mode 100644 index d724ee3cfdbcda1c39f39511046c7a884186ca98..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/fastapi/openapi/constants.py +++ /dev/null @@ -1,3 +0,0 @@ -METHODS_WITH_BODY = {"GET", "HEAD", "POST", "PUT", "DELETE", "PATCH"} -REF_PREFIX = "#/components/schemas/" -REF_TEMPLATE = "#/components/schemas/{model}" diff --git a/bundle/python-cpu/Lib/site-packages/fastapi/openapi/docs.py b/bundle/python-cpu/Lib/site-packages/fastapi/openapi/docs.py deleted file mode 100644 index 0d9242f9fa6a5212114b8f4036adfaf0e518020f..0000000000000000000000000000000000000000 --- a/bundle/python-cpu/Lib/site-packages/fastapi/openapi/docs.py +++ /dev/null @@ -1,389 +0,0 @@ -import json -from typing import Annotated, Any - -from annotated_doc import Doc -from fastapi.encoders import jsonable_encoder -from starlette.responses import HTMLResponse - - -def _html_safe_json(value: Any) -> str: - """Serialize a value to JSON with HTML special characters escaped. - - This prevents injection when the JSON is embedded inside a - - -