halib 0.1.48__tar.gz → 0.1.50__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 (42) hide show
  1. {halib-0.1.48/halib.egg-info → halib-0.1.50}/PKG-INFO +6 -3
  2. {halib-0.1.48 → halib-0.1.50}/README.md +5 -2
  3. {halib-0.1.48 → halib-0.1.50}/halib/__init__.py +12 -1
  4. {halib-0.1.48 → halib-0.1.50}/halib/common.py +25 -5
  5. halib-0.1.50/halib/research/wandb_op.py +116 -0
  6. {halib-0.1.48 → halib-0.1.50/halib.egg-info}/PKG-INFO +6 -3
  7. {halib-0.1.48 → halib-0.1.50}/halib.egg-info/SOURCES.txt +1 -0
  8. {halib-0.1.48 → halib-0.1.50}/halib.egg-info/requires.txt +1 -0
  9. {halib-0.1.48 → halib-0.1.50}/setup.py +1 -1
  10. {halib-0.1.48 → halib-0.1.50}/.gitignore +0 -0
  11. {halib-0.1.48 → halib-0.1.50}/GDriveFolder.txt +0 -0
  12. {halib-0.1.48 → halib-0.1.50}/LICENSE.txt +0 -0
  13. {halib-0.1.48 → halib-0.1.50}/guide_publish_pip.pdf +0 -0
  14. {halib-0.1.48 → halib-0.1.50}/halib/cuda.py +0 -0
  15. {halib-0.1.48 → halib-0.1.50}/halib/filetype/__init__.py +0 -0
  16. {halib-0.1.48 → halib-0.1.50}/halib/filetype/csvfile.py +0 -0
  17. {halib-0.1.48 → halib-0.1.50}/halib/filetype/jsonfile.py +0 -0
  18. {halib-0.1.48 → halib-0.1.50}/halib/filetype/textfile.py +0 -0
  19. {halib-0.1.48 → halib-0.1.50}/halib/filetype/videofile.py +0 -0
  20. {halib-0.1.48 → halib-0.1.50}/halib/filetype/yamlfile.py +0 -0
  21. {halib-0.1.48 → halib-0.1.50}/halib/online/__init__.py +0 -0
  22. {halib-0.1.48 → halib-0.1.50}/halib/online/gdrive.py +0 -0
  23. {halib-0.1.48 → halib-0.1.50}/halib/online/gdrive_mkdir.py +0 -0
  24. {halib-0.1.48 → halib-0.1.50}/halib/online/gdrive_test.py +0 -0
  25. {halib-0.1.48 → halib-0.1.50}/halib/online/projectmake.py +0 -0
  26. {halib-0.1.48 → halib-0.1.50}/halib/research/__init__.py +0 -0
  27. {halib-0.1.48 → halib-0.1.50}/halib/research/benchquery.py +0 -0
  28. {halib-0.1.48 → halib-0.1.50}/halib/research/dataset.py +0 -0
  29. {halib-0.1.48 → halib-0.1.50}/halib/research/plot.py +0 -0
  30. {halib-0.1.48 → halib-0.1.50}/halib/research/torchloader.py +0 -0
  31. {halib-0.1.48 → halib-0.1.50}/halib/rich_color.py +0 -0
  32. {halib-0.1.48 → halib-0.1.50}/halib/system/__init__.py +0 -0
  33. {halib-0.1.48 → halib-0.1.50}/halib/system/cmd.py +0 -0
  34. {halib-0.1.48 → halib-0.1.50}/halib/system/filesys.py +0 -0
  35. {halib-0.1.48 → halib-0.1.50}/halib/utils/__init__.py +0 -0
  36. {halib-0.1.48 → halib-0.1.50}/halib/utils/listop.py +0 -0
  37. {halib-0.1.48 → halib-0.1.50}/halib/utils/tele_noti.py +0 -0
  38. {halib-0.1.48 → halib-0.1.50}/halib.egg-info/dependency_links.txt +0 -0
  39. {halib-0.1.48 → halib-0.1.50}/halib.egg-info/top_level.txt +0 -0
  40. {halib-0.1.48 → halib-0.1.50}/setup.cfg +0 -0
  41. {halib-0.1.48 → halib-0.1.50}/test/test15.py +0 -0
  42. {halib-0.1.48 → halib-0.1.50}/test/test_df_creator.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: halib
