|
1 | 1 | from __future__ import annotations |
2 | 2 |
|
| 3 | +from importlib import metadata |
| 4 | +from typing import Any, Dict |
| 5 | + |
3 | 6 | from great_expectations.compatibility.not_imported import NotImported |
4 | 7 |
|
5 | 8 | BOTO_NOT_IMPORTED = NotImported( |
|
32 | 35 | except ImportError: |
33 | 36 | exceptions = BOTO_NOT_IMPORTED |
34 | 37 |
|
| 38 | + |
| 39 | +def _get_distribution_version() -> str: |
| 40 | + try: |
| 41 | + return metadata.version("great_expectations") |
| 42 | + except metadata.PackageNotFoundError: |
| 43 | + return "dev" |
| 44 | + |
| 45 | + |
| 46 | +def get_s3_boto3_options(boto3_options: Dict[str, Any]) -> Dict[str, Any]: |
| 47 | + """Return boto3 client options with a ``great-expectations`` agent suffix. |
| 48 | +
|
| 49 | + Works with Amazon S3 and any S3-compatible object store (for example |
| 50 | + Backblaze B2, Cloudflare R2, or MinIO). A caller-supplied ``config`` and |
| 51 | + ``endpoint_url`` are preserved; the suffix is appended to an existing agent |
| 52 | + string rather than replacing it. |
| 53 | + """ |
| 54 | + suffix = f"great-expectations/{_get_distribution_version()}" |
| 55 | + options = dict(boto3_options) |
| 56 | + |
| 57 | + if not Config: |
| 58 | + return options |
| 59 | + |
| 60 | + config = options.get("config") |
| 61 | + existing = getattr(config, "user_agent_extra", None) if config else None |
| 62 | + user_agent_extra = f"{existing} {suffix}" if existing else suffix |
| 63 | + |
| 64 | + if config: |
| 65 | + options["config"] = config.merge(Config(user_agent_extra=user_agent_extra)) |
| 66 | + else: |
| 67 | + options["config"] = Config(user_agent_extra=user_agent_extra) |
| 68 | + |
| 69 | + return options |
| 70 | + |
| 71 | + |
35 | 72 | try: |
36 | 73 | import sqlalchemy_redshift |
37 | 74 | except ImportError: |
|
0 commit comments