rail-engine-ingest 0.1.2__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.
Files changed (26) hide show
  1. rail_engine_ingest-0.1.2/LICENSE +21 -0
  2. rail_engine_ingest-0.1.2/MANIFEST.in +7 -0
  3. rail_engine_ingest-0.1.2/PKG-INFO +112 -0
  4. rail_engine_ingest-0.1.2/README-INGEST.md +88 -0
  5. rail_engine_ingest-0.1.2/README-RETRIEVAL.md +90 -0
  6. rail_engine_ingest-0.1.2/README.md +233 -0
  7. rail_engine_ingest-0.1.2/pyproject.toml +40 -0
  8. rail_engine_ingest-0.1.2/rail_engine_ingest.egg-info/PKG-INFO +112 -0
  9. rail_engine_ingest-0.1.2/rail_engine_ingest.egg-info/SOURCES.txt +24 -0
  10. rail_engine_ingest-0.1.2/rail_engine_ingest.egg-info/dependency_links.txt +1 -0
  11. rail_engine_ingest-0.1.2/rail_engine_ingest.egg-info/requires.txt +2 -0
  12. rail_engine_ingest-0.1.2/rail_engine_ingest.egg-info/top_level.txt +1 -0
  13. rail_engine_ingest-0.1.2/railtown/engine/ingest/__init__.py +31 -0
  14. rail_engine_ingest-0.1.2/railtown/engine/ingest/auth.py +72 -0
  15. rail_engine_ingest-0.1.2/railtown/engine/ingest/client.py +276 -0
  16. rail_engine_ingest-0.1.2/railtown/engine/ingest/models.py +102 -0
  17. rail_engine_ingest-0.1.2/setup.cfg +4 -0
  18. rail_engine_ingest-0.1.2/tests/test_embeddings.py +125 -0
  19. rail_engine_ingest-0.1.2/tests/test_indexing.py +127 -0
  20. rail_engine_ingest-0.1.2/tests/test_ingest_auth.py +93 -0
  21. rail_engine_ingest-0.1.2/tests/test_ingest_client.py +256 -0
  22. rail_engine_ingest-0.1.2/tests/test_retrieval_auth.py +107 -0
  23. rail_engine_ingest-0.1.2/tests/test_retrieval_client.py +132 -0
  24. rail_engine_ingest-0.1.2/tests/test_storage.py +556 -0
  25. rail_engine_ingest-0.1.2/tests/test_utils.py +227 -0
  26. rail_engine_ingest-0.1.2/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,7 @@
