dayhoff-tools 1.0.9__py3-none-any.whl → 1.0.15__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.
dayhoff_tools/cli/main.py CHANGED
@@ -11,12 +11,14 @@ from dayhoff_tools.cli.utility_commands import (
11
11
  rebuild_devcontainer_file,
12
12
  test_github_actions_locally,
13
13
  update_dayhoff_tools,
14
+ sync_dependencies,
14
15
  )
15
16
 
16
17
  app = typer.Typer()
17
18
 
18
19
  # Utility commands
19
20
  app.command("clean")(delete_local_branch)
21
+ app.command("deps")(sync_dependencies)
20
22
  app.command("gha")(test_github_actions_locally)
21
23
  app.command("rebuild")(rebuild_devcontainer_file)
22
24
  app.command("update")(update_dayhoff_tools)
@@ -2,6 +2,7 @@
2
2
 
3
3
  import os
4
4
  import re
5
+ import shutil
5
6
  import subprocess
6
7
  import sys
7
8
  from pathlib import Path
@@ -182,16 +183,16 @@ def get_current_version_from_toml(file_path="pyproject.toml"):
182
183
 
183
184
 
184
185
  def build_and_upload_wheel(bump_part: str = "patch"):
185
- """Build a Python wheel and upload to PyPI.
186
+ """Build a Python wheel and upload to PyPI using UV.
186
187
 
187
- Automatically increments the version number in pyproject.toml before building.
188
- Use the bump_part argument to specify major, minor, or patch increment.
189
- For example: 1.2.3 -> 1.2.4 (patch), 1.3.0 (minor), 2.0.0 (major)
188
+ Automatically increments the version number in pyproject.toml before building
189
+ based on the bump_part argument ('major', 'minor', 'patch').
190
190
 
191
- Expects the PyPI API token to be available in the PYPI_API_TOKEN environment variable.
191
+ Expects PyPI authentication to be configured via the environment variable:
192
+ - UV_PUBLISH_TOKEN
192
193
 
193
194
  Args:
194
- bump_part (str): The part of the version to bump: 'major', 'minor', or 'patch'. Defaults to 'patch'.
195
+ bump_part (str): The part of the version to bump. Defaults to 'patch'.
195
196
  """
196
197
  if bump_part not in ["major", "minor", "patch"]:
197
198
  print(
@@ -199,69 +200,198 @@ def build_and_upload_wheel(bump_part: str = "patch"):
199
200
  )
200
201
  return
201
202
 
202
- pypi_token = os.environ.get("PYPI_API_TOKEN")
203
- if not pypi_token:
204
- print("Error: PYPI_API_TOKEN environment variable not set.")
205
- print("Please set it with your PyPI API token before running this command.")
203
+ # --- Authentication Setup ---
204
+ token = os.environ.get("UV_PUBLISH_TOKEN")
205
+
206
+ if not token:
207
+ print("Error: PyPI authentication not configured.")
208
+ print(
209
+ "Please set the UV_PUBLISH_TOKEN environment variable with your PyPI API token."
210
+ )
206
211
  return
207
212
 
213
+ # Build the command with token authentication
214
+ publish_cmd = ["uv", "publish", "--token", token]
215
+ print("Using UV_PUBLISH_TOKEN for authentication.")
216
+
217
+ pyproject_path = "pyproject.toml"
218
+ current_version = None # Initialize in case the first try block fails
219
+
208
220
  try:
209
- # Get the current version before bumping
210
- current_version = get_current_version_from_toml()
221
+ # --- Clean dist directory ---
222
+ dist_dir = Path("dist")
223
+ if dist_dir.exists():
224
+ print(f"Removing existing build directory: {dist_dir}")
225
+ shutil.rmtree(dist_dir)
226
+ # --- End Clean dist directory ---
227
+
228
+ # --- Version Bumping Logic ---
229
+ current_version = get_current_version_from_toml(pyproject_path)
211
230
  print(f"Current version: {current_version}")
212
231
 
213
- # Use poetry to bump the version in pyproject.toml
214
- print(f"Bumping {bump_part} version using poetry...")
215
- subprocess.run(["poetry", "version", bump_part], check=True)
216
-
217
- # Get the new version after bumping
218
- new_version = get_current_version_from_toml()
219
- print(f"New version: {new_version}")
232
+ try:
233
+ major, minor, patch = map(int, current_version.split("."))
234
+ except ValueError:
235
+ print(
236
+ f"Error: Could not parse version '{current_version}'. Expected format X.Y.Z"
237
+ )
238
+ return
239
+
240
+ if bump_part == "major":
241
+ major += 1
242
+ minor = 0
243
+ patch = 0
244
+ elif bump_part == "minor":
245
+ minor += 1
246
+ patch = 0
247
+ else: # patch
248
+ patch += 1
249
+
250
+ new_version = f"{major}.{minor}.{patch}"
251
+ print(f"Bumping {bump_part} version to: {new_version}")
252
+
253
+ # Read pyproject.toml
254
+ with open(pyproject_path, "r") as f:
255
+ content = f.read()
220
256
 
221
- # Disable keyring to avoid issues in containers/CI
222
- print("Disabling Poetry keyring...")
223
- subprocess.run(
224
- ["poetry", "config", "keyring.enabled", "false"],
225
- check=True,
226
- capture_output=True,
257
+ # Replace the version string
258
+ pattern = re.compile(
259
+ f'^version\s*=\s*"{re.escape(current_version)}"', re.MULTILINE
227
260
  )
228
-
229
- # Configure Poetry with the API token
230
- print("Configuring Poetry with PyPI token...")
231
- subprocess.run(
232
- ["poetry", "config", "pypi-token.pypi", pypi_token],
233
- check=True,
234
- capture_output=True, # Hide token from output
261
+ new_content, num_replacements = pattern.subn(
262
+ f'version = "{new_version}"', content
235
263
  )
236
264
 
237
- # Build and upload
238
- print("Building and uploading wheel to PyPI...")
265
+ if num_replacements == 0:
266
+ print(
267
+ f"Error: Could not find 'version = \"{current_version}\"' in {pyproject_path}"
268
+ )
269
+ return # Exit before build/publish if version wasn't updated
270
+ if num_replacements > 1:
271
+ print(
272
+ f"Warning: Found multiple version lines for '{current_version}'. Only the first was updated."
273
+ )
274
+
275
+ # Write the updated content back
276
+ with open(pyproject_path, "w") as f:
277
+ f.write(new_content)
278
+ print(f"Updated {pyproject_path} with version {new_version}")
279
+ # --- End Version Bumping Logic ---
280
+
281
+ # Build wheel and sdist
282
+ print("Building wheel and sdist using uv build...")
283
+ subprocess.run(["uv", "build"], check=True)
284
+
285
+ # Upload using uv publish with explicit arguments
286
+ print("Uploading to PyPI using uv publish...")
239
287
  subprocess.run(
240
- [
241
- "poetry",
242
- "publish",
243
- "--build",
244
- ],
288
+ publish_cmd, # Use the command list built earlier
245
289
  check=True,
246
290
  )
247
291
 
248
292
  print(f"Successfully built and uploaded version {new_version} to PyPI")
249
293
 
294
+ except FileNotFoundError:
295
+ print(f"Error: {pyproject_path} not found.")
296
+ # No version change happened, so no rollback needed
250
297
  except subprocess.CalledProcessError as e:
251
298
  print(f"Error during build/upload: {e}")
299
+ # Attempt to roll back version change only if it was bumped successfully
300
+ if current_version and new_version:
301
+ try:
302
+ print(
303
+ f"Attempting to revert version in {pyproject_path} back to {current_version}..."
304
+ )
305
+ with open(pyproject_path, "r") as f:
306
+ content_revert = f.read()
307
+ # Use new_version in pattern for reverting
308
+ pattern_revert = re.compile(
309
+ f'^version\s*=\s*"{re.escape(new_version)}"', re.MULTILINE
310
+ )
311
+ reverted_content, num_revert = pattern_revert.subn(
312
+ f'version = "{current_version}"', content_revert
313
+ )
314
+ if num_revert > 0:
315
+ with open(pyproject_path, "w") as f:
316
+ f.write(reverted_content)
317
+ print(f"Successfully reverted version in {pyproject_path}.")
318
+ else:
319
+ print(
320
+ f"Warning: Could not find version {new_version} to revert in {pyproject_path}."
321
+ )
322
+ except Exception as revert_e:
323
+ print(
324
+ f"Warning: Failed to revert version change in {pyproject_path}: {revert_e}"
325
+ )
252
326
  except Exception as e:
253
327
  print(f"An unexpected error occurred: {e}")
328
+ # Also attempt rollback here if version was bumped
329
+ if current_version and "new_version" in locals() and new_version:
330
+ try:
331
+ print(
332
+ f"Attempting to revert version in {pyproject_path} back to {current_version} due to unexpected error..."
333
+ )
334
+ # (Same revert logic as above)
335
+ with open(pyproject_path, "r") as f:
336
+ content_revert = f.read()
337
+ pattern_revert = re.compile(
338
+ f'^version\s*=\s*"{re.escape(new_version)}"', re.MULTILINE
339
+ )
340
+ reverted_content, num_revert = pattern_revert.subn(
341
+ f'version = "{current_version}"', content_revert
342
+ )
343
+ if num_revert > 0:
344
+ with open(pyproject_path, "w") as f:
345
+ f.write(reverted_content)
346
+ print(f"Successfully reverted version in {pyproject_path}.")
347
+ else:
348
+ print(
349
+ f"Warning: Could not find version {new_version} to revert in {pyproject_path}."
350
+ )
351
+ except Exception as revert_e:
352
+ print(
353
+ f"Warning: Failed to revert version change in {pyproject_path}: {revert_e}"
354
+ )
254
355
 
255
356
 
256
357
  def update_dayhoff_tools():
257
- """Update the dayhoff-tools package to the latest version using poetry."""
358
+ """Update the dayhoff-tools package to the latest version using uv.
359
+
360
+ Runs `uv add dayhoff-tools@latest` which updates pyproject.toml and uv.lock.
361
+ """
258
362
  try:
259
- print("Updating dayhoff-tools to the latest version...")
260
- subprocess.run(["poetry", "update", "dayhoff-tools"], check=True)
363
+ print("Updating dayhoff-tools to the latest version using uv...")
364
+ # Use uv add to update the package and lock file
365
+ subprocess.run(["uv", "add", "dayhoff-tools@latest"], check=True)
261
366
  print("Update complete!")
262
367
  except subprocess.CalledProcessError as e:
263
368
  print(f"Error occurred while updating: {e}")
264
369
  sys.exit(1)
265
370
  except FileNotFoundError:
266
- print("Error: 'poetry' command not found. Make sure Poetry is installed.")
371
+ print("Error: 'uv' command not found. Is uv installed and in PATH?")
372
+ sys.exit(1)
373
+
374
+
375
+ def sync_dependencies():
376
+ """Update uv.lock and sync dependencies based on pyproject.toml.
377
+
378
+ Runs `uv lock` followed by `uv sync --all-groups --no-install-project`.
379
+ This ensures the lock file is up-to-date and installs all declared
380
+ dependencies without building/installing the local project itself.
381
+ """
382
+ try:
383
+ print("Updating lock file (uv lock)...")
384
+ subprocess.run(["uv", "lock"], check=True)
385
+
386
+ print("Syncing dependencies (uv sync --all-groups --no-install-project)...")
387
+ subprocess.run(
388
+ ["uv", "sync", "--all-groups", "--no-install-project"], check=True
389
+ )
390
+
391
+ print("Dependencies synced successfully.")
392
+ except subprocess.CalledProcessError as e:
393
+ print(f"Error occurred during dependency sync: {e}")
394
+ sys.exit(1)
395
+ except FileNotFoundError:
396
+ print("Error: 'uv' command not found. Is uv installed and in PATH?")
267
397
  sys.exit(1)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: dayhoff-tools
3
- Version: 1.0.9
3
+ Version: 1.0.15
4
4
  Summary: Common tools for all the repos at Dayhoff Labs
5
5
  Author: Daniel Martin-Alarcon
6
6
  Author-email: dma@dayhofflabs.com
@@ -10,16 +10,22 @@ Classifier: Programming Language :: Python :: 3.10
10
10
  Classifier: Programming Language :: Python :: 3.11
11
11
  Classifier: Programming Language :: Python :: 3.12
12
12
  Classifier: Programming Language :: Python :: 3.13
13
- Provides-Extra: core
14
- Requires-Dist: biopython (>=1.84) ; extra == "core"
15
- Requires-Dist: boto3 (>=1.36.8) ; extra == "core"
16
- Requires-Dist: docker (>=7.1.0) ; extra == "core"
17
- Requires-Dist: fair-esm (>=2.0.0) ; extra == "core"
13
+ Provides-Extra: full
14
+ Requires-Dist: biopython (>=1.84) ; extra == "full"
15
+ Requires-Dist: boto3 (>=1.36.8) ; extra == "full"
16
+ Requires-Dist: docker (>=7.1.0) ; extra == "full"
17
+ Requires-Dist: fair-esm (>=2.0.0) ; extra == "full"
18
18
  Requires-Dist: firebase-admin (>=6.5.0)
19
- Requires-Dist: h5py (>=3.11.0) ; extra == "core"
19
+ Requires-Dist: h5py (>=3.11.0) ; extra == "full"
20
+ Requires-Dist: pandas (>=2.2.3) ; extra == "full"
20
21
  Requires-Dist: pyyaml (>=6.0)
21
- Requires-Dist: questionary (>=2.0.1) ; extra == "core"
22
+ Requires-Dist: questionary (>=2.0.1) ; extra == "full"
23
+ Requires-Dist: rdkit-pypi (>=2022.9.5) ; extra == "full"
22
24
  Requires-Dist: requests (>=2.31.0)
25
+ Requires-Dist: sqlalchemy (>=2.0.40,<3.0.0) ; extra == "full"
26
+ Requires-Dist: torch (>=2.1.0) ; extra == "full"
27
+ Requires-Dist: torchvision (>=0.16.0) ; extra == "full"
28
+ Requires-Dist: transformers (==4.36.2) ; extra == "full"
23
29
  Requires-Dist: typer (>=0.9.0)
24
30
  Description-Content-Type: text/markdown
25
31
 
@@ -3,9 +3,9 @@ dayhoff_tools/chemistry/standardizer.py,sha256=uMn7VwHnx02nc404eO6fRuS4rsl4dvSPf
3
3
  dayhoff_tools/chemistry/utils.py,sha256=jt-7JgF-GeeVC421acX-bobKbLU_X94KNOW24p_P-_M,2257
4
4
  dayhoff_tools/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  dayhoff_tools/cli/cloud_commands.py,sha256=KiYEuD3nSg8QPWBYfrhdze2La_CJe4iqK-8uOAHyS8U,35827
6
- dayhoff_tools/cli/main.py,sha256=E1-3rZ26LMgJVKBz6CdJwsHs9fJsSGa2_9tot3hNgz4,3604
6
+ dayhoff_tools/cli/main.py,sha256=yorL117hknzhNybt7CTz4oKXVuQRIDXPl7huIEWga-M,3666
7
7
  dayhoff_tools/cli/swarm_commands.py,sha256=5EyKj8yietvT5lfoz8Zx0iQvVaNgc3SJX1z2zQR6o6M,5614
8
- dayhoff_tools/cli/utility_commands.py,sha256=AsZMpvUNP2xjn5cZ9_BrBNHggfuy6PLwlHw1WP0d7o0,9602
8
+ dayhoff_tools/cli/utility_commands.py,sha256=-Fe7CkcIZ8e7UWlKO-P2Dgm1p3yg-GOsXcnDwxw5uxQ,14851
9
9
  dayhoff_tools/deployment/base.py,sha256=u-AjbtHnFLoLt33dhYXHIpV-6jcieMEHHGBGN_U9Hm0,15626
10
10
  dayhoff_tools/deployment/deploy_aws.py,sha256=O0gQxHioSU_sNU8T8MD4wSOPvWc--V8eRRZzlRu035I,16446
11
11
  dayhoff_tools/deployment/deploy_gcp.py,sha256=DxBM4sUzwPK9RWLP9bSfr38n1HHl-TVrp4TsbdN8pUA,5795
@@ -25,7 +25,7 @@ dayhoff_tools/sqlite.py,sha256=jV55ikF8VpTfeQqqlHSbY8OgfyfHj8zgHNpZjBLos_E,18672
25
25
  dayhoff_tools/structure.py,sha256=ufN3gAodQxhnt7psK1VTQeu9rKERmo_PhoxIbB4QKMw,27660
26
26
  dayhoff_tools/uniprot.py,sha256=BZYJQF63OtPcBBnQ7_P9gulxzJtqyorgyuDiPeOJqE4,16456
27
27
  dayhoff_tools/warehouse.py,sha256=TqV8nex1AluNaL4JuXH5zuu9P7qmE89lSo6f_oViy6U,14965
28
- dayhoff_tools-1.0.9.dist-info/METADATA,sha256=z5v8zbt4z_B5283bqkkFlybQox_tZacU-Z6JPNyg1vc,1930
29
- dayhoff_tools-1.0.9.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
30
- dayhoff_tools-1.0.9.dist-info/entry_points.txt,sha256=iAf4jteNqW3cJm6CO6czLxjW3vxYKsyGLZ8WGmxamSc,49
31
- dayhoff_tools-1.0.9.dist-info/RECORD,,
28
+ dayhoff_tools-1.0.15.dist-info/METADATA,sha256=4RV3HI5kIxjjuNaKC9FOdXh-_efd4GqaHy_m0RsB3ak,2262
29
+ dayhoff_tools-1.0.15.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
30
+ dayhoff_tools-1.0.15.dist-info/entry_points.txt,sha256=iAf4jteNqW3cJm6CO6czLxjW3vxYKsyGLZ8WGmxamSc,49
31
+ dayhoff_tools-1.0.15.dist-info/RECORD,,