meshapi 0.1.3__tar.gz → 0.1.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- meshapi-0.1.4/CLAUDE.md +159 -0
- {meshapi-0.1.3 → meshapi-0.1.4}/PKG-INFO +141 -205
- meshapi-0.1.4/README.md +421 -0
- {meshapi-0.1.3 → meshapi-0.1.4}/livetests/conftest.py +6 -1
- {meshapi-0.1.3 → meshapi-0.1.4}/livetests/test_inference_resources.py +21 -39
- meshapi-0.1.4/livetests/test_rag.py +114 -0
- meshapi-0.1.4/livetests/test_realtime.py +128 -0
- {meshapi-0.1.3 → meshapi-0.1.4}/meshapi/__init__.py +43 -7
- {meshapi-0.1.3 → meshapi-0.1.4}/meshapi/_types.py +100 -21
- meshapi-0.1.4/meshapi/resources/rag.py +117 -0
- meshapi-0.1.4/meshapi/resources/realtime.py +325 -0
- {meshapi-0.1.3 → meshapi-0.1.4}/pyproject.toml +3 -2
- meshapi-0.1.3/README.md +0 -488
- meshapi-0.1.3/livetests/batch_file.py +0 -61
- meshapi-0.1.3/meshapi/resources/files.py +0 -44
- {meshapi-0.1.3 → meshapi-0.1.4}/.gitignore +0 -0
- {meshapi-0.1.3 → meshapi-0.1.4}/CHANGELOG.md +0 -0
- {meshapi-0.1.3 → meshapi-0.1.4}/TESTING.md +0 -0
- {meshapi-0.1.3 → meshapi-0.1.4}/livetests/compare.py +0 -0
- {meshapi-0.1.3 → meshapi-0.1.4}/livetests/config.py +0 -0
- {meshapi-0.1.3 → meshapi-0.1.4}/livetests/pytest.ini +0 -0
- {meshapi-0.1.3 → meshapi-0.1.4}/livetests/requirements.txt +0 -0
- {meshapi-0.1.3 → meshapi-0.1.4}/livetests/responses.py +0 -0
- {meshapi-0.1.3 → meshapi-0.1.4}/livetests/test_chat.py +0 -0
- {meshapi-0.1.3 → meshapi-0.1.4}/livetests/test_errors.py +0 -0
- {meshapi-0.1.3 → meshapi-0.1.4}/livetests/test_feature_matrix.py +0 -0
- {meshapi-0.1.3 → meshapi-0.1.4}/livetests/test_models.py +0 -0
- {meshapi-0.1.3 → meshapi-0.1.4}/livetests/test_stream.py +0 -0
- {meshapi-0.1.3 → meshapi-0.1.4}/livetests/test_templates.py +0 -0
- {meshapi-0.1.3 → meshapi-0.1.4}/livetests/tool_call.py +0 -0
- {meshapi-0.1.3 → meshapi-0.1.4}/meshapi/_errors.py +0 -0
- {meshapi-0.1.3 → meshapi-0.1.4}/meshapi/_http.py +0 -0
- {meshapi-0.1.3 → meshapi-0.1.4}/meshapi/resources/__init__.py +0 -0
- {meshapi-0.1.3 → meshapi-0.1.4}/meshapi/resources/batches.py +0 -0
- {meshapi-0.1.3 → meshapi-0.1.4}/meshapi/resources/chat.py +0 -0
- {meshapi-0.1.3 → meshapi-0.1.4}/meshapi/resources/compare.py +0 -0
- {meshapi-0.1.3 → meshapi-0.1.4}/meshapi/resources/embeddings.py +0 -0
- {meshapi-0.1.3 → meshapi-0.1.4}/meshapi/resources/images.py +0 -0
- {meshapi-0.1.3 → meshapi-0.1.4}/meshapi/resources/models.py +0 -0
- {meshapi-0.1.3 → meshapi-0.1.4}/meshapi/resources/responses.py +0 -0
- {meshapi-0.1.3 → meshapi-0.1.4}/meshapi/resources/templates.py +0 -0
meshapi-0.1.4/CLAUDE.md
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# MeshAPI Python SDK
|
|
2
|
+
|
|
3
|
+
Official Python client for the MeshAPI AI model gateway.
|
|
4
|
+
|
|
5
|
+
- **Package**: `meshapi`
|
|
6
|
+
- **Python**: 3.9+
|
|
7
|
+
- **Runtime dependencies**: `httpx>=0.27`, `pydantic>=2`
|
|
8
|
+
- **Build backend**: hatchling
|
|
9
|
+
|
|
10
|
+
## Project layout
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
python/
|
|
14
|
+
├── meshapi/
|
|
15
|
+
│ ├── __init__.py # MeshAPI, AsyncMeshAPI, all public exports
|
|
16
|
+
│ ├── _types.py # All Pydantic request/response models
|
|
17
|
+
│ ├── _http.py # SyncHttpClient / AsyncHttpClient (httpx-based)
|
|
18
|
+
│ ├── _errors.py # MeshAPIError exception
|
|
19
|
+
│ └── resources/
|
|
20
|
+
│ ├── chat.py # /v1/chat/completions
|
|
21
|
+
│ ├── responses.py # /v1/responses
|
|
22
|
+
│ ├── embeddings.py # /v1/embeddings
|
|
23
|
+
│ ├── compare.py # /v1/compare
|
|
24
|
+
│ ├── files.py # /v1/files (batch file objects)
|
|
25
|
+
│ ├── rag.py # /v1/files RAG endpoints (upload, embed, search)
|
|
26
|
+
│ ├── batches.py # /v1/batches
|
|
27
|
+
│ ├── models.py # /v1/models
|
|
28
|
+
│ ├── templates.py # /v1/templates
|
|
29
|
+
│ └── images.py # /v1/images/generations
|
|
30
|
+
├── tests/
|
|
31
|
+
│ ├── unit/ # Fast, no-network tests
|
|
32
|
+
│ ├── contract/ # Pydantic model parsing against local fixtures
|
|
33
|
+
│ └── integration/ # Full-stack tests against a running backend
|
|
34
|
+
├── livetests/ # Live tests against a real backend
|
|
35
|
+
└── pyproject.toml
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Common tasks
|
|
39
|
+
|
|
40
|
+
### Set up development environment
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
python -m venv .venv
|
|
44
|
+
source .venv/bin/activate # Windows: .venv\Scripts\activate
|
|
45
|
+
pip install -e ".[dev]"
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Unit and contract tests (no network)
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
pytest tests/unit/ tests/contract/ -v
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Integration tests (requires a running backend)
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
MESHAPI_BASE_URL=http://localhost:8000 MESHAPI_TOKEN=rsk_... pytest tests/integration/ -v
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Adding a new resource
|
|
61
|
+
|
|
62
|
+
1. Add Pydantic models to `_types.py` under a clearly labelled section.
|
|
63
|
+
2. Create `resources/<name>.py` with `<Name>Resource` and `Async<Name>Resource` classes.
|
|
64
|
+
3. Both classes take their respective `SyncHttpClient` / `AsyncHttpClient` in `__init__`.
|
|
65
|
+
4. Wire the resource into both `MeshAPI` and `AsyncMeshAPI` in `__init__.py`.
|
|
66
|
+
5. Import the new types and resource classes in `__init__.py` and add them to `__all__`.
|
|
67
|
+
6. Follow the pattern in `resources/templates.py`.
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Live tests
|
|
72
|
+
|
|
73
|
+
Live tests hit a real MeshAPI backend and live in `livetests/`. They use pytest with a shared `client` fixture from `conftest.py`.
|
|
74
|
+
|
|
75
|
+
### Prerequisites
|
|
76
|
+
|
|
77
|
+
- A running MeshAPI instance (default `http://localhost:8000`), **or** point at the dev API.
|
|
78
|
+
- A valid data-plane API key (`rsk_...`).
|
|
79
|
+
|
|
80
|
+
### Environment variables
|
|
81
|
+
|
|
82
|
+
Create `python/.env.livetest` (read automatically by the test harness) or export the variables in your shell before running tests.
|
|
83
|
+
|
|
84
|
+
| Variable | Required | Default | Description |
|
|
85
|
+
|----------|----------|---------|-------------|
|
|
86
|
+
| `MESHAPI_BASE_URL` | No | `http://localhost:8000` | Base URL of the MeshAPI gateway |
|
|
87
|
+
| `MESHAPI_TOKEN` | **Yes** | hardcoded dev key | Data-plane API key (`rsk_...`) |
|
|
88
|
+
| `MESHAPI_MODEL` | No | `openai/gpt-4o-mini` | Primary model used in chat/stream tests |
|
|
89
|
+
| `MESHAPI_SECOND_MODEL` | No | `anthropic/claude-haiku-4.5` | Second model for compare tests |
|
|
90
|
+
| `MESHAPI_EMBEDDINGS_MODEL` | No | `openai/text-embedding-3-small` | Model used in embeddings tests |
|
|
91
|
+
| `MESHAPI_IMAGE_GEN_MODEL` | No | _(skipped if unset)_ | Image generation model; test skipped if blank |
|
|
92
|
+
| `MESHAPI_IMAGE_URL` | No | _(skipped if unset)_ | Publicly accessible image URL for vision tests |
|
|
93
|
+
| `MESHAPI_INPUT_AUDIO_B64` | No | _(skipped if unset)_ | Base64-encoded audio for audio-input tests |
|
|
94
|
+
| `MESHAPI_INPUT_AUDIO_FORMAT` | No | `wav` | Format of the base64 audio (`wav`, `mp3`, etc.) |
|
|
95
|
+
| `MESHAPI_AUDIO_OUT_MODEL` | No | _(skipped if unset)_ | Model for audio-output tests; skipped if blank |
|
|
96
|
+
| `MESHAPI_REALTIME_MODEL` | No | `openai/gpt-realtime-mini` | Realtime-capable model used in WebSocket live tests |
|
|
97
|
+
|
|
98
|
+
Example `python/.env.livetest`:
|
|
99
|
+
|
|
100
|
+
```env
|
|
101
|
+
MESHAPI_BASE_URL=https://api-dev.meshapi.ai
|
|
102
|
+
MESHAPI_TOKEN=rsk_your_key_here
|
|
103
|
+
MESHAPI_MODEL=openai/gpt-4o-mini
|
|
104
|
+
MESHAPI_EMBEDDINGS_MODEL=openai/text-embedding-3-small
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Install dependencies
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
# From the python/ directory
|
|
111
|
+
pip install -e ".[dev]"
|
|
112
|
+
pip install httpx # required by the RAG live test for direct signed-URL PUT
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Run all live tests
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
cd livetests
|
|
119
|
+
pytest -v
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Run a single live test file
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
cd livetests
|
|
126
|
+
pytest test_rag.py -v
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Run a specific test function
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
cd livetests
|
|
133
|
+
pytest test_rag.py::test_rag_upload_embed_search -v
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Available live test files
|
|
137
|
+
|
|
138
|
+
| File | What it tests |
|
|
139
|
+
|------|---------------|
|
|
140
|
+
| `test_chat.py` | Chat completions (basic, tools, multi-turn) |
|
|
141
|
+
| `test_stream.py` | Streaming chat and responses |
|
|
142
|
+
| `test_models.py` | Model listing |
|
|
143
|
+
| `test_templates.py` | Template CRUD lifecycle |
|
|
144
|
+
| `test_inference_resources.py` | Embeddings, responses |
|
|
145
|
+
| `test_errors.py` | 401/404 error handling |
|
|
146
|
+
| `test_feature_matrix.py` | Cross-model feature matrix |
|
|
147
|
+
| `test_rag.py` | RAG upload → embed → list → search |
|
|
148
|
+
| `test_realtime.py` | WebSocket connect/close, session.created, session.update, error envelopes, iterator API, async variants |
|
|
149
|
+
|
|
150
|
+
### RAG live test notes
|
|
151
|
+
|
|
152
|
+
`test_rag_upload_embed_search` does the following:
|
|
153
|
+
1. Calls `client.rag.init_upload` with `embed=False`.
|
|
154
|
+
2. PUTs the file bytes directly to the returned `signed_url` via `httpx.put`.
|
|
155
|
+
3. Waits up to 30 s for `upload_status=ready`.
|
|
156
|
+
4. Calls `client.rag.embed` to trigger embedding.
|
|
157
|
+
5. Polls up to 90 s for `embedding_status=ready`.
|
|
158
|
+
6. Calls `client.rag.list` and asserts the file appears.
|
|
159
|
+
7. Calls `client.rag.search` scoped to the file ID and asserts non-empty results.
|