Storage and networking
Save plugin data and make permission-scoped HTTP requests.
Developer preview · macOS · Python SDK 1.1Persistent JSON storage
from browse import command, storage
@command("Remember a reading goal", id="reading-goal")
async def remember():
await storage.set("goal", {"pages": 5})
goal = await storage.get("goal", {"pages": 1})
return f"Today's goal: {goal['pages']} pages"| Call | Effect |
|---|---|
| await storage.get(key, default=None) | Read a JSON value or the default. |
| await storage.set(key, value) | Save a JSON-compatible value. |
| await storage.delete(key) | Delete a key. |
| await storage.keys() / storage.clear() | List keys or clear this extension’s storage. |
Each extension has a 5 MiB storage quota. This is plugin data, separate from website cookies and storage. Keep values small; storage is not a file API or an encrypted credential vault.
Make an HTTP request
from browse import command, net
@command("Check service status", id="service-status")
async def check_status():
response = await net.fetch("https://api.example.com/status", timeout=10)
response.raise_for_status()
return f"Service returned HTTP {response.status}"net.fetch(url, method=None, headers=None, body=None, json=None, timeout=30) returns a Response. It defaults to POST for a non-empty body and GET otherwise; use method explicitly when the endpoint needs a particular verb. json serialises a JSON body and sets Content-Type when you have not supplied it.
| Response member | Meaning |
|---|---|
| status / ok / url | HTTP status, whether it is 2xx, and the response URL. |
| headers / content / text | Lowercase header names, raw bytes and decoded text. |
| json() | Parse the response body as JSON. |
| raise_for_status() | Raise BrowseError for a non-2xx response. |
Handle errors
from browse import BrowseError, PermissionDenied, command, net
@command("Check connection", id="connection")
async def check_connection():
try:
response = await net.fetch("https://api.example.com/status", timeout=10)
response.raise_for_status()
return "Connected"
except PermissionDenied:
return "This plugin needs access to api.example.com."
except BrowseError as error:
print(error)
return "The request could not be completed."PermissionDenied is a BrowseError subclass, so catch it first when you want a distinct message. Other Python errors, such as invalid JSON, should be handled separately when relevant. print output and tracebacks appear in the extension log.