esgpull 0.9.1__py3-none-any.whl → 0.9.3__py3-none-any.whl

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.
esgpull/context.py CHANGED
@@ -7,6 +7,7 @@ from collections.abc import AsyncIterator, Callable, Coroutine, Sequence
7
7
  from dataclasses import dataclass, field
8
8
  from datetime import datetime
9
9
  from typing import Any, TypeAlias, TypeVar
10
+ from urllib.parse import urlparse
10
11
 
11
12
  if sys.version_info < (3, 11):
12
13
  from exceptiongroup import BaseExceptionGroup
@@ -18,10 +19,14 @@ from esgpull.config import Config
18
19
  from esgpull.exceptions import SolrUnstableQueryError
19
20
  from esgpull.models import DatasetRecord, File, Query
20
21
  from esgpull.tui import logger
21
- from esgpull.utils import format_date_iso, index2url, sync
22
+ from esgpull.utils import format_date_iso, sync
22
23
 
23
24
  # workaround for notebooks with running event loop
24
- if asyncio.get_event_loop().is_running():
25
+ try:
26
+ asyncio.get_running_loop()
27
+ except RuntimeError:
28
+ pass
29
+ else:
25
30
  import nest_asyncio
26
31
 
27
32
  nest_asyncio.apply()
@@ -39,6 +44,39 @@ DangerousFacets = {
39
44
  }
40
45
 
41
46
 
47
+ @dataclass
48
+ class IndexNode:
49
+ value: str
50
+
51
+ def is_bridge(self) -> bool:
52
+ return "esgf-1-5-bridge" in self.value
53
+
54
+ @property
55
+ def url(self) -> str:
56
+ parsed = urlparse(self.value)
57
+ result: str
58
+ match (parsed.scheme, parsed.netloc, parsed.path, self.is_bridge()):
59
+ case ("", "", path, True):
60
+ result = "https://" + parsed.path
61
+ case ("", "", path, False):
62
+ result = "https://" + parsed.path + "/esg-search/search"
63
+ case _:
64
+ result = self.value
65
+ if "." not in result:
66
+ raise ValueError(self.value)
67
+ return result
68
+
69
+
70
+ def quote_str(s: str) -> str:
71
+ if "*" in s:
72
+ # don't quote when `*` is present, quotes enforce exact match
73
+ return s
74
+ elif not s.startswith('"') and not s.endswith('"'):
75
+ return f'"{s}"'
76
+ else:
77
+ return s
78
+
79
+
42
80
  @dataclass
43
81
  class Result:
44
82
  query: Query
@@ -70,12 +108,12 @@ class Result:
70
108
  "format": "application/solr+json",
71
109
  # "from": self.since,
72
110
  }
73
- if index_url is None:
74
- index_url = index2url(index_node)
75
- if fields_param is not None:
76
- params["fields"] = ",".join(fields_param)
77
- else:
78
- params["fields"] = "instance_id"
111
+ index = IndexNode(value=index_url or index_node)
112
+ if not index.is_bridge():
113
+ if fields_param is not None:
114
+ params["fields"] = ",".join(fields_param)
115
+ else:
116
+ params["fields"] = "instance_id"
79
117
  if date_from is not None:
80
118
  params["from"] = format_date_iso(date_from)
81
119
  if date_to is not None:
@@ -95,21 +133,29 @@ class Result:
95
133
  # query["end"] = format_date_iso(str(facets.pop("end")))
96
134
  solr_terms: list[str] = []
97
135
  for name, values in self.query.selection.items():
98
- value_term = " ".join(values)
136
+ if index.is_bridge():
137
+ value_term = " ".join(quote_str(v) for v in values)
138
+ else:
139
+ value_term = " ".join(values)
99
140
  if name == "query": # freetext case
100
141
  solr_terms.append(value_term)
101
142
  else:
102
143
  if len(values) > 1:
103
144
  value_term = f"({value_term})"
