coiled 1.121.1.dev23__tar.gz → 1.123.0__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.

Potentially problematic release.


This version of coiled might be problematic. Click here for more details.

Files changed (101) hide show
  1. {coiled-1.121.1.dev23 → coiled-1.123.0}/PKG-INFO +1 -1
  2. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/filestore.py +7 -16
  3. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/software_utils.py +0 -123
  4. {coiled-1.121.1.dev23 → coiled-1.123.0}/.gitignore +0 -0
  5. {coiled-1.121.1.dev23 → coiled-1.123.0}/LICENSE +0 -0
  6. {coiled-1.121.1.dev23 → coiled-1.123.0}/README.md +0 -0
  7. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/__init__.py +0 -0
  8. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/__main__.py +0 -0
  9. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/analytics.py +0 -0
  10. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/auth.py +0 -0
  11. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/batch.py +0 -0
  12. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/capture_environment.py +0 -0
  13. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/__init__.py +0 -0
  14. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/batch/__init__.py +0 -0
  15. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/batch/list.py +0 -0
  16. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/batch/logs.py +0 -0
  17. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/batch/run.py +0 -0
  18. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/batch/status.py +0 -0
  19. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/batch/wait.py +0 -0
  20. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/cluster/__init__.py +0 -0
  21. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/cluster/azure_logs.py +0 -0
  22. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/cluster/better_logs.py +0 -0
  23. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/cluster/crud.py +0 -0
  24. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/cluster/get_address.py +0 -0
  25. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/cluster/list.py +0 -0
  26. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/cluster/logs.py +0 -0
  27. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/cluster/metrics.py +0 -0
  28. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/cluster/ssh.py +0 -0
  29. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/cluster/utils.py +0 -0
  30. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/config.py +0 -0
  31. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/core.py +0 -0
  32. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/curl.py +0 -0
  33. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/diagnostics.py +0 -0
  34. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/env.py +0 -0
  35. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/file.py +0 -0
  36. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/hello/__init__.py +0 -0
  37. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/hello/examples/__init__.py +0 -0
  38. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/hello/examples/exit.py +0 -0
  39. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/hello/examples/hello_world.py +0 -0
  40. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/hello/examples/nyc_parquet.py +0 -0
  41. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/hello/examples/pytorch.py +0 -0
  42. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/hello/examples/xarray_nwm.py +0 -0
  43. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/hello/hello.py +0 -0
  44. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/hello/scripts/fill_ipython.py +0 -0
  45. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/hello/scripts/nyc_parquet.py +0 -0
  46. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/hello/scripts/pytorch.py +0 -0
  47. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/hello/scripts/xarray_nwm.py +0 -0
  48. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/hello/utils.py +0 -0
  49. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/login.py +0 -0
  50. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/notebook/__init__.py +0 -0
  51. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/notebook/notebook.py +0 -0
  52. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/package_sync.py +0 -0
  53. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/prefect.py +0 -0
  54. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/prefect_serve.py +0 -0
  55. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/run.py +0 -0
  56. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/setup/__init__.py +0 -0
  57. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/setup/amp.py +0 -0
  58. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/setup/aws.py +0 -0
  59. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/setup/azure.py +0 -0
  60. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/setup/entry.py +0 -0
  61. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/setup/gcp.py +0 -0
  62. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/setup/prometheus.py +0 -0
  63. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/setup/util.py +0 -0
  64. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/sync.py +0 -0
  65. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cli/utils.py +0 -0
  66. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/cluster.py +0 -0
  67. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/coiled.yaml +0 -0
  68. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/compatibility.py +0 -0
  69. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/config.py +0 -0
  70. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/context.py +0 -0
  71. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/core.py +0 -0
  72. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/credentials/__init__.py +0 -0
  73. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/credentials/aws.py +0 -0
  74. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/credentials/google.py +0 -0
  75. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/errors.py +0 -0
  76. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/exceptions.py +0 -0
  77. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/extensions/__init__.py +0 -0
  78. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/extensions/prefect/__init__.py +0 -0
  79. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/extensions/prefect/runners.py +0 -0
  80. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/extensions/prefect/workers.py +0 -0
  81. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/function.py +0 -0
  82. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/plugins.py +0 -0
  83. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/prefect.py +0 -0
  84. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/pypi_conda_map.py +0 -0
  85. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/scan.py +0 -0
  86. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/software.py +0 -0
  87. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/spans.py +0 -0
  88. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/spark.py +0 -0
  89. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/types.py +0 -0
  90. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/utils.py +0 -0
  91. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/v2/__init__.py +0 -0
  92. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/v2/cluster.py +0 -0
  93. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/v2/core.py +0 -0
  94. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/v2/cwi_log_link.py +0 -0
  95. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/v2/states.py +0 -0
  96. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/v2/widgets/__init__.py +0 -0
  97. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/v2/widgets/interface.py +0 -0
  98. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/v2/widgets/rich.py +0 -0
  99. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/v2/widgets/util.py +0 -0
  100. {coiled-1.121.1.dev23 → coiled-1.123.0}/coiled/websockets.py +0 -0
  101. {coiled-1.121.1.dev23 → coiled-1.123.0}/pyproject.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: coiled
