sy-python 0.1.1__cp38-abi3-manylinux_2_28_aarch64.whl → 0.2.1__cp38-abi3-manylinux_2_28_aarch64.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sy-python
3
- Version: 0.1.1
3
+ Version: 0.2.1
4
4
  Classifier: Development Status :: 4 - Beta
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: License :: OSI Approved :: MIT License
@@ -0,0 +1,10 @@
1
+ sy_python-0.2.1.dist-info/METADATA,sha256=KvuM3uRtUZgqT4OXQYfNjNhpWfjqXhSaPWuxG3IDjLw,1286
2
+ sy_python-0.2.1.dist-info/WHEEL,sha256=TbOEPJcLRdoLQex6HY6MJy-GFvwdI5JUNazV49lxV2I,108
3
+ sy_python-0.2.1.dist-info/entry_points.txt,sha256=NPHeXCspWz0vGpS57shSO3ezGr5DOiByIM4ytzH_sJc,64
4
+ sypy/__init__.py,sha256=kUQ1kbnGgG15AhivJcHMjdIDjB0e8KD7za5xz4etnGg,2988
5
+ sypy/__main__.py,sha256=K9CZ6AJGxOFYSkuWRmvpm2bynZu1Ws_qDie_IPO8cjg,411
6
+ sypy/_sypy.abi3.so,sha256=JC3LTfXpMfCujuqZLRz_Fs6pQlTu1b09HQv11kjAJ3U,23846232
7
+ sypy/_sypy.pyi,sha256=w12Ij8XV6p2f_XytXr-Wfk4YTwVWQSsEAPez3UWdUcs,13815
8
+ sypy/ls_types.py,sha256=PIm8Q9jEo-b5OaGxpJ4mcTgG4Dn4uXQHFvT9ARbiu7M,1299
9
+ sypy/py.typed,sha256=qww23I-O7yv_Kf5Wu2UW3r8K1Vd12UDESBl5tmzRSI0,60
10
+ sy_python-0.2.1.dist-info/RECORD,,
sypy/__init__.py CHANGED
@@ -32,15 +32,51 @@ Example:
32
32
  >>> s3 = sypy.S3Config(..., client_options=options)
33
33
  >>> stats = sypy.sync("/local/", "s3://bucket/", s3=s3, parallel=100)
34
34
 