104
- solr_terms.append(f"{name}:{value_term}")
145
+ if name.startswith("!"):
146
+ solr_terms.append(f"NOT ({name[1:]}:{value_term})")
147
+ else:
148
+ solr_terms.append(f"{name}:{value_term}")
105
149
  if solr_terms:
106
150
  params["query"] = " AND ".join(solr_terms)
107
151
  for name, option in self.query.options.items(use_default=True):
108
152
  if option.is_bool():
109
153
  params[name] = option.name
154
+ if index.is_bridge():
155
+ _ = params.pop("retracted", None) # not supported in bridge API
110
156
  if params.get("distrib") == "true" and facets_star:
111
157
  raise SolrUnstableQueryError(pretty_repr(self.query))
112
- self.request = Request("GET", index_url, params=params)
158
+ self.request = Request("GET", index.url, params=params)
113
159
 
114
160
  def to(self, subtype: type[RT]) -> RT:
115
161
  result: RT = subtype(self.query, self.file)
@@ -478,6 +524,8 @@ class Context:
478
524
  result.process()
479
525
  if result.processed:
480
526
  hits.append(result.data)
527
+ else:
528
+ hits.append(0)
481
529
  return hits
482
530
 
483
531
  async def _hints(self, *results: ResultHints) -> list[HintsDict]:
@@ -727,3 +775,13 @@ class Context:
727
775
  date_to=date_to,
728
776
  keep_duplicates=keep_duplicates,
729
777
  )
778
+
779
+ def probe(self, index_node: str | None = None) -> None:
780
+ noraise = self.noraise
781
+ self.noraise = False
782
+ _ = self.hits(
783
+ Query(),
784
+ file=True,
785
+ index_node=index_node or self.config.api.index_node,
786
+ )
787
+ self.noraise = noraise
esgpull/esgpull.py CHANGED
@@ -22,7 +22,6 @@ from rich.progress import (
22
22
  TransferSpeedColumn,
23
23
  )
24
24
 
25
- from esgpull.auth import Auth, Credentials
26
25
  from esgpull.config import Config
27
26
  from esgpull.context import Context
28
27
  from esgpull.database import Database
@@ -64,7 +63,6 @@ class Esgpull:
64
63
  path: Path
65
64
  config: Config
66
65
  ui: UI
67
- auth: Auth
68
66
  db: Database
69
67
  context: Context
70
68
  fs: Filesystem
@@ -120,8 +118,6 @@ class Esgpull:
120
118
  verbosity=verbosity,
121
119
  record=record,
122
120
  )
123
- credentials = Credentials.from_config(self.config)
124
- self.auth = Auth.from_config(self.config, credentials)
125
121
  self.context = Context(self.config, noraise=True)
126
122
  if load_db:
127
123
  self.db = Database.from_config(self.config)
@@ -431,7 +427,6 @@ class Esgpull:
431
427
  start_callbacks[file.sha] = [callback]
