PySyft: Running Data Science Jobs on Data You Never Receive
Perform data science on data that remains in someone else's server
At a glance
- What is it?
- PySyft v2 splits into a sync engine (syft) and a remote data science client (syft-rds) that move datasets, job requests and approved outputs over Google Drive. It fits organizations that already share files and refuse to stand up new servers, and it fails badly for anyone who needs a live, low-latency query loop.
- Who is it for?
- Adopt PySyft if a data owner must approve each collaborator by hand, the data cannot leave their machine, and both sides already share a Google Drive folder. Do not adopt it if you need sub-minute turnaround on many small queries, or if your organization blocks Google Drive or has no OAuth path for the data owner.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The Problem PySyft v2 Targets, and the Organizations It Fits
The README states the premise directly: PySyft lets data scientists submit computations which are run by data owners on private data, through cloud storage their organizations already use. The data owner keeps the file. The data scientist keeps a mock. What crosses the boundary is a script, an approval, and an output file the owner chose to share.
That framing tells you who this is for. It is for a hospital, a bank, or an internal team that has data it cannot hand over, plus an external researcher who needs aggregate answers rather than rows. The README's own examples point the same way: an LLM user logs analysis where only approved results come back, and a double blind evaluation where a researcher tests a private model against a private benchmark inside an enclave. Both cases involve two parties with conflicting disclosure interests and no shared cluster.
It is not for a single team querying its own warehouse. If one party owns the data and the compute, the peer request, approve, sync cycle is pure overhead. The design assumes a trust boundary that has to be crossed on paper before it is crossed in code.
How the Sync Engine and the RDS Client Split the Work
The most important structural fact in the README is the package split. syft 0.10+ is described as the successor of syft-client, and the README separates the roles: syft is the sync engine, imported as import syft as sy, while datasets and jobs live in syft-rds, imported as from syft_rds import login_do, login_ds. The README warns that code depending on the legacy PySyft 0.9 API must pin syft<0.10. That is a hard fork in the dependency graph, not a deprecation shim.
Underneath sit narrower packages with named responsibilities: syft-datasets for dataset management and sharing, syft-job for job submission and execution, syft-permissions and syft-perms for the permission system on Syft datasites, syft-enclave for enclave execution, and syft-bg for background services. The data flow visible in the quick start is a file exchange. The data owner creates a dataset with a mock_path and a private_path, syncs, and the data scientist calls ds.datasets.get_all() after their own sync. The data scientist submits a code file. The owner approves, runs, and can pass share_outputs_with_submitter=True. The submitter then reads ds.jobs[-1].output_paths[0].
Two mechanisms are worth calling out. The README says jobs run in sandboxed Python virtual environments with controlled access to private data, which is what makes running someone else's script on your machine a defensible decision at all. And sy.resolve_dataset_file_path is the indirection that makes the mock/private split work: the same analysis.py reads a path that resolves to mock data on the scientist's machine and to the private file inside the job. The documentation states the transport is Google Drive today and extensible to any file-based transport, so the sync layer is deliberately not tied to one provider.
Getting a First Job Through: Commands, Config Keys and the Approval Gate
Installation differs by role, and the difference matters. The data scientist runs uv pip install "syft>=0.10.0" "syft-rds>=0.6.0". The data owner adds the background services: uv pip install "syft>=0.10.0" "syft-rds>=0.6.0" "syft-bg>=0.3.12". Those background services are what drive email notifications, auto-approval, and a TUI dashboard, so an owner who skips syft-bg is doing every approval by hand in a notebook.
Login is where the environment bites. The README gives do = login_do(email="do@org.com") and ds = login_ds(email="ds@org.com"), noting that the colab auth flow is the default and that non-colab users must pass token_path. The linked authentication doc covers Google Cloud OAuth setup for local and Jupyter usage, which means the data owner needs a Google Cloud project and OAuth credentials before a single byte moves. That is the real installation cost, and it is not a pip command.
From there the sequence is explicit. The scientist calls ds.add_peer("do@org.com"); the owner calls do.approve_peer_request("ds@org.com"). The owner creates the dataset with name, mock_path, private_path and a users list, then do.sync() and ds.sync(). The scientist submits with ds.submit_python_job(user="do@org.com", code_path="analysis.py"). The owner runs do.jobs[0].approve() and do.process_approved_jobs(share_outputs_with_submitter=True). Every step is a manual gate by design, and the README's own comment notes that in practice these blocks would be distributed, with each party executing on their own machine.
The Offline-First Trade-off: Latency in Exchange for No Shared Infrastructure
The README lists offline-first as a feature: full functionality even when peers are offline, with changes syncing when connectivity resumes. Read that as a design constraint rather than a bonus. Because the transport is file-based, every interaction is a sync plus a poll. There is no server holding a session, no streaming channel, and no push notification into the scientist's process.
The quick start shows the consequence. After submitting, the scientist calls ds.sync(), then the owner calls do.sync(), approves, processes, and syncs again, and only then can the scientist sync and read output_paths. Four sync calls for one job, and the README's own example still reaches for ds.jobs[-1] rather than a job handle returned from submission. For a handful of jobs a day this is fine. For an iterative analysis where a scientist wants to adjust a parameter and rerun twenty times, the round trip dominates the work.
The mock dataset is the intended mitigation, and it is a reasonable one: iterate locally against mock_path, submit once when the logic is settled. But mock and private data diverge, and the README does not describe any schema check that would catch a mock that no longer resembles the real file. If your mock drifts, you find out from a failed job after a full approval cycle.
Where PySyft v2 Is the Wrong Tool
The clearest failure mode is scale of interaction. PySyft v2 is built for a small number of reviewed jobs between two parties. It has no story in the README for dozens of concurrent submitters, and the approval model is explicitly per-collaborator: the README says data owners must approve each collaborator before any data flows. An organization onboarding fifty researchers should count fifty approval conversations, and the permission packages exist precisely because that bookkeeping is real work.
The second constraint is the transport. Google Drive is the only transport named in the README, with other file-based transports described as possible rather than shipped. Any organization that blocks Google Drive, or whose data owner cannot complete a Google Cloud OAuth setup, has no path here without writing a transport layer that the README does not document in detail. Contrast that with the enclave tutorial, which depends on an enclave rather than the Drive flow. The two are separate deployment shapes, not interchangeable settings.
The third is version churn. The README warns that syft 0.10+ is the successor of syft-client and that legacy code must pin syft<0.10. The recent releases listed are all 0.9.6 betas from 2025, which sit on the far side of that break from the 0.10+ line the README documents. Anyone reading release history to decide what to install will land on the wrong side of the split unless they read the README first.
Federated Learning Frameworks Solve a Different Half of the Problem
The obvious comparison is a federated learning framework such as Flower or NVIDIA FLARE. The difference is not quality, it is where the trust boundary sits and what crosses it.
A federated learning framework assumes the model travels and the data stays, with clients training locally and gradients or weights returning to a server that aggregates them. The data owner is a participant in a training loop, and the framework's job is to make that loop efficient and fault-tolerant. PySyft v2 does not do this. Its unit of exchange is an arbitrary Python script, and its unit of return is an output file the owner explicitly approved. The data owner is an approver, not a training client.
That makes PySyft closer in spirit to a submission portal than to a federated runtime, and it explains why the offline-first design is tolerable: nothing here needs a live gradient exchange. It also means a team that actually wants federated training should not reach for PySyft v2, and a team that wants to review arbitrary analyses before releasing results will find federated learning frameworks do not model approval at all. The two overlap only in the phrase privacy-preserving.
Licence, Maintenance Surface and What to Pin
PySyft is Apache-2.0, per the README badge and the repository metadata. Apache-2.0 is permissive and includes an explicit patent grant, which is usually what an enterprise legal review wants to see. It is not a copyleft licence, so modifications you make to the sync engine or a new transport do not have to be published. This is a description of the licence text, not legal advice; your counsel should confirm how it interacts with your own distribution model.
The maintenance cost is spread across packages, and that is the practical burden. A deployment touches syft, syft-rds, and for the owner syft-bg, each versioned independently, plus the Google Cloud OAuth credentials that have their own rotation and consent-screen lifecycle. Upgrading is not a single bump: the README's own compatibility note shows the project has already executed one API break between the 0.9 line and 0.10+, and the package table lists seven components with separate version numbers. Pin all of them, and treat the syft<0.10 boundary as a migration project rather than a patch.
The repository is not archived and the default branch is dev, so the documented workflow tracks a development branch. Read docs/workflow.md and docs/API.md from the same commit you install from, because the README's quick start and the API reference are the two places where a version mismatch will surface first.
Editorial conclusion
Adopt PySyft if a data owner must approve each collaborator by hand, the data cannot leave their machine, and both sides already share a Google Drive folder. Do not adopt it if you need sub-minute turnaround on many small queries, or if your organization blocks Google Drive or has no OAuth path for the data owner. Before committing, verify three things in a throwaway project: that login_do and login_ds complete against your tenant, that a job submitted with ds.submit_python_job actually resolves resolve_dataset_file_path to the private file rather than the mock, and that your dependency pins match the README warning that syft<0.10 is a different API.
Community notes