{"record":{"id":"b7f151478ef54088","repo":"cocoindex-io/cocoindex","slug":"aiobotocore-is-required-to-use-the-amazon-s3-sourc","errorCode":null,"errorMessage":"aiobotocore is required to use the Amazon S3 source connector. Please install cocoindex[amazon_s3].","messagePattern":"aiobotocore is required to use the Amazon S3 source connector\\. Please install cocoindex\\[amazon_s3\\]\\.","errorType":"exception","errorClass":"ImportError","httpStatus":null,"severity":"error","filePath":"python/cocoindex/connectors/amazon_s3/_source.py","lineNumber":27,"sourceCode":"\nfrom __future__ import annotations\n\n__all__ = [\n    \"S3File\",\n    \"S3FilePath\",\n    \"S3Walker\",\n    \"get_object\",\n    \"list_objects\",\n    \"read\",\n]\n\nfrom pathlib import PurePath\nfrom typing import AsyncIterator, overload\n\ntry:\n    from aiobotocore.client import AioBaseClient  # type: ignore[import-untyped]\nexcept ImportError as e:\n    raise ImportError(\n        \"aiobotocore is required to use the Amazon S3 source connector. \"\n        \"Please install cocoindex[amazon_s3].\"\n    ) from e\n\nfrom cocoindex.resources import file\n\n\ndef _etag_to_fingerprint(etag: object) -> bytes | None:\n    \"\"\"Convert an S3 ETag (a ``str``) to the ``bytes`` content fingerprint.\n\n    botocore returns ETags as quoted strings (e.g. ``'\"d41d8cd9...\"'``), but\n    :class:`~cocoindex.resources.file.FileMetadata.content_fingerprint` is typed\n    ``bytes``.  Storing the raw ``str`` makes the memo state's\n    ``tuple[datetime, bytes]`` round-trip fail on re-run (msgspec encodes a str\n    but the decoder expects bin), so encode it to bytes here.\n    \"\"\"\n    return etag.encode(\"utf-8\") if isinstance(etag, str) else None\n","sourceCodeStart":9,"sourceCodeEnd":45,"githubUrl":"https://github.com/cocoindex-io/cocoindex/blob/e84aa99b3292c5270a4b313b2a7137ad9ce8ab3b/python/cocoindex/connectors/amazon_s3/_source.py#L9-L45","documentation":"The Amazon S3 source connector in cocoindex depends on aiobotocore for async S3 access. The connector module raises this ImportError at import time when aiobotocore is not installed, because it needs AioBaseClient to type and drive S3 calls. It is an intentional guard telling you to install the connector's optional dependency group.","triggerScenarios":"Importing or using anything from python/cocoindex/connectors/amazon_s3 (e.g. amazon_s3.get_object or its source connector) in an environment where aiobotocore is absent — typically after `pip install cocoindex` without the amazon_s3 extra.","commonSituations":"Fresh virtualenv or CI container with base cocoindex only; deploying to a slim Docker image that dropped the extra; switching machines and forgetting the extras install.","solutions":["Install the optional extra: `pip install cocoindex[amazon_s3]` (or `uv add cocoindex[amazon_s3]`).","If using uv/poetry, add `cocoindex[amazon_s3]` to the project dependencies, not plain cocoindex.","Verify with `python -c \"import aiobotocore\"` that the import now succeeds before loading the connector.","If you cannot install aiobotocore, use a source connector without the S3 dependency (e.g. localfs)."],"exampleFix":"# before\npip install cocoindex\nimport cocoindex.connectors.amazon_s3 as amazon_s3  # ImportError\n\n# after\npip install \"cocoindex[amazon_s3]\"\nimport cocoindex.connectors.amazon_s3 as amazon_s3  # ok","handlingStrategy":"validation","validationCode":"try:\n    import aiobotocore  # noqa: F401\nexcept ImportError:\n    raise SystemExit(\"Install the S3 extra: pip install 'cocoindex[amazon_s3]'\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always install connector extras together with cocoindex in requirements/pyproject.","Pin the extras in CI and Docker images.","Smoke-test imports of used connectors in CI."],"tags":["python","s3","dependency","import"],"backgroundTag":"missing-optional-dependency","analyzedSha":"e84aa99b3292c5270a4b313b2a7137ad9ce8ab3b","analyzedAt":"2026-09-08T15:59:19.997Z","contentChangedAt":"2026-09-08T15:59:19.997Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}