private, distributed state made effortless
pip install syft-widget
import syft_widget as sw
class LiveClock(sw.DynamicWidget):
def get_endpoints(self):
@self.endpoint("/api/time")
def get_time():
import time
now = time.strftime("%H:%M:%S")
return {"time": now}
def get_template(self):
return '''
Time:<span data-field="time">{time}</span>
'''
clock = LiveClock("Live Clock", height="50px")
clock
working with private, distributed state shouldn't be hard
Decentralized systems need maximum interoperability - zillions of computers must collaborate without centralizing data. Because of Unix, files are the universal language that lets everyone work together.
Jupyter struggles to show live file state due to Python / JavaScript isolation. Traditional widgets can't efficiently watch files or handle real-time updates.
We spawn local servers that watch files directly, serve live updates via HTTP, and render in protected iframes - making file-backed UIs effortless.
with file-backed widgets — private, distributed state can be effortless
file-backed widgets for distributed systems
# 🚀 Instant Load + Live Updates:
#
# t=0ms: Python renders template with checkpoint data
# ┌─────────────────┐ ┌──────────────────┐
# │ Widget.__init__ │────────►│ {time} → "14:30" │ (instant!)
# └─────────────────┘ └──────────────────┘
# │ │
# ▼ ▼
# t=50ms: Spawn server ┌──────────────────┐
# ┌─────────────────┐ │ iframe renders │
# │ FastAPI server │ │ HTML + CSS │
# │ watches files │ └──────────────────┘
# └─────────────────┘ │
# │ ▼
# ▼ ┌──────────────────┐
# t=100ms: Server ready │ JS finds server │
# ┌─────────────────┐ │ via port scan │
# │ /api/time → │◄────────┤ (8000-8010) │
# │ {"time":"14:31"}│ └──────────────────┘
# └─────────────────┘ │
# ▲ ▼
# │ ┌──────────────────┐
# Files change │ Live updates via │
# FSEvents/inotify │ data-field="time"│
# │ └──────────────────┘
# │ ▲
# └───────────────────────────┘
# The magic: Users see content instantly, servers persist across reloads
widget = YourWidget() # Instant display, then live updates
resilient widgets for the private data internet
import syft_widget as sw
class MyWidget(sw.DynamicWidget):
def get_endpoints(self):
@self.endpoint("/api/data")
def get_data():
return {"value": read_file()}
def get_template(self):
return '''<div data-field="value">{value}</div>'''
# Create with options
widget = MyWidget(
server_name="my_server", # Optional name
height="200px", # Widget height
update_interval=1000, # Refresh rate (ms)
expiration_seconds=3600 # Auto-cleanup
)
import syft_serve as ss
# List all servers
ss.servers
# Access specific server
server = ss.servers['my_server']
# Server properties
server.status # "running"
server.url # http://localhost:8001
server.uptime # "2h 15m"
server.endpoints # ["/api/data"]
# Control servers
server.terminate()
ss.servers.terminate_all()
# Via widget's server property
widget.server.stdout.tail(20)
widget.server.stderr.tail(20)
# Stream logs in real-time
widget.server.stdout.follow()
# Access underlying server
widget.server # syft-serve server object
# Widget with dependencies
widget = MyWidget(
dependencies=['pandas', 'numpy'],
force_new_server=True
)
# Widget properties
widget.server_name # Server identifier
widget.update_interval # Refresh rate
widget.server # Access underlying server
# Force restart if needed
widget._restart_server()
widget._stop_server()