{"id":49546320,"url":"https://github.com/viperadnan-git/transferit-py","last_synced_at":"2026-05-02T19:39:12.502Z","repository":{"id":352528225,"uuid":"1215494430","full_name":"viperadnan-git/transferit-py","owner":"viperadnan-git","description":"Pure-Python client for transfer.it — upload and download files via the MEGA backend, no browser required.","archived":false,"fork":false,"pushed_at":"2026-04-22T03:34:31.000Z","size":93,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-02T19:39:07.556Z","etag":null,"topics":["cli","download","end-to-end-encryption","file-sharing","file-transfer","file-upload","httpx","mega","python","python-library","reverse-engineering","transfer-it","transferit","upload","websockets"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/transferit-py/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/viperadnan-git.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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-20T01:12:46.000Z","updated_at":"2026-04-29T15:20:06.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/viperadnan-git/transferit-py","commit_stats":null,"previous_names":["viperadnan-git/transferit-py"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/viperadnan-git/transferit-py","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/viperadnan-git%2Ftransferit-py","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/viperadnan-git%2Ftransferit-py/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/viperadnan-git%2Ftransferit-py/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/viperadnan-git%2Ftransferit-py/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/viperadnan-git","download_url":"https://codeload.github.com/viperadnan-git/transferit-py/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/viperadnan-git%2Ftransferit-py/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32547651,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-02T19:18:06.202Z","status":"ssl_error","status_checked_at":"2026-05-02T19:16:21.335Z","response_time":132,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: 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":["cli","download","end-to-end-encryption","file-sharing","file-transfer","file-upload","httpx","mega","python","python-library","reverse-engineering","transfer-it","transferit","upload","websockets"],"created_at":"2026-05-02T19:39:11.862Z","updated_at":"2026-05-02T19:39:12.497Z","avatar_url":"https://github.com/viperadnan-git.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003etransferit\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cem\u003eUpload and download files on \u003ca href=\"https://transfer.it\"\u003etransfer.it\u003c/a\u003e from Python or your terminal — no browser, no MEGA account, no external CLI tools.\u003c/em\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://pypi.org/project/transferit-py/\"\u003e\u003cimg src=\"https://img.shields.io/pypi/v/transferit-py.svg?color=007aff\" alt=\"PyPI\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://pypi.org/project/transferit-py/\"\u003e\u003cimg src=\"https://img.shields.io/pypi/pyversions/transferit-py.svg?color=007aff\" alt=\"Python\" /\u003e\u003c/a\u003e\n  \u003ca href=\"LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/license-MIT-007aff.svg\" alt=\"License\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n```python\nfrom transferit import Transferit\n\nwith Transferit() as tx:\n    url = tx.upload(\"report.pdf\").url     # → https://transfer.it/t/…\n```\n\n- **End-to-end encrypted** — AES-128-CTR + CBC-MAC, identical scheme to the official web client.\n- **Concurrent WebSocket uploads** — up to 8 connections per file, matching MEGA's `ulDefConcurrency`.\n- **Streaming download + decrypt** via `httpx.stream` — constant memory regardless of file size.\n- **Folders** — uploaded recursively, hierarchy preserved both ways.\n- **Every form field wired up** — title, message, password, sender, expiry, notify-on-expiry, max-downloads, recipients, scheduled delivery.\n- **Rich CLI \u0026 library API** — the same four verbs (`upload` / `download` / `info` / `metadata`) in either surface, with `--json` everywhere for scripting.\n\n## Install\n\n**As a CLI** — global `transferit` command on your PATH:\n\n```bash\nuv tool install \"transferit-py[cli]\"      # recommended\npipx install \"transferit-py[cli]\"         # alternative\n```\n\n**As a library** — inside a project:\n\n```bash\nuv add transferit-py                      # library only\nuv add \"transferit-py[cli]\"               # library + CLI entry point\npip install transferit-py                 # or pip, same story\npip install \"transferit-py[cli]\"\n```\n\nRequires **Python 3.11+**.\n\n## CLI\n\n| Command | Purpose |\n|---|---|\n| `transferit upload PATH` | Upload a file or folder; print the share link |\n| `transferit download LINK` | Mirror a transfer into a local directory |\n| `transferit info LINK` | Metadata panel + file/folder tree |\n| `transferit metadata LINK` | Metadata panel only |\n\nEvery command supports `--json` for machine-readable output. `LINK` can be either a full share URL or the bare 12-character handle.\n\n```bash\n# simplest — one file, no options\ntransferit upload report.pdf\n\n# folder upload, 7-day expiry\ntransferit upload ./project -e 7d --sender me@example.com\n\n# full \"Send files\" mode\ntransferit upload big.mp4 \\\n    --title \"Q1 demo\"      --message \"review please\" \\\n    --password hunter2     --sender me@example.com  \\\n    --expiry 7d            --notify-expiry          \\\n    --max-downloads 50                              \\\n    -r alice@example.com -r bob@example.com         \\\n    --schedule 2026-04-25T09:00\n```\n\n`--expiry` accepts any duration from `1s` to `10y`: `30s`, `5m`, `2h`, `7d`, `1w`, `1y`, or compound forms like `1y6m3d`. Run `transferit \u003ccommand\u003e --help` for the full flag list.\n\n## Library\n\nThe entire surface is a single class — **`Transferit`**. One instance owns an HTTP connection pool and (lazily) an anonymous ephemeral MEGA account that's reused across every write-side call.\n\n```python\nfrom transferit import Transferit\n\nwith Transferit(default_sender=\"me@example.com\", default_expiry=\"7d\") as tx:\n    result = tx.upload(\"./q1.pdf\", title=\"Quarterly report\")\n    # =\u003e UploadResult(xh=…, url=…, title=…, total_bytes=…, file_count=1, folder_count=0)\n\n    meta   = tx.metadata(result.url)       # → TransferInfo\n    nodes  = tx.info(result.url)           # → list[TransferNode]\n    tx.download(result.url, \"./dl\")        # → DownloadResult\n```\n\n| Method | Returns | Needs session? |\n|---|---|---|\n| `tx.upload(path, **opts)` | `UploadResult` | yes (lazily created) |\n| `tx.download(link, dir, **opts)` | `DownloadResult` | no |\n| `tx.info(link, password=…)` | `list[TransferNode]` | no |\n| `tx.metadata(link, password=…)` | `TransferInfo` | no |\n\n**`upload()`** accepts every web-form field as a kwarg — `title`, `message`, `password`, `sender`, `expiry` (int seconds or duration string), `notify_expiry`, `max_downloads`, `recipients`, `schedule`, `concurrency`, and three progress callbacks (`on_progress`, `on_file_start`, `on_file_done`).\n\n### Typed returns\n\n`TransferInfo`, `TransferNode`, `UploadResult`, `DownloadResult` are frozen dataclasses. Every one has a `.to_json_dict()` for serialisation; `TransferNode` also exposes `.is_file` / `.is_folder`. Raw server responses are kept on `.raw` as an escape hatch.\n\n```python\nmeta = tx.metadata(url)\nprint(meta.title, meta.total_bytes, meta.password_protected)\n```\n\n### Progress hooks\n\n```python\ndef on_progress(sent: int, total: int) -\u003e None:\n    print(f\"{sent/total:6.1%}  {sent:\u003e12,} / {total:,} bytes\")\n\ntx.upload(\"./big.mp4\", on_progress=on_progress)\n```\n\n`tx.download` exposes richer callbacks: `on_start`, `on_file_start`, `on_file_progress`, `on_file_done`, `on_skip`.\n\n### Defaults\n\n`Transferit(default_sender=…, default_expiry=…, default_concurrency=…)` — any of these is used when a per-call kwarg is omitted.\n\n### Low-level\n\nAdvanced callers can use `MegaAPI` directly — every MEGA command (`create_ephemeral_session`, `create_transfer`, `fetch_transfer`, `set_transfer_attributes`, …) is a method on it. Inject via `Transferit(api=MegaAPI(...))` for testing or pinning to an alternate endpoint.\n\n## How it works\n\ntransfer.it is a thin white-label on top of MEGA's `bt7` API cluster. Each upload spins up an anonymous ephemeral MEGA account, creates a transfer container, streams AES-128-CTR-encrypted chunks over WebSockets (with CBC-MAC integrity checks), and finalises the node list via a proprietary `x*` command family. Full protocol reference — API verbs, crypto scheme, WebSocket framing, password derivation — lives in [`docs/REVERSE_ENGINEERING.md`](docs/REVERSE_ENGINEERING.md).\n\n## License\n\nMIT — see [`LICENSE`](LICENSE).\n\n## Disclaimer\n\n**transferit is an independent, community-maintained project.** It is not\naffiliated with, endorsed by, sponsored by, or otherwise connected to\nMEGA Limited, transfer.it, or any of their subsidiaries. All product\nnames, logos, and brands are property of their respective owners.\n\nThis project interoperates with transfer.it by re-implementing the\npublicly-served, client-side JavaScript that the official web client\nships to every visitor — no proprietary SDK, no private endpoint, no\ncircumvention of any access control. The protocol write-up in\n[`docs/REVERSE_ENGINEERING.md`](docs/REVERSE_ENGINEERING.md) is provided\npurely for educational and interoperability purposes.\n\n**Before using transferit**, make sure your usage complies with:\n\n- [transfer.it's terms of service](https://transfer.it/terms)\n- [MEGA's terms of service](https://mega.io/terms)\n- Any export-control, data-protection, or local laws that apply to you\n\nYou are solely responsible for the content you upload and the transfers\nyou access through this library. The maintainers accept no liability for\nmisuse, data loss, service disruption, account termination, or any other\nconsequence arising from use of this software. The software is provided\n\"as is\", without warranty of any kind — see [`LICENSE`](LICENSE) for the\nfull legal text.\n\nIf you are a rights-holder and believe this project infringes on your\nrights, please open an issue on the project's repository before taking\nany other action — most concerns can be resolved directly.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fviperadnan-git%2Ftransferit-py","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fviperadnan-git%2Ftransferit-py","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fviperadnan-git%2Ftransferit-py/lists"}