432
428
  processor = Processor(
433
429
  config=self.config,
434
- auth=self.auth,
435
430
  fs=self.fs,
436
431
  files=queue,
437
432
  start_callbacks=start_callbacks,
@@ -0,0 +1,28 @@
1
+ """update tables
2
+
3
+ Revision ID: 0.9.2
4
+ Revises: 0.9.1
5
+ Create Date: 2025-09-04 16:56:29.263007
6
+
7
+ """
8
+ from alembic import op
9
+ import sqlalchemy as sa
10
+
11
+
12
+ # revision identifiers, used by Alembic.
13
+ revision = '0.9.2'
14
+ down_revision = '0.9.1'
15
+ branch_labels = None
16
+ depends_on = None
17
+
18
+
19
+ def upgrade() -> None:
20
+ # ### commands auto generated by Alembic - please adjust! ###
21
+ pass
22
+ # ### end Alembic commands ###
23
+
24
+
25
+ def downgrade() -> None:
26
+ # ### commands auto generated by Alembic - please adjust! ###
27
+ pass
28
+ # ### end Alembic commands ###
@@ -0,0 +1,28 @@
1
+ """update tables
2
+
3
+ Revision ID: 0.9.3
4
+ Revises: 0.9.2
5
+ Create Date: 2025-11-18 15:40:35.122823
6
+
7
+ """
8
+ from alembic import op
9
+ import sqlalchemy as sa
10
+
11
+
12
+ # revision identifiers, used by Alembic.
13
+ revision = '0.9.3'
14
+ down_revision = '0.9.2'
15
+ branch_labels = None
16
+ depends_on = None
17
+
18
+
19
+ def upgrade() -> None:
20
+ # ### commands auto generated by Alembic - please adjust! ###
21
+ pass
22
+ # ### end Alembic commands ###
23
+
24
+
25
+ def downgrade() -> None:
26
+ # ### commands auto generated by Alembic - please adjust! ###
27
+ pass
28
+ # ### end Alembic commands ###
esgpull/plugin.py CHANGED
@@ -12,9 +12,9 @@ from typing import Any, Callable, Literal
12
12
 
13
13
  import tomlkit
14
14
  from packaging import version
15
+ from pydantic import TypeAdapter
15
16
 
16
17
  import esgpull.models
17
- from esgpull.config import cast_value
18
18
  from esgpull.tui import logger
19
19
  from esgpull.version import __version__
20
20
 
@@ -151,7 +151,11 @@ class PluginConfig:
151
151
  enabled: set[str] = field(default_factory=set)
152
152
  disabled: set[str] = field(default_factory=set)
153
153
  plugins: dict[str, dict[str, Any]] = field(default_factory=dict)
154
- _raw: dict[str, dict[str, Any]] = field(default_factory=dict)
154
+ _raw: tomlkit.TOMLDocument = field(default_factory=tomlkit.TOMLDocument)
155
+
156
+ def __post_init__(self):
157
+ if "plugins" not in self._raw:
158
+ self._raw["plugins"] = {}
155
159
 
156
160
 
157
161
  class PluginManager:
@@ -199,12 +203,13 @@ class PluginManager:
199
203
 
200
204
  try:
201
205
  with open(self.config_path, "r") as f:
202
- raw = tomlkit.parse(f.read())
203
- self.config.enabled = set(raw.get("enabled", []))
204
- self.config.disabled = set(raw.get("disabled", []))
205
- self.config.plugins = raw.get("plugins", {})
206
- # Store the raw plugin configuration to preserve what's on disk
207
- self.config._raw = dict(raw.get("plugins", {}))
206
+ raw = tomlkit.load(f)
207
+ unwrap = raw.unwrap()
208
+ self.config.enabled = set(unwrap.get("enabled", []))
209
+ self.config.disabled = set(unwrap.get("disabled", []))
210
+ self.config.plugins = unwrap.get("plugins", {})
211
+ # Store the raw plugin configuration to preserve what's on disk
212
+ self.config._raw = raw
208
213
  except Exception as e:
209
214
  logger.error(f"Failed to load plugin config: {e}")
210
215
 
@@ -219,18 +224,16 @@ class PluginManager:
219
224
  return
220
225
 
221
226
  try:
222
- doc = tomlkit.document()
227
+ doc = self.config._raw
223
228
  doc["enabled"] = list(self.config.enabled)
224
229
  doc["disabled"] = list(self.config.disabled)
225
230
 
226
231
  # For plugins section, handle differently based on generate_full_config flag
227
232
  if generate_full_config:
228
233
  doc["plugins"] = self.config.plugins
229
- else:
230
- doc["plugins"] = self.config._raw
231
234
 
232
235
  with open(self.config_path, "w") as f:
233
- f.write(tomlkit.dumps(doc))
236
+ tomlkit.dump(doc, f)
234
237
  except Exception as e:
235
238
  logger.error(f"Failed to save plugin config: {e}")
236
239
 
@@ -464,16 +467,17 @@ class PluginManager:
464
467
  # Make sure plugin exists in both plugins and _raw dicts
465
468
  if plugin_name not in self.config.plugins:
466
469
  self.config.plugins[plugin_name] = {}
467
- if plugin_name not in self.config._raw:
468
- self.config._raw[plugin_name] = {}
470
+ if plugin_name not in self.config._raw["plugins"]:
471
+ self.config._raw["plugins"][plugin_name] = {}
469
472
 
470
473
  # Update the value in both places
471
474
  if key in self.config.plugins[plugin_name]:
472
475
  old_value = self.config.plugins[plugin_name][key]
473
- new_value = cast_value(old_value, value, key)
476
+ ta = TypeAdapter(type(old_value))
477
+ new_value = ta.validate_python(value)
474
478
  self.config.plugins[plugin_name][key] = new_value
475
479
  # Also update in _raw to keep in sync
476
- self.config._raw[plugin_name][key] = new_value
480
+ self.config._raw["plugins"][plugin_name][key] = new_value
477
481
  else:
478
482
  raise KeyError(key, self.config.plugins[plugin_name])
479
483
 
@@ -497,8 +501,8 @@ class PluginManager:
497
501
  # Make sure the plugin exists in both configs
498
502
  if plugin_name not in self.config.plugins:
499
503
  self.config.plugins[plugin_name] = {}
500
- if plugin_name not in self.config._raw:
501
- self.config._raw[plugin_name] = {}
504
+ if plugin_name not in self.config._raw["plugins"]:
505
+ self.config._raw["plugins"][plugin_name] = {}
502
506
 
503
507
  # Remove the key from both configs
504
508
  if key in self.config.plugins[plugin_name]:
@@ -508,10 +512,10 @@ class PluginManager:
508
512
 
509
513
  # Also remove from _raw if it exists
510
514
  if (
511
- plugin_name in self.config._raw
512
- and key in self.config._raw[plugin_name]
515
+ plugin_name in self.config._raw["plugins"]
516
+ and key in self.config._raw["plugins"][plugin_name]
513
517
  ):
514
- self.config._raw[plugin_name].pop(key)
518
+ self.config._raw["plugins"][plugin_name].pop(key)
515
519
 
516
520
  self.write_config()
517
521
 
esgpull/processor.py CHANGED
@@ -7,7 +7,6 @@ from typing import TypeAlias
7
7
  from aiostream.stream import merge
8
8
  from httpx import AsyncClient, HTTPError
9
9
 
10
- from esgpull.auth import Auth
11
10
  from esgpull.config import Config
12
11
  from esgpull.download import DownloadCtx, Simple
13
12
  from esgpull.exceptions import DownloadSizeError
@@ -122,13 +121,11 @@ class Processor:
122
121
  def __init__(
123
122
  self,
124
123
  config: Config,
125
- auth: Auth,
126
124
  fs: Filesystem,
127
125
  files: list[File],
128
126
  start_callbacks: dict[str, list[Callback]],
129
127
  ) -> None:
130
128
  self.config = config
131
- self.auth = auth
132
129
  self.fs = fs
133
130
  self.files = list(filter(self.should_download, files))
134
131
  self.tasks: list[Task] = []
@@ -161,7 +158,6 @@ class Processor:
161
158
  semaphore = asyncio.Semaphore(self.config.download.max_concurrent)
162
159
  async with AsyncClient(
163
160
  follow_redirects=True,
164
- cert=self.auth.cert,
165
161
  verify=self.ssl_context,
166
162
  timeout=self.config.download.http_timeout,
167
163
  ) as client:
esgpull/tui.py CHANGED
@@ -28,7 +28,7 @@ from tomlkit import dumps as tomlkit_dumps
28
28
  from yaml import dump as yaml_dump
29
29
 
30
30
  from esgpull.config import Config
31
- from esgpull.constants import ESGPULL_DEBUG
31
+ from esgpull.constants import ESGPULL_DEBUG, ESGPULL_DEBUG_LOCALS
32
32
 
33
33
  logger = logging.getLogger("esgpull")
34
34
  logging.root.setLevel(logging.DEBUG)
@@ -180,7 +180,7 @@ class UI:
180
180
  yield
181
181
  except (click.exceptions.Exit, click.exceptions.Abort):
182
182
  if temp_path is not None:
183
- atexit.register(temp_path.unlink)
183
+ atexit.register(lambda: temp_path.unlink(missing_ok=True))
184
184
  raise
185
185
  except click.exceptions.ClickException:
186
186
  raise
@@ -205,10 +205,10 @@ class UI:
205
205
  f"See [yellow]{temp_path}[/] for error log.",
206
206
  err=True,
207
207
  )
