esgpull 0.7.1__tar.gz → 0.7.3__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.
Files changed (144) hide show
  1. {esgpull-0.7.1 → esgpull-0.7.3}/PKG-INFO +13 -1
  2. {esgpull-0.7.1 → esgpull-0.7.3}/README.md +12 -0
  3. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/cli/utils.py +18 -24
  4. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/context.py +6 -1
  5. esgpull-0.7.3/esgpull/migrations/versions/0.7.2_update_tables.py +28 -0
  6. esgpull-0.7.3/esgpull/migrations/versions/0.7.3_update_tables.py +28 -0
  7. {esgpull-0.7.1 → esgpull-0.7.3}/pyproject.toml +7 -2
  8. {esgpull-0.7.1 → esgpull-0.7.3}/requirements-dev.lock +14 -9
  9. {esgpull-0.7.1 → esgpull-0.7.3}/requirements.lock +5 -5
  10. esgpull-0.7.3/tests/cli/test_parse.py +40 -0
  11. {esgpull-0.7.1 → esgpull-0.7.3}/.github/workflows/ci.yml +0 -0
  12. {esgpull-0.7.1 → esgpull-0.7.3}/.github/workflows/doc.yml +0 -0
  13. {esgpull-0.7.1 → esgpull-0.7.3}/.github/workflows/pypi-publish.yml +0 -0
  14. {esgpull-0.7.1 → esgpull-0.7.3}/.gitignore +0 -0
  15. {esgpull-0.7.1 → esgpull-0.7.3}/.pre-commit-config.yaml +0 -0
  16. {esgpull-0.7.1 → esgpull-0.7.3}/LICENSE +0 -0
  17. {esgpull-0.7.1 → esgpull-0.7.3}/alembic.ini +0 -0
  18. {esgpull-0.7.1 → esgpull-0.7.3}/docs/docs/configuration.md +0 -0
  19. {esgpull-0.7.1 → esgpull-0.7.3}/docs/docs/download.md +0 -0
  20. {esgpull-0.7.1 → esgpull-0.7.3}/docs/docs/glossary.md +0 -0
  21. {esgpull-0.7.1 → esgpull-0.7.3}/docs/docs/images/download_1.svg +0 -0
  22. {esgpull-0.7.1 → esgpull-0.7.3}/docs/docs/images/download_2.svg +0 -0
  23. {esgpull-0.7.1 → esgpull-0.7.3}/docs/docs/images/download_3.svg +0 -0
  24. {esgpull-0.7.1 → esgpull-0.7.3}/docs/docs/images/download_4.svg +0 -0
  25. {esgpull-0.7.1 → esgpull-0.7.3}/docs/docs/images/download_5.svg +0 -0
  26. {esgpull-0.7.1 → esgpull-0.7.3}/docs/docs/images/download_6.svg +0 -0
  27. {esgpull-0.7.1 → esgpull-0.7.3}/docs/docs/images/intro_1.svg +0 -0
  28. {esgpull-0.7.1 → esgpull-0.7.3}/docs/docs/images/intro_2.svg +0 -0
  29. {esgpull-0.7.1 → esgpull-0.7.3}/docs/docs/images/intro_3.svg +0 -0
  30. {esgpull-0.7.1 → esgpull-0.7.3}/docs/docs/images/intro_4.svg +0 -0
  31. {esgpull-0.7.1 → esgpull-0.7.3}/docs/docs/images/intro_5.svg +0 -0
  32. {esgpull-0.7.1 → esgpull-0.7.3}/docs/docs/images/intro_6.svg +0 -0
  33. {esgpull-0.7.1 → esgpull-0.7.3}/docs/docs/images/quickstart_1.svg +0 -0
  34. {esgpull-0.7.1 → esgpull-0.7.3}/docs/docs/images/search_1.svg +0 -0
  35. {esgpull-0.7.1 → esgpull-0.7.3}/docs/docs/images/search_2.svg +0 -0
  36. {esgpull-0.7.1 → esgpull-0.7.3}/docs/docs/images/search_3.svg +0 -0
  37. {esgpull-0.7.1 → esgpull-0.7.3}/docs/docs/images/search_4.svg +0 -0
  38. {esgpull-0.7.1 → esgpull-0.7.3}/docs/docs/images/search_5.svg +0 -0
  39. {esgpull-0.7.1 → esgpull-0.7.3}/docs/docs/images/search_6.svg +0 -0
  40. {esgpull-0.7.1 → esgpull-0.7.3}/docs/docs/images/search_7.svg +0 -0
  41. {esgpull-0.7.1 → esgpull-0.7.3}/docs/docs/images/search_ignore.svg +0 -0
  42. {esgpull-0.7.1 → esgpull-0.7.3}/docs/docs/index.md +0 -0
  43. {esgpull-0.7.1 → esgpull-0.7.3}/docs/docs/installation.md +0 -0
  44. {esgpull-0.7.1 → esgpull-0.7.3}/docs/docs/queries.md +0 -0
  45. {esgpull-0.7.1 → esgpull-0.7.3}/docs/docs/quickstart.md +0 -0
  46. {esgpull-0.7.1 → esgpull-0.7.3}/docs/docs/search.md +0 -0
  47. {esgpull-0.7.1 → esgpull-0.7.3}/docs/docs/stylesheets/extra.css +0 -0
  48. {esgpull-0.7.1 → esgpull-0.7.3}/docs/includes/abbreviations.md +0 -0
  49. {esgpull-0.7.1 → esgpull-0.7.3}/docs/mkdocs.yml +0 -0
  50. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/__init__.py +0 -0
  51. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/auth.py +0 -0
  52. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/cli/__init__.py +0 -0
  53. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/cli/add.py +0 -0
  54. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/cli/autoremove.py +0 -0
  55. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/cli/config.py +0 -0
  56. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/cli/convert.py +0 -0
  57. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/cli/datasets.py +0 -0
  58. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/cli/decorators.py +0 -0
  59. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/cli/download.py +0 -0
  60. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/cli/facet.py +0 -0
  61. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/cli/get.py +0 -0
  62. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/cli/install.py +0 -0
  63. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/cli/login.py +0 -0
  64. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/cli/remove.py +0 -0
  65. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/cli/retry.py +0 -0
  66. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/cli/search.py +0 -0
  67. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/cli/self.py +0 -0
  68. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/cli/show.py +0 -0
  69. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/cli/status.py +0 -0
  70. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/cli/track.py +0 -0
  71. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/cli/update.py +0 -0
  72. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/config.py +0 -0
  73. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/constants.py +0 -0
  74. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/database.py +0 -0
  75. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/download.py +0 -0
  76. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/esgpull.py +0 -0
  77. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/exceptions.py +0 -0
  78. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/fs.py +0 -0
  79. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/graph.py +0 -0
  80. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/install_config.py +0 -0
  81. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/migrations/README +0 -0
  82. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/migrations/env.py +0 -0
  83. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/migrations/script.py.mako +0 -0
  84. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/migrations/versions/0.3.0_update_tables.py +0 -0
  85. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/migrations/versions/0.3.1_update_tables.py +0 -0
  86. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/migrations/versions/0.3.2_update_tables.py +0 -0
  87. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/migrations/versions/0.3.3_update_tables.py +0 -0
  88. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/migrations/versions/0.3.4_update_tables.py +0 -0
  89. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/migrations/versions/0.3.5_update_tables.py +0 -0
  90. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/migrations/versions/0.3.6_update_tables.py +0 -0
  91. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/migrations/versions/0.3.7_update_tables.py +0 -0
  92. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/migrations/versions/0.3.8_update_tables.py +0 -0
  93. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/migrations/versions/0.4.0_update_tables.py +0 -0
  94. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/migrations/versions/0.5.0_update_tables.py +0 -0
  95. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/migrations/versions/0.5.1_update_tables.py +0 -0
  96. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/migrations/versions/0.5.2_update_tables.py +0 -0
  97. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/migrations/versions/0.5.3_update_tables.py +0 -0
  98. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/migrations/versions/0.5.4_update_tables.py +0 -0
  99. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/migrations/versions/0.5.5_update_tables.py +0 -0
  100. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/migrations/versions/0.6.0_update_tables.py +0 -0
  101. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/migrations/versions/0.6.1_update_tables.py +0 -0
  102. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/migrations/versions/0.6.2_update_tables.py +0 -0
  103. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/migrations/versions/0.6.3_update_tables.py +0 -0
  104. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/migrations/versions/0.6.4_update_tables.py +0 -0
  105. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/migrations/versions/0.6.5_update_tables.py +0 -0
  106. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/migrations/versions/0.7.0_update_tables.py +0 -0
  107. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/migrations/versions/0.7.1_update_tables.py +0 -0
  108. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/models/__init__.py +0 -0
  109. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/models/base.py +0 -0
  110. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/models/dataset.py +0 -0
  111. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/models/facet.py +0 -0
  112. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/models/file.py +0 -0
  113. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/models/options.py +0 -0
  114. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/models/query.py +0 -0
  115. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/models/selection.py +0 -0
  116. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/models/sql.py +0 -0
  117. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/models/synda_file.py +0 -0
  118. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/models/tag.py +0 -0
  119. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/models/utils.py +0 -0
  120. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/processor.py +0 -0
  121. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/py.typed +0 -0
  122. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/result.py +0 -0
  123. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/tui.py +0 -0
  124. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/utils.py +0 -0
  125. {esgpull-0.7.1 → esgpull-0.7.3}/esgpull/version.py +0 -0
  126. {esgpull-0.7.1 → esgpull-0.7.3}/pdm.lock +0 -0
  127. {esgpull-0.7.1 → esgpull-0.7.3}/recipe/meta.yaml +0 -0
  128. {esgpull-0.7.1 → esgpull-0.7.3}/recipe/recipe.yaml +0 -0
  129. {esgpull-0.7.1 → esgpull-0.7.3}/tests/__init__.py +0 -0
  130. {esgpull-0.7.1 → esgpull-0.7.3}/tests/cli/__init__.py +0 -0
  131. {esgpull-0.7.1 → esgpull-0.7.3}/tests/cli/test_update.py +0 -0
  132. {esgpull-0.7.1 → esgpull-0.7.3}/tests/conftest.py +0 -0
  133. {esgpull-0.7.1 → esgpull-0.7.3}/tests/test_auth.py +0 -0
  134. {esgpull-0.7.1 → esgpull-0.7.3}/tests/test_config.py +0 -0
  135. {esgpull-0.7.1 → esgpull-0.7.3}/tests/test_context.py +0 -0
  136. {esgpull-0.7.1 → esgpull-0.7.3}/tests/test_db.py +0 -0
  137. {esgpull-0.7.1 → esgpull-0.7.3}/tests/test_esgpull.py +0 -0
  138. {esgpull-0.7.1 → esgpull-0.7.3}/tests/test_fs.py +0 -0
  139. {esgpull-0.7.1 → esgpull-0.7.3}/tests/test_graph.py +0 -0
  140. {esgpull-0.7.1 → esgpull-0.7.3}/tests/test_processor.py +0 -0
  141. {esgpull-0.7.1 → esgpull-0.7.3}/tests/test_query.py +0 -0
  142. {esgpull-0.7.1 → esgpull-0.7.3}/tests/test_selection.py +0 -0
  143. {esgpull-0.7.1 → esgpull-0.7.3}/tests/test_synda.py +0 -0
  144. {esgpull-0.7.1 → esgpull-0.7.3}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: esgpull
