esgpull 0.6.3__tar.gz → 0.6.4__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 (94) hide show
  1. {esgpull-0.6.3 → esgpull-0.6.4}/PKG-INFO +1 -1
  2. esgpull-0.6.4/esgpull/migrations/versions/0.6.4_update_tables.py +25 -0
  3. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/processor.py +28 -29
  4. esgpull-0.6.4/esgpull/version.py +1 -0
  5. {esgpull-0.6.3 → esgpull-0.6.4}/pyproject.toml +1 -1
  6. {esgpull-0.6.3 → esgpull-0.6.4}/tests/test_processor.py +6 -11
  7. esgpull-0.6.3/esgpull/cli/link.py +0 -105
  8. esgpull-0.6.3/esgpull/presets.py +0 -13
  9. esgpull-0.6.3/esgpull/version.py +0 -1
  10. {esgpull-0.6.3 → esgpull-0.6.4}/LICENSE +0 -0
  11. {esgpull-0.6.3 → esgpull-0.6.4}/README.md +0 -0
  12. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/__init__.py +0 -0
  13. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/auth.py +0 -0
  14. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/cli/__init__.py +0 -0
  15. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/cli/add.py +0 -0
  16. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/cli/autoremove.py +0 -0
  17. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/cli/config.py +0 -0
  18. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/cli/convert.py +0 -0
  19. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/cli/decorators.py +0 -0
  20. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/cli/download.py +0 -0
  21. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/cli/facet.py +0 -0
  22. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/cli/get.py +0 -0
  23. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/cli/install.py +0 -0
  24. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/cli/login.py +0 -0
  25. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/cli/remove.py +0 -0
  26. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/cli/retry.py +0 -0
  27. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/cli/search.py +0 -0
  28. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/cli/self.py +0 -0
  29. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/cli/show.py +0 -0
  30. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/cli/status.py +0 -0
  31. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/cli/track.py +0 -0
  32. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/cli/update.py +0 -0
  33. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/cli/utils.py +0 -0
  34. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/config.py +0 -0
  35. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/constants.py +0 -0
  36. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/context.py +0 -0
  37. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/database.py +0 -0
  38. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/download.py +0 -0
  39. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/esgpull.py +0 -0
  40. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/exceptions.py +0 -0
  41. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/fs.py +0 -0
  42. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/graph.py +0 -0
  43. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/install_config.py +0 -0
  44. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/migrations/README +0 -0
  45. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/migrations/env.py +0 -0
  46. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/migrations/script.py.mako +0 -0
  47. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/migrations/versions/0.3.0_update_tables.py +0 -0
  48. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/migrations/versions/0.3.1_update_tables.py +0 -0
  49. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/migrations/versions/0.3.2_update_tables.py +0 -0
  50. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/migrations/versions/0.3.3_update_tables.py +0 -0
  51. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/migrations/versions/0.3.4_update_tables.py +0 -0
  52. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/migrations/versions/0.3.5_update_tables.py +0 -0
  53. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/migrations/versions/0.3.6_update_tables.py +0 -0
  54. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/migrations/versions/0.3.7_update_tables.py +0 -0
  55. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/migrations/versions/0.3.8_update_tables.py +0 -0
  56. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/migrations/versions/0.4.0_update_tables.py +0 -0
  57. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/migrations/versions/0.5.0_update_tables.py +0 -0
  58. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/migrations/versions/0.5.1_update_tables.py +0 -0
  59. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/migrations/versions/0.5.2_update_tables.py +0 -0
  60. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/migrations/versions/0.5.3_update_tables.py +0 -0
  61. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/migrations/versions/0.5.4_update_tables.py +0 -0
  62. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/migrations/versions/0.5.5_update_tables.py +0 -0
  63. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/migrations/versions/0.6.0_update_tables.py +0 -0
  64. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/migrations/versions/0.6.1_update_tables.py +0 -0
  65. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/migrations/versions/0.6.2_update_tables.py +0 -0
  66. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/migrations/versions/0.6.3_update_tables.py +0 -0
  67. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/models/__init__.py +0 -0
  68. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/models/base.py +0 -0
  69. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/models/dataset.py +0 -0
  70. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/models/facet.py +0 -0
  71. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/models/file.py +0 -0
  72. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/models/options.py +0 -0
  73. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/models/query.py +0 -0
  74. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/models/selection.py +0 -0
  75. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/models/sql.py +0 -0
  76. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/models/synda_file.py +0 -0
  77. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/models/tag.py +0 -0
  78. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/models/utils.py +0 -0
  79. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/py.typed +0 -0
  80. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/result.py +0 -0
  81. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/tui.py +0 -0
  82. {esgpull-0.6.3 → esgpull-0.6.4}/esgpull/utils.py +0 -0
  83. {esgpull-0.6.3 → esgpull-0.6.4}/tests/__init__.py +0 -0
  84. {esgpull-0.6.3 → esgpull-0.6.4}/tests/conftest.py +0 -0
  85. {esgpull-0.6.3 → esgpull-0.6.4}/tests/test_auth.py +0 -0
  86. {esgpull-0.6.3 → esgpull-0.6.4}/tests/test_config.py +0 -0
  87. {esgpull-0.6.3 → esgpull-0.6.4}/tests/test_context.py +0 -0
  88. {esgpull-0.6.3 → esgpull-0.6.4}/tests/test_db.py +0 -0
  89. {esgpull-0.6.3 → esgpull-0.6.4}/tests/test_fs.py +0 -0
  90. {esgpull-0.6.3 → esgpull-0.6.4}/tests/test_graph.py +0 -0
  91. {esgpull-0.6.3 → esgpull-0.6.4}/tests/test_query.py +0 -0
  92. {esgpull-0.6.3 → esgpull-0.6.4}/tests/test_selection.py +0 -0
  93. {esgpull-0.6.3 → esgpull-0.6.4}/tests/test_synda.py +0 -0
  94. {esgpull-0.6.3 → esgpull-0.6.4}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: esgpull