208
- if ESGPULL_DEBUG:
208
+ if ESGPULL_DEBUG or ESGPULL_DEBUG_LOCALS:
209
209
  from rich.traceback import install
210
210
 
211
- install()
211
+ install(show_locals=ESGPULL_DEBUG_LOCALS)
212
212
  raise
213
213
  elif onraise is not None:
214
214
  raise onraise
@@ -218,7 +218,7 @@ class UI:
218
218
  raise
219
219
  else:
220
220
  if temp_path is not None:
221
- atexit.register(temp_path.unlink)
221
+ atexit.register(lambda: temp_path.unlink(missing_ok=True))
222
222
  finally:
223
223
  logging.root.removeHandler(handler)
224
224
 
esgpull/utils.py CHANGED
@@ -1,7 +1,6 @@
1
1
  import asyncio
2
2
  import datetime
3
3
  from typing import Callable, Coroutine, TypeVar
4
- from urllib.parse import urlparse
5
4
 
6
5
  from rich.filesize import _to_str
7
6
 
@@ -52,19 +51,3 @@ def format_date_iso(
52
51
  date: str | datetime.datetime, fmt: str = "%Y-%m-%d"
53
52
  ) -> str:
54
53
  return parse_date(date, fmt).replace(microsecond=0).isoformat() + "Z"
