API Reference
This section documents the API of p2p_copy
. Only the functions run_relay, send and receive are intended for users, others are mainly information for developers. For module structure, see Module Layout. Generated from source code docstrings.
p2p_copy_server
run_relay
async
run_relay(host, port, use_tls=True, certfile=None, keyfile=None)
Run the WebSocket relay server for pairing and forwarding client connections.
This command starts a relay server that listens on the specified host/interface and port, optionally secured with TLS (recommended for production). The server pairs sender and receiver clients based on matching passphrase hashes, then forwards bidirectional data streams without storing content. It handles exactly one sender and one receiver per code hash, rejecting duplicates. Use for secure, firewall-friendly (port 443) P2P transfers.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
host
|
str
|
Host to bind to. |
required |
port
|
int
|
Port to bind to. |
required |
use_tls
|
bool
|
Whether to use TLS. Default is True. |
True
|
certfile
|
str
|
Path to TLS certificate file. |
None
|
keyfile
|
str
|
Path to TLS key file. |
None
|
Raises:
Type | Description |
---|---|
RuntimeError
|
If TLS is requested but certfile or keyfile is missing. |
Source code in src/p2p_copy_server/relay.py
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
|
p2p_copy.api
send
async
send(server, code, files, *, encrypt=False, compress=CompressMode.auto, resume=False)
Send one or more files or directories to a paired receiver via the relay server.
This command connects to the specified WebSocket relay server, authenticates using the shared passphrase (hashed for pairing), and streams the provided files/directories in chunks to the receiver. Supports directories by recursively including all files in alphabetical order. Optional end-to-end encryption (AES-GCM) and compression (Zstandard, auto-detected per file) can be enabled. If resume is enabled, it coordinates with the receiver to skip complete files or append to partial ones based on chained checksum verification.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
server
|
str
|
The WebSocket server URL (ws:// or wss://). |
required |
code
|
str
|
The shared passphrase/code for pairing. |
required |
files
|
List[str]
|
List of files and/or directories to send. |
required |
encrypt
|
bool
|
Enable end-to-end encryption. Default is False. Receiver needs to use the same setting. |
False
|
compress
|
CompressMode
|
Compression mode. Default is 'auto'. |
auto
|
resume
|
bool
|
Enable resume of partial transfers. Default is False. If True, attempt to skip identical files and append incomplete files based on receiver feedback. |
False
|
Returns:
Type | Description |
---|---|
int
|
Exit code: 0 on success, non-zero on error. |
Notes
- Supports resuming by comparing checksums of partial files.
- Uses chunked streaming for large files.
Source code in src/p2p_copy/api.py
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 |
|
receive
async
receive(server, code, *, encrypt=False, out=None)
Receive files from a paired sender via the relay server and write to the output directory.
This command connects to the relay server, pairs using the shared passphrase hash, and receives a manifest of incoming files/directories. Files are written to the output directory, preserving relative paths from the manifest. Supports optional end-to-end decryption (matching sender's encryption) and decompression. If the sender requests resume, this receiver reports existing file states (via checksums) to enable skipping or appending.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
server
|
str
|
The WebSocket server URL (ws:// or wss://). |
required |
code
|
str
|
The shared passphrase/code for pairing. |
required |
encrypt
|
bool
|
Enable end-to-end encryption. Default is False. Sender needs to use the same setting. |
False
|
out
|
str
|
Output directory. Default is current directory. |
None
|
Returns:
Type | Description |
---|---|
int
|
Exit code: 0 on success, non-zero on error. |
Notes
- Supports resume if sender requests it.
- Writes files to the output directory, preserving relative paths.
- Info on whether to resume and compress is received from the sender
Source code in src/p2p_copy/api.py
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 |
|
p2p_copy.security
SecurityHandler
Handle security operations like hashing, encryption, and decryption for transfers.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
code
|
str
|
The shared passphrase/code. |
required |
encrypt
|
bool
|
Whether to enable end-to-end encryption. |
required |
Source code in src/p2p_copy/security.py
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
|
encrypt_chunk
encrypt_chunk(chunk)
Encrypt a chunk if encryption is enabled.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
chunk
|
bytes
|
The chunk to encrypt. |
required |
Returns:
Type | Description |
---|---|
bytes
|
The encrypted chunk, or original if not encrypted. |
Source code in src/p2p_copy/security.py
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
|
decrypt_chunk
decrypt_chunk(chunk)
Decrypt a chunk if encryption is enabled.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
chunk
|
bytes
|
The chunk to decrypt. |
required |
Returns:
Type | Description |
---|---|
bytes
|
The decrypted chunk, or original if not encrypted. |
Source code in src/p2p_copy/security.py
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
|
build_encrypted_manifest
build_encrypted_manifest(manifest)
Build an encrypted manifest for secure transmission.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
manifest
|
str
|
The plaintext manifest JSON. |
required |
Returns:
Type | Description |
---|---|
str
|
The JSON-serialized EncryptedManifest. |
Source code in src/p2p_copy/security.py
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
|
ChainedChecksum
Generate chained SHA-256 checksums over sequential payloads.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
seed
|
bytes
|
Initial seed for the chain. Default is empty bytes. |
b''
|
Source code in src/p2p_copy/security.py
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
|
next_hash
next_hash(payload=b'')
Compute the next hash in the chain: sha256(prev_chain || payload).
Parameters:
Name | Type | Description | Default |
---|---|---|---|
payload
|
bytes
|
Data to include in this hash. Default is empty. |
b''
|
Returns:
Type | Description |
---|---|
bytes
|
The 32-byte hash, which becomes the new prev_chain. |
Source code in src/p2p_copy/security.py
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
|
import_optional_security_libs
import_optional_security_libs()
Import optional security libraries (argon2-cffi, cryptography) if encryption is used.
Source code in src/p2p_copy/security.py
7 8 9 10 11 12 13 14 15 16 17 18 |
|
p2p_copy.compressor
CompressMode
Bases: str
, Enum
Enumeration of compression modes.
Source code in src/p2p_copy/compressor.py
7 8 9 10 11 12 13 14 |
|
Compressor
Handle compression and decompression of chunks using Zstandard.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
mode
|
CompressMode
|
Compression mode. Default is 'auto'. |
auto
|
Source code in src/p2p_copy/compressor.py
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
|
determine_compression
async
determine_compression(first_chunk)
Determine if compression should be used based on the first chunk (auto mode).
Parameters:
Name | Type | Description | Default |
---|---|---|---|
first_chunk
|
bytes
|
The first chunk of data. |
required |
Returns:
Type | Description |
---|---|
bytes
|
The (possibly compressed) first chunk. |
Source code in src/p2p_copy/compressor.py
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
|
compress
compress(chunk)
Compress a chunk if compression is enabled.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
chunk
|
bytes
|
The chunk to compress. |
required |
Returns:
Type | Description |
---|---|
bytes
|
The compressed or original chunk. |
Source code in src/p2p_copy/compressor.py
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
|
decompress
decompress(chunk)
Decompress a chunk if decompression is set up.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
chunk
|
bytes
|
The chunk to decompress. |
required |
Returns:
Type | Description |
---|---|
bytes
|
The decompressed or original chunk. |
Source code in src/p2p_copy/compressor.py
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
|
set_decompression
set_decompression(compression_type)
Set up the decompressor based on the compression type.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
compression_type
|
str
|
The type of compression ('zstd' or 'none'). |
required |
Source code in src/p2p_copy/compressor.py
102 103 104 105 106 107 108 109 110 111 112 |
|
p2p_copy.protocol
Hello
dataclass
Hello message for connection initiation.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
type
|
Literal['hello']
|
Message type. |
required |
code_hash_hex
|
str
|
Hex-encoded hash of the shared code. |
required |
role
|
Literal['sender', 'receiver']
|
The role of this client. |
required |
Source code in src/p2p_copy/protocol.py
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
|
ManifestEntry
dataclass
Entry in a file manifest.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
path
|
str
|
Relative path of the file. |
required |
size
|
int
|
File size in bytes. |
required |
Source code in src/p2p_copy/protocol.py
67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
|
Manifest
dataclass
Manifest of files to send.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
type
|
Literal['manifest']
|
Message type. |
required |
entries
|
Sequence[ManifestEntry]
|
List of file entries. |
required |
resume
|
bool
|
Whether to enable resume. Default is False. |
False
|
Source code in src/p2p_copy/protocol.py
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
|
EncryptedManifest
dataclass
Encrypted manifest for secure transmission.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
type
|
Literal['enc_manifest']
|
Message type. |
required |
nonce
|
str
|
Hex-encoded nonce that is used as random seed. Further nonces are based on this and used for encryption. Must be shared with receiver so it can decrypt accordingly. |
required |
hidden_manifest
|
str
|
Hex-encoded encrypted manifest. |
required |
Source code in src/p2p_copy/protocol.py
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
|
ReceiverManifestEntry
dataclass
Receiver's report of existing file state for resume.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
path
|
str
|
Relative path. |
required |
size
|
int
|
Bytes already present. |
required |
chain_hex
|
str
|
Hex-encoded chained checksum up to 'size'. |
required |
Source code in src/p2p_copy/protocol.py
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
|
ReceiverManifest
dataclass
Manifest from receiver reporting existing files.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
type
|
Literal['receiver_manifest']
|
Message type. |
required |
entries
|
Sequence[ReceiverManifestEntry]
|
List of entries. |
required |
Source code in src/p2p_copy/protocol.py
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
|
EncryptedReceiverManifest
dataclass
Encrypted receiver manifest.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
type
|
Literal['enc_receiver_manifest']
|
Message type. |
required |
hidden_manifest
|
str
|
Hex-encoded encrypted manifest. |
required |
Source code in src/p2p_copy/protocol.py
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 |
|
dumps
dumps(msg)
JSON-dump a message with compact separators.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
msg
|
Dict[str, Any]
|
The message to serialize. |
required |
Returns:
Type | Description |
---|---|
str
|
Compact JSON string. |
Source code in src/p2p_copy/protocol.py
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
loads
loads(s)
JSON-load a string into a dict.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
s
|
str
|
JSON string. |
required |
Returns:
Type | Description |
---|---|
Dict[str, Any]
|
Parsed dictionary. |
Source code in src/p2p_copy/protocol.py
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
|
file_begin
file_begin(path, size, compression='none', append_from=0)
Create a file begin control message.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
path
|
str
|
Relative path. |
required |
size
|
int
|
Total file size. |
required |
compression
|
str
|
Compression type. Default is 'none'. |
'none'
|
append_from
|
int
|
Byte offset to append from. Default is 0. |
0
|
Returns:
Type | Description |
---|---|
str
|
JSON string of the message. |
Source code in src/p2p_copy/protocol.py
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 |
|
encrypted_file_begin
encrypted_file_begin(hidden_file_info)
Wrap encrypted file info in a control message.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
hidden_file_info
|
bytes
|
Encrypted file begin data. |
required |
Returns:
Type | Description |
---|---|
str
|
JSON string of the enc_file message. |
Source code in src/p2p_copy/protocol.py
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 |
|
pack_chunk
pack_chunk(seq, chain, payload)
Pack a chunk into a binary frame.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
seq
|
int
|
Sequence number. |
required |
chain
|
bytes
|
32-byte chain checksum. |
required |
payload
|
bytes
|
The data payload. |
required |
Returns:
Type | Description |
---|---|
bytes
|
Packed frame. |
Source code in src/p2p_copy/protocol.py
271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 |
|
unpack_chunk
unpack_chunk(frame)
Unpack a binary chunk frame.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
frame
|
bytes
|
The binary frame. |
required |
Returns:
Type | Description |
---|---|
Tuple[int, bytes, bytes]
|
(seq, chain, payload) |
Raises:
Type | Description |
---|---|
ValueError
|
If frame is too short. |
Source code in src/p2p_copy/protocol.py
292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 |
|
p2p_copy.io_utils
read_in_chunks
async
read_in_chunks(fp, *, chunk_size=CHUNK_SIZE)
Asynchronously read bytes from a file in chunks.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
fp
|
BinaryIO
|
The file pointer to read from. |
required |
chunk_size
|
int
|
Size of each chunk in bytes. Default is 1 MiB. |
CHUNK_SIZE
|
Yields:
Type | Description |
---|---|
bytes
|
The next chunk of data. |
Source code in src/p2p_copy/io_utils.py
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
|
compute_chain_up_to
async
compute_chain_up_to(path, limit=None)
Compute chained checksum over the raw bytes of a file up to a limit.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
path
|
Path
|
Path to the file. |
required |
limit
|
int
|
Maximum bytes to hash. If None, hash the entire file. |
None
|
Returns:
Type | Description |
---|---|
tuple[int, bytes]
|
(bytes_hashed, final_chain_bytes) |
Source code in src/p2p_copy/io_utils.py
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
|
iter_manifest_entries
iter_manifest_entries(paths)
Yield manifest entries for files in the given paths (files or directories).
Parameters:
Name | Type | Description | Default |
---|---|---|---|
paths
|
List[str]
|
List of file or directory paths. |
required |
Yields:
Type | Description |
---|---|
Tuple[Path, Path, int]
|
(absolute_path, relative_path, size) |
Notes
- Yields files in sorted order for directories.
- Skips non-existent or invalid paths.
Source code in src/p2p_copy/io_utils.py
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
|
ensure_dir
ensure_dir(p)
Ensure the directory exists, creating parents if needed.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
p
|
Path
|
The path to ensure is a directory. |
required |
Source code in src/p2p_copy/io_utils.py
121 122 123 124 125 126 127 128 129 130 |
|
For api usage examples, see APIExamples. For feature details, see Features.