From e433bc28c892da8178e5da4d9fbcb9a7ee43f36b Mon Sep 17 00:00:00 2001 From: "russell@unturf.com" Date: Thu, 15 Jan 2026 15:37:23 -0500 Subject: [PATCH] Add snapshot endpoints to Python and JavaScript SDKs - session_snapshot(session_id): Create snapshot of session state - service_snapshot(service_id): Create snapshot of service state - list_snapshots(): List all available snapshots - restore_snapshot(snapshot_id): Restore from snapshot - delete_snapshot(snapshot_id): Delete a snapshot All snapshot functions added to: - Module-level exports (Python __all__, JS module.exports) - Client class methods (for ease of use with stored credentials) - Full JSDoc/docstring documentation Agents should now include snapshot functions in all SDK refactoring work. --- un.js | 113 +++++++++++++++++++++++++++++++++++++++++++++ un.py | 146 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 258 insertions(+), 1 deletion(-) diff --git a/un.js b/un.js index 69d4e0e..884c8a3 100644 --- a/un.js +++ b/un.js @@ -753,6 +753,92 @@ function detectLanguage(filename) { return null; } +// ============================================================================ +// Snapshots (Save/Restore Session & Service State) +// ============================================================================ + +/** + * Create a snapshot of a session's current state. + * + * @param {string} sessionId - ID of the session to snapshot + * @param {Object} options - Optional parameters + * @returns {Promise} Result with snapshot_id, created_at, status + */ +async function sessionSnapshot(sessionId, options = {}) { + const { publicKey = null, secretKey = null } = options; + return apiRequest(`/sessions/${sessionId}/snapshot`, { + method: "POST", + data: {}, + publicKey, + secretKey, + }); +} + +/** + * Create a snapshot of a service's current state. + * + * @param {string} serviceId - ID of the service to snapshot + * @param {Object} options - Optional parameters + * @returns {Promise} Result with snapshot_id, created_at, status + */ +async function serviceSnapshot(serviceId, options = {}) { + const { publicKey = null, secretKey = null } = options; + return apiRequest(`/services/${serviceId}/snapshot`, { + method: "POST", + data: {}, + publicKey, + secretKey, + }); +} + +/** + * List all available snapshots. + * + * @param {Object} options - Optional parameters + * @returns {Promise} Result with snapshots array, count + */ +async function listSnapshots(options = {}) { + const { publicKey = null, secretKey = null } = options; + return apiRequest("/snapshots", { + method: "GET", + publicKey, + secretKey, + }); +} + +/** + * Restore a session or service from a snapshot. + * + * @param {string} snapshotId - ID of the snapshot to restore + * @param {Object} options - Optional parameters + * @returns {Promise} Result with restored_id, status + */ +async function restoreSnapshot(snapshotId, options = {}) { + const { publicKey = null, secretKey = null } = options; + return apiRequest(`/snapshots/${snapshotId}/restore`, { + method: "POST", + data: {}, + publicKey, + secretKey, + }); +} + +/** + * Delete a snapshot. + * + * @param {string} snapshotId - ID of the snapshot to delete + * @param {Object} options - Optional parameters + * @returns {Promise} Result with status + */ +async function deleteSnapshot(snapshotId, options = {}) { + const { publicKey = null, secretKey = null } = options; + return apiRequest(`/snapshots/${snapshotId}`, { + method: "DELETE", + publicKey, + secretKey, + }); +} + // ============================================================================ // Client Class // ============================================================================ @@ -847,6 +933,26 @@ class Client { async languages(options = {}) { return languages({ ...options, publicKey: this.publicKey, secretKey: this.secretKey }); } + + async sessionSnapshot(sessionId) { + return sessionSnapshot(sessionId, { publicKey: this.publicKey, secretKey: this.secretKey }); + } + + async serviceSnapshot(serviceId) { + return serviceSnapshot(serviceId, { publicKey: this.publicKey, secretKey: this.secretKey }); + } + + async listSnapshots() { + return listSnapshots({ publicKey: this.publicKey, secretKey: this.secretKey }); + } + + async restoreSnapshot(snapshotId) { + return restoreSnapshot(snapshotId, { publicKey: this.publicKey, secretKey: this.secretKey }); + } + + async deleteSnapshot(snapshotId) { + return deleteSnapshot(snapshotId, { publicKey: this.publicKey, secretKey: this.secretKey }); + } } // ============================================================================ @@ -1048,6 +1154,13 @@ module.exports = { // Image generation image, + // Snapshots + sessionSnapshot, + serviceSnapshot, + listSnapshots, + restoreSnapshot, + deleteSnapshot, + // Utilities languages, detectLanguage, diff --git a/un.py b/un.py index 5194087..8b7b786 100644 --- a/un.py +++ b/un.py @@ -91,7 +91,9 @@ __version__ = "2.0.0" __all__ = [ "execute", "execute_async", "run", "run_async", "get_job", "wait", "cancel_job", "list_jobs", - "image", "languages", "Client", + "image", "languages", + "session_snapshot", "service_snapshot", "list_snapshots", "restore_snapshot", "delete_snapshot", + "Client", ] # ============================================================================ @@ -717,6 +719,128 @@ def image( ) +# ============================================================================ +# Snapshots (Save/Restore Session & Service State) +# ============================================================================ + +def session_snapshot( + session_id: str, + *, + public_key: str = None, + secret_key: str = None, +) -> Dict[str, Any]: + """ + Create a snapshot of a session's current state. + + Args: + session_id: ID of the session to snapshot + + Returns: + dict with snapshot_id, created_at, status + + Example: + >>> snap = un.session_snapshot("sess-abc123") + >>> print(snap["snapshot_id"]) + """ + return _api_request( + f"/sessions/{session_id}/snapshot", + method="POST", + data={}, + public_key=public_key, + secret_key=secret_key, + ) + + +def service_snapshot( + service_id: str, + *, + public_key: str = None, + secret_key: str = None, +) -> Dict[str, Any]: + """ + Create a snapshot of a service's current state. + + Args: + service_id: ID of the service to snapshot + + Returns: + dict with snapshot_id, created_at, status + """ + return _api_request( + f"/services/{service_id}/snapshot", + method="POST", + data={}, + public_key=public_key, + secret_key=secret_key, + ) + + +def list_snapshots( + *, + public_key: str = None, + secret_key: str = None, +) -> Dict[str, Any]: + """ + List all available snapshots. + + Returns: + dict with snapshots (list), count + """ + return _api_request( + "/snapshots", + method="GET", + public_key=public_key, + secret_key=secret_key, + ) + + +def restore_snapshot( + snapshot_id: str, + *, + public_key: str = None, + secret_key: str = None, +) -> Dict[str, Any]: + """ + Restore a session or service from a snapshot. + + Args: + snapshot_id: ID of the snapshot to restore + + Returns: + dict with restored_id (session or service ID), status + """ + return _api_request( + f"/snapshots/{snapshot_id}/restore", + method="POST", + data={}, + public_key=public_key, + secret_key=secret_key, + ) + + +def delete_snapshot( + snapshot_id: str, + *, + public_key: str = None, + secret_key: str = None, +) -> Dict[str, Any]: + """ + Delete a snapshot. + + Args: + snapshot_id: ID of the snapshot to delete + + Returns: + dict with status + """ + return _api_request( + f"/snapshots/{snapshot_id}", + method="DELETE", + public_key=public_key, + secret_key=secret_key, + ) + + # ============================================================================ # Utility Functions # ============================================================================ @@ -891,6 +1015,26 @@ class Client: """Get supported languages (cached for 1 hour).""" return languages(public_key=self.public_key, secret_key=self.secret_key, force_refresh=force_refresh) + def session_snapshot(self, session_id: str) -> Dict[str, Any]: + """Create snapshot of session. See module-level session_snapshot() for details.""" + return session_snapshot(session_id, public_key=self.public_key, secret_key=self.secret_key) + + def service_snapshot(self, service_id: str) -> Dict[str, Any]: + """Create snapshot of service. See module-level service_snapshot() for details.""" + return service_snapshot(service_id, public_key=self.public_key, secret_key=self.secret_key) + + def list_snapshots(self) -> Dict[str, Any]: + """List all snapshots. See module-level list_snapshots() for details.""" + return list_snapshots(public_key=self.public_key, secret_key=self.secret_key) + + def restore_snapshot(self, snapshot_id: str) -> Dict[str, Any]: + """Restore from snapshot. See module-level restore_snapshot() for details.""" + return restore_snapshot(snapshot_id, public_key=self.public_key, secret_key=self.secret_key) + + def delete_snapshot(self, snapshot_id: str) -> Dict[str, Any]: + """Delete snapshot. See module-level delete_snapshot() for details.""" + return delete_snapshot(snapshot_id, public_key=self.public_key, secret_key=self.secret_key) + # ============================================================================ # CLI Interface