55
-
56
-
57
- def url2index(url: str) -> str:
58
- parsed = urlparse(url)
59
- if parsed.netloc == "":
60
- return parsed.path
61
- else:
62
- return parsed.netloc
63
-
64
-
65
- def index2url(index: str) -> str:
66
- url = "https://" + url2index(index)
67
- if "esgf-1-5-bridge" in index:
68
- return url
69
- else:
70
- return url + "/esg-search/search"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: esgpull
3
- Version: 0.9.1
3
+ Version: 0.9.3
4
4
  Summary: ESGF data discovery, download, replication tool
5
5
  Project-URL: Repository, https://github.com/ESGF/esgf-download
6
6
  Project-URL: Documentation, https://esgf.github.io/esgf-download/
@@ -21,10 +21,11 @@ Requires-Dist: cattrs>=22.2.0
21
21
  Requires-Dist: click-params>=0.4.0
22
22
  Requires-Dist: click>=8.1.3
23
23
  Requires-Dist: httpx>=0.23.0
24
- Requires-Dist: myproxyclient>=2.1.0
25
24
  Requires-Dist: nest-asyncio>=1.5.6
26
25
  Requires-Dist: packaging>=25.0
27
26
  Requires-Dist: platformdirs>=2.6.2
27
+ Requires-Dist: pydantic-settings>=2.10.1
28
+ Requires-Dist: pydantic>=2.11.7
28
29
  Requires-Dist: pyopenssl>=22.1.0
29
30
  Requires-Dist: pyparsing>=3.0.9
30
31
  Requires-Dist: pyyaml>=6.0
@@ -1,23 +1,22 @@
1
1
  esgpull/__init__.py,sha256=XItFDIMNmFUNNcKtUgXdfmGwUIWt4AAv0a4mZkfj5P8,240
