Metadata-Version: 2.4
Name: tgtdbapi
Version: 0.3.1
Summary: Python SDK for the TGT Data API and the company data services (S3/SeaweedFS, PostgreSQL, MongoDB).
Author: TGT-DS
License: Proprietary
Project-URL: Repository, https://gitlab.com/tgt-ds/tgt-databases-configuration-group/tgt-databases-tgtdbapi-server-api
Keywords: s3,seaweedfs,postgresql,mongodb,sigv4,tgt
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Operating System :: OS Independent
Classifier: Topic :: Database
Requires-Python: >=3.11
Description-Content-Type: text/markdown
Requires-Dist: psycopg[binary]>=3.2
Requires-Dist: pymongo>=4.6
Provides-Extra: test
Requires-Dist: pytest>=8; extra == "test"

# tgtdbapi

Python client for a **tgtdb-gateway** deployment — one small library to do CRUD
against three data services behind a single authenticated HTTP API:

| Service | Backend | Client |
|---|---|---|
| Object storage | S3-compatible (SeaweedFS, AWS S3, MinIO…) | `S3Client` — hand-rolled SigV4, **standard library only** |
| Structured data | PostgreSQL | `PostgresClient` (psycopg 3) |
| Documents | MongoDB | `MongoClient` (pymongo) |

Everything is configured from the environment; the library never hardcodes
endpoints or credentials, and the database drivers are imported lazily, so an
app that only touches S3 needs no database dependencies at runtime.

## Install

```bash
pip install tgtdbapi
```

## Use

Two ways in — pick what fits your network:

**A. Through the API with an OAuth2 client (works from anywhere):**

```python
from tgtdbapi import TgtAPI

api = TgtAPI(client_id, client_secret, base_url="https://api.example.com")
api.whoami()                                     # identity + effective grants
api.s3_put("my-bucket", "reports/x.pdf", data)
api.pg_select("customers", limit=10)
api.mongo_insert("analytics", "events", {"kind": "signup"})
```

**B. Direct to the services (native protocols, needs network access):**

```python
from tgtdbapi import TgtDB

db = TgtDB.from_env()                       # reads TGTDB_* from the environment

db.s3.put("my-bucket", "reports/august.pdf", pdf_bytes)
rows = db.pg.query("SELECT id, name FROM customers WHERE active = %s", [True])
db.mongo.insert_one("analytics", "events", {"kind": "signup"})
```

Or one service at a time:

```python
from tgtdbapi import S3Client

s3 = S3Client("https://storage.example.com", access_key, secret_key,
              default_bucket="my-bucket")
s3.put(None, "hello.txt", b"hi")
print(s3.get(None, "hello.txt"))
url = s3.presign(None, "hello.txt", expires=300)     # shareable, no credentials
```

Read-only callers can fetch objects with a scoped token instead of keys:

```python
S3Client.get_via_token(base_url, token, "my-bucket", "reports/august.pdf")
```

## Configuration

| Variable | Purpose |
|---|---|
| `TGTDB_S3_ENDPOINT` · `TGTDB_S3_ACCESS_KEY` · `TGTDB_S3_SECRET_KEY` | S3 access (`TGTDB_S3_BUCKET` sets a default bucket) |
| `TGTDB_PG_DSN` *(or `TGTDB_PG_HOST/PORT/DB/USER/PASSWORD`)* | PostgreSQL |
| `TGTDB_MONGO_URI` *(or `TGTDB_MONGO_HOST/PORT/USER/PASSWORD`)* | MongoDB |

Every setting also accepts the `TGT_*` prefix. The full reference lives in
`tgtdbapi/config.py`.

## Errors

All failures derive from `TgtDBError`: `ConfigError`, `S3Error`,
`PermissionDeniedError`, `NotFoundError`, `PostgresError`, `MongoError` — so you
can catch broadly or precisely.

## Notes

- Permissions are enforced by the services themselves (a read-only credential
  cannot write; a PostgreSQL role remains subject to row-level security).
- Object keys are content-addressed as `blobs/<sha256[0:2]>/<sha256>`, so moving
  between S3 providers is a copy, not a rewrite.
- Proprietary software. Published so that internal projects can install it with
  plain `pip install`; it contains no credentials and no deployment details.
