freva-client 2410.0.0b1__py3-none-any.whl → 2410.0.1__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.

Potentially problematic release.


This version of freva-client might be problematic. Click here for more details.

freva_client/__init__.py CHANGED
@@ -17,5 +17,5 @@ need to apply data analysis plugins, please visit the
17
17
  from .auth import authenticate
18
18
  from .query import databrowser
19
19
 
20
- __version__ = "2410.0.0-beta1"
20
+ __version__ = "2410.0.1"
21
21
  __all__ = ["authenticate", "databrowser", "__version__"]
@@ -49,7 +49,9 @@ def authenticate_cli(
49
49
  "-f",
50
50
  help="Force token recreation, even if current token is still valid.",
51
51
  ),
52
- verbose: int = typer.Option(0, "-v", help="Increase verbosity", count=True),
52
+ verbose: int = typer.Option(
53
+ 0, "-v", help="Increase verbosity", count=True
54
+ ),
53
55
  version: Optional[bool] = typer.Option(
54
56
  False,
55
57
  "-V",
@@ -163,7 +163,9 @@ def metadata_search(
163
163
  parse_json: bool = typer.Option(
164
164
  False, "-j", "--json", help="Parse output in json format."
165
165
  ),
166
- verbose: int = typer.Option(0, "-v", help="Increase verbosity", count=True),
166
+ verbose: int = typer.Option(
167
+ 0, "-v", help="Increase verbosity", count=True
168
+ ),
167
169
  version: Optional[bool] = typer.Option(
168
170
  False,
169
171
  "-V",
@@ -185,7 +187,9 @@ def metadata_search(
185
187
  result = databrowser.metadata_search(
186
188
  *(facets or []),
187
189
  time=time or "",
188
- time_select=cast(Literal["file", "flexible", "strict"], time_select.value),
190
+ time_select=cast(
191
+ Literal["file", "flexible", "strict"], time_select.value
192
+ ),
189
193
  flavour=cast(
190
194
  Literal["freva", "cmip6", "cmip5", "cordex", "nextgems"],
191
195
  flavour.value,
@@ -249,7 +253,9 @@ def data_search(
249
253
  "--time-select",
250
254
  help=TimeSelect.get_help(),
251
255
  ),
252
- zarr: bool = typer.Option(False, "--zarr", help="Create zarr stream files."),
256
+ zarr: bool = typer.Option(
257
+ False, "--zarr", help="Create zarr stream files."
258
+ ),
253
259
  access_token: Optional[str] = typer.Option(
254
260
  None,
255
261
  "--access-token",
@@ -283,7 +289,9 @@ def data_search(
283
289
  "the hostname is read from a config file"
284
290
  ),
285
291
  ),
286
- verbose: int = typer.Option(0, "-v", help="Increase verbosity", count=True),
292
+ verbose: int = typer.Option(
293
+ 0, "-v", help="Increase verbosity", count=True
294
+ ),
287
295
  multiversion: bool = typer.Option(
288
296
  False,
289
297
  "--multi-version",
@@ -417,7 +425,9 @@ def intake_catalogue(
417
425
  "the hostname is read from a config file"
418
426
  ),
419
427
  ),
420
- verbose: int = typer.Option(0, "-v", help="Increase verbosity", count=True),
428
+ verbose: int = typer.Option(
429
+ 0, "-v", help="Increase verbosity", count=True
430
+ ),
421
431
  multiversion: bool = typer.Option(
422
432
  False,
423
433
  "--multi-version",
@@ -459,7 +469,9 @@ def intake_catalogue(
459
469
  print(Path(temp_f.name).read_text())
460
470
 
461
471
 
462
- @databrowser_app.command(name="data-count", help="Count the databrowser search results")
472
+ @databrowser_app.command(
473
+ name="data-count", help="Count the databrowser search results"
474
+ )
463
475
  @exception_handler
464
476
  def count_values(
465
477
  search_keys: Optional[List[str]] = typer.Argument(
@@ -535,7 +547,9 @@ def count_values(
535
547
  parse_json: bool = typer.Option(
536
548
  False, "-j", "--json", help="Parse output in json format."
537
549
  ),
538
- verbose: int = typer.Option(0, "-v", help="Increase verbosity", count=True),
550
+ verbose: int = typer.Option(
551
+ 0, "-v", help="Increase verbosity", count=True
552
+ ),
539
553
  version: Optional[bool] = typer.Option(
540
554
  False,
541
555
  "-V",
@@ -562,7 +576,9 @@ def count_values(
562
576
  result = databrowser.count_values(
563
577
  *facets,
564
578
  time=time or "",
565
- time_select=cast(Literal["file", "flexible", "strict"], time_select),
579
+ time_select=cast(
580
+ Literal["file", "flexible", "strict"], time_select
581
+ ),
566
582
  flavour=cast(
567
583
  Literal["freva", "cmip6", "cmip5", "cordex", "nextgems"],
568
584
  flavour.value,
@@ -578,7 +594,9 @@ def count_values(
578
594
  databrowser(
579
595
  *facets,
580
596
  time=time or "",
581
- time_select=cast(Literal["file", "flexible", "strict"], time_select),
597
+ time_select=cast(
598
+ Literal["file", "flexible", "strict"], time_select
599
+ ),
582
600
  flavour=cast(
583
601
  Literal["freva", "cmip6", "cmip5", "cordex", "nextgems"],
584
602
  flavour.value,
@@ -602,108 +620,3 @@ def count_values(
602
620
  print(f"{key}: {', '.join(counts)}")
603
621
  else:
604
622
  print(result)
605
-
606
-
607
- user_data_app = typer.Typer(help="Add or delete user data.")
608
- databrowser_app.add_typer(user_data_app, name="user-data")
609
-
610
-
611
- @user_data_app.command(name="add", help="Add user data into the databrowser.")
612
- @exception_handler
613
- def user_data_add(
614
- username: str = typer.Argument(..., help="Username of the data owner"),
615
- paths: List[str] = typer.Option(
616
- ...,
617
- "--path",
618
- "-p",
619
- help="Paths to the user's data to be added.",
620
- ),
621
- facets: Optional[List[str]] = typer.Option(
622
- None,
623
- "--facet",
624
- "-f",
625
- help="Facet key-value pairs for metadata in the format key=value.",
626
- ),
627
- host: Optional[str] = typer.Option(
628
- None,
629
- "--host",
630
- help=(
631
- "Set the hostname of the databrowser. If not set (default), "
632
- "the hostname is read from a config file."
633
- ),
634
- ),
635
- access_token: Optional[str] = typer.Option(
636
- None,
637
- "--access-token",
638
- help="Access token for authentication when adding user data.",
639
- ),
640
- verbose: int = typer.Option(0, "-v", help="Increase verbosity", count=True),
641
- ) -> None:
642
- """Add user data into the databrowser."""
643
- logger.set_verbosity(verbose)
644
- logger.debug("Checking if the user has the right to add data")
645
- result = databrowser(host=host)
646
- _auth(result._cfg.auth_url, access_token)
647
-
648
- facet_dict = {}
649
- if facets:
650
- for facet in facets:
651
- if "=" not in facet:
652
- logger.error(
653
- f"Invalid facet format: {facet}. Expected format: key=value."
654
- )
655
- raise typer.Exit(code=1)
656
- key, value = facet.split("=", 1)
657
- facet_dict[key] = value
658
-
659
- logger.debug(
660
- f"Adding user data for {username} with paths {paths} and facets {facet_dict}"
661
- )
662
- result.add_user_data(username=username, paths=paths, facets=facet_dict)
663
- logger.info("User data started crawling. Check the Databrowser to see the updates.")
664
-
665
-
666
- @user_data_app.command(name="delete", help="Delete user data from the databrowser.")
667
- @exception_handler
668
- def user_data_remove(
669
- username: str = typer.Argument(..., help="Username of the data owner"),
670
- search_keys: List[str] = typer.Option(
671
- None,
672
- "--search-key",
673
- "-s",
674
- help="Search keys for the data to be deleted in the format key=value.",
675
- ),
676
- host: Optional[str] = typer.Option(
677
- None,
678
- "--host",
679
- help=(
680
- "Set the hostname of the databrowser. If not set (default), "
681
- "the hostname is read from a config file."
682
- ),
683
- ),
684
- access_token: Optional[str] = typer.Option(
685
- None,
686
- "--access-token",
687
- help="Access token for authentication when deleting user data.",
688
- ),
689
- verbose: int = typer.Option(0, "-v", help="Increase verbosity", count=True),
690
- ) -> None:
691
- """Delete user data from the databrowser."""
692
- logger.set_verbosity(verbose)
693
- logger.debug("Checking if the user has the right to delete data")
694
- result = databrowser(host=host)
695
- _auth(result._cfg.auth_url, access_token)
696
-
697
- search_key_dict = {}
698
- if search_keys:
699
- for search_key in search_keys:
700
- if "=" not in search_key:
701
- logger.error(
702
- f"Invalid search key format: {search_key}. "
703
- "Expected format: key=value."
704
- )
705
- raise typer.Exit(code=1)
706
- key, value = search_key.split("=", 1)
707
- search_key_dict[key] = value
708
- result.delete_user_data(username=username, search_keys=search_key_dict)
709
- logger.info("User data deleted successfully.")
freva_client/query.py CHANGED
@@ -206,7 +206,9 @@ class databrowser:
206
206
  self,
207
207
  *facets: str,
208
208
  uniq_key: Literal["file", "uri"] = "file",
209
- flavour: Literal["freva", "cmip6", "cmip5", "cordex", "nextgems"] = "freva",
209
+ flavour: Literal[
210
+ "freva", "cmip6", "cmip5", "cordex", "nextgems"
211
+ ] = "freva",
210
212
  time: Optional[str] = None,
211
213
  host: Optional[str] = None,
212
214
  time_select: Literal["flexible", "strict", "file"] = "flexible",
@@ -241,7 +243,8 @@ class databrowser:
241
243
  self, facets: Tuple[str, ...], search_kw: Dict[str, List[str]]
242
244
  ) -> None:
243
245
  metadata = {
244
- k: v[::2] for (k, v) in self._facet_search(extended_search=True).items()
246
+ k: v[::2]
247
+ for (k, v) in self._facet_search(extended_search=True).items()
245
248
  }
246
249
  primary_key = list(metadata.keys() or ["project"])[0]
247
250
  num_facets = 0
@@ -264,7 +267,9 @@ class databrowser:
264
267
  headers = {}
265
268
  if self._stream_zarr:
266
269
  query_url = self._cfg.zarr_loader_url
267
- token = self._auth.check_authentication(auth_url=self._cfg.auth_url)
270
+ token = self._auth.check_authentication(
271
+ auth_url=self._cfg.auth_url
272
+ )
268
273
  headers = {"Authorization": f"Bearer {token['access_token']}"}
269
274
  result = self._get(query_url, headers=headers, stream=True)
270
275
  if result is not None:
@@ -272,7 +277,9 @@ class databrowser:
272
277
  for res in result.iter_lines():
273
278
  yield res.decode("utf-8")
274
279
  except KeyboardInterrupt:
275
- pprint("[red][b]User interrupt: Exit[/red][/b]", file=sys.stderr)
280
+ pprint(
281
+ "[red][b]User interrupt: Exit[/red][/b]", file=sys.stderr
282
+ )
276
283
 
277
284
  def __repr__(self) -> str:
278
285
  params = ", ".join(
@@ -299,7 +306,9 @@ class databrowser:
299
306
 
300
307
  # Create a table-like structure for available flavors and search facets
301
308
  style = 'style="text-align: left"'
302
- facet_heading = f"Available search facets for <em>{self._flavour}</em> flavour"
309
+ facet_heading = (
310
+ f"Available search facets for <em>{self._flavour}</em> flavour"
311
+ )
303
312
  html_repr = (
304
313
  "<table>"
305
314
  f"<tr><th colspan='2' {style}>{self.__class__.__name__}"
@@ -338,9 +347,13 @@ class databrowser:
338
347
  kwargs: Dict[str, Any] = {"stream": True}
339
348
  url = self._cfg.intake_url
340
349
  if self._stream_zarr:
341
- token = self._auth.check_authentication(auth_url=self._cfg.auth_url)
350
+ token = self._auth.check_authentication(
351
+ auth_url=self._cfg.auth_url
352
+ )
342
353
  url = self._cfg.zarr_loader_url
343
- kwargs["headers"] = {"Authorization": f"Bearer {token['access_token']}"}
354
+ kwargs["headers"] = {
355
+ "Authorization": f"Bearer {token['access_token']}"
356
+ }
344
357
  kwargs["params"] = {"catalogue-type": "intake"}
345
358
  result = self._get(url, **kwargs)
346
359
  if result is None:
@@ -352,7 +365,9 @@ class databrowser:
352
365
  for content in result.iter_content(decode_unicode=False):
353
366
  stream.write(content)
354
367
  except Exception as error:
355
- raise ValueError(f"Couldn't write catalogue content: {error}") from None
368
+ raise ValueError(
369
+ f"Couldn't write catalogue content: {error}"
370
+ ) from None
356
371
 
357
372
  def intake_catalogue(self) -> intake_esm.core.esm_datastore:
358
373
  """Create an intake esm catalogue object from the search.
@@ -389,7 +404,9 @@ class databrowser:
389
404
  def count_values(
390
405
  cls,
391
406
  *facets: str,
392
- flavour: Literal["freva", "cmip6", "cmip5", "cordex", "nextgems"] = "freva",
407
+ flavour: Literal[
408
+ "freva", "cmip6", "cmip5", "cordex", "nextgems"
409
+ ] = "freva",
393
410
  time: Optional[str] = None,
394
411
  host: Optional[str] = None,
395
412
  time_select: Literal["flexible", "strict", "file"] = "flexible",
@@ -487,7 +504,9 @@ class databrowser:
487
504
  result = this._facet_search(extended_search=extended_search)
488
505
  counts = {}
489
506
  for facet, value_counts in result.items():
490
- counts[facet] = dict(zip(value_counts[::2], map(int, value_counts[1::2])))
507
+ counts[facet] = dict(
508
+ zip(value_counts[::2], map(int, value_counts[1::2]))
509
+ )
491
510
  return counts
492
511
 
493
512
  @cached_property
@@ -512,14 +531,17 @@ class databrowser:
512
531
 
513
532
  """
514
533
  return {
515
- k: v[::2] for (k, v) in self._facet_search(extended_search=True).items()
534
+ k: v[::2]
535
+ for (k, v) in self._facet_search(extended_search=True).items()
516
536
  }
517
537
 
518
538
  @classmethod
519
539
  def metadata_search(
520
540
  cls,
521
541
  *facets: str,
522
- flavour: Literal["freva", "cmip6", "cmip5", "cordex", "nextgems"] = "freva",
542
+ flavour: Literal[
543
+ "freva", "cmip6", "cmip5", "cordex", "nextgems"
544
+ ] = "freva",
523
545
  time: Optional[str] = None,
524
546
  host: Optional[str] = None,
525
547
  time_select: Literal["flexible", "strict", "file"] = "flexible",
@@ -642,7 +664,9 @@ class databrowser:
642
664
  )
643
665
  return {
644
666
  k: v[::2]
645
- for (k, v) in this._facet_search(extended_search=extended_search).items()
667
+ for (k, v) in this._facet_search(
668
+ extended_search=extended_search
669
+ ).items()
646
670
  }
647
671
 
648
672
  @classmethod
@@ -709,172 +733,26 @@ class databrowser:
709
733
  constraints = data["primary_facets"]
710
734
  return {f: v for f, v in data["facets"].items() if f in constraints}
711
735
 
712
- def add_user_data(
713
- self, username: str, paths: List[str], facets: Dict[str, str]
714
- ) -> None:
715
- """Add user data to the databrowser.
716
-
717
- Via this functionality, user would be able to add data to the databrowser.
718
- It accepts file paths and metadata facets to categorize and store the user's
719
- data.
720
-
721
- Parameters
722
- ~~~~~~~~~~
723
- username: str
724
- The username of user.
725
- paths: list[str]
726
- A list of paths to the data files that should be uploaded or cataloged.
727
- facets: dict[str, str]
728
- A dictionary containing metadata facets (key-value pairs) to describe the
729
- data.
730
-
731
- Returns
732
- ~~~~~~~~
733
- None
734
- If the operation is successful, no return value is provided.
735
-
736
- Raises
737
- ~~~~~~~
738
- ValueError
739
- If the operation fails to add the user data.
740
-
741
- Example
742
- ~~~~~~~
743
- .. execute_code::
744
-
745
- from freva_client import authenticate, databrowser
746
- token_info = authenticate(username="janedoe")
747
- db = databrowser()
748
- db.add_user_data(
749
- "janedoe",
750
- ["."],
751
- {"project": "cmip5", "experiment": "something"}
752
- )
753
- """
754
- url = f"{self._cfg.userdata_url}/{username}"
755
- token = self._auth.check_authentication(auth_url=self._cfg.auth_url)
756
- headers = {"Authorization": f"Bearer {token['access_token']}"}
757
- params = {"paths": paths}
758
- if "username" in facets:
759
- del facets["username"]
760
- data = facets
761
- result = self._put(url, data=data, headers=headers, params=params)
762
-
763
- if result is None:
764
- raise ValueError("Failed to add user data")
765
-
766
- def delete_user_data(self, username: str, search_keys: Dict[str, str]) -> None:
767
- """
768
- Delete user data from the databrowser.
769
-
770
- Uing this, user would be able to delete the user's data from the databrowser
771
- based on the provided search keys.
772
-
773
- Parameters
774
- ~~~~~~~~~~
775
- username: str
776
- The username associated with the data to be deleted.
777
- search_keys: dict[str, str]
778
- A dictionary containing the search keys to identify the data to be deleted.
779
-
780
- Returns
781
- ~~~~~~~~
782
- None
783
- If the operation is successful, no return value is provided.
784
-
785
- Raises
786
- ~~~~~~~
787
- ValueError
788
- If the operation fails to delete the user data.
789
-
790
- Example
791
- ~~~~~~~
792
- .. execute_code::
793
-
794
- from freva_client import databrowser, authenticate
795
- token_info = authenticate(username="janedoe")
796
- db = databrowser()
797
- db.delete_user_data(
798
- "janedoe",
799
- {"project": "cmip5", "experiment": "something"}
800
- )
801
- """
802
- url = f"{self._cfg.userdata_url}/{username}"
803
- token = self._auth.check_authentication(auth_url=self._cfg.auth_url)
804
- headers = {"Authorization": f"Bearer {token['access_token']}"}
805
- data = search_keys
806
- result = self._delete(url, headers=headers, json=data)
807
- if result is None:
808
- raise ValueError("Failed to delete user data")
809
-
810
- def _get(self, url: str, **kwargs: Any) -> Optional[requests.models.Response]:
736
+ def _get(
737
+ self, url: str, **kwargs: Any
738
+ ) -> Optional[requests.models.Response]:
811
739
  """Apply the get method to the databrowser."""
812
740
  logger.debug("Searching %s with parameters: %s", url, self._params)
813
741
  params = kwargs.pop("params", {})
814
742
  kwargs.setdefault("timeout", 30)
815
743
  try:
816
- res = requests.get(url, params={**self._params, **params}, **kwargs)
817
- res.raise_for_status()
818
- return res
819
- except KeyboardInterrupt:
820
- pprint("[red][b]User interrupt: Exit[/red][/b]", file=sys.stderr)
821
- except (
822
- requests.exceptions.ConnectionError,
823
- requests.exceptions.HTTPError,
824
- ) as error:
825
- msg = f"Search request failed with {error}"
826
- if self._fail_on_error:
827
- raise ValueError(msg) from None
828
- logger.warning(msg)
829
- return None
830
-
831
- def _put(
832
- self, url: str, data: Dict[str, Any], **kwargs: Any
833
- ) -> Optional[requests.models.Response]:
834
- """Apply the PUT method to the databrowser."""
835
- logger.debug(
836
- "PUT request to %s with data: %s and parameters: %s",
837
- url,
838
- data,
839
- self._params,
840
- )
841
- kwargs.setdefault("timeout", 30)
842
- params = kwargs.pop("params", {})
843
- try:
844
- res = requests.put(
845
- url, json=data, params={**self._params, **params}, **kwargs
744
+ res = requests.get(
745
+ url, params={**self._params, **params}, **kwargs
846
746
  )
847
747
  res.raise_for_status()
848
748
  return res
849
749
  except KeyboardInterrupt:
850
750
  pprint("[red][b]User interrupt: Exit[/red][/b]", file=sys.stderr)
851
-
852
751
  except (
853
752
  requests.exceptions.ConnectionError,
854
753
  requests.exceptions.HTTPError,
855
754
  ) as error:
856
- msg = f"adding user data request failed with {error}"
857
- if self._fail_on_error:
858
- raise ValueError(msg) from None
859
- logger.warning(msg)
860
- return None
861
-
862
- def _delete(self, url: str, **kwargs: Any) -> Optional[requests.models.Response]:
863
- """Apply the DELETE method to the databrowser."""
864
- logger.debug("DELETE request to %s with parameters: %s", url, self._params)
865
- params = kwargs.pop("params", {})
866
- kwargs.setdefault("timeout", 30)
867
- try:
868
- res = requests.delete(url, params={**self._params, **params}, **kwargs)
869
- res.raise_for_status()
870
- return res
871
- except KeyboardInterrupt:
872
- pprint("[red][b]User interrupt: Exit[/red][/b]", file=sys.stderr)
873
- except (
874
- requests.exceptions.ConnectionError,
875
- requests.exceptions.HTTPError,
876
- ) as error:
877
- msg = f"DELETE request failed with {error}"
755
+ msg = f"Search request failed with {error}"
878
756
  if self._fail_on_error:
879
757
  raise ValueError(msg) from None
880
758
  logger.warning(msg)
@@ -57,7 +57,9 @@ class Config:
57
57
  host = f"{host}:{port}"
58
58
  return f"{scheme}://{host}"
59
59
 
60
- def _read_config(self, path: Path, file_type: Literal["toml", "ini"]) -> str:
60
+ def _read_config(
61
+ self, path: Path, file_type: Literal["toml", "ini"]
62
+ ) -> str:
61
63
  """Read the configuration."""
62
64
  data_types = {"toml": self._read_toml, "ini": self._read_ini}
63
65
  try:
@@ -70,9 +72,11 @@ class Config:
70
72
  def overview(self) -> Dict[str, Any]:
71
73
  """Get an overview of the all databrowser flavours and search keys."""
72
74
  try:
73
- res = requests.get(f"{self.databrowser_url}/overview", timeout=15)
75
+ res = requests.get(f"{self.databrowser_url}/overview", timeout=3)
74
76
  except requests.exceptions.ConnectionError:
75
- raise ValueError(f"Could not connect to {self.databrowser_url}") from None
77
+ raise ValueError(
78
+ f"Could not connect to {self.databrowser_url}"
79
+ ) from None
76
80
  return cast(Dict[str, Any], res.json())
77
81
 
78
82
  def _get_databrowser_host_from_config(self) -> str:
@@ -87,7 +91,9 @@ class Config:
87
91
  Path(appdirs.user_config_dir("freva")) / "freva.toml": "toml",
88
92
  Path(self.get_dirs(user=True)) / "freva.toml": "toml",
89
93
  freva_config: "toml",
90
- Path(os.environ.get("EVALUATION_SYSTEM_CONFIG_FILE") or eval_conf): "ini",
94
+ Path(
95
+ os.environ.get("EVALUATION_SYSTEM_CONFIG_FILE") or eval_conf
96
+ ): "ini",
91
97
  }
92
98
  for config_path, config_type in paths.items():
93
99
  if config_path.is_file():
@@ -130,7 +136,8 @@ class Config:
130
136
  def metadata_url(self) -> str:
131
137
  """Define the endpoint for the metadata search."""
132
138
  return (
133
- f"{self.databrowser_url}/metadata_search/" f"{self.flavour}/{self.uniq_key}"
139
+ f"{self.databrowser_url}/metadata_search/"
140
+ f"{self.flavour}/{self.uniq_key}"
134
141
  )
135
142
 
136
143
  @staticmethod
@@ -170,8 +177,3 @@ class Config:
170
177
  # The default scheme is 'posix_prefix' or 'nt', and should work for e.g.
171
178
  # installing into a virtualenv
172
179
  return Path(sysconfig.get_path("data")) / "share" / "freva"
173
-
174
- @property
175
- def userdata_url(self) -> str:
176
- """Define the url for adding and deleting user-data."""
177
- return f"{self.databrowser_url}/userdata"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: freva-client
3
- Version: 2410.0.0b1
3
+ Version: 2410.0.1
4
4
  Summary: Search for climate data based on key-value pairs
5
5
  Author-email: "DKRZ, Clint" <freva@dkrz.de>
6
6
  Requires-Python: >=3.8
@@ -22,6 +22,7 @@ Requires-Dist: authlib
22
22
  Requires-Dist: requests
23
23
  Requires-Dist: intake_esm
24
24
  Requires-Dist: rich
25
+ Requires-Dist: setuptools
25
26
  Requires-Dist: tomli
26
27
  Requires-Dist: typer
27
28
  Requires-Dist: tox ; extra == "dev"
@@ -0,0 +1,19 @@
1
+ freva_client/__init__.py,sha256=v82gUih2G4ZlHhKautrsVEn3KkWnvI2Hwg5LLYk4AC4,851
2
+ freva_client/__main__.py,sha256=JVj12puT4o8JfhKLAggR2-NKCZa3wKwsYGi4HQ61DOQ,149
3
+ freva_client/auth.py,sha256=o33EKI5CxMOBY0nWFLmZT-V6v2U9L1qGjLcE7y4PIoE,6814
4
+ freva_client/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ freva_client/query.py,sha256=VJHUxuESORsXgyqFs7xbCpoGjCmQikM3453yMtOEmFw,27950
6
+ freva_client/cli/__init__.py,sha256=NgTqBZGdozmTZtJduJUMrZj-opGw2KoT20tg6sc_xqo,149
7
+ freva_client/cli/auth_cli.py,sha256=_WaEL6iSeE2agv-G-qka-cC6UoedtfoCAC_Vqfk0jKw,1856
8
+ freva_client/cli/cli_app.py,sha256=AE7nSnm5okwrp6y4a8vas8QzPZGyGhhCUl8bc8jKBUg,886
9
+ freva_client/cli/cli_parser.py,sha256=c-_WG56g6arLvnayb9SO1OeHt7AjBV4egI_vTEYee4I,5042
10
+ freva_client/cli/cli_utils.py,sha256=ygwkNYqnjYJFRQu1M0r1VFQLAAl5lT05bM4tVsR0Xpc,841
11
+ freva_client/cli/databrowser_cli.py,sha256=kFu44cAzwQ-HLd--d649ER6BCCxjRt9LeJA7xgIBlJ4,20924
12
+ freva_client/utils/__init__.py,sha256=ySHn-3CZBwfZW2s0EpZ3INxUWOw1V4LOlKIxSLYr52U,1000
13
+ freva_client/utils/databrowser_utils.py,sha256=sPnPk8KgQSztfr7sDrBYillFiSzYIB5if66pv-VFR40,6380
14
+ freva_client/utils/logger.py,sha256=xd_3jjbsD1UBWlZZe8OUtKLpG7lbLcH46yiJ_bftyKg,2464
15
+ freva_client-2410.0.1.data/data/share/freva/freva.toml,sha256=64Rh4qvWc9TaGJMXMi8tZW14FnESt5Z24y17BfD2VyM,736
16
+ freva_client-2410.0.1.dist-info/entry_points.txt,sha256=zGyEwHrH_kAGLsCXv00y7Qnp-WjXkUuIomHkfGMCxtA,53
17
+ freva_client-2410.0.1.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
18
+ freva_client-2410.0.1.dist-info/METADATA,sha256=naCBSzYCuR8mFwvbYwSonFdnet0sjKv7ev47wLsgQUk,2476
19
+ freva_client-2410.0.1.dist-info/RECORD,,
@@ -1,19 +0,0 @@
1
- freva_client/__init__.py,sha256=wKmUair1qaDAzWO71EFDTZyh1PzU-f2p4zadN6AitDI,857
2
- freva_client/__main__.py,sha256=JVj12puT4o8JfhKLAggR2-NKCZa3wKwsYGi4HQ61DOQ,149
3
- freva_client/auth.py,sha256=o33EKI5CxMOBY0nWFLmZT-V6v2U9L1qGjLcE7y4PIoE,6814
4
- freva_client/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- freva_client/query.py,sha256=OCtabmCaiZwc2i4Y8Wru7FA40U0aGDJlpgmffw2MTnk,32791
6
- freva_client/cli/__init__.py,sha256=NgTqBZGdozmTZtJduJUMrZj-opGw2KoT20tg6sc_xqo,149
7
- freva_client/cli/auth_cli.py,sha256=HOx4qocAlYeO138wAnx-Kn2pieAQSK18zHq1k8EGjAo,1842
8
- freva_client/cli/cli_app.py,sha256=AE7nSnm5okwrp6y4a8vas8QzPZGyGhhCUl8bc8jKBUg,886
9
- freva_client/cli/cli_parser.py,sha256=c-_WG56g6arLvnayb9SO1OeHt7AjBV4egI_vTEYee4I,5042
10
- freva_client/cli/cli_utils.py,sha256=ygwkNYqnjYJFRQu1M0r1VFQLAAl5lT05bM4tVsR0Xpc,841
11
- freva_client/cli/databrowser_cli.py,sha256=YqO06GUpPV2F7kfK-HfDNc5_cPvfK_Fz60OIa4DaEH8,24403
12
- freva_client/utils/__init__.py,sha256=ySHn-3CZBwfZW2s0EpZ3INxUWOw1V4LOlKIxSLYr52U,1000
13
- freva_client/utils/databrowser_utils.py,sha256=-mex2FOr5VemqEHPHGdEq_FNjh4KeNmcNod02QAbT2c,6459
14
- freva_client/utils/logger.py,sha256=xd_3jjbsD1UBWlZZe8OUtKLpG7lbLcH46yiJ_bftyKg,2464
15
- freva_client-2410.0.0b1.data/data/share/freva/freva.toml,sha256=64Rh4qvWc9TaGJMXMi8tZW14FnESt5Z24y17BfD2VyM,736
16
- freva_client-2410.0.0b1.dist-info/entry_points.txt,sha256=zGyEwHrH_kAGLsCXv00y7Qnp-WjXkUuIomHkfGMCxtA,53
17
- freva_client-2410.0.0b1.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
18
- freva_client-2410.0.0b1.dist-info/METADATA,sha256=CIbbV38llOTKBormGTpFOVP3UPFsJRk2_57hdvgLWiI,2452
19
- freva_client-2410.0.0b1.dist-info/RECORD,,