2
- esgpull/auth.py,sha256=QZ-l1ySLMP0fvuwYHRLv9FZYp1gqfju_eGaTMDByUxw,5205
3
- esgpull/config.py,sha256=9atYqxc3PiJKY1hfoEWZxf5Ba6U9SzMUs4QvcWWGFy0,13423
4
- esgpull/constants.py,sha256=WjG7xzMZNckOv5GhRehBtI7hoSwwLZvwkvEq5RG-dv4,1189
5
- esgpull/context.py,sha256=_XBAA9XM-fcJXLsqFlg1ziwQdndDoFxketdcFhi4oSM,23430
2
+ esgpull/config.py,sha256=APA3IqYyz_TY2FAm_TNSLsFIkOxmdGnbFLnd2H2YXIs,12042
3
+ esgpull/constants.py,sha256=VlgRJDth5aDjyTopJ2W2JU83353XcRf18RIFAZt7yck,1263
4
+ esgpull/context.py,sha256=JEnIQGF1owl56n0azF8K3GNIU8TgeMu31NSfTqVAGQg,25123
6
5
  esgpull/database.py,sha256=1wGeNbJp0gOLo5Q1N53JfiwVbZ8nfvZVkKlvEaJwOpU,6716
7
6
  esgpull/download.py,sha256=aR2c_SOuZtgX7tI2a9_N4Mn86ABq1k7Mxq_BdojFrP4,5600
8
- esgpull/esgpull.py,sha256=-OwaWvwmkur_mdVNKKxdxlASeK93tmOceV__jGRMwqo,19666
7
+ esgpull/esgpull.py,sha256=mqvrXnyCzTSU3j_u5pYidpLs2j86TEFDPX6MhCnNfMs,19458
9
8
  esgpull/exceptions.py,sha256=wgLyhyIITdusNucPjnnURJX1Jxv1VVIr9PzJV_77qhg,3275
10
9
  esgpull/fs.py,sha256=sc7Af2E3yh3V9KVuSPSXFBuFtlQ3L99UZmS1ZJuiBeM,7280
11
10
  esgpull/graph.py,sha256=Yl2VuF8PNn0R5xRyEK58Q1Xlx8B1PfhbTwt1JftFDro,15929
12
11
  esgpull/install_config.py,sha256=hzYpcHMtPMOK9fYcvVH-Hn_8zYsbs3yXlYgMumXo1zE,5598
13
- esgpull/plugin.py,sha256=wW19V55E1Fn2_ooZ5aTc58uJVSQ0WT43P29G3TlMD6A,18748
14
- esgpull/processor.py,sha256=WLf4NFO_dp27E0GhZAiekiRD-gT6uyFJJnFZKbFV5vU,5484
12
+ esgpull/plugin.py,sha256=t6iejis65UREQ71gnj1-gVFhlrGt1z1n3SpJ6KiP57E,18904
13
+ esgpull/processor.py,sha256=ubhlKMMOY_ieZEcN9zcDPlmZxQDXqb2QVmeCwWo7zOE,5376
15
14
  esgpull/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
15
  esgpull/result.py,sha256=f64l9gPFpFWgctmHVYrNWJvuXXB1sxpxXzJEIssLXxc,1020
17
- esgpull/tui.py,sha256=jpfDK_g_taNPEu0FeJ4MM1vtNJfOJY5x3dkUxRkoPEA,11210
18
- esgpull/utils.py,sha256=Rw_pU_rDvD6b2_h4Hzi8b5Hmb0ufuhrdL0Xwr8kLFcg,1584
16
+ esgpull/tui.py,sha256=XJs8AUm28YLWl3ephpxY8jHFvG7HrIr08u3RdYvABdE,11338
17
+ esgpull/utils.py,sha256=pLMQfY0p2oNIFyCZhHBD74BOAJtmt9QV6dTJ79VsfF8,1213
19
18
  esgpull/version.py,sha256=IHT4mKrIr8eV-C3HtmIVD85iGVH25n2ohoff31kaJ1A,93
20
- esgpull/cli/__init__.py,sha256=Q-U7opBTHxF5yUyyv15Cj-4Y9MaDMJ4i5FxNL-EmHfs,1683
19
+ esgpull/cli/__init__.py,sha256=W0q_eyhvtPgyX5cXKSDDLUUrskGLzgNoJ9VCY9fJ6pY,1701
21
20
  esgpull/cli/add.py,sha256=h8xFy5ORzY9O4SPPo4VCtTybeJJ5GcA18w4TZeL0DqU,3507
