dayhoff-tools 1.0.6__tar.gz → 1.0.8__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 (30) hide show
  1. {dayhoff_tools-1.0.6 → dayhoff_tools-1.0.8}/PKG-INFO +1 -1
  2. {dayhoff_tools-1.0.6 → dayhoff_tools-1.0.8}/dayhoff_tools/cli/cloud_commands.py +92 -65
  3. {dayhoff_tools-1.0.6 → dayhoff_tools-1.0.8}/dayhoff_tools/fasta.py +2 -2
  4. {dayhoff_tools-1.0.6 → dayhoff_tools-1.0.8}/pyproject.toml +1 -1
  5. {dayhoff_tools-1.0.6 → dayhoff_tools-1.0.8}/README.md +0 -0
  6. {dayhoff_tools-1.0.6 → dayhoff_tools-1.0.8}/dayhoff_tools/__init__.py +0 -0
  7. {dayhoff_tools-1.0.6 → dayhoff_tools-1.0.8}/dayhoff_tools/chemistry/standardizer.py +0 -0
  8. {dayhoff_tools-1.0.6 → dayhoff_tools-1.0.8}/dayhoff_tools/chemistry/utils.py +0 -0
  9. {dayhoff_tools-1.0.6 → dayhoff_tools-1.0.8}/dayhoff_tools/cli/__init__.py +0 -0
  10. {dayhoff_tools-1.0.6 → dayhoff_tools-1.0.8}/dayhoff_tools/cli/main.py +0 -0
  11. {dayhoff_tools-1.0.6 → dayhoff_tools-1.0.8}/dayhoff_tools/cli/swarm_commands.py +0 -0
  12. {dayhoff_tools-1.0.6 → dayhoff_tools-1.0.8}/dayhoff_tools/cli/utility_commands.py +0 -0
  13. {dayhoff_tools-1.0.6 → dayhoff_tools-1.0.8}/dayhoff_tools/deployment/base.py +0 -0
  14. {dayhoff_tools-1.0.6 → dayhoff_tools-1.0.8}/dayhoff_tools/deployment/deploy_aws.py +0 -0
  15. {dayhoff_tools-1.0.6 → dayhoff_tools-1.0.8}/dayhoff_tools/deployment/deploy_gcp.py +0 -0
  16. {dayhoff_tools-1.0.6 → dayhoff_tools-1.0.8}/dayhoff_tools/deployment/deploy_utils.py +0 -0
  17. {dayhoff_tools-1.0.6 → dayhoff_tools-1.0.8}/dayhoff_tools/deployment/job_runner.py +0 -0
  18. {dayhoff_tools-1.0.6 → dayhoff_tools-1.0.8}/dayhoff_tools/deployment/processors.py +0 -0
  19. {dayhoff_tools-1.0.6 → dayhoff_tools-1.0.8}/dayhoff_tools/deployment/swarm.py +0 -0
  20. {dayhoff_tools-1.0.6 → dayhoff_tools-1.0.8}/dayhoff_tools/embedders.py +0 -0
  21. {dayhoff_tools-1.0.6 → dayhoff_tools-1.0.8}/dayhoff_tools/file_ops.py +0 -0
  22. {dayhoff_tools-1.0.6 → dayhoff_tools-1.0.8}/dayhoff_tools/gcp.py +0 -0
  23. {dayhoff_tools-1.0.6 → dayhoff_tools-1.0.8}/dayhoff_tools/h5.py +0 -0
  24. {dayhoff_tools-1.0.6 → dayhoff_tools-1.0.8}/dayhoff_tools/kegg.py +0 -0
  25. {dayhoff_tools-1.0.6 → dayhoff_tools-1.0.8}/dayhoff_tools/logs.py +0 -0
  26. {dayhoff_tools-1.0.6 → dayhoff_tools-1.0.8}/dayhoff_tools/mmseqs.py +0 -0
  27. {dayhoff_tools-1.0.6 → dayhoff_tools-1.0.8}/dayhoff_tools/sqlite.py +0 -0
  28. {dayhoff_tools-1.0.6 → dayhoff_tools-1.0.8}/dayhoff_tools/structure.py +0 -0
  29. {dayhoff_tools-1.0.6 → dayhoff_tools-1.0.8}/dayhoff_tools/uniprot.py +0 -0
  30. {dayhoff_tools-1.0.6 → dayhoff_tools-1.0.8}/dayhoff_tools/warehouse.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: dayhoff-tools
