quicksearch-python-sdk 1.0.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.
- quicksearch_python_sdk-1.0.4/.github/workflows/publish.yml +36 -0
- quicksearch_python_sdk-1.0.4/.gitignore +10 -0
- quicksearch_python_sdk-1.0.4/.python-version +1 -0
- quicksearch_python_sdk-1.0.4/LICENSE +21 -0
- quicksearch_python_sdk-1.0.4/PKG-INFO +386 -0
- quicksearch_python_sdk-1.0.4/README.md +351 -0
- quicksearch_python_sdk-1.0.4/examples/async_usage.py +124 -0
- quicksearch_python_sdk-1.0.4/examples/basic_usage.py +159 -0
- quicksearch_python_sdk-1.0.4/examples/batch_example.py +263 -0
- quicksearch_python_sdk-1.0.4/examples/consumer_example.py +199 -0
- quicksearch_python_sdk-1.0.4/examples/error_handling.py +191 -0
- quicksearch_python_sdk-1.0.4/main.py +6 -0
- quicksearch_python_sdk-1.0.4/pyproject.toml +87 -0
- quicksearch_python_sdk-1.0.4/quicksearch/__init__.py +61 -0
- quicksearch_python_sdk-1.0.4/quicksearch/_version.py +3 -0
- quicksearch_python_sdk-1.0.4/quicksearch/async_batch_processor.py +133 -0
- quicksearch_python_sdk-1.0.4/quicksearch/async_client.py +365 -0
- quicksearch_python_sdk-1.0.4/quicksearch/batch_processor.py +158 -0
- quicksearch_python_sdk-1.0.4/quicksearch/client.py +99 -0
- quicksearch_python_sdk-1.0.4/quicksearch/exceptions.py +56 -0
- quicksearch_python_sdk-1.0.4/quicksearch/models.py +116 -0
- quicksearch_python_sdk-1.0.4/quicksearch/sync_client.py +393 -0
- quicksearch_python_sdk-1.0.4/tests/__init__.py +1 -0
- quicksearch_python_sdk-1.0.4/tests/conftest.py +61 -0
- quicksearch_python_sdk-1.0.4/tests/test_async_batch.py +264 -0
- quicksearch_python_sdk-1.0.4/tests/test_async_client.py +141 -0
- quicksearch_python_sdk-1.0.4/tests/test_batch_models.py +206 -0
- quicksearch_python_sdk-1.0.4/tests/test_integration.py +224 -0
- quicksearch_python_sdk-1.0.4/tests/test_models.py +139 -0
- quicksearch_python_sdk-1.0.4/tests/test_sync_batch.py +270 -0
- quicksearch_python_sdk-1.0.4/tests/test_sync_client.py +199 -0
- quicksearch_python_sdk-1.0.4/uv.lock +1126 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*.*.*"
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
pypi-publish:
|
|
13
|
+
name: Upload release to PyPI
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
permissions:
|
|
16
|
+
id-token: write
|
|
17
|
+
|
|
18
|
+
steps:
|
|
19
|
+
- name: Checkout repository
|
|
20
|
+
uses: actions/checkout@v4
|
|
21
|
+
|
|
22
|
+
- name: Set up Python
|
|
23
|
+
uses: actions/setup-python@v5
|
|
24
|
+
with:
|
|
25
|
+
python-version: "3.11"
|
|
26
|
+
|
|
27
|
+
- name: Install build dependencies
|
|
28
|
+
run: |
|
|
29
|
+
python -m pip install --upgrade pip
|
|
30
|
+
pip install build
|
|
31
|
+
|
|
32
|
+
- name: Build package
|
|
33
|
+
run: python -m build
|
|
34
|
+
|
|
35
|
+
- name: Publish to PyPI
|
|
36
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.11
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 QuickSearch
|
|
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,386 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: quicksearch-python-sdk
|
|
3
|
+
Version: 1.0.4
|
|
4
|
+
Summary: Python SDK for QuickSearch event log storage system
|
|
5
|
+
Project-URL: Homepage, https://github.com/quicksearch/quicksearch-python-sdk
|
|
6
|
+
Project-URL: Repository, https://github.com/quicksearch/quicksearch-python-sdk
|
|
7
|
+
Project-URL: Issues, https://github.com/quicksearch/quicksearch-python-sdk/issues
|
|
8
|
+
Author: QuickSearch Team
|
|
9
|
+
License: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: api-client,events,logging,search,syslog
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
21
|
+
Classifier: Topic :: System :: Logging
|
|
22
|
+
Requires-Python: >=3.9
|
|
23
|
+
Requires-Dist: httpx>=0.28.1
|
|
24
|
+
Requires-Dist: pydantic>=2.11.7
|
|
25
|
+
Provides-Extra: dev
|
|
26
|
+
Requires-Dist: black>=24.10.0; extra == 'dev'
|
|
27
|
+
Requires-Dist: mypy>=1.19.1; extra == 'dev'
|
|
28
|
+
Requires-Dist: pytest-asyncio>=1.0.0; extra == 'dev'
|
|
29
|
+
Requires-Dist: pytest-cov>=7.0.0; extra == 'dev'
|
|
30
|
+
Requires-Dist: pytest-mock>=3.15.1; extra == 'dev'
|
|
31
|
+
Requires-Dist: pytest>=8.4.0; extra == 'dev'
|
|
32
|
+
Requires-Dist: respx>=0.22.0; extra == 'dev'
|
|
33
|
+
Requires-Dist: ruff>=0.13.1; extra == 'dev'
|
|
34
|
+
Description-Content-Type: text/markdown
|
|
35
|
+
|
|
36
|
+
# QuickSearch Python SDK
|
|
37
|
+
|
|
38
|
+
[](https://badge.fury.io/py/quicksearch-python-sdk)
|
|
39
|
+
[](https://pypi.org/project/quicksearch-python-sdk/)
|
|
40
|
+
[](https://opensource.org/licenses/MIT)
|
|
41
|
+
|
|
42
|
+
A Python library for interacting with the QuickSearch event log storage system.
|
|
43
|
+
|
|
44
|
+
## Features
|
|
45
|
+
|
|
46
|
+
- **Simple API**: Clean, pythonic interface for event ingestion and search
|
|
47
|
+
- **Type Safety**: Full type hints and Pydantic models for data validation
|
|
48
|
+
- **Async Support**: Both synchronous and asynchronous clients included
|
|
49
|
+
- **Error Handling**: Comprehensive exception classes for easy error handling
|
|
50
|
+
- **Flexible Authentication**: Support for API keys and JWT tokens
|
|
51
|
+
|
|
52
|
+
## Installation
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Using uv
|
|
56
|
+
uv add quicksearch-python-sdk
|
|
57
|
+
|
|
58
|
+
# Using pip
|
|
59
|
+
pip install quicksearch-python-sdk
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Quick Start
|
|
63
|
+
|
|
64
|
+
### Synchronous Client
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
from quicksearch import QuickSearchClient, EventData
|
|
68
|
+
|
|
69
|
+
# Initialize client
|
|
70
|
+
client = QuickSearchClient(
|
|
71
|
+
base_url="http://localhost:3000",
|
|
72
|
+
api_key="your-api-key-here"
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
# Ingest an event
|
|
76
|
+
event = EventData(
|
|
77
|
+
type="user_login",
|
|
78
|
+
application="web_app",
|
|
79
|
+
data={"user_id": "12345", "ip_address": "192.168.1.100"}
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
response = client.ingest_event(event)
|
|
83
|
+
print(f"Event ID: {response.eventId}")
|
|
84
|
+
|
|
85
|
+
# Search for events
|
|
86
|
+
result = client.search_events(query="login", limit=10)
|
|
87
|
+
for event in result.events:
|
|
88
|
+
print(f"{event['timestamp_iso']}: {event['message']}")
|
|
89
|
+
|
|
90
|
+
# Cleanup
|
|
91
|
+
client.close()
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Using Context Manager
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
from quicksearch import QuickSearchClient, EventData
|
|
98
|
+
|
|
99
|
+
with QuickSearchClient(api_key="your-api-key") as client:
|
|
100
|
+
response = client.ingest_event(EventData(type="test_event"))
|
|
101
|
+
print(f"Success: {response.success}")
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Asynchronous Client
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
import asyncio
|
|
108
|
+
from quicksearch import AsyncQuickSearchClient, EventData
|
|
109
|
+
|
|
110
|
+
async def main():
|
|
111
|
+
async with AsyncQuickSearchClient(api_key="your-api-key") as client:
|
|
112
|
+
# Ingest an event
|
|
113
|
+
event = EventData(type="user_login", data={"user_id": "12345"})
|
|
114
|
+
response = await client.ingest_event(event)
|
|
115
|
+
print(f"Event ID: {response.eventId}")
|
|
116
|
+
|
|
117
|
+
# Search for events
|
|
118
|
+
result = await client.search_events(query="login")
|
|
119
|
+
print(f"Found {result.count} events")
|
|
120
|
+
|
|
121
|
+
asyncio.run(main())
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## API Reference
|
|
125
|
+
|
|
126
|
+
### QuickSearchClient (Synchronous)
|
|
127
|
+
|
|
128
|
+
#### Constructor
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
QuickSearchClient(
|
|
132
|
+
base_url: str = "http://localhost:3000",
|
|
133
|
+
api_key: str | None = None,
|
|
134
|
+
jwt_token: str | None = None,
|
|
135
|
+
timeout: float = 30.0,
|
|
136
|
+
verify_ssl: bool = True
|
|
137
|
+
)
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
#### Methods
|
|
141
|
+
|
|
142
|
+
##### `ingest_event(event)`
|
|
143
|
+
|
|
144
|
+
Ingest a single event.
|
|
145
|
+
|
|
146
|
+
**Parameters:**
|
|
147
|
+
- `event` (EventData | dict): Event data
|
|
148
|
+
|
|
149
|
+
**Returns:** `EventResponse`
|
|
150
|
+
|
|
151
|
+
**Example:**
|
|
152
|
+
```python
|
|
153
|
+
event = EventData(
|
|
154
|
+
type="user_login",
|
|
155
|
+
application="web_app",
|
|
156
|
+
message="User logged in",
|
|
157
|
+
data={"user_id": "12345"}
|
|
158
|
+
)
|
|
159
|
+
response = client.ingest_event(event)
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
##### `ingest_events(events)`
|
|
163
|
+
|
|
164
|
+
Ingest multiple events in batch.
|
|
165
|
+
|
|
166
|
+
**Parameters:**
|
|
167
|
+
- `events` (list[EventData] | list[dict]): List of event data
|
|
168
|
+
|
|
169
|
+
**Returns:** `list[EventResponse]`
|
|
170
|
+
|
|
171
|
+
**Example:**
|
|
172
|
+
```python
|
|
173
|
+
events = [
|
|
174
|
+
EventData(type="click", data={"button": "submit"}),
|
|
175
|
+
EventData(type="view", data={"page": "home"}),
|
|
176
|
+
]
|
|
177
|
+
responses = client.ingest_events(events)
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
##### `search_events(**kwargs)`
|
|
181
|
+
|
|
182
|
+
Search for events.
|
|
183
|
+
|
|
184
|
+
**Parameters:**
|
|
185
|
+
- `query` (str | None): Search query string
|
|
186
|
+
- `limit` (int): Maximum results (default: 100)
|
|
187
|
+
- `source` (str | None): Filter by source
|
|
188
|
+
- `severity` (str | None): Filter by severity
|
|
189
|
+
- `timestamp_gte` (str | None): Filter by timestamp (ISO format)
|
|
190
|
+
|
|
191
|
+
**Returns:** `EventSearchResult`
|
|
192
|
+
|
|
193
|
+
**Example:**
|
|
194
|
+
```python
|
|
195
|
+
result = client.search_events(
|
|
196
|
+
query="error",
|
|
197
|
+
source="syslog",
|
|
198
|
+
severity="critical",
|
|
199
|
+
limit=50
|
|
200
|
+
)
|
|
201
|
+
print(f"Found {result.count} events")
|
|
202
|
+
for event in result.events:
|
|
203
|
+
print(event)
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
##### `ingest_syslog(syslog_data)`
|
|
207
|
+
|
|
208
|
+
Ingest a syslog message.
|
|
209
|
+
|
|
210
|
+
**Parameters:**
|
|
211
|
+
- `syslog_data` (SyslogData | str | dict): Syslog data or raw string
|
|
212
|
+
|
|
213
|
+
**Returns:** `EventResponse`
|
|
214
|
+
|
|
215
|
+
**Example:**
|
|
216
|
+
```python
|
|
217
|
+
# Structured syslog
|
|
218
|
+
from quicksearch import SyslogData
|
|
219
|
+
|
|
220
|
+
syslog = SyslogData(
|
|
221
|
+
severity="error",
|
|
222
|
+
hostname="web-server-01",
|
|
223
|
+
message="Authentication failed",
|
|
224
|
+
data={"user": "admin"}
|
|
225
|
+
)
|
|
226
|
+
response = client.ingest_syslog(syslog)
|
|
227
|
+
|
|
228
|
+
# Raw syslog string
|
|
229
|
+
raw_syslog = "<34>Oct 11 22:14:15 mymachine su: 'su root' failed for user"
|
|
230
|
+
response = client.ingest_syslog(raw_syslog)
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### AsyncQuickSearchClient (Asynchronous)
|
|
234
|
+
|
|
235
|
+
The async client has the same methods as the sync client, but all methods are async.
|
|
236
|
+
|
|
237
|
+
```python
|
|
238
|
+
async with AsyncQuickSearchClient(api_key="your-api-key") as client:
|
|
239
|
+
response = await client.ingest_event(EventData(type="test"))
|
|
240
|
+
result = await client.search_events(query="test")
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
## Data Models
|
|
244
|
+
|
|
245
|
+
### EventData
|
|
246
|
+
|
|
247
|
+
```python
|
|
248
|
+
EventData(
|
|
249
|
+
type: str, # Required
|
|
250
|
+
application: str | None = None,
|
|
251
|
+
timestamp: str | None = None, # ISO 8601 format
|
|
252
|
+
message: str | None = None,
|
|
253
|
+
data: dict[str, Any] = {},
|
|
254
|
+
source: str | None = None
|
|
255
|
+
)
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### SyslogData
|
|
259
|
+
|
|
260
|
+
```python
|
|
261
|
+
SyslogData(
|
|
262
|
+
type: str | None = None,
|
|
263
|
+
severity: str | None = None,
|
|
264
|
+
hostname: str | None = None,
|
|
265
|
+
message: str | None = None,
|
|
266
|
+
data: dict[str, Any] = {}
|
|
267
|
+
)
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### EventResponse
|
|
271
|
+
|
|
272
|
+
```python
|
|
273
|
+
EventResponse(
|
|
274
|
+
success: bool,
|
|
275
|
+
message: str,
|
|
276
|
+
eventId: str | None = None
|
|
277
|
+
)
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### EventSearchResult
|
|
281
|
+
|
|
282
|
+
```python
|
|
283
|
+
EventSearchResult(
|
|
284
|
+
success: bool,
|
|
285
|
+
events: list[dict[str, Any]],
|
|
286
|
+
count: int,
|
|
287
|
+
estimated_total: int | None = None,
|
|
288
|
+
processing_time_ms: int | None = None,
|
|
289
|
+
query: str | None = None
|
|
290
|
+
)
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
## Error Handling
|
|
294
|
+
|
|
295
|
+
The SDK provides specific exception types for different error scenarios:
|
|
296
|
+
|
|
297
|
+
```python
|
|
298
|
+
from quicksearch import (
|
|
299
|
+
QuickSearchClient,
|
|
300
|
+
EventData,
|
|
301
|
+
AuthenticationError,
|
|
302
|
+
PermissionError,
|
|
303
|
+
ValidationError,
|
|
304
|
+
RateLimitError,
|
|
305
|
+
ServerError,
|
|
306
|
+
ConnectionError
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
client = QuickSearchClient(api_key="your-api-key")
|
|
310
|
+
|
|
311
|
+
try:
|
|
312
|
+
response = client.ingest_event(EventData(type="test"))
|
|
313
|
+
except AuthenticationError:
|
|
314
|
+
print("Invalid API key or token")
|
|
315
|
+
except PermissionError:
|
|
316
|
+
print("API key lacks required permission")
|
|
317
|
+
except ValidationError as e:
|
|
318
|
+
print(f"Invalid data: {e}")
|
|
319
|
+
except RateLimitError:
|
|
320
|
+
print("Daily API limit exceeded")
|
|
321
|
+
except ServerError:
|
|
322
|
+
print("Server error occurred")
|
|
323
|
+
except ConnectionError:
|
|
324
|
+
print("Failed to connect to server")
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
## Authentication
|
|
328
|
+
|
|
329
|
+
### API Key Authentication
|
|
330
|
+
|
|
331
|
+
```python
|
|
332
|
+
# Via Authorization header (default)
|
|
333
|
+
client = QuickSearchClient(api_key="your-api-key")
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### JWT Token Authentication
|
|
337
|
+
|
|
338
|
+
```python
|
|
339
|
+
client = QuickSearchClient(jwt_token="your-jwt-token")
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
## Testing
|
|
343
|
+
|
|
344
|
+
The SDK includes comprehensive tests. To run them:
|
|
345
|
+
|
|
346
|
+
```bash
|
|
347
|
+
# Install development dependencies
|
|
348
|
+
uv sync --all-extras
|
|
349
|
+
|
|
350
|
+
# Run tests
|
|
351
|
+
uv run pytest
|
|
352
|
+
|
|
353
|
+
# Run tests with coverage
|
|
354
|
+
uv run pytest --cov=quicksearch --cov-report=html
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
## Development
|
|
358
|
+
|
|
359
|
+
```bash
|
|
360
|
+
# Install development dependencies
|
|
361
|
+
uv sync --all-extras
|
|
362
|
+
|
|
363
|
+
# Format code
|
|
364
|
+
uv run black quicksearch tests
|
|
365
|
+
|
|
366
|
+
# Lint code
|
|
367
|
+
uv run ruff check quicksearch tests
|
|
368
|
+
|
|
369
|
+
# Type check
|
|
370
|
+
uv run mypy quicksearch
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
## Requirements
|
|
374
|
+
|
|
375
|
+
- Python 3.9 or higher
|
|
376
|
+
- requests >= 2.31.0
|
|
377
|
+
- httpx >= 0.25.0
|
|
378
|
+
- pydantic >= 2.5.0
|
|
379
|
+
|
|
380
|
+
## License
|
|
381
|
+
|
|
382
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
383
|
+
|
|
384
|
+
## Support
|
|
385
|
+
|
|
386
|
+
For issues and questions, please visit the [GitHub repository](https://github.com/quicksearch/quicksearch-python-sdk).
|