22
21
  esgpull/cli/autoremove.py,sha256=g76_qnc3q84zSO7W0JsbWtGN4AfWBXTkQJO6gPCs2Pw,1336
23
22
  esgpull/cli/config.py,sha256=g7Me173B_SWtdnQcitcTDnj-06-1SW0f8Z8SOcjMAcQ,3683
@@ -26,17 +25,17 @@ esgpull/cli/decorators.py,sha256=X5Ja6HlB_AgpTohpbF2EjtT5sA0IdPxX20g-j1K7raM,672
26
25
  esgpull/cli/download.py,sha256=3_Fm8JJYBWKs63oQ1OLaHJCv9ccbeY2gIW8SDasaYNE,2356
27
26
  esgpull/cli/facet.py,sha256=V1u-DxNkhswwSt0qpXvuHrCI_tE8jAJGEe6_fMhYbaM,584
28
27
  esgpull/cli/get.py,sha256=2WXL01Ri0P_2Rf1xrp9bnsrrxir6whxkAC0SnohjFpg,678
28
+ esgpull/cli/index_nodes.py,sha256=v6DySuWsxtBkWIaKnUVUqJdjAb7J5OIpfgP3B0Ut-ls,2627
29
29
  esgpull/cli/install.py,sha256=fd8nKwIFvOivgn_gOGn7XIk1BB9LXnhQB47KuIIy5AU,2880
30
- esgpull/cli/login.py,sha256=FZ63SsB4fCDixwf7gMUR697Dk89W1OvpgeadKE4IqEU,2153
31
- esgpull/cli/plugins.py,sha256=eTAwWqvrzDKs122_Wa3sOkuriSoInymxWySQQahrlHg,13357
30
+ esgpull/cli/plugins.py,sha256=lM8eQIH4H_bIy49rC2flmTstpr9ILDBYXp1YYYMv7qw,13366
32
31
  esgpull/cli/remove.py,sha256=9fqE8NJdr1mHypu_N-TBJy_yl3elUBSfzEARxxTkqKg,2662
33
32
  esgpull/cli/retry.py,sha256=UVpAjW_N7l6RTJ-T5qXojwcXPzzjT7sDKb_wBdvavrg,1310
34
- esgpull/cli/search.py,sha256=c2OI0Xvw6h2zBnC8msjxidKJZ0KKUuWJK9FuAmQ15ZU,6369
33
+ esgpull/cli/search.py,sha256=E64uvlmgFGyNAvtBk9dlFbNeulNfAHUCQta8PHBxSPo,6968
35
34
  esgpull/cli/self.py,sha256=psgFcgkDyemquZEpoWp2cyjgampCgDzRc1QBvzqGs24,7941
36
35
  esgpull/cli/show.py,sha256=B-h7bKMrwgjnTHio2du8IPOLlKCaan56RQKAtzlQzcw,2822
37
36
  esgpull/cli/status.py,sha256=HEyj6QFABblADtYf1PWmSzghKX3fs33x9p5vpSqA514,2521
38
37
  esgpull/cli/track.py,sha256=Q9ZvvV5FFGzp6wQZflAd_OFmqhAWgl1JFBad2dCbEF0,3089
39
- esgpull/cli/update.py,sha256=3JBf1HqglazUYZ63uHtm5y3ZAuS2XLGcwrsVYBkrmb0,9432
38
+ esgpull/cli/update.py,sha256=TiVKXBxye2ZW627zoNyMQtCPhkdiLiTDngRjaVUqGO4,9460
40
39
  esgpull/cli/utils.py,sha256=dE5dIH6tWmhItarLDrNldiUuuX5qUjnVpnu4KkE6V1g,7199
41
40
  esgpull/migrations/README,sha256=heMzebYwlGhnE8_4CWJ4LS74WoEZjBy-S-mIJRxAEKI,39