3
- Version: 1.0.6
3
+ Version: 1.0.8
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
@@ -129,19 +129,25 @@ def _get_env_var(variable: str) -> Optional[str]:
129
129
 
130
130
  # --- GCP Functions ---
131
131
  def _is_gcp_user_authenticated() -> bool:
132
- """Check if a user is authenticated with GCP (not a compute service account)."""
133
- gcloud_path = _find_executable("gcloud")
134
- cmd = [
135
- gcloud_path,
136
- "auth",
137
- "list",
138
- "--filter=status:ACTIVE",
139
- "--format=value(account)",
140
- ]
141
- _, stdout, _ = _run_command(cmd, capture=True, check=False)
132
+ """Check if the current gcloud user authentication is valid and non-interactive.
142
133
 
143
- account = stdout.strip()
144
- return bool(account) and "compute@developer.gserviceaccount.com" not in account
134
+ Returns:
135
+ True if `gcloud auth print-access-token --quiet` succeeds (exit code 0),
136
+ False otherwise (indicating potential need for interactive login).
137
+ """
138
+ try:
139
+ gcloud_path = _find_executable("gcloud")
140
+ # Attempt to get a token silently. If this fails, login is likely expired or needs interaction.
141
+ returncode, _, _ = _run_command(
142
+ [gcloud_path, "auth", "print-access-token", "--quiet"],
143
+ capture=True, # We don't need the token, just the exit code
144
+ check=False, # Don't raise on failure
145
+ suppress_output=True, # Hide any potential output/errors from this check
146
+ )
147
+ return returncode == 0
148
+ except FileNotFoundError:
149
+ # If gcloud isn't found, they are definitely not authenticated.
150
+ return False
145
151
 
146
152
 
147
153
  def _get_current_gcp_user() -> str:
@@ -350,51 +356,62 @@ def gcp_use_devcon(
350
356
  export: bool = typer.Option(
351
357
  False, "--export", "-x", help="Print export commands for the current shell."
352
358
  ),
353
- auth_first: bool = typer.Option(
354
- False, "--auth", "-a", help="Authenticate user first if needed."
355
- ),
356
359
  ):
357
- """Switch to devcon service account impersonation mode."""
360
+ """Configure gcloud CLI to impersonate the devcon SA by setting RC file variables.
361
+
362
+ NOTE: This command DOES NOT automatically update Application Default Credentials (ADC).
363
+ After running this, or after sourcing the export commands, you may need to run:
364
+ 'gcloud auth application-default login --impersonate-service-account=...' manually
365
+ if you need libraries (like DVC) to use these credentials.
366
+
367
+ Ensures the primary user login is valid first to allow potential impersonation.
368
+ """
358
369
  if not _is_gcp_user_authenticated():
359
- if auth_first:
360
- print(
361
- f"{YELLOW}You need to authenticate first. Running authentication...{NC}",
362
- file=sys.stderr,
363
- )
364
- _run_gcloud_login()
365
- else:
366
- print(
367
- f"{RED}Error: Not authenticated with GCP. Run 'dh gcp login' first or use --auth flag.{NC}",
368
- file=sys.stderr,
369
- )
370
- sys.exit(1)
370
+ print(
371
+ f"{RED}Error: GCP user authentication is invalid or requires interactive login.{NC}",
372
+ file=sys.stderr,
373
+ )
374
+ print(
375
+ f"{YELLOW}Please run 'gcloud auth login' interactively first, then try this command again.{NC}",
376
+ file=sys.stderr,
377
+ )
378
+ sys.exit(1)
371
379
 
372
- # Modify RC files to persist across sessions
380
+ # Set gcloud CLI impersonation (persisted to RC files)
373
381
  _modify_rc_files("CLOUDSDK_AUTH_IMPERSONATE_SERVICE_ACCOUNT", f"'{GCP_DEVCON_SA}'")