3
- Version: 0.7.1
3
+ Version: 0.7.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/
@@ -60,6 +60,18 @@ for dataset in datasets:
60
60
  - Command-line interface
61
61
  - HTTP download (async multi-file)
62
62
 
63
+ ## Installation
64
+
65
+ Install `esgpull` using pip or conda:
66
+
67
+ ```shell
68
+ pip install esgpull
69
+ ```
70
+
71
+ ```shell
72
+ conda install -c conda-forge ipsl::esgpull
73
+ ```
74
+
63
75
  ## Usage
64
76
 
65
77
  ```console
@@ -25,6 +25,18 @@ for dataset in datasets:
25
25
  - Command-line interface
26
26
  - HTTP download (async multi-file)
27
27
 
28
+ ## Installation
29
+
30
+ Install `esgpull` using pip or conda:
31
+
32
+ ```shell
33
+ pip install esgpull
34
+ ```
35
+
36
+ ```shell
37
+ conda install -c conda-forge ipsl::esgpull
38
+ ```
39
+
28
40
  ## Usage
29
41
 
30
42
  ```console
@@ -15,7 +15,7 @@ from rich.text import Text
15
15
  from esgpull import Esgpull
16
16
  from esgpull.graph import Graph
17
17
  from esgpull.models import Dataset, File, Option, Options, Query, Selection
