The simplest one/two ways local/remote sync module in python.
Project description
QSYNC
introduction
sync_module is the simplest way to set-up a one/two ways syncronisations between folders and even between two distinct devices, from a single python script ! just use it like so :
from qsync import SyncIniter
from sys import argv
from multiprocessing import freeze_support
import argparse
from qsync import server
def main():
# nothing usefull, just parsing command line args
parser = argparse.ArgumentParser(description="")
parser.add_argument('sync_src', type=str,
help='sync source directory')
parser.add_argument('sync_dst', type=str,
help='sync destination directory')
parser.add_argument('-bd', action='store_true',
help='bi directionnal mode')
parser.add_argument('--force-id', type=str,
help='force a specific id associated to the sync process (necessary to acces via http)')
parser.add_argument('--remote', type=str,
help='open sync server, specify destination ip')
parser.add_argument('--loop-time', type=float,
help='adjust the time between two sync (each use has it\'s own optimal inter-loop time to avoid sync errors'))
args = parser.parse_args()
sync_src = args.sync_src.replace("\\", "/")
sync_dst = args.sync_dst.replace("\\", "/")
bi_d = args.bd
if args.remote:
remote_ip = args.remote
remote = True
else:
remote_ip = ""
remote = False
force_id = args.force_id
loop_time = args.loop_time
# sync_src and sync_dst must be two strings containing two path
# bi_directionnal is an optionnal boolean, default set to False
# remote is an optionnal boolean, set to True if the sync_dst path is on a remote location
# force_id let you specify the sync id, usefull in case of remote and/or want to keep a sync state after shutdown
# loop_time let you adjust the time between two sync (each use has it\'s own optimal inter-loop time to avoid sync errors)
s = SyncIniter(sync_src, sync_dst, bi_directionnal=bi_d,
remote=remote, force_id=force_id, remote_ip=remote_ip,loop_time=loop_time)
s.start_sync()
print(f"started to sync, bi directionnal mode : {bi_d}, remote: {remote}")
print(f"\n\nSYNC ID :\n{s.sync_id}\n\n")
# start the server if the other side is on a remote machine if not already running
if remote:
try:
get("https://127.0.0.1:2121/is_running", timeout=1, verify=False)
except TimeoutError:
server.app.run(host="0.0.0.0", port=2121, ssl_context='adhoc')
if __name__ == "__main__":
freeze_support()
main()
A cli is also available with this module :
usage: __main__.py [-h] [-bd] [--force-id FORCE_ID] [--remote REMOTE] [--loop-time LOOP_TIME]
sync_src sync_dst
positional arguments:
sync_src sync source directory
sync_dst sync destination directory
optional arguments:
-h, --help show this help message and exit
-bd bi directionnal mode
--force-id FORCE_ID force a specific id associated to the sync process (necessary to acces via
http)
--remote REMOTE open sync server, specify destination ip
--loop-time LOOP_TIME
adjust the time between two sync (each use has it's own optimal inter-loop
time to avoid sync errors)
(remote sync does not need to be in real time, each device will store changes and wait the other when they can't connect to each other)
Example :
C:\> python -m qsync "D:\test_src" "C:\Users\USER\Documents\test_dst" -bd --remote "192.168.0.64" --force-id "0x1bfdc4f5e421fe563476d2441980349d79c32ccae555134b3eb7a4b62f68f1e66aa574f933289edbc6043b25977b69f2c921961fd60596e4281464fc84f76d3c16df24db5c15fcf98ab071aaf6711da44efcc0024f37a0213b98e42739eb5398cf760a307149cfb58dfa5a" --loop-time 10
Errors :
InvalidPathError
raised in start_sync() when a path don't exists
how qsync server works in a remote context :
(Sync does not need to be in real time, each device will store changes and wait the other when they can't connect to each other)
Specifications :
- The qsync sync server is an http server, to encrypt data it uses on-the-fly certificates.
- Because of these certificates, you must force whatever client you use to not verify certificates.
for example, qsync uses
requests.get(< args >,verify=False)
. - This server enable a great range of uses of qsync, from mobile-to-pc folders sync at multiple-pc sync.
- the sync id is an hexadecimal representation of a 256 digits lenght number and must be present on any http requests, so the two sync ends must share this id. Once you got this id, to start the other sync process you need to use --force-id FORCE_ID optionnal argument. Or place it in your script as optionnal argument into the SyncIniter class :
SyncIniter(< args >, remote=True, force_id=force_id, remote_ip=remote_ip)
How does it make its things to syncronize :
-
The main infinite loop make two requests :
- "https://{self.sRemoteIP}:2121/remote_map" to try to syncronize the folders map between two devices
- "https://{self.sRemoteIP}:2121/sync_map" to try to ask the other device what's new, trigger multiple requests from the other device
-
The server has 7 URLs :
/is_running
, to check if the server is already running/sync_map?sync_id=...
, to trigger many requests that will make pending changes on your filesystem/remote_map?sync_id=...
, return a JSON response containing the current filesystem map/get_file?sync_id=...&full_path=...
, make you download a specific file. Full_path is the full path to get the file from the other side's filesystem (server side)./upload_file?sync_id=...&full_path=...
, POST only. Upload a specific file. Full_path is thefull path to upload the file from the other side's filesystem (server side)./remove?sync_id=...&full_path=...
, Suppress something. File or folder (server side)./mkdir?sync_id=...&full_path=...
, Create a folder (server side). Full_path is the full path to create the folder from the other side's filesystem (server side).
The server make sure each request don't tries to download/modify... things outside the root folder of your sync. If anything wrong is made, an explicit error message will be return as response. Each uploaded file's name is also checked.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file qsync-0.1.8.tar.gz
.
File metadata
- Download URL: qsync-0.1.8.tar.gz
- Upload date:
- Size: 11.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.4.1 importlib_metadata/3.10.0 pkginfo/1.7.0 requests/2.23.0 requests-toolbelt/0.9.1 tqdm/4.55.0 CPython/3.9.1
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | eed56b8836e5c53d09217a811c165de8c4c548ee82a316d042bb03c514b66aff |
|
MD5 | b583ffaedc4a6853a26715e1d2cf3ad5 |
|
BLAKE2b-256 | 7a3ce499226bb89c11c0fb258e63ed048ab4d7e84c9a8b1f07427eb292f85f43 |
File details
Details for the file qsync-0.1.8-py3-none-any.whl
.
File metadata
- Download URL: qsync-0.1.8-py3-none-any.whl
- Upload date:
- Size: 11.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.4.1 importlib_metadata/3.10.0 pkginfo/1.7.0 requests/2.23.0 requests-toolbelt/0.9.1 tqdm/4.55.0 CPython/3.9.1
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 50b140aa9021838fc608498574eca2e196623332eca486b613ae301032f2d3fb |
|
MD5 | 671a1d81df4f2c22d3366d179b915f86 |
|
BLAKE2b-256 | 363aba61ff5aa4a051c658775fd061a252ae99bb3e54d04634edaa64b6a4b7cc |