3
- Version: 0.6.3
3
+ Version: 0.6.4
4
4
  Summary: ESGF data discovery, download, replication tool
5
5
  Author-Email: Sven Rodriguez <srodriguez@ipsl.fr>
6
6
  License: BSD 3-Clause License
@@ -0,0 +1,25 @@
1
+ """update tables
2
+
3
+ Revision ID: 0.6.4
4
+ Revises: 0.6.3
5
+ Create Date: 2024-07-09 11:04:30.762439
6
+
7
+ """
8
+
9
+ # revision identifiers, used by Alembic.
10
+ revision = "0.6.4"
11
+ down_revision = "0.6.3"
12
+ branch_labels = None
13
+ depends_on = None
14
+
15
+
16
+ def upgrade() -> None:
17
+ # ### commands auto generated by Alembic - please adjust! ###
18
+ pass
19
+ # ### end Alembic commands ###
20
+
21
+
22
+ def downgrade() -> None:
23
+ # ### commands auto generated by Alembic - please adjust! ###
24
+ pass
25
+ # ### end Alembic commands ###
@@ -41,7 +41,6 @@ class Task:
41
41
  def __init__(
42
42
  self,
43
43
  config: Config,
44
- auth: Auth,
45
44
  fs: Filesystem,
46
45
  # *,
47
46
  # url: str | None = None,
@@ -49,7 +48,6 @@ class Task:
49
48
  start_callbacks: list[Callback] | None = None,
50
49
  ) -> None:
51
50
  self.config = config
52
- self.auth = auth
53
51
  self.fs = fs
54
52
  self.ctx = DownloadCtx(file)
55
53
  if not self.config.download.disable_checksum:
@@ -61,16 +59,6 @@ class Task:
61
59
  # else:
62
60
  # raise ValueError("no arguments")
63
61
  self.downloader = Simple()
64
- msg: str | None = None
65
- if not default_ssl_context_loaded:
66
- msg = load_default_ssl_context()
67
- self.ssl_context: ssl.SSLContext | bool
68
- if self.config.download.disable_ssl:
69
- self.ssl_context = False
70
- else:
71
- if msg is not None:
72
- logger.info(msg)
73
- self.ssl_context = default_ssl_context
74
62
  if start_callbacks is None:
75
63
  self.start_callbacks = []
76
64
  else:
@@ -93,20 +81,13 @@ class Task:
93
81
  # raise ValueError(f"{url} is not valid")
94
82
 
95
83
  async def stream(
96
- self, semaphore: asyncio.Semaphore
84
+ self,
85
+ semaphore: asyncio.Semaphore,
86
+ client: AsyncClient,
97
87
  ) -> AsyncIterator[Result]:
98
88
  ctx = self.ctx
99
89
  try:
100
- async with (
101
- semaphore,
102
- self.fs.open(ctx.file) as file_obj,
103
- AsyncClient(
104
- follow_redirects=True,
105
- cert=self.auth.cert,
106
- verify=self.ssl_context,
107
- timeout=self.config.download.http_timeout,
108
- ) as client,
109
- ):
90
+ async with semaphore, self.fs.open(ctx.file) as file_obj:
110
91
  for callback in self.start_callbacks:
111
92
  callback()
112
93
  stream = self.downloader.stream(
@@ -117,6 +98,7 @@ class Task:
117
98
  async for ctx in stream:
118
99
  if ctx.chunk is not None:
119
100
  await file_obj.write(ctx.chunk)
101
+ ctx.chunk = None
120
102
  if ctx.error:
121
103
  err = DownloadSizeError(ctx.completed, ctx.file.size)
122
104
  yield Err(ctx, err)
@@ -129,7 +111,8 @@ class Task:
129
111
  HTTPError,
130
112
  DownloadSizeError,
131
113
  GeneratorExit,
132
- ssl.SSLError
114
+ ssl.SSLError,
115
+ FileNotFoundError,
133
116
  # KeyboardInterrupt,
134
117
  ) as err:
135
118
  yield Err(ctx, err)
@@ -145,13 +128,23 @@ class Processor:
145
128
  start_callbacks: dict[str, list[Callback]],
146
129
  ) -> None:
147
130
  self.config = config
131
+ self.auth = auth
148
132
  self.fs = fs
149
133
  self.files = list(filter(self.should_download, files))
150
134
  self.tasks = []
135
+ msg: str | None = None
136
+ if not default_ssl_context_loaded:
137
+ msg = load_default_ssl_context()
138
+ self.ssl_context: ssl.SSLContext | bool
139
+ if self.config.download.disable_ssl:
140
+ self.ssl_context = False
141
+ else:
142
+ if msg is not None:
143
+ logger.info(msg)
144
+ self.ssl_context = default_ssl_context
151
145
  for file in files:
152
146
  task = Task(
153
147
  config=config,
154
- auth=auth,
155
148
  fs=fs,
156
149
  file=file,
157
150
  start_callbacks=start_callbacks[file.sha],
@@ -166,7 +159,13 @@ class Processor:
166
159
 
167
160
  async def process(self) -> AsyncIterator[Result]:
168
161
  semaphore = asyncio.Semaphore(self.config.download.max_concurrent)
169
- streams = [task.stream(semaphore) for task in self.tasks]
170
- async with merge(*streams).stream() as stream:
171
- async for result in stream:
172
- yield result
162
+ async with AsyncClient(
163
+ follow_redirects=True,
164
+ cert=self.auth.cert,
165
+ verify=self.ssl_context,
166
+ timeout=self.config.download.http_timeout,
167
+ ) as client:
168
+ streams = [task.stream(semaphore, client) for task in self.tasks]
169
+ async with merge(*streams).stream() as stream:
170
+ async for result in stream:
171
+ yield result
@@ -0,0 +1 @@
1
+ __version__ = "0.6.4"
@@ -33,7 +33,7 @@ dependencies = [
33
33
  "platformdirs>=2.6.2",
34
34
  "pyparsing>=3.0.9",
35
35
  ]
36
- version = "0.6.3"
36
+ version = "0.6.4"
37
37
 
38
38
  [project.license]
39
39
  file = "LICENSE"
@@ -3,7 +3,6 @@ import asyncio
3
3
  import httpx
4
4
  import pytest
5
5
 
6
- from esgpull.auth import Auth
7
6
  from esgpull.fs import FileCheck, Filesystem
8
7
  from esgpull.models import File
9
8
  from esgpull.processor import Task
@@ -58,19 +57,15 @@ def fs(config):
58
57
 
59
58
 
60
59
  @pytest.fixture
61
- def auth(config):
62
- return Auth.from_config(config)
63
-
64
-
65
- @pytest.fixture
66
- def task(config, auth, fs, smallfile):
67
- return Task(config, auth, fs, file=smallfile)
60
+ def task(config, fs, smallfile):
61
+ return Task(config, fs, file=smallfile)
68
62
 
69
63
 
70
64
  async def run_task(task_):
71
65
  semaphore = asyncio.Semaphore(1)
72
- async for result in task_.stream(semaphore):
73
- ...
66
+ async with httpx.AsyncClient() as client:
67
+ async for result in task_.stream(semaphore, client):
68
+ ...
74
69
  return result
75
70
 
76
71
 
@@ -78,7 +73,7 @@ async def run_task(task_):
78
73
  raises=(httpx.ConnectTimeout, httpx.ReadTimeout),
79
74
  reason="this is dependent on the IPSL data node's health (unstable)",
80
75
  )
81
- def test_task(auth, fs, smallfile, task):
76
+ def test_task(fs, smallfile, task):
82
77
  result = asyncio.run(run_task(task))
83
78
  if not result.ok:
84
79
  raise result.err