374
- _modify_rc_files("GOOGLE_IMPERSONATE_SERVICE_ACCOUNT", f"'{GCP_DEVCON_SA}'")
375
382
  _modify_rc_files("GOOGLE_CLOUD_PROJECT", f"'{GCP_PROJECT_ID}'")
376
383
 
377
384
  if export:
378
- # Print export commands for the current shell to stdout
385
+ # Print export commands for the current shell (for gcloud CLI)
379
386
  print(f"export CLOUDSDK_AUTH_IMPERSONATE_SERVICE_ACCOUNT='{GCP_DEVCON_SA}'")
380
- print(f"export GOOGLE_IMPERSONATE_SERVICE_ACCOUNT='{GCP_DEVCON_SA}'")
381
387
  print(f"export GOOGLE_CLOUD_PROJECT='{GCP_PROJECT_ID}'")
382
388
 
383
- # Print confirmation to stderr so it doesn't affect eval
389
+ # Print confirmation and instructions for ADC to stderr
384
390
  print(
385
- f"{GREEN}GCP service account impersonation for '{GCP_DEVCON_SA}' set up successfully.{NC}",
391
+ f"{GREEN}GCP gcloud CLI impersonation for '{GCP_DEVCON_SA}' exported.{NC}",
386
392
  file=sys.stderr,
387
393
  )
388
- print(f"{GREEN}You now have standard devcon permissions.{NC}", file=sys.stderr)
389
- else:
390
- # Just print confirmation
391
394
  print(
392
- f"{GREEN}Switched to devcon service account impersonation. You now have standard devcon permissions.{NC}"
395
+ f"{YELLOW}NOTE: ADC file not updated by export. To update ADC for libraries, run:{NC}",
396
+ file=sys.stderr,
393
397
  )
394
398
  print(
395
- f"Changes will take effect in new shell sessions. To apply in current shell, run:"
399
+ f"{YELLOW} gcloud auth application-default login --impersonate-service-account={GCP_DEVCON_SA}{NC}",
400
+ file=sys.stderr,
396
401
  )
402
+ else:
403
+ # Print confirmation
404
+ print(
405
+ f"{GREEN}RC files updated to use devcon SA for future gcloud CLI sessions.{NC}"
406
+ )
407
+ print(f"To apply gcloud CLI settings in current shell, run:")
397
408
  print(f' {YELLOW}eval "$(dh gcp use-devcon --export)"{NC}')
409
+ print(
410
+ f"{YELLOW}NOTE: ADC file not updated. To update ADC for libraries, run:{NC}"
411
+ )
412
+ print(
413
+ f"{YELLOW} gcloud auth application-default login --impersonate-service-account={GCP_DEVCON_SA}{NC}"
414
+ )
398
415
 
399
416
 
400
417
  @gcp_app.command("use-user")
@@ -402,50 +419,60 @@ def gcp_use_user(
402
419
  export: bool = typer.Option(
403
420
  False, "--export", "-x", help="Print export commands for the current shell."
404
421
  ),
405
- auth_first: bool = typer.Option(
406
- False, "--auth", "-a", help="Authenticate user first if needed."
407
- ),
408
422
  ):
409
- """Switch to personal account mode (no impersonation)."""
423
+ """Configure gcloud CLI to use the personal user account by setting RC file variables.
424
+
425
+ NOTE: This command DOES NOT automatically update Application Default Credentials (ADC).
426
+ After running this, or after sourcing the export commands, you may need to run:
427
+ 'gcloud auth application-default login' manually
428
+ if you need libraries (like DVC) to use your personal credentials.
429
+
430
+ Ensures the primary user login is valid first.
431
+ """
410
432
  if not _is_gcp_user_authenticated():
411
- if auth_first:
412
- print(
413
- f"{YELLOW}You need to authenticate first. Running authentication...{NC}",
414
- file=sys.stderr,
415
- )
416
- _run_gcloud_login()
417
- else:
418
- print(
419
- f"{RED}Error: Not authenticated with GCP. Run 'dh gcp login' first or use --auth flag.{NC}",
420
- file=sys.stderr,
421
- )
422
- sys.exit(1)
433
+ print(
434
+ f"{RED}Error: GCP user authentication is invalid or requires interactive login.{NC}",
435
+ file=sys.stderr,
436
+ )
437
+ print(
438
+ f"{YELLOW}Please run 'gcloud auth login' interactively first, then try this command again.{NC}",
439
+ file=sys.stderr,
440
+ )
441
+ sys.exit(1)
423
442
 