1
+ # Include custom README files for both packages
2
+ include README-INGEST.md
3
+ include README-RETRIEVAL.md
4
+ # Include standard README.md (for backward compatibility)
5
+ include README.md
6
+ # Include LICENSE
7
+ include LICENSE
@@ -0,0 +1,112 @@
1
+ Metadata-Version: 2.4
2
+ Name: rail-engine-ingest
3
+ Version: 0.1.2
4
+ Summary: Python SDK for Railtown AI Rail Engine - Ingestion
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,ingestion,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 Ingestion SDK
26
+
27
+ Python SDK for ingesting data into Railtown AI Rail Engine - handles embeddings, storage, indexing, and webhook publishing.
28
+
29
+ ## Overview
30
+
31
+ 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.
32
+
33
+ ## Installation
34
+
35
+ ```bash
36
+ uv pip install rail-engine-ingest
37
+ ```
38
+
39
+ ## Quick Start
40
+
41
+ ```python
42
+
43
+ # Copy your ENGINE_TOKEN from https://cndr.railtown.ai Project Settings
44
+
45
+ import asyncio
46
+ from railtown.engine.ingest import RailEngineIngest
47
+ import base64
48
+ import json
49
+
50
+ engine_token = os.getenv("ENGINE_TOKEN")
51
+
52
+ async def main():
53
+ # Initialize client
54
+ async with RailEngineIngest(engine_token=engine_token) as client:
55
+ # Ingest data
56
+ data = {
57
+ "name": "Chicken Shawarma",
58
+ "meal": "lunch",
59
+ "calories": 95
60
+ }
61
+ response = await client.upsert(data)
62
+ print(f"Status: {response.status_code}")
63
+
64
+ asyncio.run(main())
65
+ ```
66
+
67
+ ## Configuration
68
+
69
+ ### Environment Variable
70
+
71
+ - `ENGINE_TOKEN` - Base64-encoded JSON string containing ingestion credentials
72
+
73
+ ### Constructor Parameters
74
+
75
+ - `engine_token` (optional) - ENGINE_TOKEN string (if not provided, reads from env)
76
+ - `model` (optional) - Pydantic model type for validating ingested data
77
+
78
+ ## Features
79
+
80
+ - **Single `upsert()` method** - Unified interface for ingesting data
81
+ - **Multiple data formats** - Accepts Pydantic models, dictionaries, or JSON strings
82
+ - **Model validation** - Optional Pydantic model validation
83
+ - **Direct JSON payload** - Sends data directly as JSON to the ingestion endpoint
84
+ - **Async/await support** - Built for modern async Python applications
85
+
86
+ ## Error Handling
87
+
88
+ The SDK provides custom exception classes:
89
+
90
+ - `RailtownError` - Base exception
91
+ - `RailtownBadRequestError` - 400 Bad Request
92
+ - `RailtownUnauthorizedError` - 401 Unauthorized
93
+ - `RailtownNotFoundError` - 404 Not Found
94
+ - `RailtownConflictError` - 409 Conflict
95
+ - `RailtownServerError` - 5xx Server errors
96
+
97
+ Exceptions are raised on errors.
98
+
99
+ ## Requirements
100
+
101
+ - uv
102
+ - Python 3.10+
103
+ - httpx >= 0.24.0
104
+ - pydantic >= 1.10.0
105
+
106
+ ## Related Package
107
+
108
+ For retrieving and searching data from Rail Engine, see [`rail-engine-ingest`](https://pypi.org/project/rail-engine-ingest/).
109
+
110
+ ## License
111
+
112
+ 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,40 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "rail-engine-ingest"
7
+ version = "0.1.2"
8
+ description = "Python SDK for Railtown AI Rail Engine - Ingestion"
9
+ readme = "README-INGEST.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", "ingestion", "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.engine.ingest*", "railtown.engine.exceptions*"]
37
+ namespaces = false
38
+
39
+ [tool.setuptools.package-data]
40
+ "*" = ["py.typed"]
@@ -0,0 +1,112 @@
1
+ Metadata-Version: 2.4
2
+ Name: rail-engine-ingest
3
+ Version: 0.1.2
4
+ Summary: Python SDK for Railtown AI Rail Engine - Ingestion
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,ingestion,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 Ingestion SDK
26
+
27
+ Python SDK for ingesting data into Railtown AI Rail Engine - handles embeddings, storage, indexing, and webhook publishing.
28
+
29
+ ## Overview
30
+
31
+ 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.
32
+
33
+ ## Installation
34
+
35
+ ```bash
36
+ uv pip install rail-engine-ingest
37
+ ```
38
+
39
+ ## Quick Start
40
+
41
+ ```python
42
+
43
+ # Copy your ENGINE_TOKEN from https://cndr.railtown.ai Project Settings
44
+
45
+ import asyncio
46
+ from railtown.engine.ingest import RailEngineIngest
47
+ import base64
48
+ import json
49
+
50
+ engine_token = os.getenv("ENGINE_TOKEN")
51
+
52
+ async def main():
53
+ # Initialize client
54
+ async with RailEngineIngest(engine_token=engine_token) as client:
55
+ # Ingest data
56
+ data = {
57
+ "name": "Chicken Shawarma",
58
+ "meal": "lunch",
59
+ "calories": 95
60
+ }
61
+ response = await client.upsert(data)
62
+ print(f"Status: {response.status_code}")
63
+
64
+ asyncio.run(main())
65
+ ```
66
+
67
+ ## Configuration
68
+
69
+ ### Environment Variable
70
+
71
+ - `ENGINE_TOKEN` - Base64-encoded JSON string containing ingestion credentials
72
+
73
+ ### Constructor Parameters
74
+
75
+ - `engine_token` (optional) - ENGINE_TOKEN string (if not provided, reads from env)
76
+ - `model` (optional) - Pydantic model type for validating ingested data
77
+
78
+ ## Features
79
+
80
+ - **Single `upsert()` method** - Unified interface for ingesting data
81
+ - **Multiple data formats** - Accepts Pydantic models, dictionaries, or JSON strings
82
+ - **Model validation** - Optional Pydantic model validation
83
+ - **Direct JSON payload** - Sends data directly as JSON to the ingestion endpoint
84
+ - **Async/await support** - Built for modern async Python applications
85
+
86
+ ## Error Handling
87
+
88
+ The SDK provides custom exception classes:
89
+
90
+ - `RailtownError` - Base exception
91
+ - `RailtownBadRequestError` - 400 Bad Request
92
+ - `RailtownUnauthorizedError` - 401 Unauthorized
93
+ - `RailtownNotFoundError` - 404 Not Found
94
+ - `RailtownConflictError` - 409 Conflict
95
+ - `RailtownServerError` - 5xx Server errors
96
+
97
+ Exceptions are raised on errors.
98
+
99
+ ## Requirements
100
+
101
+ - uv
102
+ - Python 3.10+
103
+ - httpx >= 0.24.0
104
+ - pydantic >= 1.10.0
105
+
106
+ ## Related Package
107
+
108
+ For retrieving and searching data from Rail Engine, see [`rail-engine-ingest`](https://pypi.org/project/rail-engine-ingest/).
109
+
110
+ ## License
111
+
112
+ MIT