Metadata-Version: 2.5
Name: beamcode
Version: 1.1.3
Summary: Beamcode — encrypted file transfer (share_url, password, download limits). Same product as beamcode.vjyas.online.
Project-URL: Homepage, https://beamcode.vjyas.online
Project-URL: Documentation, https://beamcode.vjyas.online/how
Project-URL: Repository, https://github.com/jyoshnavi/QRFileTransfer
Author: Beamcode
License-Expression: MIT
Keywords: aes-gcm,beamcode,cli,encryption,file-transfer,qr,sdk
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: End Users/Desktop
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Communications :: File Sharing
Classifier: Topic :: Security :: Cryptography
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: click>=8.1
Requires-Dist: cryptography>=42
Requires-Dist: httpx>=0.27
Requires-Dist: pyperclip>=1.8
Requires-Dist: qrcode>=7.4
Requires-Dist: rich>=13.7
Provides-Extra: dev
Requires-Dist: pytest-httpx>=0.30; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Description-Content-Type: text/markdown

# Beamcode for Python

**Encrypted file transfer over the internet** — same product as
[beamcode.vjyas.online](https://beamcode.vjyas.online).

```bash
pip install beamcode
```

You encrypt files on your machine, upload ciphertext, and share a link (or QR).
Anyone with the link can download on **any network** — no accounts, no shared Wi‑Fi.

---

## How Beamcode works

```text
  You (sender)                         Receiver (any device)
  ────────────                         ─────────────────────
  1. Pick files / URLs
  2. Encrypt locally (AES-256-GCM)
  3. Upload ciphertext  ──►  Beamcode cloud
  4. Get share_url (+ optional QR)
       │
       └── copy / chat / email  ──►  5. Open link
                                     6. Decrypt locally
                                     7. Save files
```

| Term | What it means |
|------|----------------|
| **share_url** | Link to copy. Includes encryption key in `#k=…` |
| **compact** | Short `bc:id:key` string — denser for QR codes |
| **pair code** | Short check code (e.g. `N26NSM`) to confirm the key by phone |
| **Downloads** | How many times the **full package** can be downloaded |
| **Password** | Optional extra lock (receiver must pass the same password) |
| **TTL** | How long the beam lives before it expires |
| **E2E encrypted** | Server never sees plaintext |

On the web UI, **"1/10 package downloads used"** means the beam allows 10
downloads and 1 was used. In this Python package the default is **1** download.

---

## Install & check

```bash
pip install beamcode
beamcode doctor          # crypto + API health
beamcode --help
```

Requires **Python 3.10+**.

---

## Quick start (recommended)

Progress is a **single automatic bar** — you do **not** need `on_progress`.

```python
from beamcode import send_files, receive

result = send_files(
    ["./video.mp4", "https://example.com/doc.pdf"],
    ttl="1h",
    max_downloads=1,
)

print(result.share_url)   # give this to the receiver

paths = receive(result.share_url, out_dir="./inbox")
print(paths)
```

With password:

```python
result = send_files(
    ["./secret.pdf"],
    ttl="24h",
    max_downloads=3,
    password="my-secret-pw",   # 10–128 characters
)

paths = receive(
    result.share_url,
    out_dir="./inbox",
    password="my-secret-pw",   # required if sender set one
)
```

---

## Features

| Feature | Details |
|---------|---------|
| Any filetype | PDF, video, zip, JSON, binaries — treated as opaque bytes |
| Multi-file | Several paths in one beam, or `zip=True` to bundle |
| Remote URL attach | Pass `https://…` — Beamcode fetches then encrypts |
| Auto progress | One bar for send and receive (terminal + notebooks) |
| Large files | Disk-backed encrypt/upload up to server max (~2 GB) |
| Multipart resume | Failed large uploads can resume from checkpoint |
| Password | Optional download gate (10–128 chars) |
| Download limit | `max_downloads` (SDK default **1**) |
| TTL | `15m` / `1h` / `24h` / `7d` |
| Room PIN | `generate_pin=True` → 8-digit PIN for `/join` |
| Presence | Optional `--watch` / presence tokens in share URL |
| Revoke / extend / bump | Manage a live beam after send |
| Web compatible | Links open in the Beamcode web app and vice versa |

---

## SDK reference

### `send_files(sources, **options) → ShareResult`

Encrypt and upload one or more **local paths** and/or **http(s) URLs**.

```python
from beamcode import send_files

result = send_files(
    ["./a.pdf", "./clip.mp4", "https://example.com/doc.pdf"],
    ttl="1h",
    max_downloads=1,
    password=None,
    zip=False,
    generate_pin=False,
    auto_delete_on_exhaust=False,
    allow_private_urls=False,
    api_url=None,
    turnstile_token=None,
    resume=True,
    show_progress=None,
    on_progress=None,
)
```

#### Parameters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `sources` | list of paths / URLs | *required* | Local files and/or `http(s)` URLs to attach |
| `ttl` | `"15m"`\|`"1h"`\|`"24h"`\|`"7d"` or seconds | `"1h"` | Link lifetime |
| `max_downloads` | `int` | `1` | Max full package downloads (web often defaults to 10) |
| `password` | `str` \| `None` | `None` | Optional; **10–128 chars**; receiver must pass it |
| `zip` | `bool` | `False` | Bundle multiple files into one zip before encrypt |
| `generate_pin` | `bool` | `False` | Issue 8-digit room PIN for same-room `/join` |
| `auto_delete_on_exhaust` | `bool` | `False` | Delete storage after last download slot is used |
| `allow_private_urls` | `bool` | `False` | Allow fetching localhost / private IPs (advanced) |
| `api_url` | `str` \| `None` | production | Override API (`BEAMCODE_API_URL` also works) |
| `turnstile_token` | `str` \| `None` | env / `None` | CAPTCHA token if API enables Turnstile |
| `resume` | `bool` | `True` | Resume multipart uploads from checkpoint |
| `show_progress` | `bool` \| `None` | auto | `True`/`False` force bar; `None` = auto |
| `on_progress` | callback \| `None` | `None` | Custom callback; alone replaces auto UI |
| `client` | `BeamcodeClient` \| `None` | new client | Reuse an existing client |

#### `ShareResult` fields

| Field | Description |
|-------|-------------|
| `share_url` | **Primary** — copy and share this |
| `compact` | `bc:id:key` for dense QR |
| `pair_code` | Short human check code |
| `id` | Transfer id |
| `revoke_token` | Needed to revoke / extend / bump |
| `presence_token` | Embedded in share URL as `p=` |
| `public_url` | Public path without secrets |
| `expires_at` | Unix ms expiry |
| `pin` | Room PIN if `generate_pin=True` |
| `filenames` | Names included in the beam |
| `max_downloads` | Download limit for this beam |
| `password_protected` | `True` if a password was set |

---

### `receive(payload, **options) → list[Path]`

Download and decrypt a beam.

```python
from beamcode import receive

paths = receive(
    "https://beamcode.vjyas.online/d/…#k=…",
    out_dir="./inbox",
    password=None,           # required if sender set password
    encryption_key=None,     # only if key missing from URL
    api_url=None,
    show_progress=None,
    on_progress=None,
)
```

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `payload` | `str` | *required* | `share_url`, `bc:id:key`, or id (+ key) |
| `out_dir` | path | `"."` | Folder to write files |
| `password` | `str` \| `None` | `None` | Must match sender password if set |
| `encryption_key` | `str` \| `None` | from URL | If fragment/`bc:` has no key |
| `api_url` | `str` \| `None` | production | Override API |
| `show_progress` | `bool` \| `None` | auto | Single progress bar |
| `on_progress` | callback \| `None` | `None` | Custom progress only |
| `client` | `BeamcodeClient` \| `None` | new | Reuse client |

Accepted payload forms:

- Full URL: `https://beamcode.vjyas.online/d/{id}#k=…&p=…`
- Compact: `bc:{id}:{key}` or `bc:{id}:{key}:{presence}`
- Bare id + `encryption_key=`

---

### `BeamcodeClient` (low-level)

For custom apps that need direct API control:

```python
from beamcode import BeamcodeClient

with BeamcodeClient() as client:          # or BeamcodeClient("https://…")
    print(client.health())
    print(client.get_limits())
    # create_transfer / upload_file / upload_multipart_file /
    # complete_transfer / get_download_ticket / revoke_transfer /
    # extend_transfer / bump_downloads / lookup_pin / get_presence …
```

---

### Progress behaviour

| Call style | What you see |
|------------|----------------|
| `send_files([...])` | One automatic bar |
| `receive(url)` | One automatic bar |
| `show_progress=False` | Silent |
| `on_progress=fn` only | Your callback only (no auto bar) |
| `show_progress=True, on_progress=fn` | Bar **and** callback |

Env kill-switch: `BEAMCODE_NO_PROGRESS=1`.

---

## CLI reference

```bash
beamcode send PATH_OR_URL [PATH_OR_URL...] [OPTIONS]
beamcode receive PAYLOAD [--out DIR] [--password …] [--key …]
beamcode join PIN --key KEY [--out DIR]
beamcode revoke ID --token REVOKE_TOKEN
beamcode extend ID --token REVOKE_TOKEN --add-sec SECONDS
beamcode bump ID --token REVOKE_TOKEN [--add N | --max N]
beamcode limits
beamcode doctor
```

### `beamcode send` options

| Flag | Default | Description |
|------|---------|-------------|
| `--ttl` | `1h` | `15m` / `1h` / `24h` / `7d` |
| `--downloads` | `1` | Max package downloads |
| `--password` | off | Download password (10–128 chars) |
| `--zip` | off | Zip multiple sources |
| `--pin` | off | Issue room PIN |
| `--auto-delete` | off | Purge after last download |
| `--api-url` | production | Custom API |
| `--turnstile-token` | env | CAPTCHA when required |
| `--no-resume` | off | Disable multipart resume |
| `--no-qr` | off | Skip ASCII QR |
| `--no-clipboard` | off | Don’t copy share_url |
| `--json` | off | Machine-readable result |
| `--watch` | off | Print open/download receipts |
| `--allow-private-urls` | off | Fetch private IPs |

Examples:

```bash
beamcode send ./report.pdf
beamcode send ./a.mp4 ./b.pdf --downloads 5 --password 'my-secret-pw' --ttl 24h
beamcode send https://example.com/whitepaper.pdf ./notes.txt --zip
beamcode receive "https://beamcode.vjyas.online/d/…#k=…" --out ./inbox
beamcode receive "…" --password 'my-secret-pw'
```

---

## Environment variables

| Variable | Purpose |
|----------|---------|
| `BEAMCODE_API_URL` | API base (default `https://beamcode.vjyas.online`) |
| `BEAMCODE_TURNSTILE_TOKEN` | Turnstile token when CAPTCHA is enabled |
| `BEAMCODE_CHECKPOINT_DIR` | Multipart resume checkpoint folder |
| `BEAMCODE_NO_PROGRESS` | `1` / `true` → hide auto progress bar |

---

## Security notes

- Encryption is **required**. The key lives in `#k=` / `bc:` — treat `share_url` like a secret.
- Password is an **extra** gate on download, not a replacement for the key.
- Remote fetch blocks private/loopback hosts by default (SSRF protection, including redirects).
- Large-file path uses disk streaming (≈1 MiB crypto window), not full-file RAM.

---

## Development

```bash
cd python
pip install -e ".[dev]"
pytest
beamcode doctor
```

## Publish to PyPI

Tag-driven via GitHub Actions (`.github/workflows/python-package.yml`).

1. [PyPI Trusted Publishing](https://pypi.org/manage/account/publishing/) — workflow `python-package.yml`, **Environment blank**
2. `git tag py-v1.1.3 && git push origin py-v1.1.3`

## License

MIT — same as the Beamcode monorepo.