3
- Version: 1.121.1.dev23
3
+ Version: 1.123.0
4
4
  Summary: Python client for coiled.io dask clusters
5
5
  Project-URL: Homepage, https://coiled.io
6
6
  Maintainer-email: Coiled <info@coiled.io>
@@ -135,24 +135,13 @@ def upload_to_filestore_with_ui(fs, local_dir):
135
135
  },
136
136
  ])
137
137
 
138
- upload_info = FilestoreManager.get_signed_upload_urls(fs["id"], files_for_upload=files)
139
-
140
- upload_urls = upload_info.get("urls")
141
- existing_blobs = upload_info.get("existing")
138
+ upload_urls = FilestoreManager.get_signed_upload_urls(fs["id"], files_for_upload=files)
142
139
 
143
140
  for local_path, relative_path, size in files:
144
- skip_upload = False
145
- existing_blob_info = existing_blobs.get(relative_path)
146
- if existing_blob_info:
147
- modified = os.path.getmtime(local_path)
148
- if size == existing_blob_info["size"] and modified < existing_blob_info["modified"]:
149
- skip_upload = True
150
-
151
- if not skip_upload:
152
- progress.batch_title = progress_title(local_path)
153
- progress.refresh()
141
+ progress.batch_title = progress_title(local_path)
142
+ progress.refresh()
154
143
 
155
- FilestoreManager.upload_to_signed_url(local_path, upload_urls[relative_path])
144
+ FilestoreManager.upload_to_signed_url(local_path, upload_urls[relative_path])
156
145
 
157
146
  done_files += 1
158
147
  done_bytes += size
@@ -212,7 +201,9 @@ class FilestoreManagerWithoutHttp:
212
201
  @classmethod
213
202
  def get_signed_upload_urls(cls, fs_id, files_for_upload):
214
203
  paths = [p for _, p, _ in files_for_upload] # relative paths
215
- return cls.make_req(f"/api/v2/filestore/fs/{fs_id}/signed-urls/upload", post=True, data={"paths": paths})
204
+ return cls.make_req(f"/api/v2/filestore/fs/{fs_id}/signed-urls/upload", post=True, data={"paths": paths}).get(
205
+ "urls"
206
+ )
216
207
 
217
208
  @classmethod
218
209
  def get_download_list_with_urls(cls, fs_id):
@@ -595,126 +595,6 @@ def get_mamba_auth(netloc: str) -> tuple[str, str] | None:
595
595
  return get_mamba_auth_dict().get(netloc, None)
596
596
 
597
597
 