18
- from esgpull.tui import UI, TempUI, Verbosity
18
+ from esgpull.tui import UI, TempUI, Verbosity, logger
19
19
  from esgpull.utils import format_size
20
20
 
21
21
 
@@ -121,9 +121,15 @@ def totable(docs: list[OrderedDict[str, Any]]) -> Table:
121
121
  return table
122
122
 
123
123
 
124
+ def safe_value(value: str) -> str:
125
+ if " " in value:
126
+ return f'"{value}"'
127
+ else:
128
+ return value
129
+
130
+
124
131
  def parse_facets(facets: list[str]) -> Selection:
125
132
  facet_dict: dict[str, list[str]] = {}
126
- exact_terms: list[str] | None = None
127
133
  for facet in facets:
128
134
  match facet.split(":"):
129
135
  case [value]:
@@ -132,28 +138,9 @@ def parse_facets(facets: list[str]) -> Selection:
132
138
  ...
133
139
  case _:
134
140
  raise BadArgumentUsage(f"{facet!r} is not valid syntax.")
135
- if value.startswith("/"):
136
- if exact_terms is not None:
137
- raise BadArgumentUsage("Nested exact string is forbidden.")
138
- exact_terms = []
139
- if exact_terms is not None:
140
- if name != "query":
141
- raise BadArgumentUsage(
142
- "Cannot use facet term inside an exact string."
143
- )
144
- exact_terms.append(value)
145
- if value.endswith("/"):
146
- final_exact_str = " ".join(exact_terms)
147
- value = '"' + final_exact_str.strip("/") + '"'
148
- exact_terms = None
149
- else:
150
- continue
151
- facet_dict.setdefault(name, [])
152
- facet_dict[name].append(value)
153
- else:
154
- values = value.split(",")
155
- facet_dict.setdefault(name, [])
156
- facet_dict[name].extend(values)
141
+ values = list(map(safe_value, value.split(",")))
142
+ facet_dict.setdefault(name, [])
143
+ facet_dict[name].extend(values)
157
144
  selection = Selection()