3
- Version: 0.1.48
3
+ Version: 0.1.50
4
4
  Summary: Small library for common tasks
5
5
  Author: Hoang Van Ha
6
6
  Author-email: hoangvanhauit@gmail.com
@@ -15,9 +15,12 @@ License-File: LICENSE.txt
15
15
 
16
16
  Helper package for coding and automation
17
17
 
18
- **Version 0.1.48**
18
+ **Version 0.1.50**
19
19
 
20
- + add `research` module to help with research tasks, including `benchquery` for benchmarking queries from dataframe
20
+ + add `pprint_local_path` to print local path (file/directory) in clickable link (as file URI)
21
+
22
+ + add `research` package to help with research tasks, including `benchquery` for benchmarking queries from dataframe
23
+ + add `wandb` module to allow easy sync offline data to Weights & Biases (wandb) and batch clear wandb runs.
21
24
 
22
25
  **Version 0.1.47**
23
26
  + add `pprint_box` to print object/string in a box frame (like in `inspect`)
@@ -1,8 +1,11 @@
1
1
  Helper package for coding and automation
2
2
 
3
- **Version 0.1.48**
3
+ **Version 0.1.50**
4
4
 
5
- + add `research` module to help with research tasks, including `benchquery` for benchmarking queries from dataframe
5
+ + add `pprint_local_path` to print local path (file/directory) in clickable link (as file URI)
6
+
7
+ + add `research` package to help with research tasks, including `benchquery` for benchmarking queries from dataframe
8
+ + add `wandb` module to allow easy sync offline data to Weights & Biases (wandb) and batch clear wandb runs.
6
9
 
7
10
  **Version 0.1.47**
8
11
  + add `pprint_box` to print object/string in a box frame (like in `inspect`)
@@ -21,7 +21,9 @@ __all__ = [
21
21
  "plt",
22
22
  "pprint",
23
23
  "pprint_box",
24
+ "pprint_local_path",
24
25
  "px",
26
+ "pprint_local_path",
25
27
  "rcolor_all_str",
26
28
  "rcolor_palette_all",
27
29
  "rcolor_palette",
@@ -36,6 +38,7 @@ __all__ = [
36
38
  "time",
37
39
  ]
38
40
  import warnings
41
+
39
42
  warnings.filterwarnings("ignore", message="Unable to import Axes3D")
40
43
 
41
44
  # common libraries
@@ -54,7 +57,15 @@ from .system import cmd
54
57
  from .system import filesys as fs
55
58
  from .filetype import csvfile
56
59
  from .cuda import tcuda
57
- from .common import console, console_log, ConsoleLog, now_str, norm_str, pprint_box
60
+ from .common import (
61
+ console,
62
+ console_log,
63
+ ConsoleLog,
64
+ now_str,
65
+ norm_str,
66
+ pprint_box,
67
+ pprint_local_path,
68
+ )
58
69
 
59
70
  # for log
60
71
  from loguru import logger
@@ -1,13 +1,17 @@
1
- import arrow
2
1
  import re
2
+ import rich
3
+ import arrow
4
+ import pathlib
5
+ from pathlib import Path
6
+ import urllib.parse
7
+
8
+ from rich import print
9
+ from rich.panel import Panel
3
10
  from rich.console import Console
4
11
  from rich.pretty import pprint, Pretty
5
- from rich.panel import Panel
6
- import rich
7
12
 
8
13
  console = Console()
9
14
 
10
-
11
15
  def seed_everything(seed=42):
12
16
  import random
13
17
  import numpy as np
@@ -54,7 +58,6 @@ def pprint_box(obj, title="", border_style="green"):
54
58
  Panel(Pretty(obj, expand_all=True), title=title, border_style=border_style)
55
59
  )
56
60
 
