{"id":28458733,"url":"https://github.com/openmined/fastsyftbox","last_synced_at":"2026-03-08T00:32:28.375Z","repository":{"id":292964667,"uuid":"982500355","full_name":"OpenMined/fastsyftbox","owner":"OpenMined","description":"FastAPI + Syftbox Events","archived":false,"fork":false,"pushed_at":"2025-09-18T07:07:40.000Z","size":674,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-11-23T20:02:53.204Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/OpenMined.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"openmined"}},"created_at":"2025-05-13T01:36:22.000Z","updated_at":"2025-09-18T07:07:44.000Z","dependencies_parsed_at":"2025-05-13T03:23:59.168Z","dependency_job_id":"746ef919-c263-496d-9c68-a7250a7bb1bd","html_url":"https://github.com/OpenMined/fastsyftbox","commit_stats":null,"previous_names":["openmined/fastsyftbox"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/OpenMined/fastsyftbox","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenMined%2Ffastsyftbox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenMined%2Ffastsyftbox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenMined%2Ffastsyftbox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenMined%2Ffastsyftbox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/OpenMined","download_url":"https://codeload.github.com/OpenMined/fastsyftbox/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenMined%2Ffastsyftbox/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30238879,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-08T00:30:53.000Z","status":"ssl_error","status_checked_at":"2026-03-08T00:30:44.061Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-06-07T00:39:39.418Z","updated_at":"2026-03-08T00:32:28.356Z","avatar_url":"https://github.com/OpenMined.png","language":"Python","funding_links":["https://github.com/sponsors/openmined"],"categories":[],"sub_categories":[],"readme":"\u003ch1 style=\"border: none; margin-bottom: 0;\"\u003efastsyftbox\u003c/h1\u003e\n\u003ca href=\"https://syftbox.net/\" target=\"_blank\"\u003e\n  \u003cpicture\u003e\n    \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"img/mwsyftbox_white_on.png\"\u003e\n    \u003cimg alt=\"Logo\" src=\"img/mwsyftbox_black_on.png\" width=\"200px\" align=\"right\" /\u003e\n  \u003c/picture\u003e\n\u003c/a\u003e\n\n[![PyPI - Version](https://img.shields.io/pypi/v/fastsyftbox)](https://pypi.org/project/fastsyftbox/)\n[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/fastsyftbox)](https://pypi.org/project/fastsyftbox/)\n[![PyPI - Downloads](https://img.shields.io/pypi/dm/fastsyftbox)](https://pypi.org/project/fastsyftbox/)\n[![Tests](https://github.com/OpenMined/fastsyftbox/actions/workflows/pr-tests.yml/badge.svg)](https://github.com/OpenMined/fastsyftbox/actions/workflows/pr-tests.yml)\n[![License](https://img.shields.io/github/license/OpenMined/fastsyftbox)](https://github.com/OpenMined/fastsyftbox/blob/main/LICENSE)\n[![MadeWith](https://img.shields.io/badge/MadeWith-SyftBox-blue)](https://syftbox.net/)\n\n\u003cbr /\u003e\n\n## Build offline-first Python apps with FastAPI and SyftBox — FAST.\n\n## 🚀 Features\n\n- Build **local admin UIs** with [FastAPI](https://fastapi.tiangolo.com/).\n- Build **delay-tolerant UIs/APIs** using SyftEvents.\n- Keep private data offline with **SyftBox HTTP over RPC**.\n- Builtin JS SDK with `fetch` compatible syntax\n- Debug APIs with a built-in **Postman-style interface**.\n\n---\n\n## 🔧 Purpose\n\nHow can you build a web app that runs on your **own device**, without uploading data to the cloud?\n\nWith SyftBox, you can:\n- Run a webserver anywhere that can go offline and keep functioning when it comes back online.\n- Access your data **even when offline** or when your laptop lid is closed.\n\n---\n\n## ⚡ Quick Start\n\nInstall with [uv](https://github.com/astral-sh/uv) and create your app:\n```bash\nuvx fastsyftbox version\nuvx fastsyftbox create app test\n```\n\nTo start in hot-reloading more:\n```\ncd test\n./run.sh\n```\n\nThis generates a sample FastAPI app in `app.py`:\n```python\n\n\napp = FastSyftBox(\n    app_name=app_name,\n    syftbox_endpoint_tags=[\n        \"syftbox\"\n    ],  # endpoints with this tag are also available via Syft RPC\n    include_syft_openapi=True,  # Create OpenAPI endpoints for syft-rpc routes\n)\n\n\n# normal fastapi\n@app.get(\"/\", response_class=HTMLResponse)\ndef root():\n    return HTMLResponse(\"\u003chtml\u003e\u003cbody\u003e\u003ch1\u003eWelcome to {app_name}\u003c/h1\u003e\")\n\n\n# build a model with pydantic\nclass MessageModel(BaseModel):\n    message: str\n    name: str | None = None\n\n# make syftbox rpc endpoints easily\n# syft://{datasite}/app_data/{app_name}/rpc/hello\n@app.post(\"/hello\", tags=[\"syftbox\"])\ndef hello_handler(request: MessageModel):\n    print(\"got request\", request)\n    response = MessageModel(message=f\"Hi {request.name}\", name=\"Bob\")\n    return response.model_dump_json()\n\n# Debug your RPC endpoints in the browser\napp.enable_debug_tool(\n    endpoint=\"/hello\",\n    example_request=str(MessageModel(message=\"Hello!\", name=\"Alice\").model_dump_json()),\n    publish=True,\n)\n```\n\n## HTTP / JS\n\nVanilla JS fetch:\n```js\nconst url = \"http://somewebsite.com/api\"\nconst request = await fetch(url, {\n    method: 'POST',\n    headers,\n    body\n});\n```\n\nBecomes syftFetch:\n```js\nconst syftUrl = \"syft://madhava@openmined.org/app_data/fastsyftbox/rpc/hello\"\nconst request = await syftFetch(syftUrl, {\n    method: 'POST',\n    headers,\n    body\n});\n```\n\nUnder the hood:\n- Translates to the correct HTTP request\n- Adds `syft-x` headers\n- Waits for queued response\n- Polls future until completed\n\n\n## What is SyftBox?\n\u003ca href=\"https://syftbox.net/\" target=\"_blank\"\u003e\u003cimg src=\"img/syftbox_icon.png\" style=\"width:200px; max-width: 200px;\" align=\"right\" target=\"_blank\" /\u003e\u003c/a\u003e\nSyftBox is a new platform for building privacy-preserving applications and experiences that work over the internet without uploading your data. Instead of sending your data to a server, SyftBox lets you run powerful AI and analytics locally or in trusted environments, so your personal information stays private and secure.\n\n\u003ca href=\"https://syftbox.net/\" target=\"_blank\"\u003eRead more about SyftBox here\u003c/a\u003e\n\u003cdiv style=\"clear: both;\"\u003e\u003c/div\u003e\n\n## 🧱 Your Dependencies\nAdd any Python dependencies to `requirements.txt` and `run.sh` will install them fresh every run.\n\n\n## 🧪 RPC Debug Tool\n\nIts like Postman but for SyftBox RPC.\n\nA built-in HTML/JS tool helps you debug your HTTP over RPC endpoints.\nTo enable:\n\n```python\napp.enable_debug_tool(\n    endpoint=\"/hello\",\n    example_request=str(MessageModel(message=\"Hello!\", name=\"Alice\").model_dump_json()),\n    publish=True,\n)\n```\n\n### 🧭 Construct syft:// RPC URLs\n![Debug Tool Screenshot](img/debug_1.png)\n\n### 🎯 Configure custom headers\n![Debug Tool Screenshot](img/debug_2.png)\n\n### 🔍 View real-time responses\n![Debug Tool Screenshot](img/debug_3.png)\n\nThen visit either:\nhttp://localhost:${SYFTBOX_ASSIGNED_PORT}/rpc-debug\nor if you have publish=True\nhttps://syftbox.net/datasites/{{ email }}/public/{{ app_name }}/rpc-debug.html\n\n\n## 📥 SyftBox App Install via GitHub\n```bash\nsyftbox app install GITHUB_URL\n```\nThis executes run.sh and binds your app to a random port:\nhttp://localhost:${SYFTBOX_ASSIGNED_PORT}\n\n\n## 📚 Example `fastsyftbox` Apps\n- 🎬 \u003ca href=\"https://github.com/madhavajay/youtube-wrapped\" target=\"_blank\"\u003eYouTube Wrapped\u003c/a\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenmined%2Ffastsyftbox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenmined%2Ffastsyftbox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenmined%2Ffastsyftbox/lists"}