Metadata-Version: 2.4
Name: bckt-sdk
Version: 0.1.0b1
Summary: The official Python SDK for BCKT storage, uploads and logs.
Project-URL: Homepage, https://bckt.io
Project-URL: Repository, https://github.com/bcktio/bckt-python
Project-URL: Documentation, https://bckt.io/docs
Author-email: BCKT <hello@bckt.io>
License-Expression: MIT
License-File: LICENSE
Keywords: bckt,cdn,logs,sdk,storage
Classifier: Development Status :: 4 - Beta
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
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: Programming Language :: Python :: 3.14
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: httpx<1,>=0.28
Provides-Extra: dev
Requires-Dist: build<2,>=1.2; extra == 'dev'
Requires-Dist: mypy<2,>=1.15; extra == 'dev'
Requires-Dist: pytest<9,>=8; extra == 'dev'
Requires-Dist: ruff<1,>=0.12; extra == 'dev'
Requires-Dist: twine<7,>=6; extra == 'dev'
Description-Content-Type: text/markdown

<p align="center">
  <a href="https://bckt.io">
    <img src="docs/assets/bckt-sdk-header-1200x630-transparent.png" alt="BCKT object storage, edge delivery and logs" width="100%">
  </a>
</p>

# BCKT for Python

Upload the file. Keep the URL. Find the log.

The official Python SDK for BCKT. Files, direct browser uploads and structured logs, with typed sync and async clients.

Python 3.10 or newer. HTTPX handles the connections. Your API key stays on the server.

This is a beta. Local checks cover HTTP requests, streaming, queue failures and the package. It still needs a live BCKT acceptance run before calling it production-tested.

## Get started

```bash
python -m pip install --pre bckt-sdk
```

```python
import os
from bckt import Bckt

with Bckt(os.environ["BCKT_API_KEY"]) as bckt:
    uploaded = bckt.files.upload_file(
        "./photo.webp",
        folder="phone/photos",
        private=False,
    )

print(uploaded["url"])
```

The package is installed as `bckt-sdk` and imported as `bckt`. If you are working from this repository before the first PyPI release, use `python -m pip install -e .` instead.

Create a key in [API and S3](https://bckt.io/dashboard/credentials). Give it only the scopes your application needs. Don't put it in client-side code or a shared repository.

## Don't load the whole backup into memory

`upload_file` streams from disk. `upload` also accepts bytes, a binary file or an iterator of byte chunks. Streams need their byte length up front.

```python
from pathlib import Path
import os
from bckt import Bckt

backup = Path("./backup.enc")

with Bckt(os.environ["BCKT_API_KEY"]) as bckt, backup.open("rb") as source:
    bckt.files.upload(
        source,
        filename=backup.name,
        size=backup.stat().st_size,
        folder="backups",
        private=True,
    )
```

Encrypt sensitive backups before uploading and keep an independent copy. Streams are consumed once. The SDK does not silently restart a failed upload.

## Already using async?

```python
import asyncio
import os
from bckt import AsyncBckt

async def main():
    async with AsyncBckt(os.environ["BCKT_API_KEY"]) as bckt:
        uploaded = await bckt.files.upload_file("./photo.webp", folder="photos")
        print(uploaded["url"])

        async for file in bckt.files.iterate(folder="photos"):
            print(file["id"], file["original_name"])

asyncio.run(main())
```

`AsyncBckt` uses native async HTTP requests. Keep one client open for the life of your worker or request handler instead of opening a connection pool per operation.

## Let the browser send the photo

Your server checks the user and issues an upload ticket. The browser sends the image straight to BCKT. Your server does not relay the file or expose its API key.

```python
ticket = bckt.files.create_upload_url(
    filename="photo.webp",
    size=image_size,
    content_type="image/webp",
    folder="phone/photos",
    private=False,
)
```

Validate the user's permission, file size and file type before issuing a ticket. Send the raw file body, not multipart form data. A ticket expires after 15 minutes. Don't log or share it.

The [browser upload example](examples/browser-upload/README.md) includes a local Python server and a working file picker. It is a development demo, not an account or session system.

## A file key is not a file ID

Uploads return `file_key` and `url`. Management methods take the UUID from `files.list()`, not the public file key or URL.

```python
files = bckt.files.list(folder="phone/photos", search="photo.webp")

for file in files["files"]:
    access = bckt.files.get_access_url(file["id"])
    print(file["original_name"], access["url"])
```

Use `get_access_url` for private files. The plain CDN URL returned by an upload is not a signed access link. Upload tickets currently last 15 minutes; private access links last one hour. Read the returned expiration instead of calculating it yourself.

`files.iterate()` handles pagination. `files.download()` streams bytes through a context manager, and `download_to()` refuses to overwrite an existing file. The [file example](examples/files.py) shows both operations.

## Logs you can find again

Create your stream in the dashboard or with `logs.streams.create()` before sending events.

```python
bckt.logs.streams.create("Payments", "payments")

bckt.logs.send("payments", {
    "level": "info",
    "event_type": "payment.completed",
    "entity_id": "order_123",
    "message": "Payment received",
    "payload": {"amount": 29.99, "currency": "EUR"},
})
```

`send` waits for API acceptance. `send_batch` accepts up to 1,000 events in one request. A successful response means BCKT accepted the events, not that your business transaction succeeded.

For frequent events, use a bounded queue:

```python
with bckt.logs.create_logger("server") as logger:
    logger.info("Worker started", {"worker": "invoices"})
```

Call `close()` during application shutdown. The queue lives in memory and is lost if the process exits. Failed batches stay queued and pause delivery until you retry or discard them. Read [queue behaviour](docs/operations.md) before using it for anything important.

## Handle the failure

```python
from bckt import BcktError

try:
    bckt.files.upload_file("./report.pdf", private=True)
except BcktError as error:
    print(error.code, error.status, error.request_id)
    if error.uncertain:
        print("Check whether it arrived before uploading again.")
```

Reads have bounded retries. Writes do not. A lost response after a write may mean the operation succeeded. The SDK exposes that uncertainty instead of creating a second file or log batch.

Local filesystem errors retain their native Python error types. Download stream errors are raised while consuming the context manager.

## Pick what you need

| Task | Methods |
| --- | --- |
| Upload content | `files.upload`, `files.upload_file`, `files.upload_json` |
| Authorize a direct upload | `files.create_upload_url` |
| Browse files | `files.list`, `files.iterate` |
| Read files | `files.get_access_url`, `files.download`, `files.download_to` |
| Manage files | `files.set_visibility`, `files.delete`, `files.delete_many` |
| Work with folders | `folders.list`, `folders.create`, `folders.delete` |
| Send and search logs | `logs.send`, `logs.send_batch`, `logs.query` |
| Work with streams | `logs.streams.list`, `logs.streams.create` |
| Buffer logs | `logs.create_logger` |
| Sign an S3 operation | `s3.create_presigned_url` |

The async client has the same resources with `await`, `async for` and `async with` where needed. API responses keep their original snake_case fields, including keys inside your own payloads. See the [method reference](docs/reference.md) for arguments, returns and permissions.

## Something broken?

Open an issue with your Python version, SDK version and a small reproduction. Include the BCKT request ID if you have one. Remove API keys, signed URLs and customer data before posting.

Account question? [hello@bckt.io](mailto:hello@bckt.io).

MIT licensed.