35
+ # Dry-run with typed summary
36
+ >>> stats = sypy.sync("/source", "/dest", dry_run=True)
37
+ >>> summary = stats.dry_run_summary
38
+ >>> print(f"Would create {summary['would_create']['count']} files")
39
+
35
40
  """
36
41
 
42
+ from typing import TypedDict
43
+
44
+
45
+ class DryRunChange(TypedDict):
46
+ """Details about changes that would be made"""
47
+
48
+ count: int
49
+ bytes: int
50
+
51
+
52
+ class DryRunSummary(TypedDict):
53
+ """Summary of what would happen in a dry-run"""
54
+
55
+ would_create: DryRunChange
56
+ would_update: DryRunChange
57
+ would_delete: DryRunChange
58
+ total_files: int
59
+ total_bytes: int
60
+
61
+
62
+ # Import TypedDict for ls functionality
37
63
  from sypy._sypy import (
64
+ # Dry-run classes
65
+ ChangeAction,
38
66
  # Client options
39
67
  CloudClientOptions,
68
+ DirectoryChange,
69
+ DryRunDetails,
70
+ FileChange,
40
71
  # Config classes
41
72
  GcsConfig,
73
+ # List classes
74
+ ListEntry,
75
+ # Progress classes
76
+ ProgressSnapshot,
42
77
  S3Config,
43
78
  SshConfig,
79
+ SymlinkChange,
44
80
  # Classes
45
81
  SyncError,
46
82
  SyncOptions,
@@ -48,23 +84,39 @@ from sypy._sypy import (
48
84
  SyncStats,
49
85
  # Version
50
86
  __version__,
87
+ # Functions
88
+ ls,
51
89
  # CLI functions
52
90
  main,
53
- # Functions
54
91
  parse_path,
55
92
  run_daemon,
56
93
  run_server,
57
94
  sync,
58
95
  sync_with_options,
59
96
  )
97
+ from sypy.ls_types import ListEntryDict
60
98
 
61
99
  __all__ = [
100
+ # Dry-run classes
101
+ "ChangeAction",
62
102
  # Client options
63
103
  "CloudClientOptions",
104
+ "DirectoryChange",
105
+ # TypedDicts
106
+ "DryRunChange",
107
+ "DryRunDetails",
108
+ "DryRunSummary",
109
+ "FileChange",
64
110
  # Config classes
65
111
  "GcsConfig",
112
+ # List classes
113
+ "ListEntry",
114
+ "ListEntryDict",
115
+ # Progress classes
116
+ "ProgressSnapshot",
66
117
  "S3Config",
67
118
  "SshConfig",
119
+ "SymlinkChange",
68
120
  # Classes
69
121
  "SyncError",
70
122
  "SyncOptions",
@@ -72,9 +124,10 @@ __all__ = [
72
124
  "SyncStats",
73
125
  # Version
74
126
  "__version__",
127
+ # Functions
128
+ "ls",
75
129
  # CLI functions
76
130
  "main",
77
- # Functions
78
131
  "parse_path",
79
132
  "run_daemon",
80
133
  "run_server",
sypy/_sypy.abi3.so CHANGED
Binary file
sypy/_sypy.pyi CHANGED
@@ -197,6 +197,57 @@ class SyncStats:
197
197
  def success(self) -> bool: ...
198
198
  @property
199
199
  def transfer_rate(self) -> float: ...
200
+ @property
201
+ def dry_run_summary(self) -> dict[str, dict[str, int] | int]: ...
202
+
203
+ class ProgressSnapshot:
204
+ total_bytes: int
205
+ """Estimated total bytes to process (may be 0 if unknown)."""
206
+
207
+ bytes: int
208
+ """Bytes completed so far."""
209
+
210
+ bytes_per_sec: int
211
+ """Instantaneous speed in bytes per second."""
212
+
213
+ transfers: int
214
+ """Number of transfers (files) completed."""
215
+
216
+ total_transfers: int
217
+ """Total number of transfers planned."""
218
+
219
+ active_transfers: int
220
+ """Number of currently active (in-flight) transfers."""
221
+
222
+ percentage: float | None
223
+ """Percentage complete (0.0 to 100.0), None if total_bytes is 0/unknown."""
224
+
225
+ elapsed_secs: float
226
+ """Elapsed time in seconds since sync started."""
227
+
228
+ @property
229
+ def transferring(self) -> list[str]: ...
230
+ """List of currently transferring file paths."""
231
+
232
+ @property
233
+ def current_file(self) -> str | None: ...
234
+ """Current file being transferred (first in transferring list), or None."""
235
+
236
+ @property
237
+ def speed_human(self) -> str: ...
238
+ """Speed as a human-readable string (e.g., "10.5 MB/s")."""
239
+
240
+ @property
241
+ def bytes_human(self) -> str: ...
242
+ """Bytes as a human-readable string (e.g., "1.5 GB")."""
243
+
244
+ @property
245
+ def total_bytes_human(self) -> str: ...
246
+ """Total bytes as a human-readable string (e.g., "10.2 GB")."""
247
+
248
+ @property
249
+ def eta_secs(self) -> float | None: ...
250
+ """Estimated time remaining in seconds, or None if unknown."""
200
251
 
201
252
  class SyncPath:
202
253
  def __init__(self, path: str) -> None: ...
@@ -367,15 +418,12 @@ class SyncOptions:
367
418
  ) -> None: ...
368
419
 
369
420
  # Type alias for progress callback
370
- type ProgressCallback = Callable[[int, int, str, str], None]
421
+ type ProgressCallback = Callable[[ProgressSnapshot], None]
371
422
  """
372
423
  Progress callback function signature.
373
424
 
374
425
  Args:
375
- current: Current progress count
376
- total: Total count
377
- path: Current file path
378
- action: Current action ("scanning", "creating", "updating", etc.)
426
+ snapshot: ProgressSnapshot describing current sync state
379
427
  """
380
428
 
381
429
  def sync(
@@ -395,6 +443,7 @@ def sync(
395
443
  max_size: str | None = None,
396
444
  bwlimit: str | None = None,
397
445
  progress_callback: ProgressCallback | None = None,
446
+ progress_frequency_ms: int = 1000,
398
447
  daemon_auto: bool = False,
399
448
  resume: bool = True,
400
449
  ignore_times: bool = False,
@@ -418,9 +467,54 @@ def sync_with_options(
418
467
  dest: str,
419
468
  options: SyncOptions,
420
469
  progress_callback: ProgressCallback | None = None,
470
+ progress_frequency_ms: int = 1000,
421
471
  ) -> SyncStats: ...
422
472
  def parse_path(path: str) -> SyncPath: ...
423
473
 
474
+ class ListEntry:
475
+ path: str
476
+ """Relative path of the entry."""
477
+
478
+ size: int
479
+ """File size in bytes (0 for directories)."""
480
+
481
+ mod_time: str
482
+ """Modification time in RFC3339 format."""
483
+
484
+ is_dir: bool
485
+ """Whether this is a directory."""
486
+
487
+ entry_type: str
488
+ """Entry type: "file", "directory", or "symlink"."""
489
+
490
+ mime_type: str | None
491
+ """MIME type (inferred from extension)."""
492
+
493
+ symlink_target: str | None
494
+ """Symlink target path (if this is a symlink)."""
495
+
496
+ is_sparse: bool | None
497
+ """Whether this is a sparse file."""
498
+
499
+ allocated_size: int | None
500
+ """Actual allocated size on disk (may differ from size for sparse files)."""
501
+
502
+ inode: int | None
503
+ """Inode number (Unix only)."""
504
+
505
+ num_links: int | None
506
+ """Number of hard links to this file."""
507
+
508
+ def to_dict(self) -> dict[str, str | int | bool | None]: ...
509
+
510
+ def ls(
511
+ path: str,
512
+ recursive: bool = False,
513
+ max_depth: int | None = None,
514
+ files_only: bool = False,
515
+ dirs_only: bool = False,
516
+ ) -> list[ListEntry]: ...
517
+
424
518
  # CLI functions
425
519
  def main(args: list[str] | None = None) -> int: ...
426
520
  def run_server(path: str) -> None: ...
sypy/ls_types.py ADDED
@@ -0,0 +1,55 @@
1
+ """
2
+ TypedDict definitions for sy-ls functionality.
3
+
4
+ This module provides TypedDict types for type-safe usage of the ls() function
5
+ and ListEntry objects.
6
+ """
7
+
8
+ from typing import TypedDict
9
+
10
+
11
+ class ListEntryDict(TypedDict, total=False):
12
+ """
13
+ TypedDict representing a directory listing entry.
14
+
15
+ All fields are required except those marked Optional.
16
+ Use this for type hints when calling entry.to_dict().
17
+
18
+ Example:
19
+ >>> entries = sypy.ls("/path")
20
+ >>> dicts: list[ListEntryDict] = [e.to_dict() for e in entries]
21
+
22
+ """
23
+
24
+ path: str
25
+ """Relative path of the entry."""
26
+
27
+ size: int
28
+ """File size in bytes (0 for directories)."""
29
+
30
+ mod_time: str
31
+ """Modification time in RFC3339 format."""
32
+
33
+ is_dir: bool
34
+ """Whether this is a directory."""
35
+
36
+ entry_type: str
37
+ """Entry type: "file", "directory", or "symlink"."""
38
+
39
+ mime_type: str | None
40
+ """MIME type (inferred from extension)."""
41
+
42
+ symlink_target: str | None
43
+ """Symlink target path (if this is a symlink)."""
44
+
45
+ is_sparse: bool | None
46
+ """Whether this is a sparse file."""
47
+
48
+ allocated_size: int | None
49
+ """Actual allocated size on disk."""
50
+
51
+ inode: int | None
52
+ """Inode number (Unix only)."""
53
+
54
+ num_links: int | None
55
+ """Number of hard links to this file."""
@@ -1,9 +0,0 @@
1
- sy_python-0.1.1.dist-info/METADATA,sha256=JKVKjYrA-sy0rbnpAf74BcGXNbNpoJzD3y_RqFE-ovY,1286
2
- sy_python-0.1.1.dist-info/WHEEL,sha256=TbOEPJcLRdoLQex6HY6MJy-GFvwdI5JUNazV49lxV2I,108
3
- sy_python-0.1.1.dist-info/entry_points.txt,sha256=NPHeXCspWz0vGpS57shSO3ezGr5DOiByIM4ytzH_sJc,64
4
- sypy/__init__.py,sha256=woMOP3zuYbOdeV5FjQ0pVCwu_gc594E8l_PUzC3w3ec,1831
5
- sypy/__main__.py,sha256=K9CZ6AJGxOFYSkuWRmvpm2bynZu1Ws_qDie_IPO8cjg,411
6
- sypy/_sypy.abi3.so,sha256=z9t88NHyetrc2SLEpt2BAIKSTWsUtPAC78WdiuzWWV4,23402576
7
- sypy/_sypy.pyi,sha256=hw0YHmaKn7Aw2Dmg0RpaAPnKxk7sz2jRUwwDitb3eNc,11313
8
- sypy/py.typed,sha256=qww23I-O7yv_Kf5Wu2UW3r8K1Vd12UDESBl5tmzRSI0,60
9
- sy_python-0.1.1.dist-info/RECORD,,