rail-engine 0.1.3__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.
- rail_engine-0.1.3/LICENSE +21 -0
- rail_engine-0.1.3/MANIFEST.in +7 -0
- rail_engine-0.1.3/PKG-INFO +114 -0
- rail_engine-0.1.3/README-INGEST.md +88 -0
- rail_engine-0.1.3/README-RETRIEVAL.md +90 -0
- rail_engine-0.1.3/README.md +233 -0
- rail_engine-0.1.3/pyproject.toml +41 -0
- rail_engine-0.1.3/rail_engine.egg-info/PKG-INFO +114 -0
- rail_engine-0.1.3/rail_engine.egg-info/SOURCES.txt +30 -0
- rail_engine-0.1.3/rail_engine.egg-info/dependency_links.txt +1 -0
- rail_engine-0.1.3/rail_engine.egg-info/requires.txt +2 -0
- rail_engine-0.1.3/rail_engine.egg-info/top_level.txt +1 -0
- rail_engine-0.1.3/railtown/__init__.py +3 -0
- rail_engine-0.1.3/railtown/engine/__init__.py +25 -0
- rail_engine-0.1.3/railtown/engine/auth.py +68 -0
- rail_engine-0.1.3/railtown/engine/client.py +431 -0
- rail_engine-0.1.3/railtown/engine/embeddings.py +90 -0
- rail_engine-0.1.3/railtown/engine/exceptions.py +53 -0
- rail_engine-0.1.3/railtown/engine/indexing.py +88 -0
- rail_engine-0.1.3/railtown/engine/models.py +92 -0
- rail_engine-0.1.3/railtown/engine/storage.py +334 -0
- rail_engine-0.1.3/railtown/engine/utils.py +85 -0
- rail_engine-0.1.3/setup.cfg +4 -0
- rail_engine-0.1.3/tests/test_embeddings.py +125 -0
- rail_engine-0.1.3/tests/test_indexing.py +127 -0
- rail_engine-0.1.3/tests/test_ingest_auth.py +93 -0
- rail_engine-0.1.3/tests/test_ingest_client.py +256 -0
- rail_engine-0.1.3/tests/test_retrieval_auth.py +107 -0
- rail_engine-0.1.3/tests/test_retrieval_client.py +132 -0
- rail_engine-0.1.3/tests/test_storage.py +556 -0
- rail_engine-0.1.3/tests/test_utils.py +227 -0
- rail_engine-0.1.3/tests/test_webhook_handler.py +270 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Railtown AI
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: rail-engine
|
|
3
|
+
Version: 0.1.3
|
|
4
|
+
Summary: Python SDK for Railtown AI Rail Engine - Retrieval
|
|
5
|
+
Author-email: Railtown AI <support@railtown.ai>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/railtownai/railengine-sdk
|
|
8
|
+
Project-URL: Documentation, https://github.com/railtownai/railengine-sdk
|
|
9
|
+
Project-URL: Repository, https://github.com/railtownai/railengine-sdk
|
|
10
|
+
Keywords: railtown,rail-engine,retrieval,sdk
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Requires-Python: >=3.10
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Requires-Dist: httpx>=0.24.0
|
|
22
|
+
Requires-Dist: pydantic>=1.10.0
|
|
23
|
+
Dynamic: license-file
|
|
24
|
+
|
|
25
|
+
# Rail Engine Retrieval SDK
|
|
26
|
+
|
|
27
|
+
Python SDK for retrieving and searching data from Railtown AI Rail Engine - handles embeddings, storage documents, and indexed content.
|
|
28
|
+
|
|
29
|
+
## Overview
|
|
30
|
+
|
|
31
|
+
The `rail-engine` package provides a Pythonic interface for retrieving and searching data from Rail Engine. It supports async/await patterns, client-side filtering, automatic pagination, and Pydantic model deserialization.
|
|
32
|
+
|
|
33
|
+
## Installation
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
uv pip install rail-engine
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Quick Start
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
import asyncio
|
|
43
|
+
from railtown.engine import RailEngine
|
|
44
|
+
|
|
45
|
+
async def main():
|
|
46
|
+
# Initialize client (reads from ENGINE_PAT and ENGINE_ID env vars)
|
|
47
|
+
async with RailEngine() as client:
|
|
48
|
+
# Search vector store
|
|
49
|
+
results = client.search_vector_store(
|
|
50
|
+
query="apple"
|
|
51
|
+
)
|
|
52
|
+
async for item in results:
|
|
53
|
+
print(item)
|
|
54
|
+
|
|
55
|
+
asyncio.run(main())
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Configuration
|
|
59
|
+
|
|
60
|
+
### Environment Variables
|
|
61
|
+
|
|
62
|
+
- `ENGINE_PAT` (required) - Personal Access Token
|
|
63
|
+
- `ENGINE_ID` (required) - Engine ID (can also be passed to constructor)
|
|
64
|
+
- `RAILTOWN_API_URL` (optional) - Base API URL (defaults to `https://cndr.railtown.ai/api`)
|
|
65
|
+
|
|
66
|
+
### Constructor Parameters
|
|
67
|
+
|
|
68
|
+
- `pat` (optional) - PAT token (if not provided, reads from `ENGINE_PAT` env)
|
|
69
|
+
- `engine_id` (optional) - Engine ID (if not provided, reads from `ENGINE_ID` env, required if not in env)
|
|
70
|
+
- `api_url` (optional) - Base API URL (if not provided, reads from `RAILTOWN_API_URL` env or defaults to production)
|
|
71
|
+
- `model` (optional) - Pydantic model type for deserializing retrieved data
|
|
72
|
+
|
|
73
|
+
## Features
|
|
74
|
+
|
|
75
|
+
- **Multiple retrieval methods**:
|
|
76
|
+
- `search_vector_store()` - Semantic search in vector stores
|
|
77
|
+
- `get_storage_document_by_id()` - Get document by ID
|
|
78
|
+
- `get_storage_document_by_customer_key()` - Get documents by customer key
|
|
79
|
+
- `query_storage_by_jsonpath()` - Query using JSONPath
|
|
80
|
+
- `list_storage_documents()` - List all documents with pagination
|
|
81
|
+
- `search_index()` - Full-text search using Azure Search
|
|
82
|
+
- **Client-side filtering** - Filter results using `filter_fn` parameter
|
|
83
|
+
- **Automatic pagination** - Handles pagination automatically
|
|
84
|
+
- **Model deserialization** - Optional Pydantic model support with per-call override
|
|
85
|
+
- **Graceful error handling** - Returns None or empty iterables on errors
|
|
86
|
+
- **Async/await support** - Built for modern async Python applications
|
|
87
|
+
|
|
88
|
+
## Error Handling
|
|
89
|
+
|
|
90
|
+
The SDK provides custom exception classes:
|
|
91
|
+
|
|
92
|
+
- `RailtownError` - Base exception
|
|
93
|
+
- `RailtownBadRequestError` - 400 Bad Request
|
|
94
|
+
- `RailtownUnauthorizedError` - 401 Unauthorized
|
|
95
|
+
- `RailtownNotFoundError` - 404 Not Found
|
|
96
|
+
- `RailtownConflictError` - 409 Conflict
|
|
97
|
+
- `RailtownServerError` - 5xx Server errors
|
|
98
|
+
|
|
99
|
+
Returns `None` or empty iterables on errors (graceful degradation).
|
|
100
|
+
|
|
101
|
+
## Requirements
|
|
102
|
+
|
|
103
|
+
- uv
|
|
104
|
+
- Python 3.10+
|
|
105
|
+
- httpx >= 0.24.0
|
|
106
|
+
- pydantic >= 1.10.0
|
|
107
|
+
|
|
108
|
+
## Related Package
|
|
109
|
+
|
|
110
|
+
For ingesting data into Rail Engine, see [`rail-engine`](https://pypi.org/project/rail-engine/).
|
|
111
|
+
|
|
112
|
+
## License
|
|
113
|
+
|
|
114
|
+
MIT
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Rail Engine Ingestion SDK
|
|
2
|
+
|
|
3
|
+
Python SDK for ingesting data into Railtown AI Rail Engine - handles embeddings, storage, indexing, and webhook publishing.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The `rail-engine-ingest` package provides a Pythonic interface for publishing data to Rail Engine. It supports async/await patterns, Pydantic model validation, and familiar configuration patterns.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
uv pip install rail-engine-ingest
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
```python
|
|
18
|
+
|
|
19
|
+
# Copy your ENGINE_TOKEN from https://cndr.railtown.ai Project Settings
|
|
20
|
+
|
|
21
|
+
import asyncio
|
|
22
|
+
from railtown.engine.ingest import RailEngineIngest
|
|
23
|
+
import base64
|
|
24
|
+
import json
|
|
25
|
+
|
|
26
|
+
engine_token = os.getenv("ENGINE_TOKEN")
|
|
27
|
+
|
|
28
|
+
async def main():
|
|
29
|
+
# Initialize client
|
|
30
|
+
async with RailEngineIngest(engine_token=engine_token) as client:
|
|
31
|
+
# Ingest data
|
|
32
|
+
data = {
|
|
33
|
+
"name": "Chicken Shawarma",
|
|
34
|
+
"meal": "lunch",
|
|
35
|
+
"calories": 95
|
|
36
|
+
}
|
|
37
|
+
response = await client.upsert(data)
|
|
38
|
+
print(f"Status: {response.status_code}")
|
|
39
|
+
|
|
40
|
+
asyncio.run(main())
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Configuration
|
|
44
|
+
|
|
45
|
+
### Environment Variable
|
|
46
|
+
|
|
47
|
+
- `ENGINE_TOKEN` - Base64-encoded JSON string containing ingestion credentials
|
|
48
|
+
|
|
49
|
+
### Constructor Parameters
|
|
50
|
+
|
|
51
|
+
- `engine_token` (optional) - ENGINE_TOKEN string (if not provided, reads from env)
|
|
52
|
+
- `model` (optional) - Pydantic model type for validating ingested data
|
|
53
|
+
|
|
54
|
+
## Features
|
|
55
|
+
|
|
56
|
+
- **Single `upsert()` method** - Unified interface for ingesting data
|
|
57
|
+
- **Multiple data formats** - Accepts Pydantic models, dictionaries, or JSON strings
|
|
58
|
+
- **Model validation** - Optional Pydantic model validation
|
|
59
|
+
- **Direct JSON payload** - Sends data directly as JSON to the ingestion endpoint
|
|
60
|
+
- **Async/await support** - Built for modern async Python applications
|
|
61
|
+
|
|
62
|
+
## Error Handling
|
|
63
|
+
|
|
64
|
+
The SDK provides custom exception classes:
|
|
65
|
+
|
|
66
|
+
- `RailtownError` - Base exception
|
|
67
|
+
- `RailtownBadRequestError` - 400 Bad Request
|
|
68
|
+
- `RailtownUnauthorizedError` - 401 Unauthorized
|
|
69
|
+
- `RailtownNotFoundError` - 404 Not Found
|
|
70
|
+
- `RailtownConflictError` - 409 Conflict
|
|
71
|
+
- `RailtownServerError` - 5xx Server errors
|
|
72
|
+
|
|
73
|
+
Exceptions are raised on errors.
|
|
74
|
+
|
|
75
|
+
## Requirements
|
|
76
|
+
|
|
77
|
+
- uv
|
|
78
|
+
- Python 3.10+
|
|
79
|
+
- httpx >= 0.24.0
|
|
80
|
+
- pydantic >= 1.10.0
|
|
81
|
+
|
|
82
|
+
## Related Package
|
|
83
|
+
|
|
84
|
+
For retrieving and searching data from Rail Engine, see [`rail-engine-ingest`](https://pypi.org/project/rail-engine-ingest/).
|
|
85
|
+
|
|
86
|
+
## License
|
|
87
|
+
|
|
88
|
+
MIT
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Rail Engine Retrieval SDK
|
|
2
|
+
|
|
3
|
+
Python SDK for retrieving and searching data from Railtown AI Rail Engine - handles embeddings, storage documents, and indexed content.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The `rail-engine` package provides a Pythonic interface for retrieving and searching data from Rail Engine. It supports async/await patterns, client-side filtering, automatic pagination, and Pydantic model deserialization.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
uv pip install rail-engine
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
```python
|
|
18
|
+
import asyncio
|
|
19
|
+
from railtown.engine import RailEngine
|
|
20
|
+
|
|
21
|
+
async def main():
|
|
22
|
+
# Initialize client (reads from ENGINE_PAT and ENGINE_ID env vars)
|
|
23
|
+
async with RailEngine() as client:
|
|
24
|
+
# Search vector store
|
|
25
|
+
results = client.search_vector_store(
|
|
26
|
+
query="apple"
|
|
27
|
+
)
|
|
28
|
+
async for item in results:
|
|
29
|
+
print(item)
|
|
30
|
+
|
|
31
|
+
asyncio.run(main())
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Configuration
|
|
35
|
+
|
|
36
|
+
### Environment Variables
|
|
37
|
+
|
|
38
|
+
- `ENGINE_PAT` (required) - Personal Access Token
|
|
39
|
+
- `ENGINE_ID` (required) - Engine ID (can also be passed to constructor)
|
|
40
|
+
- `RAILTOWN_API_URL` (optional) - Base API URL (defaults to `https://cndr.railtown.ai/api`)
|
|
41
|
+
|
|
42
|
+
### Constructor Parameters
|
|
43
|
+
|
|
44
|
+
- `pat` (optional) - PAT token (if not provided, reads from `ENGINE_PAT` env)
|
|
45
|
+
- `engine_id` (optional) - Engine ID (if not provided, reads from `ENGINE_ID` env, required if not in env)
|
|
46
|
+
- `api_url` (optional) - Base API URL (if not provided, reads from `RAILTOWN_API_URL` env or defaults to production)
|
|
47
|
+
- `model` (optional) - Pydantic model type for deserializing retrieved data
|
|
48
|
+
|
|
49
|
+
## Features
|
|
50
|
+
|
|
51
|
+
- **Multiple retrieval methods**:
|
|
52
|
+
- `search_vector_store()` - Semantic search in vector stores
|
|
53
|
+
- `get_storage_document_by_id()` - Get document by ID
|
|
54
|
+
- `get_storage_document_by_customer_key()` - Get documents by customer key
|
|
55
|
+
- `query_storage_by_jsonpath()` - Query using JSONPath
|
|
56
|
+
- `list_storage_documents()` - List all documents with pagination
|
|
57
|
+
- `search_index()` - Full-text search using Azure Search
|
|
58
|
+
- **Client-side filtering** - Filter results using `filter_fn` parameter
|
|
59
|
+
- **Automatic pagination** - Handles pagination automatically
|
|
60
|
+
- **Model deserialization** - Optional Pydantic model support with per-call override
|
|
61
|
+
- **Graceful error handling** - Returns None or empty iterables on errors
|
|
62
|
+
- **Async/await support** - Built for modern async Python applications
|
|
63
|
+
|
|
64
|
+
## Error Handling
|
|
65
|
+
|
|
66
|
+
The SDK provides custom exception classes:
|
|
67
|
+
|
|
68
|
+
- `RailtownError` - Base exception
|
|
69
|
+
- `RailtownBadRequestError` - 400 Bad Request
|
|
70
|
+
- `RailtownUnauthorizedError` - 401 Unauthorized
|
|
71
|
+
- `RailtownNotFoundError` - 404 Not Found
|
|
72
|
+
- `RailtownConflictError` - 409 Conflict
|
|
73
|
+
- `RailtownServerError` - 5xx Server errors
|
|
74
|
+
|
|
75
|
+
Returns `None` or empty iterables on errors (graceful degradation).
|
|
76
|
+
|
|
77
|
+
## Requirements
|
|
78
|
+
|
|
79
|
+
- uv
|
|
80
|
+
- Python 3.10+
|
|
81
|
+
- httpx >= 0.24.0
|
|
82
|
+
- pydantic >= 1.10.0
|
|
83
|
+
|
|
84
|
+
## Related Package
|
|
85
|
+
|
|
86
|
+
For ingesting data into Rail Engine, see [`rail-engine`](https://pypi.org/project/rail-engine/).
|
|
87
|
+
|
|
88
|
+
## License
|
|
89
|
+
|
|
90
|
+
MIT
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
# Rail Engine Python SDK
|
|
2
|
+
|
|
3
|
+
Python SDK for Railtown AI Rail Engine - providing a Pythonic interface for ingesting and retrieving data from Rail Engine.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The Rail Engine Python SDK is split into two separate packages:
|
|
8
|
+
|
|
9
|
+
- **`rail-engine-ingest`** - For publishing data to Rail Engine (handles embeddings, storage, indexing, and webhook publishing)
|
|
10
|
+
- **`rail-engine`** - For retrieving and searching data (embeddings, storage documents, and indexed content)
|
|
11
|
+
|
|
12
|
+
Both packages support:
|
|
13
|
+
|
|
14
|
+
- Async/await patterns
|
|
15
|
+
- Client-side filtering
|
|
16
|
+
- Automatic pagination
|
|
17
|
+
- Pydantic model support for type safety
|
|
18
|
+
- Familiar configuration patterns (like OpenAI SDK)
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
### Ingestion Package
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
uv pip install rail-engine-ingest
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Retrieval Package
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
uv pip install rail-engine
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Both Packages
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
uv pip install rail-engine-ingest rail-engine
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Quick Start
|
|
41
|
+
|
|
42
|
+
### Ingestion
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
import asyncio
|
|
46
|
+
from railtown.engine.ingest import RailEngineIngest
|
|
47
|
+
import base64
|
|
48
|
+
import json
|
|
49
|
+
|
|
50
|
+
# Create ENGINE_TOKEN (base64-encoded JSON)
|
|
51
|
+
token_data = {
|
|
52
|
+
"IngestionUrl": "https://eng123.railtownlogs.com",
|
|
53
|
+
"IngestionApiToken": "your-auth-token",
|
|
54
|
+
"EngineId": "your-engine-guid"
|
|
55
|
+
}
|
|
56
|
+
engine_token = base64.b64encode(json.dumps(token_data).encode()).decode()
|
|
57
|
+
|
|
58
|
+
async def main():
|
|
59
|
+
# Initialize client
|
|
60
|
+
async with RailEngineIngest(engine_token=engine_token) as client:
|
|
61
|
+
# Ingest data
|
|
62
|
+
data = {
|
|
63
|
+
"EventId": "event-123",
|
|
64
|
+
"ProjectId": "project-456",
|
|
65
|
+
"food_name": "Apple",
|
|
66
|
+
"calories": 95
|
|
67
|
+
}
|
|
68
|
+
response = await client.upsert(data)
|
|
69
|
+
print(f"Status: {response.status_code}")
|
|
70
|
+
|
|
71
|
+
asyncio.run(main())
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Retrieval
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
import asyncio
|
|
78
|
+
from railtown.engine import RailEngine
|
|
79
|
+
|
|
80
|
+
async def main():
|
|
81
|
+
# Initialize client (reads from ENGINE_PAT and ENGINE_ID env vars)
|
|
82
|
+
async with RailEngine() as client:
|
|
83
|
+
# Search vector store
|
|
84
|
+
results = client.search_vector_store(
|
|
85
|
+
engine_id=client.engine_id,
|
|
86
|
+
vector_store="VectorStore1",
|
|
87
|
+
query="apple"
|
|
88
|
+
)
|
|
89
|
+
async for item in results:
|
|
90
|
+
print(item)
|
|
91
|
+
|
|
92
|
+
asyncio.run(main())
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Configuration
|
|
96
|
+
|
|
97
|
+
### Ingestion (`rail-engine-ingest`)
|
|
98
|
+
|
|
99
|
+
**Environment Variable:**
|
|
100
|
+
|
|
101
|
+
- `ENGINE_TOKEN` - Base64-encoded JSON string containing ingestion credentials
|
|
102
|
+
|
|
103
|
+
**Constructor Parameters:**
|
|
104
|
+
|
|
105
|
+
- `engine_token` (optional) - ENGINE_TOKEN string (if not provided, reads from env)
|
|
106
|
+
- `model` (optional) - Pydantic model type for validating ingested data
|
|
107
|
+
|
|
108
|
+
### Retrieval (`rail-engine`)
|
|
109
|
+
|
|
110
|
+
**Environment Variables:**
|
|
111
|
+
|
|
112
|
+
- `ENGINE_PAT` (required) - Personal Access Token
|
|
113
|
+
- `ENGINE_ID` (required) - Engine ID (can also be passed to constructor)
|
|
114
|
+
- `RAILTOWN_API_URL` (optional) - Base API URL (defaults to `https://cndr.railtown.ai/api`)
|
|
115
|
+
|
|
116
|
+
**Constructor Parameters:**
|
|
117
|
+
|
|
118
|
+
- `pat` (optional) - PAT token (if not provided, reads from `ENGINE_PAT` env)
|
|
119
|
+
- `engine_id` (optional) - Engine ID (if not provided, reads from `ENGINE_ID` env, required if not in env)
|
|
120
|
+
- `api_url` (optional) - Base API URL (if not provided, reads from `RAILTOWN_API_URL` env or defaults to production)
|
|
121
|
+
- `model` (optional) - Pydantic model type for deserializing retrieved data
|
|
122
|
+
|
|
123
|
+
## Features
|
|
124
|
+
|
|
125
|
+
### Ingestion Features
|
|
126
|
+
|
|
127
|
+
- **Single `upsert()` method** - Unified interface for ingesting data
|
|
128
|
+
- **Multiple data formats** - Accepts Pydantic models, dictionaries, or JSON strings
|
|
129
|
+
- **Model validation** - Optional Pydantic model validation
|
|
130
|
+
- **Direct JSON payload** - Sends data directly as JSON to the ingestion endpoint
|
|
131
|
+
- **UTF-8 encoding** - All text operations use UTF-8
|
|
132
|
+
|
|
133
|
+
### Retrieval Features
|
|
134
|
+
|
|
135
|
+
- **Multiple retrieval methods**:
|
|
136
|
+
- `search_vector_store()` - Semantic search in vector stores
|
|
137
|
+
- `get_storage_document_by_id()` - Get document by ID
|
|
138
|
+
- `get_storage_document_by_customer_key()` - Get documents by customer key
|
|
139
|
+
- `query_storage_by_jsonpath()` - Query using JSONPath
|
|
140
|
+
- `list_storage_documents()` - List all documents with pagination
|
|
141
|
+
- `search_index()` - Full-text search using Azure Search
|
|
142
|
+
- **Client-side filtering** - Filter results using `filter_fn` parameter
|
|
143
|
+
- **Automatic pagination** - Handles pagination automatically
|
|
144
|
+
- **Model deserialization** - Optional Pydantic model support with per-call override
|
|
145
|
+
- **Graceful error handling** - Returns None or empty iterables on errors
|
|
146
|
+
|
|
147
|
+
## Examples
|
|
148
|
+
|
|
149
|
+
See the [`samples/`](samples/) directory for comprehensive examples:
|
|
150
|
+
|
|
151
|
+
- [`samples/ingestion_example.py`](samples/ingestion_example.py) - Ingestion examples
|
|
152
|
+
- [`samples/retrieval_example.py`](samples/retrieval_example.py) - Retrieval examples
|
|
153
|
+
- [`samples/README.md`](samples/README.md) - Samples documentation
|
|
154
|
+
|
|
155
|
+
## API Reference
|
|
156
|
+
|
|
157
|
+
### Ingestion Client (`RailEngineIngest`)
|
|
158
|
+
|
|
159
|
+
#### Methods
|
|
160
|
+
|
|
161
|
+
- `upsert(data)` - Upsert data to Rail Engine
|
|
162
|
+
- Accepts: Pydantic model instance, dict, or JSON string
|
|
163
|
+
- Returns: HTTP response
|
|
164
|
+
|
|
165
|
+
#### Properties
|
|
166
|
+
|
|
167
|
+
- `ingestion_url` - Ingestion URL from decoded ENGINE_TOKEN
|
|
168
|
+
- `ingestion_api_token` - API token from decoded ENGINE_TOKEN
|
|
169
|
+
- `engine_id` - Engine ID from decoded ENGINE_TOKEN
|
|
170
|
+
|
|
171
|
+
### Retrieval Client (`RailEngine`)
|
|
172
|
+
|
|
173
|
+
#### Methods
|
|
174
|
+
|
|
175
|
+
- `search_vector_store(engine_id, vector_store, query, filter_fn=None, model=None)` - Search vector store
|
|
176
|
+
- `get_storage_document_by_id(engine_id, engine_document_id, filter_fn=None, model=None)` - Get document by ID
|
|
177
|
+
- `get_storage_document_by_customer_key(engine_id, customer_key, page_number=1, page_size=25, filter_fn=None, model=None)` - Get documents by customer key
|
|
178
|
+
- `query_storage_by_jsonpath(engine_id, json_path_query, filter_fn=None, model=None)` - Query by JSONPath
|
|
179
|
+
- `list_storage_documents(engine_id, customer_key=None, page_number=1, page_size=100, filter_fn=None, model=None)` - List documents
|
|
180
|
+
- `search_index(project_id, engine_id, query, filter_fn=None, model=None)` - Search index
|
|
181
|
+
|
|
182
|
+
#### Properties
|
|
183
|
+
|
|
184
|
+
- `pat` - PAT token
|
|
185
|
+
- `engine_id` - Engine ID
|
|
186
|
+
- `api_url` - Base API URL
|
|
187
|
+
- `model` - Default model type
|
|
188
|
+
|
|
189
|
+
## Error Handling
|
|
190
|
+
|
|
191
|
+
The SDK provides custom exception classes:
|
|
192
|
+
|
|
193
|
+
- `RailtownError` - Base exception
|
|
194
|
+
- `RailtownBadRequestError` - 400 Bad Request
|
|
195
|
+
- `RailtownUnauthorizedError` - 401 Unauthorized
|
|
196
|
+
- `RailtownNotFoundError` - 404 Not Found
|
|
197
|
+
- `RailtownConflictError` - 409 Conflict
|
|
198
|
+
- `RailtownServerError` - 5xx Server errors
|
|
199
|
+
|
|
200
|
+
**Ingestion**: Raises exceptions on errors
|
|
201
|
+
**Retrieval**: Returns `None` or empty iterables on errors (graceful degradation)
|
|
202
|
+
|
|
203
|
+
## Requirements
|
|
204
|
+
|
|
205
|
+
- Python 3.10+
|
|
206
|
+
- httpx >= 0.24.0
|
|
207
|
+
- pydantic >= 1.10.0
|
|
208
|
+
|
|
209
|
+
## Testing
|
|
210
|
+
|
|
211
|
+
Run the test suite:
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
# Install development dependencies
|
|
215
|
+
uv pip install -r requirements-dev.txt
|
|
216
|
+
|
|
217
|
+
# Run all tests
|
|
218
|
+
pytest
|
|
219
|
+
|
|
220
|
+
# Run with coverage
|
|
221
|
+
pytest --cov=railtown --cov-report=html
|
|
222
|
+
|
|
223
|
+
# Run specific test file
|
|
224
|
+
pytest tests/test_ingest_client.py
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## License
|
|
228
|
+
|
|
229
|
+
MIT
|
|
230
|
+
|
|
231
|
+
## Support
|
|
232
|
+
|
|
233
|
+
For issues, questions, or contributions, please visit the [GitHub repository](https://github.com/railtownai/railengine-sdk).
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "rail-engine"
|
|
7
|
+
version = "0.1.3"
|
|
8
|
+
description = "Python SDK for Railtown AI Rail Engine - Retrieval"
|
|
9
|
+
readme = "README-RETRIEVAL.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
authors = [
|
|
12
|
+
{name = "Railtown AI", email = "support@railtown.ai"}
|
|
13
|
+
]
|
|
14
|
+
license = {text = "MIT"}
|
|
15
|
+
keywords = ["railtown", "rail-engine", "retrieval", "sdk"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 4 - Beta",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"License :: OSI Approved :: MIT License",
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"Programming Language :: Python :: 3.10",
|
|
22
|
+
"Programming Language :: Python :: 3.11",
|
|
23
|
+
"Programming Language :: Python :: 3.12",
|
|
24
|
+
]
|
|
25
|
+
dependencies = [
|
|
26
|
+
"httpx>=0.24.0",
|
|
27
|
+
"pydantic>=1.10.0",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
[project.urls]
|
|
31
|
+
Homepage = "https://github.com/railtownai/railengine-sdk"
|
|
32
|
+
Documentation = "https://github.com/railtownai/railengine-sdk"
|
|
33
|
+
Repository = "https://github.com/railtownai/railengine-sdk"
|
|
34
|
+
|
|
35
|
+
[tool.setuptools.packages.find]
|
|
36
|
+
include = ["railtown*"]
|
|
37
|
+
exclude = ["railtown.engine.ingest*"]
|
|
38
|
+
namespaces = false
|
|
39
|
+
|
|
40
|
+
[tool.setuptools.package-data]
|
|
41
|
+
"*" = ["py.typed"]
|