sy-python 0.1.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.
@@ -0,0 +1,30 @@
1
+ Metadata-Version: 2.4
2
+ Name: sy-python
3
+ Version: 0.1.1
4
+ Classifier: Development Status :: 4 - Beta
5
+ Classifier: Intended Audience :: Developers
6
+ Classifier: License :: OSI Approved :: MIT License
7
+ Classifier: Operating System :: MacOS
8
+ Classifier: Operating System :: POSIX :: Linux
9
+ Classifier: Operating System :: Microsoft :: Windows
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.8
12
+ Classifier: Programming Language :: Python :: 3.9
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: Implementation :: CPython
17
+ Classifier: Programming Language :: Rust
18
+ Classifier: Topic :: System :: Archiving :: Backup
19
+ Classifier: Topic :: System :: Filesystems
20
+ Classifier: Typing :: Typed
21
+ Requires-Dist: pytest>=7.0 ; extra == 'dev'
22
+ Requires-Dist: tqdm>=4.0 ; extra == 'dev'
23
+ Provides-Extra: dev
24
+ Summary: Python bindings for sy - Modern file synchronization tool
25
+ Keywords: rsync,sync,file-transfer,backup
26
+ License: MIT
27
+ Requires-Python: >=3.8
28
+ Project-URL: Documentation, https://github.com/nijaru/sy#readme
29
+ Project-URL: Homepage, https://github.com/nijaru/sy
30
+ Project-URL: Repository, https://github.com/nijaru/sy
@@ -0,0 +1,9 @@
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,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: maturin (1.11.5)
3
+ Root-Is-Purelib: false
4
+ Tag: cp38-abi3-manylinux_2_28_aarch64
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ sy=sypy.__main__:main
3
+ sypy=sypy.__main__:main
sypy/__init__.py ADDED
@@ -0,0 +1,83 @@
1
+ """
2
+ sypy - Python bindings for sy file synchronization tool.
3
+
4
+ Fast, modern file synchronization with support for local, SSH, S3, and GCS.
5
+
6
+ Example:
7
+ >>> import sypy
8
+ >>> stats = sypy.sync("/source", "/dest")
9
+ >>> print(f"Synced {stats.files_created} files")
10
+
11
+ # With options
12
+ >>> stats = sypy.sync(
13
+ ... "/source", "/dest",
14
+ ... dry_run=True,
15
+ ... exclude=["*.log", "node_modules"],
16
+ ... )
17
+
18
+ # With S3 credentials
19
+ >>> s3 = sypy.S3Config(
20
+ ... access_key_id="...",
21
+ ... secret_access_key="...",
22
+ ... region="us-east-1",
23
+ ... )
24
+ >>> stats = sypy.sync("/local/", "s3://bucket/path/", s3=s3)
25
+
26
+ # With GCS credentials
27
+ >>> gcs = sypy.GcsConfig(credentials_file="/path/to/key.json")
28
+ >>> stats = sypy.sync("/local/", "gs://bucket/path/", gcs=gcs)
29
+
30
+ # With custom client options for high throughput
31
+ >>> options = sypy.CloudClientOptions.high_throughput()
32
+ >>> s3 = sypy.S3Config(..., client_options=options)
33
+ >>> stats = sypy.sync("/local/", "s3://bucket/", s3=s3, parallel=100)
34
+
35
+ """
36
+
37
+ from sypy._sypy import (
38
+ # Client options
39
+ CloudClientOptions,
40
+ # Config classes
41
+ GcsConfig,
42
+ S3Config,
43
+ SshConfig,
44
+ # Classes
45
+ SyncError,
46
+ SyncOptions,
47
+ SyncPath,
48
+ SyncStats,
49
+ # Version
50
+ __version__,
51
+ # CLI functions
52
+ main,
53
+ # Functions
54
+ parse_path,
55
+ run_daemon,
56
+ run_server,
57
+ sync,
58
+ sync_with_options,
59
+ )
60
+
61
+ __all__ = [
62
+ # Client options
63
+ "CloudClientOptions",
64
+ # Config classes
65
+ "GcsConfig",
66
+ "S3Config",
67
+ "SshConfig",
68
+ # Classes
69
+ "SyncError",
70
+ "SyncOptions",
71
+ "SyncPath",
72
+ "SyncStats",
73
+ # Version
74
+ "__version__",
75
+ # CLI functions
76
+ "main",
77
+ # Functions
78
+ "parse_path",
79
+ "run_daemon",
80
+ "run_server",
81
+ "sync",
82
+ "sync_with_options",
83
+ ]
sypy/__main__.py ADDED
@@ -0,0 +1,21 @@
1
+ """
2
+ Entry point for `python -m sypy` command.
3
+
4
+ This allows running sy as a Python module:
5
+ python -m sypy /source /dest
6
+ python -m sypy --server /path
7
+ python -m sypy --daemon --socket ~/.sy/daemon.sock
8
+ """
9
+
10
+ import sys
11
+
12
+
13
+ def main() -> int:
14
+ """Main entry point for the sy CLI."""
15
+ from sypy._sypy import main as _main
16
+
17
+ return _main(sys.argv)
18
+
19
+
20
+ if __name__ == "__main__":
21
+ sys.exit(main())
sypy/_sypy.abi3.so ADDED
Binary file
sypy/_sypy.pyi ADDED
@@ -0,0 +1,427 @@
1
+ from collections.abc import Callable
2
+
3
+ __version__: str
4
+
5
+ class CloudClientOptions:
6
+ pool_max_idle_per_host: int
7
+ """Maximum idle connections per host. Default: 50."""
8
+
9
+ pool_idle_timeout_secs: int
10
+ """How long to keep idle connections (seconds). Default: 30."""
11
+
12
+ connect_timeout_secs: int
13
+ """Connection timeout (seconds). Default: 5."""
14
+
15
+ request_timeout_secs: int
16
+ """Request timeout including transfer (seconds). Default: 60."""
17
+
18
+ max_retries: int
19
+ """Maximum retry attempts. Default: 3."""
20
+
21
+ retry_timeout_secs: int
22
+ """Maximum time for retries (seconds). Default: 15."""
23
+
24
+ allow_http: bool
25
+ """Allow HTTP (non-TLS) connections. Default: False."""
26
+
27
+ def __init__(
28
+ self,
29
+ pool_max_idle_per_host: int = 50,
30
+ pool_idle_timeout_secs: int = 30,
31
+ connect_timeout_secs: int = 5,
32
+ request_timeout_secs: int = 60,
33
+ max_retries: int = 3,
34
+ retry_timeout_secs: int = 15,
35
+ allow_http: bool = False,
36
+ ) -> None: ...
37
+ @staticmethod
38
+ def high_throughput() -> CloudClientOptions: ...
39
+ @staticmethod
40
+ def low_latency() -> CloudClientOptions: ...
41
+
42
+ class S3Config:
43
+ access_key_id: str | None
44
+ """AWS access key ID."""
45
+
46
+ secret_access_key: str | None
47
+ """AWS secret access key."""
48
+
49
+ session_token: str | None
50
+ """AWS session token (for temporary credentials)."""
51
+
52
+ region: str | None
53
+ """AWS region (e.g., "us-east-1")."""
54
+
55
+ endpoint: str | None
56
+ """Custom endpoint URL for S3-compatible services."""
57
+
58
+ profile: str | None
59
+ """AWS profile name to use from ~/.aws/credentials."""
60
+
61
+ client_options: CloudClientOptions | None
62
+ """HTTP client options (timeouts, retries, connection pool)."""
63
+
64
+ def __init__(
65
+ self,
66
+ access_key_id: str | None = None,
67
+ secret_access_key: str | None = None,
68
+ session_token: str | None = None,
69
+ region: str | None = None,
70
+ endpoint: str | None = None,
71
+ profile: str | None = None,
72
+ client_options: CloudClientOptions | None = None,
73
+ ) -> None: ...
74
+
75
+ class GcsConfig:
76
+ credentials_file: str | None
77
+ """Path to service account JSON key file."""
78
+
79
+ project_id: str | None
80
+ """GCP project ID."""
81
+
82
+ credentials_json: str | None
83
+ """Service account JSON as a string (alternative to credentials_file)."""
84
+
85
+ client_options: CloudClientOptions | None
86
+ """HTTP client options (timeouts, retries, connection pool)."""
87
+
88
+ def __init__(
89
+ self,
90
+ credentials_file: str | None = None,
91
+ project_id: str | None = None,
92
+ credentials_json: str | None = None,
93
+ client_options: CloudClientOptions | None = None,
94
+ ) -> None: ...
95
+
96
+ class SshConfig:
97
+ key_file: str | None
98
+ """Path to private key file."""
99
+
100
+ port: int | None
101
+ """SSH port (default: 22)."""
102
+
103
+ password: str | None
104
+ """SSH password (usually not needed with key authentication)."""
105
+
106
+ compression: bool
107
+ """Enable compression for SSH connection."""
108
+
109
+ proxy_jump: str | None
110
+ """Proxy jump host (e.g., "bastion@proxy.example.com")."""
111
+
112
+ connect_timeout: int | None
113
+ """Connection timeout in seconds."""
114
+
115
+ pool_size: int | None
116
+ """Number of parallel SSH connections."""
117
+
118
+ def __init__(
119
+ self,
120
+ key_file: str | None = None,
121
+ port: int | None = None,
122
+ password: str | None = None,
123
+ compression: bool = False,
124
+ proxy_jump: str | None = None,
125
+ connect_timeout: int | None = None,
126
+ pool_size: int | None = None,
127
+ ) -> None: ...
128
+
129
+ class SyncError:
130
+ path: str
131
+ """Path that caused the error."""
132
+
133
+ error: str
134
+ """Error message."""
135
+
136
+ action: str
137
+ """Action that was being performed."""
138
+
139
+ class SyncStats:
140
+ files_scanned: int
141
+ """Number of files scanned."""
142
+
143
+ files_created: int
144
+ """Number of files created."""
145
+
146
+ files_updated: int
147
+ """Number of files updated."""
148
+
149
+ files_skipped: int
150
+ """Number of files skipped (already up-to-date)."""
151
+
152
+ files_deleted: int
153
+ """Number of files deleted."""
154
+
155
+ bytes_transferred: int
156
+ """Total bytes transferred."""
157
+
158
+ files_delta_synced: int
159
+ """Number of files synced using delta algorithm."""
160
+
161
+ delta_bytes_saved: int
162
+ """Bytes saved by delta sync."""
163
+
164
+ files_compressed: int
165
+ """Number of files compressed during transfer."""
166
+
167
+ compression_bytes_saved: int
168
+ """Bytes saved by compression."""
169
+
170
+ files_verified: int
171
+ """Number of files verified."""
172
+
173
+ verification_failures: int
174
+ """Number of verification failures."""
175
+
176
+ duration_secs: float
177
+ """Duration of the sync operation in seconds."""
178
+
179
+ bytes_would_add: int
180
+ """Bytes that would be added (dry-run only)."""
181
+
182
+ bytes_would_change: int
183
+ """Bytes that would change (dry-run only)."""
184
+
185
+ bytes_would_delete: int
186
+ """Bytes that would be deleted (dry-run only)."""
187
+
188
+ dirs_created: int
189
+ """Number of directories created."""
190
+
191
+ symlinks_created: int
192
+ """Number of symlinks created."""
193
+
194
+ @property
195
+ def errors(self) -> list[SyncError]: ...
196
+ @property
197
+ def success(self) -> bool: ...
198
+ @property
199
+ def transfer_rate(self) -> float: ...
200
+
201
+ class SyncPath:
202
+ def __init__(self, path: str) -> None: ...
203
+ @property
204
+ def path(self) -> str: ...
205
+ @property
206
+ def is_local(self) -> bool: ...
207
+ @property
208
+ def is_remote(self) -> bool: ...
209
+ @property
210
+ def is_s3(self) -> bool: ...
211
+ @property
212
+ def is_gcs(self) -> bool: ...
213
+ @property
214
+ def is_daemon(self) -> bool: ...
215
+ @property
216
+ def has_trailing_slash(self) -> bool: ...
217
+ @property
218
+ def host(self) -> str | None: ...
219
+ @property
220
+ def user(self) -> str | None: ...
221
+ @property
222
+ def bucket(self) -> str | None: ...
223
+
224
+ class SyncOptions:
225
+ dry_run: bool
226
+ """Dry run mode - show changes without applying."""
227
+
228
+ delete: bool
229
+ """Delete files in destination not present in source."""
230
+
231
+ delete_threshold: int
232
+ """Maximum percentage of files that can be deleted (0-100)."""
233
+
234
+ trash: bool
235
+ """Move deleted files to trash instead of permanent deletion."""
236
+
237
+ force_delete: bool
238
+ """Skip deletion safety checks."""
239
+
240
+ parallel: int
241
+ """Number of parallel file transfers."""
242
+
243
+ max_errors: int
244
+ """Maximum number of errors before aborting (0 = unlimited)."""
245
+
246
+ min_size: str | None
247
+ """Minimum file size to sync (e.g., "1MB")."""
248
+
249
+ max_size: str | None
250
+ """Maximum file size to sync (e.g., "1GB")."""
251
+
252
+ exclude: list[str]
253
+ """Exclude patterns."""
254
+
255
+ include: list[str]
256
+ """Include patterns."""
257
+
258
+ bwlimit: str | None
259
+ """Bandwidth limit (e.g., "10MB")."""
260
+
261
+ resume: bool
262
+ """Enable resume support for interrupted transfers."""
263
+
264
+ verify: bool
265
+ """Verify file integrity after write."""
266
+
267
+ compress: bool
268
+ """Enable compression for network transfers."""
269
+
270
+ preserve_xattrs: bool
271
+ """Preserve extended attributes."""
272
+
273
+ preserve_hardlinks: bool
274
+ """Preserve hard links."""
275
+
276
+ preserve_acls: bool
277
+ """Preserve access control lists."""
278
+
279
+ preserve_permissions: bool
280
+ """Preserve permissions."""
281
+
282
+ preserve_times: bool
283
+ """Preserve modification times."""
284
+
285
+ ignore_times: bool
286
+ """Ignore modification times, always compare checksums."""
287
+
288
+ size_only: bool
289
+ """Only compare file size, skip mtime checks."""
290
+
291
+ checksum: bool
292
+ """Always compare checksums instead of size+mtime."""
293
+
294
+ update: bool
295
+ """Skip files where destination is newer."""
296
+
297
+ ignore_existing: bool
298
+ """Skip files that already exist in destination."""
299
+
300
+ gitignore: bool
301
+ """Apply .gitignore rules."""
302
+
303
+ exclude_vcs: bool
304
+ """Exclude .git directories."""
305
+
306
+ bidirectional: bool
307
+ """Bidirectional sync mode."""
308
+
309
+ conflict_resolve: str
310
+ """Conflict resolution strategy ("newer", "larger", "smaller", "source", "dest", "rename")."""
311
+
312
+ daemon_auto: bool
313
+ """Use daemon mode for fast repeated syncs."""
314
+
315
+ retry: int
316
+ """Maximum retry attempts for network operations."""
317
+
318
+ retry_delay: int
319
+ """Initial delay between retries in seconds."""
320
+
321
+ s3: S3Config | None
322
+ """S3 configuration for S3/S3-compatible storage."""
323
+
324
+ gcs: GcsConfig | None
325
+ """GCS configuration for Google Cloud Storage."""
326
+
327
+ ssh: SshConfig | None
328
+ """SSH configuration for remote connections."""
329
+
330
+ def __init__(
331
+ self,
332
+ dry_run: bool = False,
333
+ delete: bool = False,
334
+ delete_threshold: int = 50,
335
+ trash: bool = False,
336
+ force_delete: bool = False,
337
+ parallel: int = 10,
338
+ max_errors: int = 100,
339
+ min_size: str | None = None,
340
+ max_size: str | None = None,
341
+ exclude: list[str] | None = None,
342
+ include: list[str] | None = None,
343
+ bwlimit: str | None = None,
344
+ resume: bool = True,
345
+ verify: bool = False,
346
+ compress: bool = False,
347
+ preserve_xattrs: bool = False,
348
+ preserve_hardlinks: bool = False,
349
+ preserve_acls: bool = False,
350
+ preserve_permissions: bool = False,
351
+ preserve_times: bool = False,
352
+ ignore_times: bool = False,
353
+ size_only: bool = False,
354
+ checksum: bool = False,
355
+ update: bool = False,
356
+ ignore_existing: bool = False,
357
+ gitignore: bool = False,
358
+ exclude_vcs: bool = False,
359
+ bidirectional: bool = False,
360
+ conflict_resolve: str = "newer",
361
+ daemon_auto: bool = False,
362
+ retry: int = 3,
363
+ retry_delay: int = 1,
364
+ s3: S3Config | None = None,
365
+ gcs: GcsConfig | None = None,
366
+ ssh: SshConfig | None = None,
367
+ ) -> None: ...
368
+
369
+ # Type alias for progress callback
370
+ type ProgressCallback = Callable[[int, int, str, str], None]
371
+ """
372
+ Progress callback function signature.
373
+
374
+ Args:
375
+ current: Current progress count
376
+ total: Total count
377
+ path: Current file path
378
+ action: Current action ("scanning", "creating", "updating", etc.)
379
+ """
380
+
381
+ def sync(
382
+ source: str,
383
+ dest: str,
384
+ *,
385
+ dry_run: bool = False,
386
+ delete: bool = False,
387
+ delete_threshold: int = 50,
388
+ parallel: int = 10,
389
+ verify: bool = False,
390
+ compress: bool = False,
391
+ checksum: bool = False,
392
+ exclude: list[str] | None = None,
393
+ include: list[str] | None = None,
394
+ min_size: str | None = None,
395
+ max_size: str | None = None,
396
+ bwlimit: str | None = None,
397
+ progress_callback: ProgressCallback | None = None,
398
+ daemon_auto: bool = False,
399
+ resume: bool = True,
400
+ ignore_times: bool = False,
401
+ size_only: bool = False,
402
+ update: bool = False,
403
+ ignore_existing: bool = False,
404
+ gitignore: bool = False,
405
+ exclude_vcs: bool = False,
406
+ preserve_xattrs: bool = False,
407
+ preserve_hardlinks: bool = False,
408
+ preserve_permissions: bool = False,
409
+ preserve_times: bool = False,
410
+ retry: int = 3,
411
+ retry_delay: int = 1,
412
+ s3: S3Config | None = None,
413
+ gcs: GcsConfig | None = None,
414
+ ssh: SshConfig | None = None,
415
+ ) -> SyncStats: ...
416
+ def sync_with_options(
417
+ source: str,
418
+ dest: str,
419
+ options: SyncOptions,
420
+ progress_callback: ProgressCallback | None = None,
421
+ ) -> SyncStats: ...
422
+ def parse_path(path: str) -> SyncPath: ...
423
+
424
+ # CLI functions
425
+ def main(args: list[str] | None = None) -> int: ...
426
+ def run_server(path: str) -> None: ...
427
+ def run_daemon(socket_path: str, root_path: str | None = None) -> None: ...
sypy/py.typed ADDED
@@ -0,0 +1 @@
1
+ # PEP 561 marker file - this package supports type checking