57
-
58
61
  def console_rule(msg, do_norm_msg=True, is_end_tag=False):
59
62
  msg = norm_str(msg) if do_norm_msg else msg
60
63
  if is_end_tag:
@@ -86,3 +89,20 @@ class ConsoleLog:
86
89
  if exc_type is not None:
87
90
  print(f"An exception of type {exc_type} occurred.")
88
91
  print(f"Exception message: {exc_value}")
92
+
93
+
94
+ def pprint_local_path(local_path, tag=""):
95
+ # Create a file URI
96
+ file_path = Path(local_path).resolve()
97
+ is_file = file_path.is_file()
98
+ is_dir = file_path.is_dir()
99
+ type_str = "📄" if is_file else "📁" if is_dir else "❓"
100
+ file_uri = file_path.as_uri()
101
+ content_str = f"{type_str} [link={file_uri}]{file_uri}[/link]"
102
+ if isinstance(tag, str) and len(tag) > 0:
103
+ with ConsoleLog(tag):
104
+ console.print(content_str)
105
+ else:
106
+ # If tag is not provided, just print the link
107
+ console.print(f"{content_str}")
108
+ return file_uri
@@ -0,0 +1,116 @@
1
+ import glob
2
+ from rich.pretty import pprint
3
+ import os
4
+ import subprocess
5
+ import argparse
6
+ import wandb
7
+ from tqdm import tqdm
8
+ from rich.console import Console
9
+ console = Console()
10
+
11
+ def sync_runs(outdir):
12
+ outdir = os.path.abspath(outdir)
13
+ assert os.path.exists(outdir), f"Output directory {outdir} does not exist."
14
+ sub_dirs = [name for name in os.listdir(outdir) if os.path.isdir(os.path.join(outdir, name))]
15
+ assert len(sub_dirs) > 0, f"No subdirectories found in {outdir}."
16
+ console.rule("Parent Directory")
17
+ console.print(f"[yellow]{outdir}[/yellow]")
18
+
19
+ exp_dirs = [os.path.join(outdir, sub_dir) for sub_dir in sub_dirs]
20
+ wandb_dirs = []
21
+ for exp_dir in exp_dirs:
22
+ wandb_dirs.extend(glob.glob(f"{exp_dir}/wandb/*run-*"))
23
+ if len(wandb_dirs) == 0:
24
+ console.print(f"No wandb runs found in {outdir}.")
25
+ return
26
+ else:
27
+ console.print(f"Found [bold]{len(wandb_dirs)}[/bold] wandb runs in {outdir}.")
28
+ for i, wandb_dir in enumerate(wandb_dirs):
29
+ console.rule(f"Syncing wandb run {i + 1}/{len(wandb_dirs)}")
30
+ console.print(f"Syncing: {wandb_dir}")
31
+ process = subprocess.Popen(
32
+ ["wandb", "sync", wandb_dir],
33
+ stdout=subprocess.PIPE,
34
+ stderr=subprocess.STDOUT,
35
+ text=True,
36
+ )
37
+
38
+ for line in process.stdout:
39
+ console.print(line.strip())
40
+ if " ERROR Error while calling W&B API" in line:
41
+ break
42
+ process.stdout.close()
43
+ process.wait()
44
+ if process.returncode != 0:
45
+ console.print(f"[red]Error syncing {wandb_dir}. Return code: {process.returncode}[/red]")
46
+ else:
47
+ console.print(f"Successfully synced {wandb_dir}.")
48
+
49
+ def delete_runs(project, pattern=None):
50
+ console.rule("Delete W&B Runs")
51
+ confirm_msg = f"Are you sure you want to delete all runs in"
52
+ confirm_msg += f" \n\tproject: [red]{project}[/red]"
53
+ if pattern:
54
+ confirm_msg += f"\n\tpattern: [blue]{pattern}[/blue]"
55
+
56
+ console.print(confirm_msg)
57
+ confirmation = input(f"This action cannot be undone. [y/N]: ").strip().lower()
58
+ if confirmation != "y":
59
+ print("Cancelled.")
60
+ return
61
+
62
+ print("Confirmed. Proceeding...")
63
+ api = wandb.Api()
64
+ runs = api.runs(project)
65
+
66
+ deleted = 0
67
+ console.rule("Deleting W&B Runs")
68
+ if len(runs) == 0:
69
+ print("No runs found in the project.")
70
+ return
71
+ for run in tqdm(runs):
72
+ if pattern is None or pattern in run.name:
73
+ run.delete()
74
+ console.print(f"Deleted run: [red]{run.name}[/red]")
75
+ deleted += 1
76
+
77
+ console.print(f"Total runs deleted: {deleted}")
78
+
79
+
80
+ def valid_argument(args):
81
+ if args.op == "sync":
82
+ assert os.path.exists(args.outdir), f"Output directory {args.outdir} does not exist."
83
+ elif args.op == "delete":
84
+ assert isinstance(args.project, str) and len(args.project.strip()) > 0, "Project name must be a non-empty string."
85
+ else:
86
+ raise ValueError(f"Unknown operation: {args.op}")
87
+
88
+ def parse_args():
89
+ parser = argparse.ArgumentParser(description="Operations on W&B runs")
90
+ parser.add_argument("-op", "--op", type=str, help="Operation to perform", default="sync", choices=["delete", "sync"])
91
+ parser.add_argument("-prj", "--project", type=str, default="fire-paper2-2025", help="W&B project name")
92
+ parser.add_argument("-outdir", "--outdir", type=str, help="arg1 description", default="./zout/train")
93
+ parser.add_argument("-pt", "--pattern",
94
+ type=str,
95
+ default=None,
96
+ help="Run name pattern to match for deletion",
97
+ )
98
+
99
+ return parser.parse_args()
100
+
101
+
102
+ def main():
103
+ args = parse_args()
104
+ # Validate arguments, stop if invalid
105
+ valid_argument(args)
106
+
107
+ op = args.op
108
+ if op == "sync":
109
+ sync_runs(args.outdir)
110
+ elif op == "delete":
111
+ delete_runs(args.project, args.pattern)
112
+ else:
113
+ raise ValueError(f"Unknown operation: {op}")
114
+
115
+ if __name__ == "__main__":
116
+ main()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: halib
3
- Version: 0.1.48
3
+ Version: 0.1.50
4
4
  Summary: Small library for common tasks