424
- # Modify RC files to persist across sessions
443
+ # Unset gcloud CLI impersonation (persisted to RC files)
425
444
  _modify_rc_files("CLOUDSDK_AUTH_IMPERSONATE_SERVICE_ACCOUNT", None)
426
- _modify_rc_files("GOOGLE_IMPERSONATE_SERVICE_ACCOUNT", None)
427
445
  _modify_rc_files("GOOGLE_CLOUD_PROJECT", f"'{GCP_PROJECT_ID}'")
428
446
 
429
447
  if export:
430
- # Print export commands for the current shell to stdout
448
+ # Print export commands for the current shell (for gcloud CLI)
431
449
  print(f"unset CLOUDSDK_AUTH_IMPERSONATE_SERVICE_ACCOUNT")
432
- print(f"unset GOOGLE_IMPERSONATE_SERVICE_ACCOUNT")
433
450
  print(f"export GOOGLE_CLOUD_PROJECT='{GCP_PROJECT_ID}'")
434
451
 
435
- # Print confirmation to stderr so it doesn't affect eval
452
+ # Print confirmation and instructions for ADC to stderr
436
453
  print(
437
- f"{GREEN}Switched to personal account mode. You are now using your own permissions.{NC}",
454
+ f"{GREEN}GCP gcloud CLI impersonation unset and exported.{NC}",
438
455
  file=sys.stderr,
439
456
  )
440
- else:
441
- # Just print confirmation
442
457
  print(
443
- f"{GREEN}Switched to personal account mode. You are now using your own permissions.{NC}"
458
+ f"{YELLOW}NOTE: ADC file not updated by export. To update ADC for libraries, run:{NC}",
459
+ file=sys.stderr,
444
460
  )
445
461
  print(
446
- f"Changes will take effect in new shell sessions. To apply in current shell, run:"
462
+ f"{YELLOW} gcloud auth application-default login{NC}",
463
+ file=sys.stderr,
447
464
  )
465
+ else:
466
+ # Print confirmation
467
+ print(
468
+ f"{GREEN}RC files updated to use personal account for future gcloud CLI sessions.{NC}"
469
+ )
470
+ print(f"To apply gcloud CLI settings in current shell, run:")
448
471
  print(f' {YELLOW}eval "$(dh gcp use-user --export)"{NC}')
472
+ print(
473
+ f"{YELLOW}NOTE: ADC file not updated. To update ADC for libraries, run:{NC}"
474
+ )
475
+ print(f"{YELLOW} gcloud auth application-default login{NC}")
449
476
 
450
477
 
451
478
  # --- AWS Commands ---
@@ -14,7 +14,7 @@ import requests
14
14
  from Bio import SeqIO
15
15
  from Bio.SeqRecord import SeqRecord
16
16
  from tqdm import tqdm
17
- from tqdm.notebook import tqdm_notebook
17
+ from tqdm.notebook import tqdm as tqdm_notebook
18
18
 
19
19
  logger = logging.getLogger(__name__)
20
20
 
@@ -923,7 +923,7 @@ def fetch_uniprot_fasta(
923
923
  # Calculate number of batches for progress bar
924
924
  num_batches = math.ceil(len(accession_list) / batch_size)
925
925
 
926
- # Process accessions in batches with progress bar
926
+ # Process accessions in batches with progress bar (using notebook version)
927
927
  for i in tqdm_notebook(
928
928
  range(0, len(accession_list), batch_size),
929
929
  desc="Downloading sequences",
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
4
4
 
5
5
  [project]
6
6
  name = "dayhoff-tools"
7
- version = "1.0.6"
7
+ version = "1.0.8"
8
8
  description = "Common tools for all the repos at Dayhoff Labs"
9
9
  authors = [
10
10
  {name = "Daniel Martin-Alarcon", email = "dma@dayhofflabs.com"}
File without changes