42
41
  esgpull/migrations/env.py,sha256=am2HhFrlIZNlXCaA5Ye7yKbIJ2MRSO5UFmUwB8l9fyE,2285
@@ -70,6 +69,8 @@ esgpull/migrations/versions/0.7.3_update_tables.py,sha256=4pNkM7VaGQqkLuIoLKuM0f
70
69
  esgpull/migrations/versions/0.8.0_update_tables.py,sha256=5rr3guWipnnuciFuviUxZUasdPw6x06WZCmY5nNCn5k,555
71
70
  esgpull/migrations/versions/0.9.0_update_tables.py,sha256=nXfPiyuseD5BXvu59zkeSTzb6EA7txpBudclU-MIyU0,555
72
71
  esgpull/migrations/versions/0.9.1_update_tables.py,sha256=ITewU2qgdCwhorsl2d_t7ENt_6KecG3z5xfRr_LwrtY,541
72
+ esgpull/migrations/versions/0.9.2_update_tables.py,sha256=aux--HPA_jUtvk7Zb2ZRXRhnRLT-whqZ0lLWt8Apyac,541
73
+ esgpull/migrations/versions/0.9.3_update_tables.py,sha256=-k1CneOa7OTO6xPZ8uR0ccy-4B8TU3kM12-oYKFEOlA,541
73
74
  esgpull/migrations/versions/14c72daea083_query_add_column_updated_at.py,sha256=MKqz0tfwGwRkgP4QDd-cpUmXCVr4tM_wlC2BfxqJ1_w,1031
74
75
  esgpull/migrations/versions/c7c8541fa741_query_add_column_added_at.py,sha256=Al_o7fDmoRqc9vBCQgtgrNbSPIOBxdMZ5T-ztakqVeY,1033
75
76
  esgpull/migrations/versions/d14f179e553c_file_add_composite_index_dataset_id_.py,sha256=0vJvttugWmgKns4g-K4i3EU6eid2Z_K2e3H6Ktevf7c,860
@@ -86,8 +87,8 @@ esgpull/models/sql.py,sha256=K8Nre5HKFPjkRzUUW6p6Qk7aG8upbw8C3pnmCFlg7d8,8942
86
87
  esgpull/models/synda_file.py,sha256=6o5unPhzVJGnbpA2MxcS0r-hrBwocHYVnLrqjSGtmuk,2387
87
88
  esgpull/models/tag.py,sha256=5CQDB9rAeCqog63ec9LPFN46HOFNkHPy-maY4gkBQ3E,461
88
89
  esgpull/models/utils.py,sha256=exwlIlIKYjhhfUE82w1kU_HeSQOSY97PTvpkhW0udMA,1631
89
- esgpull-0.9.1.dist-info/METADATA,sha256=Iy0nz7xstS0pywi5LNuLt-giW-5ng-X_lYb7WTrv8eE,3781
90
- esgpull-0.9.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
91
- esgpull-0.9.1.dist-info/entry_points.txt,sha256=vyh7HvFrCp4iyMrTkDoSF3weaYrlNj2OJe0Fq5q4QB4,45
92
- esgpull-0.9.1.dist-info/licenses/LICENSE,sha256=lUqGPGWDHHxjkUDuYgjLLY2XQXXn_EHU7fnrQWHGugc,1540
93
- esgpull-0.9.1.dist-info/RECORD,,
90
+ esgpull-0.9.3.dist-info/METADATA,sha256=0wlDuo4TCJskBSO9v4FRuoLTAm7531jOPJDQAQJWBP4,3818
91
+ esgpull-0.9.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
92
+ esgpull-0.9.3.dist-info/entry_points.txt,sha256=vyh7HvFrCp4iyMrTkDoSF3weaYrlNj2OJe0Fq5q4QB4,45
93
+ esgpull-0.9.3.dist-info/licenses/LICENSE,sha256=lUqGPGWDHHxjkUDuYgjLLY2XQXXn_EHU7fnrQWHGugc,1540
94
+ esgpull-0.9.3.dist-info/RECORD,,