5
5
  Author: Hoang Van Ha
6
6
  Author-email: hoangvanhauit@gmail.com
@@ -15,9 +15,12 @@ License-File: LICENSE.txt
15
15
 
16
16
  Helper package for coding and automation
17
17
 
18
- **Version 0.1.48**
18
+ **Version 0.1.50**
19
19
 
20
- + add `research` module to help with research tasks, including `benchquery` for benchmarking queries from dataframe
20
+ + add `pprint_local_path` to print local path (file/directory) in clickable link (as file URI)
21
+
22
+ + add `research` package to help with research tasks, including `benchquery` for benchmarking queries from dataframe
23
+ + add `wandb` module to allow easy sync offline data to Weights & Biases (wandb) and batch clear wandb runs.
21
24
 
22
25
  **Version 0.1.47**
23
26
  + add `pprint_box` to print object/string in a box frame (like in `inspect`)
@@ -29,6 +29,7 @@ halib/research/benchquery.py
29
29
  halib/research/dataset.py
30
30
  halib/research/plot.py
31
31
  halib/research/torchloader.py
32
+ halib/research/wandb_op.py
32
33
  halib/system/__init__.py
33
34
  halib/system/cmd.py
34
35
  halib/system/filesys.py
@@ -26,3 +26,4 @@ itables
26
26
  timebudget
27
27
  tqdm
28
28
  tube_dl
29
+ wandb
@@ -8,7 +8,7 @@ with open("requirements.txt") as f:
8
8
 
9
9
  setuptools.setup(
10
10
  name="halib",
11
- version="0.1.48",
11
+ version="0.1.50",
12
12
  author="Hoang Van Ha",
13
13
  author_email="hoangvanhauit@gmail.com",
14
14
  description="Small library for common tasks",
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