598
- def _parse_rattler_auth_data(auth_data: dict) -> tuple[str, str] | None:
599
- """Parse rattler authentication data into username/password tuple.
600
-
601
- Handles rattler Authentication variants:
602
- - {"BearerToken": "token"}
603
- - {"CondaToken": "token"}
604
- - {"BasicHTTP": {"username": "user", "password": "pass"}}
605
-
606
- Returns:
607
- Tuple of (username, password) or None if unknown auth type
608
- """
609
- if "BearerToken" in auth_data:
610
- return (AUTH_BEARER_USERNAME, auth_data["BearerToken"])
611
- elif "CondaToken" in auth_data:
612
- return (CONDA_TOKEN_USERNAME, auth_data["CondaToken"])
613
- elif "BasicHTTP" in auth_data:
614
- basic_auth = auth_data["BasicHTTP"]
615
- return (
616
- basic_auth.get("username", ""),
617
- basic_auth.get("password", ""),
618
- )
619
- else:
620
- return None
621
-
622
-
623
- @functools.lru_cache
624
- def get_rattler_auth_dict(home_dir: Path | None = None) -> dict[str, tuple[str, str]]:
625
- # RATTLER_AUTH_FILE is an env var that can override the default location
626
- env_auth_file = os.environ.get("RATTLER_AUTH_FILE")
627
- if env_auth_file:
628
- auth_file = Path(env_auth_file)
629
- else:
630
- if home_dir is None:
631
- home_dir = Path.home()
632
- auth_file = home_dir / ".rattler" / "credentials.json"
633
- domain_auth = {}
634
- if auth_file.exists():
635
- with auth_file.open("r") as f:
636
- auth_data = json.load(f)
637
- for domain, auth in auth_data.items():
638
- parsed_auth = _parse_rattler_auth_data(auth)
639
- if parsed_auth:
640
- domain_auth[domain] = parsed_auth
641
- else:
642
- logger.debug(f"Encountered unknown rattler auth type {list(auth.keys())} for domain {domain}")
643
- return domain_auth
644
-
645
-
646
- def get_rattler_keyring_auth(netloc: str) -> tuple[str, str] | None:
647
- """Returns the Requests tuple auth for a given domain from rattler keyring storage."""
648
- if not HAVE_KEYRING:
649
- logger.debug("keyring not available, skipping rattler keyring auth")
650
- return None
651
-
652
- def try_keyring_auth(host: str) -> tuple[str, str] | None:
653
- """Try to get auth from keyring for a specific host using rattler's storage format."""
654
- try:
655
- # Use the existing get_keyring_auth function with "rattler" as the URL
656
- # and the host as the username to get rattler-stored credentials
657
- auth_parts = get_keyring_auth("rattler", host)
658
- if auth_parts:
659
- username, password = auth_parts
660
- if password:
661
- try:
662
- auth_data = json.loads(password)
663
- parsed_auth = _parse_rattler_auth_data(auth_data)
664
- if parsed_auth:
665
- return parsed_auth
666
- except json.JSONDecodeError:
667
- # If it's not JSON, treat it as a simple username/password
668
- return (username or host, password)
669
-
670
- except Exception as e:
671
- logger.debug(f"Error getting rattler keyring auth for {host}: {e}")
672
- return None
673
-
674
- return None
675
-
676
- # Try exact match first
677
- auth_parts = try_keyring_auth(netloc)
678
- if auth_parts:
679
- logger.debug(f"Found rattler keyring auth for {netloc}")
680
- return auth_parts
681
-
682
- # Try parent domain matches if exact match failed
683
- # If looking for foo.example.com, try example.com (but not com)
684
- parts = netloc.split(".")
685
- for i in range(1, len(parts) - 1): # Stop before single TLD
686
- parent_domain = ".".join(parts[i:])
687
-
688
- auth_parts = try_keyring_auth(parent_domain)
689
- if auth_parts:
690
- logger.debug(f"Found rattler keyring auth for {parent_domain} (matching {netloc})")
691
- return auth_parts
692
-
693
- logger.debug(f"No rattler keyring auth found for {netloc}")
694
- return None
695
-
696
-
697
- def get_rattler_auth(netloc: str) -> tuple[str, str] | None:
698
- """Returns the Requests tuple auth for a given domain from rattler keyring or auth file."""
699
- # Try keyring first (primary storage method for rattler/pixi)
700
- auth_parts = get_rattler_keyring_auth(netloc)
701
- if auth_parts:
702
- return auth_parts
703
-
704
- # Fall back to file-based storage
705
- # rattler allows wildcards, so we have to check for exact matches first
706
- auth_parts = get_rattler_auth_dict().get(netloc, None)
707
- if auth_parts:
708
- return auth_parts
709
-
710
- # then check for wildcard matches in file storage
711
- for domain, auth in get_rattler_auth_dict().items():
712
- if domain.startswith("*.") and netloc.endswith(domain[1:]):
713
- return auth
714
-
715
- return None
716
-
717
-
718
598
  @functools.lru_cache
719
599
  def get_conda_config() -> dict:
720
600
  """Returns the current conda config as dictionary"""
@@ -866,7 +746,6 @@ def set_auth_for_url(url: Url | str) -> str:
866
746
  use_keyring = dask.config.get("coiled.package_sync.conda.cred_sources.keyring", True)
867
747
  use_conda_auth = dask.config.get("coiled.package_sync.conda.cred_sources.conda", True)
868
748
  use_mamba_auth = dask.config.get("coiled.package_sync.conda.cred_sources.mamba", True)
869
- use_rattler_auth = dask.config.get("coiled.package_sync.conda.cred_sources.rattler", True)
870
749
 
871
750
  no_auth_url = parsed_url._replace(auth=None).url
872
751
  auth_parts = (
@@ -880,8 +759,6 @@ def set_auth_for_url(url: Url | str) -> str:
880
759
  or (get_conda_auth(no_auth_url) if use_conda_auth else None)
881
760
  # mamba could have URL stored by netloc/path or netloc
882
761
  or ((get_mamba_auth(f"{netloc}{path}") or get_mamba_auth(netloc)) if use_mamba_auth else None)
883
- # rattler/pixi stores URL stored by netloc in keyring or a fallback file
884
- or (get_rattler_auth(netloc) if use_rattler_auth else None)
885
762
  )
886
763
  if auth_parts is not None:
887
764
  username, password = auth_parts
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