Metadata-Version: 2.4
Name: hivelms-client
Version: 1.0.0
Summary: An SDK for the Hive LMS API
Requires-Python: >=3.12
Requires-Dist: email-validator>=2.3.0
Requires-Dist: pydantic-extra-types>=2.11.0
Requires-Dist: pydantic>=2.12.5
Requires-Dist: pyrfc6266>=1.0.2
Requires-Dist: requests>=2.32.5
Provides-Extra: dev
Requires-Dist: pytest>=7.4; extra == 'dev'
Requires-Dist: python-dotenv>=1.0; extra == 'dev'
Requires-Dist: requests-mock>=1.11; extra == 'dev'
Description-Content-Type: text/markdown

# HiveLMS Python Client

An SDK for the [Hive LMS](https://hive.test) HTTP API, implemented in Python using Pydantic v2 models and a small HTTP client wrapper around `requests`.

This library is generated from the authoritative OpenAPI spec in `schema.json` and aims to provide a clean, typed, and well‑structured interface to all public Hive endpoints.

---

## Installation

The package is intended to be installed via `uv` or `pip` from source for now.

```bash
# Using uv
uv sync --extra dev

# Or using pip directly (from the project root)
pip install .
```

Python 3.12+ is required.

---

## Quick Start

### Creating a client

The main entry point is `HiveClient`, which exposes per‑resource handlers (assignments, course, queues, schedule, tags, etc.).

```python
from hivelms_client.hive_client import HiveClient

client = HiveClient(
    host="hive.test",
    username="admin",
    password="Password1",
    use_https=True,
)
```

By default the client will:

- Authenticate with the Hive token endpoint
- Store the access token
- Attach it automatically to subsequent requests

If you already have a token, you can construct a low‑level `HiveHttpClient` directly and inject it into handlers, but `HiveClient` is usually all you need.

---

## Handlers and Resources

Each top‑level Hive resource has a corresponding handler class under `hivelms_client/handlers/`. For example:

- `assignments` → `AssignmentsHandler`
- `course` → `CourseHandler` (and nested sub‑handlers like `modules`, `exercises`, `subjects`, `programs`)
- `queues` → `QueuesHandler` (and nested `items` handler)
- `schedule` → `ScheduleHandler` (and nested `lessons` handler)
- `tags` → `TagsHandler`
- `time` → `TimeHandler`
- `helps` → `HelpHandler` and `HelpResponsesHandler`
- `management` → `ManagementHandler`

These are all accessible as attributes on `HiveClient`:

```python
client.assignments_handler   # AssignmentsHandler
client.course_handler        # CourseHandler
client.queues_handler        # QueuesHandler
client.schedule_handler      # ScheduleHandler
client.tags_handler          # TagsHandler
client.time_handler          # TimeHandler
client.notification_handler  # NotificationHandler
client.management_handler    # ManagementHandler
```

### Sub‑resource handlers

Nested API paths are modeled as nested handlers. For example:

- Queue items: `/queues/{queue_id}/items/...`
- Course modules: `/course/modules/...`
- Schedule lessons: `/schedule/lessons/...`

These appear as attributes on their parent handler:

```python
# Queue items
queue_items = client.queues_handler.items
queue_items.delete(queue_id=123, item_id=456)

# Course modules
modules = client.course_handler.modules
modules.create(body=module_request)

# Schedule lessons
lessons = client.schedule_handler.lessons
lessons.get(lesson_id=456)
```

The method names follow a consistent convention:

- `search` – GET a collection
- `get` – GET a single resource or a GET action
- `create` – POST create
- `update` – PUT
- `patch` – PATCH
- `delete` – DELETE
- Other verbs (e.g. `lock`, `duplicate`) are used for action‑style endpoints.

Within sub‑resource handlers, method names omit the subresource name where it would be redundant (e.g. `QueueItemsHandler.delete(...)` instead of `delete_item`).

---

## Models

All request and response bodies are defined as Pydantic models under `hivelms_client/models/`, organized per top‑level resource:

- `assignments/`
- `course/`
- `help/`
- `management/`
- `notification/`
- `queues/`
- `schedule/`
- `tag/`
- `time/`
- `hive_common/` – shared/common models

The models are generated directly from `schema.json` and:

- Use precise types and constraints (e.g. `Annotated[str, Field(min_length=1, max_length=255)]`)
- Represent enums via the `HiveOption` base class (or `Literal[...]` for single‑option enums)
- Use `InlineBytes` for binary fields

Creation and patch models follow a naming convention:

- `*CreationRequest` for creation requests (from `*Request` in the OpenAPI spec)
- `*PatchRequest` for patch requests (from `Patched*Request` in the OpenAPI spec)

Example (simplified):

```python
from hivelms_client.models.assignments.assignment import AssignmentInput

request = AssignmentInput(
    name="Homework 1",
    # ... other fields ...
)
created = client.assignments_handler.create(request)
print(created.id)
```

---

## HTTP Client Layer

Under the hood, handlers use `HiveHttpClient` (defined in `hivelms_client/http_client.py`) to perform HTTP requests.

Key features:

- Wraps `requests.Session`
- Adds base URL and `path_prefix` support
- Manages authentication headers
- Exposes a `get_subclient(path_prefix: str)` helper to build nested clients for sub‑resources
- Raises rich exceptions from `hivelms_client.exceptions` on error responses

You normally won’t need to instantiate `HiveHttpClient` yourself; the `HiveClient` does it for you.

---

## Example Usage

### Working with queues

```python
from hivelms_client.hive_client import HiveClient
from hivelms_client.models.queues.queue_items import QueueItemInput

client = HiveClient(host="hive.test", username="admin", password="Password1")

# Search queues
queues = client.queues_handler.search()
for queue in queues:
    print(queue.id, queue.name)

# Get a single queue
queue = client.queues_handler.get(queues[0].id)

# Work with queue items via the sub‑handler
items = client.queues_handler.items

created_item = items.create(
    queue_id=queue.id,
    item=QueueItemInput(title="New item", description="Investigate bug"),
)

items.delete(queue_id=queue.id, item_id=created_item.id)
```

### Working with courses and modules

```python
from hivelms_client.models.course.module import ModuleInput

module_request = ModuleInput(name="Getting Started", parent_subject=1, order="1")
module = client.course_handler.modules.create(module_request)

# Fetch module details
module = client.course_handler.modules.get(module.id)
```

### Working with schedule lessons

```python
# List lessons
lessons = client.schedule_handler.lessons.search()

# Get a specific lesson
lesson = client.schedule_handler.lessons.get(lessons[0].id)
```

---

## Testing

The project uses `pytest` for tests. To run the full test suite:

```bash
uv run pytest
```

Tests use a running Hive instance at `https://hive.test` and a snapshot of server data in `tests/data/server_data.json`. Fixtures in `tests/conftest.py` provide ready‑to‑use admin and student clients.

---

## Contributing & Regeneration

The OpenAPI schema in `schema.json` is the single source of truth for the client.

High‑level workflow for extending the client:

1. Update `schema.json` (or pull the latest version).
2. Generate/update Pydantic models under `hivelms_client/models/`.
3. Add or update handlers under `hivelms_client/handlers/` to cover new endpoints.
4. Wire new handlers into `HiveClient`.
5. Add tests under `tests/` for each new handler method.
6. Run `uv run pytest` before submitting changes.

See `.github/copilot-instructions.md` and `.agent/conventions.md` for detailed internal conventions and codegen rules.

---

## License

This project is licensed under the terms specified in the repository (see the root LICENSE file, if present). If no license file is present, consult the project maintainers before reusing the code in other projects.

