feat(cli): add private NanoShare sync client
Build and Push Docker Container / build-and-push (push) Successful in 1m3s
Build and Push Docker Container / build-and-push (push) Successful in 1m3s
- Add a separate installable NanoShare CLI package under cli/. - Implement browser login with local callback and refresh-token config. - Add upload, list, download, sync, and watch CLI commands. - Add private owner-only file download endpoint for CLI downloads. - Add CLI auth endpoints for browser login and token refresh. - Return file_id from ServiceLink uploads for reliable sync state. - Exclude the CLI package from NanoShare container builds. - Include tests for private downloads and sync state updates.
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import time
|
||||
import uuid
|
||||
|
||||
PROTOCOL_VERSION = 1
|
||||
JSON_CT = 'application/json'
|
||||
|
||||
def request_envelope(method: str, params: dict | None = None, *, source: str, target: str) -> dict:
|
||||
return {
|
||||
'sl': PROTOCOL_VERSION,
|
||||
'id': uuid.uuid4().hex,
|
||||
'kind': 'request',
|
||||
'method': method,
|
||||
'source': source,
|
||||
'target': target,
|
||||
'params': dict(params or {}),
|
||||
'meta': {'ts': time.time()},
|
||||
}
|
||||
|
||||
def unwrap_response(data: dict):
|
||||
if data.get('kind') == 'response':
|
||||
if data.get('ok') is True:
|
||||
return data.get('result')
|
||||
error = data.get('error') if isinstance(data.get('error'), dict) else {}
|
||||
code = error.get('code', 'remote_error')
|
||||
message = error.get('message', 'remote error')
|
||||
raise RuntimeError(f'{code}: {message}')
|
||||
if data.get('ok') is False and data.get('error'):
|
||||
raise RuntimeError(str(data.get('error')))
|
||||
return data
|
||||
Reference in New Issue
Block a user