cosmochains 0.0.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cosmochains-0.0.2/PKG-INFO +47 -0
- cosmochains-0.0.2/README.md +0 -0
- cosmochains-0.0.2/pyproject.toml +73 -0
- cosmochains-0.0.2/pyproject.toml.orig +59 -0
- cosmochains-0.0.2/src/cosmochains/__init__.py +152 -0
- cosmochains-0.0.2/src/cosmochains/backends/__init__.py +12 -0
- cosmochains-0.0.2/src/cosmochains/backends/base.py +108 -0
- cosmochains-0.0.2/src/cosmochains/backends/cache.py +24 -0
- cosmochains-0.0.2/src/cosmochains/backends/dropbox.py +268 -0
- cosmochains-0.0.2/src/cosmochains/backends/github.py +333 -0
- cosmochains-0.0.2/src/cosmochains/backends/googledrive.py +319 -0
- cosmochains-0.0.2/src/cosmochains/backends/huggingface.py +281 -0
- cosmochains-0.0.2/src/cosmochains/backends/huggingface_bucket.py +203 -0
- cosmochains-0.0.2/src/cosmochains/catalog.py +125 -0
- cosmochains-0.0.2/src/cosmochains/cli/__init__.py +0 -0
- cosmochains-0.0.2/src/cosmochains/cli/app.py +21 -0
- cosmochains-0.0.2/src/cosmochains/cli/commands/__init__.py +2 -0
- cosmochains-0.0.2/src/cosmochains/cli/commands/delete.py +41 -0
- cosmochains-0.0.2/src/cosmochains/cli/commands/download.py +42 -0
- cosmochains-0.0.2/src/cosmochains/cli/commands/info.py +60 -0
- cosmochains-0.0.2/src/cosmochains/cli/commands/initialize.py +46 -0
- cosmochains-0.0.2/src/cosmochains/cli/commands/list.py +56 -0
- cosmochains-0.0.2/src/cosmochains/cli/commands/upload.py +337 -0
- cosmochains-0.0.2/src/cosmochains/cli/options.py +30 -0
- cosmochains-0.0.2/src/cosmochains/config.py +105 -0
- cosmochains-0.0.2/src/cosmochains/local.py +93 -0
- cosmochains-0.0.2/src/cosmochains/models.py +266 -0
- cosmochains-0.0.2/src/cosmochains/py.typed +0 -0
- cosmochains-0.0.2/src/cosmochains/readers/__init__.py +200 -0
- cosmochains-0.0.2/src/cosmochains/readers/base.py +100 -0
- cosmochains-0.0.2/src/cosmochains/readers/cobaya_.py +78 -0
- cosmochains-0.0.2/src/cosmochains/readers/getdist_.py +90 -0
- cosmochains-0.0.2/src/cosmochains/readers/hdf5.py +110 -0
- cosmochains-0.0.2/src/cosmochains/readers/montepython_.py +58 -0
- cosmochains-0.0.2/src/cosmochains/readers/numpy_.py +68 -0
- cosmochains-0.0.2/src/cosmochains/readers/zarr_.py +52 -0
- cosmochains-0.0.2/src/cosmochains/stats.py +70 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: cosmochains
|
|
3
|
+
Version: 0.0.2
|
|
4
|
+
Summary: Cloud-based MCMC chain repository manager
|
|
5
|
+
Author: Rodrigo Calderon
|
|
6
|
+
Author-email: Rodrigo Calderon <calderon.cosmology@gmail.com>
|
|
7
|
+
Requires-Dist: numpy>=1.26
|
|
8
|
+
Requires-Dist: pydantic>=2.7
|
|
9
|
+
Requires-Dist: pyyaml>=6.0
|
|
10
|
+
Requires-Dist: typer>=0.12
|
|
11
|
+
Requires-Dist: rich>=13.0
|
|
12
|
+
Requires-Dist: shellingham>=1.5
|
|
13
|
+
Requires-Dist: tomli-w>=1.0
|
|
14
|
+
Requires-Dist: huggingface-hub>=0.23 ; extra == 'all-backends'
|
|
15
|
+
Requires-Dist: python-dotenv>=1.0 ; extra == 'all-backends'
|
|
16
|
+
Requires-Dist: h5py>=3.10 ; extra == 'all-backends'
|
|
17
|
+
Requires-Dist: pygithub>=2.1 ; extra == 'all-backends'
|
|
18
|
+
Requires-Dist: google-api-python-client>=2.100 ; extra == 'all-backends'
|
|
19
|
+
Requires-Dist: google-auth>=2.20 ; extra == 'all-backends'
|
|
20
|
+
Requires-Dist: dropbox>=12.0 ; extra == 'all-backends'
|
|
21
|
+
Requires-Dist: pytest>=8.0 ; extra == 'dev'
|
|
22
|
+
Requires-Dist: pytest-mock>=3.14 ; extra == 'dev'
|
|
23
|
+
Requires-Dist: mkdocs-material>=9.5 ; extra == 'docs'
|
|
24
|
+
Requires-Dist: mkdocstrings[python]>=0.25 ; extra == 'docs'
|
|
25
|
+
Requires-Dist: dropbox>=12.0 ; extra == 'dropbox'
|
|
26
|
+
Requires-Dist: getdist>=1.4 ; extra == 'getdist'
|
|
27
|
+
Requires-Dist: pygithub>=2.1 ; extra == 'github'
|
|
28
|
+
Requires-Dist: google-api-python-client>=2.100 ; extra == 'google-drive'
|
|
29
|
+
Requires-Dist: google-auth>=2.20 ; extra == 'google-drive'
|
|
30
|
+
Requires-Dist: h5py>=3.10 ; extra == 'hdf5'
|
|
31
|
+
Requires-Dist: huggingface-hub>=0.23 ; extra == 'hf'
|
|
32
|
+
Requires-Dist: python-dotenv>=1.0 ; extra == 'hf'
|
|
33
|
+
Requires-Dist: h5py>=3.10 ; extra == 'hf'
|
|
34
|
+
Requires-Dist: zarr>=2.18 ; extra == 'zarr'
|
|
35
|
+
Requires-Python: >=3.12
|
|
36
|
+
Provides-Extra: all-backends
|
|
37
|
+
Provides-Extra: dev
|
|
38
|
+
Provides-Extra: docs
|
|
39
|
+
Provides-Extra: dropbox
|
|
40
|
+
Provides-Extra: getdist
|
|
41
|
+
Provides-Extra: github
|
|
42
|
+
Provides-Extra: google-drive
|
|
43
|
+
Provides-Extra: hdf5
|
|
44
|
+
Provides-Extra: hf
|
|
45
|
+
Provides-Extra: zarr
|
|
46
|
+
Description-Content-Type: text/markdown
|
|
47
|
+
|
|
File without changes
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "cosmochains"
|
|
3
|
+
version = "0.0.2"
|
|
4
|
+
description = "Cloud-based MCMC chain repository manager"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.12"
|
|
7
|
+
dependencies = [
|
|
8
|
+
"numpy>=1.26",
|
|
9
|
+
"pydantic>=2.7",
|
|
10
|
+
"pyyaml>=6.0",
|
|
11
|
+
"typer>=0.12",
|
|
12
|
+
"rich>=13.0",
|
|
13
|
+
"shellingham>=1.5",
|
|
14
|
+
"tomli-w>=1.0",
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
[[project.authors]]
|
|
18
|
+
name = "Rodrigo Calderon"
|
|
19
|
+
email = "calderon.cosmology@gmail.com"
|
|
20
|
+
|
|
21
|
+
[project.optional-dependencies]
|
|
22
|
+
hf = [
|
|
23
|
+
"huggingface-hub>=0.23",
|
|
24
|
+
"python-dotenv>=1.0",
|
|
25
|
+
"h5py>=3.10",
|
|
26
|
+
]
|
|
27
|
+
hdf5 = ["h5py>=3.10"]
|
|
28
|
+
zarr = ["zarr>=2.18"]
|
|
29
|
+
getdist = ["getdist>=1.4"]
|
|
30
|
+
github = ["PyGithub>=2.1"]
|
|
31
|
+
google-drive = [
|
|
32
|
+
"google-api-python-client>=2.100",
|
|
33
|
+
"google-auth>=2.20",
|
|
34
|
+
]
|
|
35
|
+
dropbox = ["dropbox>=12.0"]
|
|
36
|
+
all-backends = [
|
|
37
|
+
"huggingface-hub>=0.23",
|
|
38
|
+
"python-dotenv>=1.0",
|
|
39
|
+
"h5py>=3.10",
|
|
40
|
+
"PyGithub>=2.1",
|
|
41
|
+
"google-api-python-client>=2.100",
|
|
42
|
+
"google-auth>=2.20",
|
|
43
|
+
"dropbox>=12.0",
|
|
44
|
+
]
|
|
45
|
+
dev = [
|
|
46
|
+
"pytest>=8.0",
|
|
47
|
+
"pytest-mock>=3.14",
|
|
48
|
+
]
|
|
49
|
+
docs = [
|
|
50
|
+
"mkdocs-material>=9.5",
|
|
51
|
+
"mkdocstrings[python]>=0.25",
|
|
52
|
+
]
|
|
53
|
+
|
|
54
|
+
[project.scripts]
|
|
55
|
+
cosmochains = "cosmochains.cli.app:main"
|
|
56
|
+
|
|
57
|
+
[build-system]
|
|
58
|
+
requires = ["uv_build>=0.9.9,<0.10.0"]
|
|
59
|
+
build-backend = "uv_build"
|
|
60
|
+
|
|
61
|
+
[tool.pytest.ini_options]
|
|
62
|
+
markers = [
|
|
63
|
+
"integration: requires credentials and network access",
|
|
64
|
+
"integration_github: GitHub integration tests",
|
|
65
|
+
"integration_googledrive: Google Drive integration tests",
|
|
66
|
+
"integration_dropbox: Dropbox integration tests",
|
|
67
|
+
]
|
|
68
|
+
|
|
69
|
+
[dependency-groups]
|
|
70
|
+
dev = [
|
|
71
|
+
"jupyter>=1.1.1",
|
|
72
|
+
"nbconvert>=7.17.1",
|
|
73
|
+
]
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "cosmochains"
|
|
3
|
+
version = "0.0.2"
|
|
4
|
+
description = "Cloud-based MCMC chain repository manager"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
authors = [
|
|
7
|
+
{ name = "Rodrigo Calderon", email = "calderon.cosmology@gmail.com" }
|
|
8
|
+
]
|
|
9
|
+
requires-python = ">=3.12"
|
|
10
|
+
dependencies = [
|
|
11
|
+
"numpy>=1.26",
|
|
12
|
+
"pydantic>=2.7",
|
|
13
|
+
"pyyaml>=6.0",
|
|
14
|
+
"typer>=0.12",
|
|
15
|
+
"rich>=13.0",
|
|
16
|
+
"shellingham>=1.5",
|
|
17
|
+
"tomli-w>=1.0",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
[project.optional-dependencies]
|
|
21
|
+
hf = ["huggingface-hub>=0.23", "python-dotenv>=1.0", "h5py>=3.10"]
|
|
22
|
+
hdf5 = ["h5py>=3.10"]
|
|
23
|
+
zarr = ["zarr>=2.18"]
|
|
24
|
+
getdist = ["getdist>=1.4"]
|
|
25
|
+
github = ["PyGithub>=2.1"]
|
|
26
|
+
google-drive = ["google-api-python-client>=2.100", "google-auth>=2.20"]
|
|
27
|
+
dropbox = ["dropbox>=12.0"]
|
|
28
|
+
all-backends = [
|
|
29
|
+
"huggingface-hub>=0.23",
|
|
30
|
+
"python-dotenv>=1.0",
|
|
31
|
+
"h5py>=3.10",
|
|
32
|
+
"PyGithub>=2.1",
|
|
33
|
+
"google-api-python-client>=2.100",
|
|
34
|
+
"google-auth>=2.20",
|
|
35
|
+
"dropbox>=12.0",
|
|
36
|
+
]
|
|
37
|
+
dev = ["pytest>=8.0", "pytest-mock>=3.14"]
|
|
38
|
+
docs = ["mkdocs-material>=9.5", "mkdocstrings[python]>=0.25"]
|
|
39
|
+
|
|
40
|
+
[project.scripts]
|
|
41
|
+
cosmochains = "cosmochains.cli.app:main"
|
|
42
|
+
|
|
43
|
+
[build-system]
|
|
44
|
+
requires = ["uv_build>=0.9.9,<0.10.0"]
|
|
45
|
+
build-backend = "uv_build"
|
|
46
|
+
|
|
47
|
+
[tool.pytest.ini_options]
|
|
48
|
+
markers = [
|
|
49
|
+
"integration: requires credentials and network access",
|
|
50
|
+
"integration_github: GitHub integration tests",
|
|
51
|
+
"integration_googledrive: Google Drive integration tests",
|
|
52
|
+
"integration_dropbox: Dropbox integration tests",
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
[dependency-groups]
|
|
56
|
+
dev = [
|
|
57
|
+
"jupyter>=1.1.1",
|
|
58
|
+
"nbconvert>=7.17.1",
|
|
59
|
+
]
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import concurrent.futures
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
import numpy as np
|
|
7
|
+
|
|
8
|
+
from .backends.base import ChainBackend
|
|
9
|
+
from .catalog import resolve_name
|
|
10
|
+
from .config import get_default_backend
|
|
11
|
+
from .local import read
|
|
12
|
+
from .models import Chain, ChainArrays, ChainMetadata
|
|
13
|
+
from .readers import get_reader, read_from_zip
|
|
14
|
+
from .stats import Stats, marginal_stats
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _backend(backend: ChainBackend | None) -> ChainBackend:
|
|
18
|
+
return backend if backend is not None else get_default_backend()
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def load_chain(
|
|
22
|
+
name: str | list[str],
|
|
23
|
+
backend: ChainBackend | None = None,
|
|
24
|
+
) -> Chain | dict[str, Chain]:
|
|
25
|
+
"""Download and return one or more chains by name.
|
|
26
|
+
|
|
27
|
+
When *name* is a list the chains are fetched concurrently and returned as
|
|
28
|
+
a ``{name: Chain}`` mapping. When *name* is a string a single
|
|
29
|
+
:class:`~cosmochains.models.Chain` is returned.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
name: Chain name or list of chain names as registered in the catalog.
|
|
33
|
+
backend: Backend instance to use. Falls back to
|
|
34
|
+
:func:`~cosmochains.config.get_default_backend` when ``None``.
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
A single :class:`~cosmochains.models.Chain` or a ``dict[str, Chain]``
|
|
38
|
+
when *name* is a list.
|
|
39
|
+
|
|
40
|
+
Raises:
|
|
41
|
+
KeyError: If *name* is not found in the catalog.
|
|
42
|
+
RuntimeError: If no backend is configured and environment variables are
|
|
43
|
+
missing.
|
|
44
|
+
|
|
45
|
+
Example:
|
|
46
|
+
>>> import os
|
|
47
|
+
>>> os.environ["COSMOCHAINS_REPO"] = "myorg/my-chains"
|
|
48
|
+
>>> from cosmochains import load_chain
|
|
49
|
+
>>> chain = load_chain("planck2018_TTTEEE")
|
|
50
|
+
>>> chain.samples.shape
|
|
51
|
+
(5000, 6)
|
|
52
|
+
"""
|
|
53
|
+
b = _backend(backend)
|
|
54
|
+
if isinstance(name, list):
|
|
55
|
+
with concurrent.futures.ThreadPoolExecutor() as pool:
|
|
56
|
+
futures = {n: pool.submit(_load_one, n, b) for n in name}
|
|
57
|
+
return {n: f.result() for n, f in futures.items()}
|
|
58
|
+
return _load_one(name, b)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def _load_one(name: str, backend: ChainBackend) -> Chain:
|
|
62
|
+
path = backend.download(name)
|
|
63
|
+
catalog = backend.get_catalog()
|
|
64
|
+
entry = resolve_name(name, catalog)
|
|
65
|
+
fmt = entry.get("format", "hdf5")
|
|
66
|
+
if fmt in ("hdf5", "h5"):
|
|
67
|
+
from .readers.hdf5 import read_hdf5
|
|
68
|
+
|
|
69
|
+
return read_hdf5(path)
|
|
70
|
+
arrays = _read_arrays(path, fmt)
|
|
71
|
+
metadata = ChainMetadata.model_validate(backend.download_metadata(name))
|
|
72
|
+
return arrays.to_chain(metadata)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def _read_arrays(path: Path, fmt: str) -> ChainArrays:
|
|
76
|
+
if fmt in ("getdist", "zarr"):
|
|
77
|
+
return read_from_zip(path, fmt)
|
|
78
|
+
return get_reader(path).read(path)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def list_chains(backend: ChainBackend | None = None) -> list[str]:
|
|
82
|
+
"""Return the names of all chains registered in the catalog.
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
backend: Backend instance to use. Falls back to
|
|
86
|
+
:func:`~cosmochains.config.get_default_backend` when ``None``.
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
Sorted list of chain name strings.
|
|
90
|
+
"""
|
|
91
|
+
return _backend(backend).list_chains()
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def get_metadata(name: str, backend: ChainBackend | None = None) -> ChainMetadata:
|
|
95
|
+
"""Fetch and return the metadata for a single chain without loading its arrays.
|
|
96
|
+
|
|
97
|
+
Uses the lightweight :meth:`~cosmochains.backends.base.ChainBackend.download_metadata`
|
|
98
|
+
path — no chain file is downloaded.
|
|
99
|
+
|
|
100
|
+
Args:
|
|
101
|
+
name: Chain name as registered in the catalog.
|
|
102
|
+
backend: Backend instance to use. Falls back to
|
|
103
|
+
:func:`~cosmochains.config.get_default_backend` when ``None``.
|
|
104
|
+
|
|
105
|
+
Returns:
|
|
106
|
+
:class:`~cosmochains.models.ChainMetadata` for the requested chain.
|
|
107
|
+
"""
|
|
108
|
+
b = _backend(backend)
|
|
109
|
+
return ChainMetadata.model_validate(b.download_metadata(name))
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def load_samples(name: str, backend: ChainBackend | None = None) -> np.ndarray:
|
|
113
|
+
"""Download a chain and return its sample array.
|
|
114
|
+
|
|
115
|
+
Args:
|
|
116
|
+
name: Chain name as registered in the catalog.
|
|
117
|
+
backend: Backend instance to use. Falls back to
|
|
118
|
+
:func:`~cosmochains.config.get_default_backend` when ``None``.
|
|
119
|
+
|
|
120
|
+
Returns:
|
|
121
|
+
NumPy array of shape ``(n_samples, n_params)``.
|
|
122
|
+
"""
|
|
123
|
+
return load_chain(name, backend=backend).samples
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def load_weights(name: str, backend: ChainBackend | None = None) -> np.ndarray:
|
|
127
|
+
"""Download a chain and return its importance weights.
|
|
128
|
+
|
|
129
|
+
Args:
|
|
130
|
+
name: Chain name as registered in the catalog.
|
|
131
|
+
backend: Backend instance to use. Falls back to
|
|
132
|
+
:func:`~cosmochains.config.get_default_backend` when ``None``.
|
|
133
|
+
|
|
134
|
+
Returns:
|
|
135
|
+
NumPy array of shape ``(n_samples,)``.
|
|
136
|
+
"""
|
|
137
|
+
return load_chain(name, backend=backend).weights
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
__all__ = [
|
|
141
|
+
"read",
|
|
142
|
+
"marginal_stats",
|
|
143
|
+
"Stats",
|
|
144
|
+
"load_chain",
|
|
145
|
+
"list_chains",
|
|
146
|
+
"get_metadata",
|
|
147
|
+
"load_samples",
|
|
148
|
+
"load_weights",
|
|
149
|
+
"Chain",
|
|
150
|
+
"ChainMetadata",
|
|
151
|
+
"ChainBackend",
|
|
152
|
+
]
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from .base import ChainBackend
|
|
2
|
+
from .huggingface import HuggingFaceBackend
|
|
3
|
+
from .huggingface_bucket import HuggingFaceBucketBackend
|
|
4
|
+
|
|
5
|
+
__all__ = ["ChainBackend", "HuggingFaceBackend", "HuggingFaceBucketBackend"]
|
|
6
|
+
|
|
7
|
+
from typing import TYPE_CHECKING
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from .dropbox import DropboxBackend
|
|
11
|
+
from .github import GitHubBackend
|
|
12
|
+
from .googledrive import GoogleDriveBackend
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
from typing import Protocol, runtime_checkable
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
@runtime_checkable
|
|
6
|
+
class ChainBackend(Protocol):
|
|
7
|
+
"""Structural protocol that all storage backends must satisfy.
|
|
8
|
+
|
|
9
|
+
Implementations are duck-typed: any class that provides all methods below
|
|
10
|
+
is a valid backend regardless of inheritance.
|
|
11
|
+
|
|
12
|
+
Built-in implementations:
|
|
13
|
+
|
|
14
|
+
- :class:`~cosmochains.backends.huggingface.HuggingFaceBackend` —
|
|
15
|
+
HuggingFace dataset repository (Git-backed, atomic uploads).
|
|
16
|
+
- :class:`~cosmochains.backends.huggingface_bucket.HuggingFaceBucketBackend`
|
|
17
|
+
— HuggingFace S3-compatible bucket (non-atomic, no versioning).
|
|
18
|
+
- :class:`~cosmochains.backends.github.GitHubBackend` —
|
|
19
|
+
dedicated branch of a GitHub repository (atomic uploads via Git Data API;
|
|
20
|
+
100 MB per-file limit). Requires ``cosmochains[github]``.
|
|
21
|
+
- :class:`~cosmochains.backends.googledrive.GoogleDriveBackend` —
|
|
22
|
+
Google Drive folder (non-atomic; deleted files go to trash). Requires
|
|
23
|
+
``cosmochains[google-drive]``.
|
|
24
|
+
- :class:`~cosmochains.backends.dropbox.DropboxBackend` —
|
|
25
|
+
Dropbox folder path (non-atomic; chunked upload for files > 150 MB).
|
|
26
|
+
Requires ``cosmochains[dropbox]``.
|
|
27
|
+
|
|
28
|
+
Select a backend at runtime via the ``COSMOCHAINS_BACKEND`` environment
|
|
29
|
+
variable or the ``--backend`` CLI flag. Auth tokens can be set with the
|
|
30
|
+
generic ``COSMOCHAINS_TOKEN`` variable or backend-specific variables
|
|
31
|
+
(``HF_TOKEN``, ``GITHUB_TOKEN``, ``GOOGLE_APPLICATION_CREDENTIALS``,
|
|
32
|
+
``DROPBOX_REFRESH_TOKEN`` + key/secret).
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
def download(self, name: str) -> Path:
|
|
36
|
+
"""Download a chain file and return its local cache path.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
name: Chain name as registered in the catalog.
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
:class:`pathlib.Path` to the cached local file.
|
|
43
|
+
"""
|
|
44
|
+
...
|
|
45
|
+
|
|
46
|
+
def upload(self, name: str, local_path: Path, metadata: dict) -> None:
|
|
47
|
+
"""Upload a chain file and its metadata YAML to the remote store.
|
|
48
|
+
|
|
49
|
+
Args:
|
|
50
|
+
name: Chain name to register in the remote catalog.
|
|
51
|
+
local_path: Local file to upload.
|
|
52
|
+
metadata: Metadata dict that will be serialized as YAML alongside
|
|
53
|
+
the chain file.
|
|
54
|
+
"""
|
|
55
|
+
...
|
|
56
|
+
|
|
57
|
+
def download_metadata(self, name: str) -> dict:
|
|
58
|
+
"""Fetch and return the metadata dict for *name*.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
name: Chain name as registered in the catalog.
|
|
62
|
+
|
|
63
|
+
Returns:
|
|
64
|
+
Raw metadata dict loaded from the YAML sidecar file.
|
|
65
|
+
"""
|
|
66
|
+
...
|
|
67
|
+
|
|
68
|
+
def list_chains(self) -> list[str]:
|
|
69
|
+
"""Return the names of all concrete chains in the remote catalog.
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
List of chain name strings (aliases excluded).
|
|
73
|
+
"""
|
|
74
|
+
...
|
|
75
|
+
|
|
76
|
+
def get_catalog(self) -> dict:
|
|
77
|
+
"""Fetch and return the full catalog from the remote store.
|
|
78
|
+
|
|
79
|
+
Returns:
|
|
80
|
+
Catalog dict; empty dict when the catalog does not yet exist.
|
|
81
|
+
"""
|
|
82
|
+
...
|
|
83
|
+
|
|
84
|
+
def update_catalog(self, catalog: dict) -> None:
|
|
85
|
+
"""Write *catalog* back to the remote store, replacing the current version.
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
catalog: Complete catalog dict to persist.
|
|
89
|
+
"""
|
|
90
|
+
...
|
|
91
|
+
|
|
92
|
+
def delete(self, name: str) -> None:
|
|
93
|
+
"""Delete a chain's files and metadata from the remote store.
|
|
94
|
+
|
|
95
|
+
Also removes any catalog aliases that point to *name*.
|
|
96
|
+
|
|
97
|
+
Args:
|
|
98
|
+
name: Chain name as registered in the catalog.
|
|
99
|
+
"""
|
|
100
|
+
...
|
|
101
|
+
|
|
102
|
+
def create_repo(self, *, private: bool = False) -> None:
|
|
103
|
+
"""Create the remote repository or bucket if it does not already exist.
|
|
104
|
+
|
|
105
|
+
Args:
|
|
106
|
+
private: If ``True``, create a private repository/bucket.
|
|
107
|
+
"""
|
|
108
|
+
...
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import hashlib
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def cache_path(backend_key: str, repo_id: str, relative: str) -> Path:
|
|
8
|
+
"""Return a local cache path for a remote file, creating parent dirs as needed.
|
|
9
|
+
|
|
10
|
+
Args:
|
|
11
|
+
backend_key: Short identifier for the backend (e.g. ``"github"``).
|
|
12
|
+
repo_id: Repository / folder identifier used to namespace the cache.
|
|
13
|
+
relative: Relative file path within the remote store
|
|
14
|
+
(e.g. ``"chains/run1/chain.hdf5"``).
|
|
15
|
+
|
|
16
|
+
Returns:
|
|
17
|
+
Absolute :class:`pathlib.Path` inside
|
|
18
|
+
``~/.cache/cosmochains/<backend_key>/<hash>/``.
|
|
19
|
+
Parent directories are created automatically.
|
|
20
|
+
"""
|
|
21
|
+
safe = hashlib.sha256(repo_id.encode()).hexdigest()[:16]
|
|
22
|
+
p = Path.home() / ".cache" / "cosmochains" / backend_key / safe / relative
|
|
23
|
+
p.parent.mkdir(parents=True, exist_ok=True)
|
|
24
|
+
return p
|