diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 807cb41..6cfc27b 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.8", "3.9", "3.10", "3.11"] + python-version: ["3.9", "3.10", "3.11"] steps: - uses: actions/checkout@v3 diff --git a/planetary_computer/__init__.py b/planetary_computer/__init__.py index 6088948..fc2990b 100644 --- a/planetary_computer/__init__.py +++ b/planetary_computer/__init__.py @@ -13,12 +13,14 @@ ) from planetary_computer.settings import set_subscription_key from planetary_computer._adlfs import get_adlfs_filesystem, get_container_client +from planetary_computer._obstore import get_obstore from planetary_computer.version import __version__ __all__ = [ "get_adlfs_filesystem", "get_container_client", + "get_obstore", "set_subscription_key", "sign_asset", "sign_assets", diff --git a/planetary_computer/_obstore.py b/planetary_computer/_obstore.py new file mode 100644 index 0000000..d0d9613 --- /dev/null +++ b/planetary_computer/_obstore.py @@ -0,0 +1,62 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +from planetary_computer.sas import get_token + +if TYPE_CHECKING: + import sys + + from obstore.store import ( + AzureConfig, + AzureCredentialProvider, + AzureSASToken, + AzureStore, + ClientConfig, + RetryConfig, + ) + + if sys.version_info >= (3, 11): + from typing import Unpack + else: + from typing_extensions import Unpack + + +def get_obstore( # type: ignore[misc] # overlap with kwargs + account_name: str, + container_name: str, + *, + prefix: str | None = None, + config: AzureConfig | None = None, + client_options: ClientConfig | None = None, + retry_config: RetryConfig | None = None, + credential_provider: AzureCredentialProvider | None = None, + **kwargs: Unpack[AzureConfig], # type: ignore # noqa +) -> AzureStore: + try: + import obstore + except ImportError as e: + raise ImportError( + "'planetary_computer.get_obstore_store' requires " + "the optional dependency 'obstore'." + ) from e + + def default_credential_provider() -> AzureSASToken: + token = get_token(account_name, container_name) + return { + "sas_token": token.token, + "expires_at": token.expiry, + } + + credential_provider = credential_provider or default_credential_provider + + return obstore.store.AzureStore( + account_name=account_name, + container_name=container_name, + prefix=prefix, + config=config, + client_options=client_options, + retry_config=retry_config, + credential_provider=credential_provider, + **kwargs, # type: ignore # (container_name key overlaps with positional arg) + ) diff --git a/pyproject.toml b/pyproject.toml index a2bbc21..eb99ff0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta" name = "planetary-computer" authors = [{name = "microsoft", email = "planetarycomputer@microsoft.com"}] description = "Planetary Computer SDK for Python" -requires-python = ">=3.7" +requires-python = ">=3.9" dependencies = [ "click>=7.1", "pydantic>=1.7.3", @@ -34,6 +34,7 @@ dev = [ "pytest", "responses", ] +obstore = ["obstore"] [project.scripts] planetarycomputer = "planetary_computer.scripts.cli:app" @@ -42,4 +43,4 @@ planetarycomputer = "planetary_computer.scripts.cli:app" include-package-data = false [tool.setuptools.dynamic] -version = {attr = "planetary_computer.version.__version__"} \ No newline at end of file +version = {attr = "planetary_computer.version.__version__"} diff --git a/scripts/cibuild b/scripts/cibuild index bd40609..e77ffc3 100755 --- a/scripts/cibuild +++ b/scripts/cibuild @@ -19,7 +19,7 @@ if [ "${BASH_SOURCE[0]}" = "${0}" ]; then else # Install/upgrade dependencies python -m pip install --upgrade pip - pip install -e .[adlfs,azure,dev] + pip install -e .[adlfs,azure,dev,obstore] ./scripts/test fi