@@ -1,105 +0,0 @@
1
- # from __future__ import annotations
2
-
3
- # import click
4
- # from click.exceptions import Abort, Exit
5
-
6
- # from esgpull import Esgpull
7
- # from esgpull.cli.decorators import args, opts
8
- # from esgpull.cli.utils import get_queries, valid_name_tag
9
- # from esgpull.graph import Graph
10
- # from esgpull.tui import Verbosity
11
-
12
-
13
- # @click.command()
14
- # @args.query_id
15
- # @opts.tag
16
- # @opts.children
17
- # @opts.verbosity
18
- # def link(
19
- # query_id: str | None,
20
- # tag: str | None,
21
- # children: bool,
22
- # verbosity: Verbosity,
23
- # ) -> None:
24
- # """
25
- # Link known files to query/tag.
26
- # Offline mode to avoid searching esgf ?
27
- # """
28
- # esg = Esgpull(verbosity=verbosity)
29
- # with esg.ui.logging("remove", onraise=Abort):
30
- # if query_id is None and tag is None:
31
- # raise click.UsageError("No query or tag provided.")
32
- # if not valid_name_tag(esg.graph, esg.ui, query_id, tag):
33
- # raise Exit(1)
34
- # queries = get_queries(
35
- # esg.graph,
36
- # query_id,
37
- # tag,
38
- # children=children,
39
- # )
40
- # nb = len(queries)
41
- # ies = "ies" if nb > 1 else "y"
42
- # graph = Graph(None)
43
- # graph.add(*queries)
44
- # esg.ui.print(graph)
45
- # msg = f"Remove {nb} quer{ies}?"
46
- # if not esg.ui.ask(msg, default=True):
47
- # raise Abort
48
- # for query in queries:
49
- # if not children and esg.graph.get_children(query.sha):
50
- # esg.ui.print(
51
- # ":stop_sign: Some queries block "
52
- # f"removal of {query.rich_name}."
53
- # )
54
- # if esg.ui.ask("Show blocking queries?", default=False):
55
- # esg.ui.print(esg.graph.subgraph(query, children=True))
56
- # raise Exit(1)
57
- # esg.db.delete(*queries)
58
- # esg.ui.print(":+1:")
59
-
60
-
61
- # @click.command()
62
- # @args.query_id
63
- # @opts.tag
64
- # @opts.children
65
- # @opts.verbosity
66
- # def unlink(
67
- # query_id: str | None,
68
- # tag: str | None,
69
- # children: bool,
70
- # verbosity: Verbosity,
71
- # ) -> None:
72
- # """
73
- # Unlink files that were associated to query/tag
74
- # """
75
- # esg = Esgpull(verbosity=verbosity)
76
- # with esg.ui.logging("remove", onraise=Abort):
77
- # if query_id is None and tag is None:
78
- # raise click.UsageError("No query or tag provided.")
79
- # if not valid_name_tag(esg.graph, esg.ui, query_id, tag):
80
- # raise Exit(1)
81
- # queries = get_queries(
82
- # esg.graph,
83
- # query_id,
84
- # tag,
85
- # children=children,
86
- # )
87
- # nb = len(queries)
88
- # ies = "ies" if nb > 1 else "y"
89
- # graph = Graph(None)
90
- # graph.add(*queries)
91
- # esg.ui.print(graph)
92
- # msg = f"Remove {nb} quer{ies}?"
93
- # if not esg.ui.ask(msg, default=True):
94
- # raise Abort
95
- # for query in queries:
96
- # if not children and esg.graph.get_children(query.sha):
97
- # esg.ui.print(
98
- # ":stop_sign: Some queries block "
99
- # f"removal of {query.rich_name}."
100
- # )
101
- # if esg.ui.ask("Show blocking queries?", default=False):
102
- # esg.ui.print(esg.graph.subgraph(query, children=True))
103
- # raise Exit(1)
104
- # esg.db.delete(*queries)
105
- # esg.ui.print(":+1:")
@@ -1,13 +0,0 @@
1
- # from esgpull.models import Query
2
-
3
-
4
- # IPCC_SCENARIOS = Query(
5
- # select=dict(
6
- # query=(
7
- # "experiment:(rcp26 rcp45 rcp60 rcp85) OR "
8
- # "experiment_id:(ssp119 ssp126 ssp245 ssp370 ssp460 ssp585)"
9
- # )
10
- # )
11
- # )
12
-
13
- # TEMPERATURE = Query(select=dict(variable=["tas", "tos", "tasmin", "tasmax"]))
@@ -1 +0,0 @@
1
- __version__ = "0.6.3"
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