Metadata-Version: 2.3
Name: timeback
Version: 0.1.0
Summary: A Python client for the TimeBack API (OneRoster 1.2 implementation)
Author: Casey Schmid
Author-email: casey.schmid@2hourlearning.com
Requires-Python: >=3.9,<4.0
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Dist: httpx (>=0.27.2,<0.28.0)
Requires-Dist: pydantic (>=2.12.3,<3.0.0)
Requires-Dist: python-dotenv (>=1.2.1,<2.0.0)
Description-Content-Type: text/markdown

# Timeback

Python client for the Timeback API (OneRoster 1.2 plus adjacent services).

## Installation

### Using Poetry (recommended)

```bash
poetry install
poetry shell
```

### From built wheel

```bash
poetry build
pip install dist/timeback-0.1.0-py3-none-any.whl
```

## Configuration

Required environment variables:

- `TIMEBACK_CLIENT_ID`
- `TIMEBACK_CLIENT_SECRET`
- `TIMEBACK_ENVIRONMENT` in {`production`, `staging`}

Optional per-service base URL overrides:

- `TIMEBACK_QTI_API_BASE_URL` (defaults by environment)
- `TIMEBACK_CALIPER_API_BASE_URL` (defaults by environment)

Defaults by environment:

- production
  - OneRoster: `https://api.alpha-1edtech.ai/`
  - QTI: `https://qti.alpha-1edtech.ai/api`
  - Caliper: `https://caliper.alpha-1edtech.ai`
- staging
  - OneRoster: `https://api.staging.alpha-1edtech.ai/`
  - QTI: `https://qti-staging.alpha-1edtech.ai/api`
  - Caliper: `https://caliper-staging.alpha-1edtech.ai`

## Quick start

```python
from timeback import Timeback

client = Timeback()
user = client.oneroster.rostering.get_user("<sourcedId>")
print(user.sourcedId, user.givenName, user.familyName)
```

Override QTI/Caliper base URLs explicitly:

```python
client = Timeback(
    environment="staging",
    qti_api_base_url="https://my-qti.example.com/api",
    caliper_api_base_url="https://my-caliper.example.com",
)

# Raw HTTP clients (services can be added later)
qti_health = client.qti_http.get("/health")
caliper_status = client.caliper_http.get("/status")
```

## Services and endpoints

- OneRoster
  - `client.oneroster.rostering.get_user(sourced_id, fields=None)`

Design rules: service methods contain no business logic; each method calls a single endpoint function in `timeback/services/.../endpoints/`, which may import utilities from `.../utils/`. All endpoints/utilities return typed Pydantic models/enums from `timeback/models` and `timeback/enums`.

See docs for structure and procedures:

- `timeback/docs/coding_guidelines.md`
- `timeback/docs/add_endpoint_procedure.md`
- `timeback/docs/oneroster/rostering/get_user.md`

## Testing

Run all unit tests:

```bash
poetry run pytest -q -m "not integration"
```

Run integration tests (real API calls; requires network and creds):

```bash
export TIMEBACK_ENVIRONMENT=production
export TIMEBACK_CLIENT_ID=...
export TIMEBACK_CLIENT_SECRET=...
poetry run pytest -q -m integration
```

## Development

Formatting and linting:

```bash
poetry run black .
poetry run flake8 .
poetry run mypy .
```

Build and publish:

```bash
poetry build
poetry publish  # requires configured credentials
```