158
145
  for name, values in facet_dict.items():
159
146
  selection[name] = values
@@ -170,6 +157,13 @@ def parse_query(
170
157
  replica: str | None,
171
158
  retracted: str | None,
172
159
  ) -> Query:
160
+ logger.info(f"{facets=}")
161
+ logger.info(f"{tags=}")
162
+ logger.info(f"{require=}")
163
+ logger.info(f"{distrib=}")
164
+ logger.info(f"{latest=}")
165
+ logger.info(f"{replica=}")
166
+ logger.info(f"{retracted=}")
173
167
  options = Options(
174
168
  distrib=distrib or Option.notset,
175
169
  latest=latest or Option.notset,
@@ -1,6 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import asyncio
4
+ import json
4
5
  import sys
5
6
  from collections.abc import AsyncIterator, Callable, Coroutine, Sequence
6
7
  from dataclasses import dataclass, field
@@ -441,7 +442,9 @@ class Context:
441
442
  try:
442
443
  resp = await self.client.send(result.request)
443
444
  resp.raise_for_status()
444
- result.json = resp.json()
445
+ result.json = json.loads(
446
+ resp.content.decode(encoding="latin-1")
447
+ )
445
448
  logger.info(f"✓ Fetched in {resp.elapsed}s {resp.url}")
446
449
  except HTTPError as exc:
447
450
  result.exc = exc
@@ -464,6 +467,8 @@ class Context:
464
467
  group = BaseExceptionGroup("fetch", excs)
465
468
  if self.noraise:
466
469
  logger.exception(group)
470
+ for exc in excs:
471
+ logger.exception(exc)
467
472
  else:
468
473
  raise group
469
474
 
@@ -0,0 +1,28 @@
1
+ """update tables
2
+
3
+ Revision ID: 0.7.2
4
+ Revises: 0.7.1
5
+ Create Date: 2024-09-17 15:04:11.203421
6
+
7
+ """
8
+ from alembic import op
9
+ import sqlalchemy as sa
10
+
11
+
12
+ # revision identifiers, used by Alembic.
13
+ revision = '0.7.2'
14
+ down_revision = '0.7.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.7.3
4
+ Revises: 0.7.2
5
+ Create Date: 2024-09-20 12:22:11.989996
6
+
7
+ """
8
+ from alembic import op
9
+ import sqlalchemy as sa
10
+
11
+
12
+ # revision identifiers, used by Alembic.
13
+ revision = '0.7.3'
14
+ down_revision = '0.7.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 ###
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "esgpull"
7
- version = "0.7.1"
7
+ version = "0.7.3"
8
8
  classifiers = [
9
9
  "License :: OSI Approved :: BSD License",
10
10
  "Programming Language :: Python :: 3",
@@ -102,5 +102,10 @@ dev-dependencies = [
102
102
  "types-pyyaml>=6.0.12.20240808",
103
103
  "types-aiofiles>=24.1.0.20240626",
104
104
  "pytest-mypy>=0.10.3",
105
- "pytest-xdist>=3.6.1"
105
+ "pytest-xdist>=3.6.1",
106
+ "ipdb>=0.13.13",
107
+ "orjson>=3.10.7"
106
108
  ]
109
+
110
+ [tool.rye.scripts]
111
+ esg = {cmd = "esgpull", env-file = ".env"}
@@ -16,7 +16,7 @@ aiostream==0.6.2
16
16
  # via esgpull
17
17
  alembic==1.13.2
18
18
  # via esgpull
19
- anyio==4.4.0
19
+ anyio==4.5.0
20
20
  # via httpx
21
21
  asttokens==2.4.1
22
22
  # via stack-data
@@ -53,6 +53,7 @@ cryptography==43.0.1
53
53
  debugpy==1.8.5
54
54
  # via ipykernel
55
55
  decorator==5.1.1
56
+ # via ipdb
56
57
  # via ipython
57
58
  deprecated==1.2.14
58
59
  # via click-params
@@ -65,7 +66,7 @@ execnet==2.1.1
65
66
  # via pytest-xdist
66
67
  executing==2.1.0
67
68
  # via stack-data
68
- filelock==3.16.0
69
+ filelock==3.16.1
69
70
  # via pytest-mypy
70
71
  ghp-import==2.1.0
71
72
  # via mkdocs
@@ -77,15 +78,17 @@ httpcore==1.0.5
77
78
  # via httpx
78
79
  httpx==0.27.2
79
80
  # via esgpull
80
- idna==3.8
81
+ idna==3.10
81
82
  # via anyio
82
83
  # via httpx
83
84
  # via requests
84
85
  iniconfig==2.0.0
85
86
  # via pytest
87
+ ipdb==0.13.13
86
88
  ipykernel==6.29.5
87
89
  # via jupyter-console
88
90
  ipython==8.27.0
91
+ # via ipdb
89
92
  # via ipykernel
90
93
  # via jupyter-console
91
94
  jedi==0.19.1
@@ -93,7 +96,7 @@ jedi==0.19.1
93
96
  jinja2==3.1.4
94
97
  # via mkdocs
95
98
  # via mkdocs-material
96
- jupyter-client==8.6.2
99
+ jupyter-client==8.6.3
97
100
  # via ipykernel
98
101
  # via jupyter-console
99
102
  jupyter-console==6.6.3
@@ -125,7 +128,7 @@ mkdocs==1.6.1
125
128
  # via mkdocs-material
126
129
  mkdocs-get-deps==0.2.0
127
130
  # via mkdocs
128
- mkdocs-material==9.5.34
131
+ mkdocs-material==9.5.35
129
132
  mkdocs-material-extensions==1.3.1
130
133
  # via mkdocs-material
131
134
  myproxyclient==2.1.1
@@ -137,6 +140,7 @@ mypy-extensions==1.0.0
137
140
  nest-asyncio==1.6.0
138
141
  # via esgpull
139
142
  # via ipykernel
143
+ orjson==3.10.7
140
144
  packaging==24.1
141
145
  # via ipykernel
142
146
  # via mkdocs
@@ -149,7 +153,7 @@ pathspec==0.12.1
149
153
  # via mkdocs
150
154
  pexpect==4.9.0
151
155
  # via ipython
152
- platformdirs==4.3.2
156
+ platformdirs==4.3.6
153
157
  # via esgpull
154
158
  # via jupyter-core
155
159
  # via mkdocs-get-deps
@@ -206,7 +210,7 @@ requests==2.32.3
206
210
  # via mkdocs-material
207
211
  rich==13.8.1
208
212
  # via esgpull
209
- setuptools==74.1.2
213
+ setuptools==75.1.0
210
214
  # via esgpull
211
215
  six==1.16.0
212
216
  # via asttokens
@@ -215,13 +219,14 @@ six==1.16.0
215
219
  sniffio==1.3.1
216
220
  # via anyio
217
221
  # via httpx
218
- sqlalchemy==2.0.34
222
+ sqlalchemy==2.0.35
219
223
  # via alembic
220
224
  # via esgpull
221
225
  stack-data==0.6.3
222
226
  # via ipython
223
227
  tomli==2.0.1
224
228
  # via coverage
229
+ # via ipdb
225
230
  # via mypy
226
231
  # via pytest
227
232
  tomlkit==0.13.2
@@ -238,7 +243,7 @@ traitlets==5.14.3
238
243
  # via jupyter-core
239
244
  # via matplotlib-inline
240
245
  types-aiofiles==24.1.0.20240626
241
- types-pyyaml==6.0.12.20240808
246
+ types-pyyaml==6.0.12.20240917
242
247
  typing-extensions==4.12.2
243
248
  # via aiostream
244
249
  # via alembic
@@ -16,7 +16,7 @@ aiostream==0.6.2
16
16
  # via esgpull
17
17
  alembic==1.13.2
18
18
  # via esgpull
19
- anyio==4.4.0
19
+ anyio==4.5.0
20
20
  # via httpx
21
21
  attrs==24.2.0
22
22
  # via cattrs
@@ -48,7 +48,7 @@ httpcore==1.0.5
48
48
  # via httpx
49
49
  httpx==0.27.2
50
50
  # via esgpull
51
- idna==3.8
51
+ idna==3.10
52
52
  # via anyio
53
53
  # via httpx
54
54
  mako==1.3.5
@@ -63,7 +63,7 @@ myproxyclient==2.1.1
63
63
  # via esgpull
64
64
  nest-asyncio==1.6.0
65
65
  # via esgpull
66
- platformdirs==4.3.2
66
+ platformdirs==4.3.6
67
67
  # via esgpull
68
68
  pycparser==2.22
69
69
  # via cffi
@@ -78,14 +78,14 @@ pyyaml==6.0.2
78
78
  # via esgpull
79
79
  rich==13.8.1
80
80
  # via esgpull
81
- setuptools==74.1.2
81
+ setuptools==75.1.0
82
82
  # via esgpull
83
83
  six==1.16.0
84
84
  # via myproxyclient
85
85
  sniffio==1.3.1
86
86
  # via anyio
87
87
  # via httpx
88
- sqlalchemy==2.0.34
88
+ sqlalchemy==2.0.35
89
89
  # via alembic
90
90
  # via esgpull
91
91
  tomlkit==0.13.2
@@ -0,0 +1,40 @@
1
+ import pytest
2
+
3
+ from esgpull.cli.utils import parse_facets
4
+ from esgpull.models import Selection
5
+
6
+ test_cases = [
7
+ (["ocean", "temperature"], Selection(query=["ocean", "temperature"])),
8
+ (["ocean temperature"], Selection(query='"ocean temperature"')),
9
+ (
10
+ [
11
+ "project:CMIP6",
12
+ "experiment_id:ssp126,ssp245,ssp585",
13
+ "variable_id:hurt,lai,pr,sfcWind,tasmax,tasmin,ts,tos",
14
+ "frequency:day",
15
+ "nominal_resolution:100 km",
16
+ ],
17
+ Selection(
18
+ project="CMIP6",
19
+ experiment_id=["ssp126", "ssp245", "ssp585"],
20
+ variable_id=[
21
+ "hurt",
22
+ "lai",
23
+ "pr",
24
+ "sfcWind",
25
+ "tasmax",
26
+ "tasmin",
27
+ "ts",
28
+ "tos",
29
+ ],
30
+ frequency="day",
31
+ nominal_resolution='"100 km"',
32
+ ),
33
+ ),
34
+ ]
35
+
36
+
37
+ @pytest.mark.parametrize("facets, expected_query", test_cases)
38
+ def test_parse_facets(facets, expected_query):
39
+ result = parse_facets(facets)
40
+ assert result == expected_query
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes