quraite 0.1.0__tar.gz → 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.
- quraite-0.1.2/PKG-INFO +386 -0
- quraite-0.1.2/README.md +351 -0
- {quraite-0.1.0 → quraite-0.1.2}/pyproject.toml +2 -2
- {quraite-0.1.0 → quraite-0.1.2}/quraite/__init__.py +3 -3
- {quraite-0.1.0 → quraite-0.1.2}/quraite/adapters/__init__.py +134 -134
- {quraite-0.1.0 → quraite-0.1.2}/quraite/adapters/agno_adapter.py +157 -159
- {quraite-0.1.0 → quraite-0.1.2}/quraite/adapters/base.py +123 -123
- {quraite-0.1.0 → quraite-0.1.2}/quraite/adapters/bedrock_agents_adapter.py +343 -343
- {quraite-0.1.0 → quraite-0.1.2}/quraite/adapters/flowise_adapter.py +275 -275
- {quraite-0.1.0 → quraite-0.1.2}/quraite/adapters/google_adk_adapter.py +211 -209
- {quraite-0.1.0 → quraite-0.1.2}/quraite/adapters/http_adapter.py +255 -239
- quraite-0.1.0/quraite/adapters/langgraph_adapter.py → quraite-0.1.2/quraite/adapters/langchain_adapter.py +305 -304
- quraite-0.1.0/quraite/adapters/langgraph_server_adapter.py → quraite-0.1.2/quraite/adapters/langchain_server_adapter.py +252 -252
- {quraite-0.1.0 → quraite-0.1.2}/quraite/adapters/langflow_adapter.py +192 -192
- {quraite-0.1.0 → quraite-0.1.2}/quraite/adapters/n8n_adapter.py +220 -220
- {quraite-0.1.0 → quraite-0.1.2}/quraite/adapters/openai_agents_adapter.py +267 -269
- {quraite-0.1.0 → quraite-0.1.2}/quraite/adapters/pydantic_ai_adapter.py +307 -312
- {quraite-0.1.0 → quraite-0.1.2}/quraite/adapters/smolagents_adapter.py +148 -152
- {quraite-0.1.0 → quraite-0.1.2}/quraite/logger.py +61 -61
- {quraite-0.1.0 → quraite-0.1.2}/quraite/schema/message.py +91 -91
- {quraite-0.1.0 → quraite-0.1.2}/quraite/schema/response.py +16 -16
- {quraite-0.1.0 → quraite-0.1.2}/quraite/serve/__init__.py +1 -1
- {quraite-0.1.0 → quraite-0.1.2}/quraite/serve/cloudflared.py +210 -210
- {quraite-0.1.0 → quraite-0.1.2}/quraite/serve/local_agent.py +360 -360
- quraite-0.1.2/quraite/traces/traces_adk_openinference.json +379 -0
- quraite-0.1.2/quraite/traces/traces_agno_multi_agent.json +669 -0
- quraite-0.1.2/quraite/traces/traces_agno_openinference.json +321 -0
- quraite-0.1.2/quraite/traces/traces_crewai_openinference.json +155 -0
- quraite-0.1.2/quraite/traces/traces_langgraph_openinference.json +349 -0
- quraite-0.1.2/quraite/traces/traces_langgraph_openinference_multi_agent.json +2705 -0
- quraite-0.1.2/quraite/traces/traces_langgraph_traceloop.json +510 -0
- quraite-0.1.2/quraite/traces/traces_openai_agents_multi_agent_1.json +402 -0
- quraite-0.1.2/quraite/traces/traces_openai_agents_openinference.json +341 -0
- quraite-0.1.2/quraite/traces/traces_pydantic_openinference.json +286 -0
- quraite-0.1.2/quraite/traces/traces_pydantic_openinference_multi_agent_1.json +399 -0
- quraite-0.1.2/quraite/traces/traces_pydantic_openinference_multi_agent_2.json +398 -0
- quraite-0.1.2/quraite/traces/traces_smol_agents_openinference.json +397 -0
- quraite-0.1.2/quraite/traces/traces_smol_agents_tool_calling_openinference.json +704 -0
- {quraite-0.1.0 → quraite-0.1.2}/quraite/tracing/__init__.py +25 -24
- {quraite-0.1.0 → quraite-0.1.2}/quraite/tracing/constants.py +15 -16
- {quraite-0.1.0 → quraite-0.1.2}/quraite/tracing/span_exporter.py +101 -115
- {quraite-0.1.0 → quraite-0.1.2}/quraite/tracing/span_processor.py +47 -49
- {quraite-0.1.0 → quraite-0.1.2}/quraite/tracing/tool_extractors.py +309 -290
- {quraite-0.1.0 → quraite-0.1.2}/quraite/tracing/trace.py +564 -564
- {quraite-0.1.0 → quraite-0.1.2}/quraite/tracing/types.py +179 -179
- {quraite-0.1.0 → quraite-0.1.2}/quraite/tracing/utils.py +170 -170
- {quraite-0.1.0 → quraite-0.1.2}/quraite/utils/json_utils.py +269 -269
- quraite-0.1.0/PKG-INFO +0 -44
- quraite-0.1.0/README.md +0 -9
- {quraite-0.1.0 → quraite-0.1.2}/quraite/schema/__init__.py +0 -0
- {quraite-0.1.0 → quraite-0.1.2}/quraite/utils/__init__.py +0 -0
quraite-0.1.2/PKG-INFO
ADDED
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: quraite
|
|
3
|
+
Version: 0.1.2
|
|
4
|
+
Summary: This project provides adaptors and methods to integrate with the Quraite platform
|
|
5
|
+
Author: Shiv Mohith
|
|
6
|
+
Author-email: Shiv Mohith <shivmohith8@gmail.com>
|
|
7
|
+
Requires-Dist: aiohttp>=3.13.2
|
|
8
|
+
Requires-Dist: fastapi>=0.121.1
|
|
9
|
+
Requires-Dist: httpx>=0.28.1
|
|
10
|
+
Requires-Dist: openinference-semantic-conventions>=0.1.25
|
|
11
|
+
Requires-Dist: opentelemetry-api>=1.37.0
|
|
12
|
+
Requires-Dist: opentelemetry-sdk>=1.37.0
|
|
13
|
+
Requires-Dist: pydantic>=2.12.4
|
|
14
|
+
Requires-Dist: python-dotenv>=1.2.1
|
|
15
|
+
Requires-Dist: uvicorn>=0.38.0
|
|
16
|
+
Requires-Dist: agno>=2.3.4 ; extra == 'agno'
|
|
17
|
+
Requires-Dist: boto3>=1.40.70 ; extra == 'bedrock'
|
|
18
|
+
Requires-Dist: google-adk>=1.18.0 ; extra == 'google-adk'
|
|
19
|
+
Requires-Dist: langchain>=1.0.5 ; extra == 'langchain'
|
|
20
|
+
Requires-Dist: langgraph>=1.0.3 ; extra == 'langchain'
|
|
21
|
+
Requires-Dist: openai-agents>=0.5.0 ; extra == 'openai-agents'
|
|
22
|
+
Requires-Dist: pydantic-ai>=1.25.0 ; extra == 'pydantic-ai'
|
|
23
|
+
Requires-Dist: pyngrok>=7.5.0 ; extra == 'pyngrok'
|
|
24
|
+
Requires-Dist: smolagents>=1.23.0 ; extra == 'smolagents'
|
|
25
|
+
Requires-Python: >=3.10
|
|
26
|
+
Provides-Extra: agno
|
|
27
|
+
Provides-Extra: bedrock
|
|
28
|
+
Provides-Extra: google-adk
|
|
29
|
+
Provides-Extra: langchain
|
|
30
|
+
Provides-Extra: openai-agents
|
|
31
|
+
Provides-Extra: pydantic-ai
|
|
32
|
+
Provides-Extra: pyngrok
|
|
33
|
+
Provides-Extra: smolagents
|
|
34
|
+
Description-Content-Type: text/markdown
|
|
35
|
+
|
|
36
|
+
# Quraite Python SDK
|
|
37
|
+
|
|
38
|
+
[](https://www.python.org/downloads/)
|
|
39
|
+
[](LICENSE)
|
|
40
|
+
[](https://opentelemetry.io/)
|
|
41
|
+
|
|
42
|
+
The **Quraite Python SDK** provides adapters and methods to integrate AI agent with the [Quraite platform](https://quraite.ai) for evaluation. It offers a unified interface for different agent frameworks, automatic tracing at every turn for agent trajectory evaluation, and easy local server setup with tunneling capabilities.
|
|
43
|
+
|
|
44
|
+
## Features
|
|
45
|
+
|
|
46
|
+
- 🔌 **Framework Adapters**: Support for multiple AI agent frameworks (LangChain, Pydantic AI, Agno, Google ADK, OpenAI Agents, Smolagents, AWS Bedrock, Flowise, Langflow, N8n, and more)
|
|
47
|
+
- 📊 **Automatic Tracing**: Built-in OpenInference-based (OpenTelemetry-based tracing support coming soon) tracing for agent trajectory evaluation. Track token usage, costs, latency, and model information for each agent invocation
|
|
48
|
+
- 🚀 **Local Server**: Easy-to-use local server with optional tunneling (Cloudflare/ngrok) for public access and integration with Quraite platform
|
|
49
|
+
|
|
50
|
+
## Installation
|
|
51
|
+
|
|
52
|
+
### Basic Installation
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
pip install quraite
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Framework-Specific Installation
|
|
59
|
+
|
|
60
|
+
Install with optional dependencies for specific frameworks:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# LangChain
|
|
64
|
+
pip install 'quraite[langchain]'
|
|
65
|
+
|
|
66
|
+
# Pydantic AI
|
|
67
|
+
pip install 'quraite[pydantic-ai]'
|
|
68
|
+
|
|
69
|
+
# Agno
|
|
70
|
+
pip install 'quraite[agno]'
|
|
71
|
+
|
|
72
|
+
# Google ADK
|
|
73
|
+
pip install 'quraite[google-adk]'
|
|
74
|
+
|
|
75
|
+
# OpenAI Agents
|
|
76
|
+
pip install 'quraite[openai-agents]'
|
|
77
|
+
|
|
78
|
+
# Smolagents
|
|
79
|
+
pip install 'quraite[smolagents]'
|
|
80
|
+
|
|
81
|
+
# AWS Bedrock
|
|
82
|
+
pip install 'quraite[bedrock]'
|
|
83
|
+
|
|
84
|
+
# Multiple frameworks
|
|
85
|
+
pip install 'quraite[langchain,pydantic-ai,agno]'
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Quick Start
|
|
89
|
+
|
|
90
|
+
### Example: LangChain Agent with Local Server
|
|
91
|
+
|
|
92
|
+
Pass your compiled LangChain agent to the adapter and expose it as an HTTP API:
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
import asyncio
|
|
96
|
+
import uvicorn
|
|
97
|
+
from dotenv import load_dotenv
|
|
98
|
+
from openinference.instrumentation import TracerProvider
|
|
99
|
+
from openinference.instrumentation.langchain import LangChainInstrumentor
|
|
100
|
+
|
|
101
|
+
from quraite.adapters import LangChainAdapter
|
|
102
|
+
from quraite.serve.local_agent import LocalAgentServer
|
|
103
|
+
from quraite.tracing.span_exporter import QuraiteInMemorySpanExporter
|
|
104
|
+
from quraite.tracing.span_processor import QuraiteSimpleSpanProcessor
|
|
105
|
+
|
|
106
|
+
load_dotenv()
|
|
107
|
+
|
|
108
|
+
# Set up tracing
|
|
109
|
+
# Use Quraite's in-memory span exporter to capture the agent trajectory
|
|
110
|
+
# and use it for evaluation.
|
|
111
|
+
tracer_provider = TracerProvider()
|
|
112
|
+
quraite_span_exporter = QuraiteInMemorySpanExporter()
|
|
113
|
+
quraite_span_processor = QuraiteSimpleSpanProcessor(quraite_span_exporter)
|
|
114
|
+
tracer_provider.add_span_processor(quraite_span_processor)
|
|
115
|
+
LangChainInstrumentor().instrument(tracer_provider=tracer_provider)
|
|
116
|
+
|
|
117
|
+
# Your compiled LangChain agent (created elsewhere)
|
|
118
|
+
# agent = create_agent(...)
|
|
119
|
+
|
|
120
|
+
# Wrap with Quraite adapter
|
|
121
|
+
adapter = LangChainAdapter(
|
|
122
|
+
agent_graph=agent, # Pass your compiled LangChain agent here
|
|
123
|
+
tracer_provider=tracer_provider,
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
# Create and start server with Cloudflare tunnel
|
|
127
|
+
server = LocalAgentServer(
|
|
128
|
+
wrapped_agent=adapter,
|
|
129
|
+
agent_id="your-agent-id", # Optional: for Quraite platform integration
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
app = server.create_app(
|
|
133
|
+
port=8080,
|
|
134
|
+
host="0.0.0.0",
|
|
135
|
+
tunnel="cloudflare", # Options: "cloudflare", "ngrok", or "none"
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
# Option 1: Use the start method to start the server
|
|
139
|
+
asyncio.run(server.start(host="0.0.0.0", port=8080))
|
|
140
|
+
|
|
141
|
+
# Option 2: Use uvicorn to start the server for auto-reload
|
|
142
|
+
# if __name__ == "__main__":
|
|
143
|
+
# uvicorn.run("local_server:app", host="0.0.0.0", port=8080, reload=True)
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
The server exposes:
|
|
147
|
+
|
|
148
|
+
- `GET /` - Health check endpoint
|
|
149
|
+
- `POST /v1/agents/completions` - Agent invocation endpoint. This is the endpoint that Quraite will use to invoke your agent.
|
|
150
|
+
|
|
151
|
+
When using `tunnel="cloudflare"` or `tunnel="ngrok"`, your agent will be publicly accessible via the generated URL.
|
|
152
|
+
|
|
153
|
+
## Supported Frameworks
|
|
154
|
+
|
|
155
|
+
| Framework | Adapter | Installation |
|
|
156
|
+
| -------------------- | ------------------------ | -------------------------------------- |
|
|
157
|
+
| **LangChain** | `LangChainAdapter` | `pip install 'quraite[langchain]'` |
|
|
158
|
+
| **Pydantic AI** | `PydanticAIAdapter` | `pip install 'quraite[pydantic-ai]'` |
|
|
159
|
+
| **Agno** | `AgnoAdapter` | `pip install 'quraite[agno]'` |
|
|
160
|
+
| **Google ADK** | `GoogleADKAdapter` | `pip install 'quraite[google-adk]'` |
|
|
161
|
+
| **OpenAI Agents** | `OpenaiAgentsAdapter` | `pip install 'quraite[openai-agents]'` |
|
|
162
|
+
| **Smolagents** | `SmolagentsAdapter` | `pip install 'quraite[smolagents]'` |
|
|
163
|
+
| **AWS Bedrock** | `BedrockAgentsAdapter` | `pip install 'quraite[bedrock]'` |
|
|
164
|
+
| **Flowise** | `FlowiseAdapter` | Included in base package |
|
|
165
|
+
| **Langflow** | `LangflowAdapter` | Included in base package |
|
|
166
|
+
| **N8n** | `N8nAdapter` | Included in base package |
|
|
167
|
+
| **HTTP** | `HttpAdapter` | Included in base package |
|
|
168
|
+
| **LangChain Server** | `LangChainServerAdapter` | `pip install 'quraite[langchain]'` |
|
|
169
|
+
|
|
170
|
+
## Core Concepts
|
|
171
|
+
|
|
172
|
+
### Adapters
|
|
173
|
+
|
|
174
|
+
Adapters provide a unified interface (`BaseAdapter`) for different agent frameworks. Each adapter converts framework-specific agent response formats to the Quraite agent message format.
|
|
175
|
+
|
|
176
|
+
If you are building your own agent framework, you can create a custom adapter by extending the `BaseAdapter` class and implementing the `ainvoke` method.
|
|
177
|
+
|
|
178
|
+
### Tracing for Agent Trajectory Evaluation
|
|
179
|
+
|
|
180
|
+
**Capture agent trajectories without modifying your code.** Get comprehensive trace data including token usage, costs, and latency for every agent step.
|
|
181
|
+
|
|
182
|
+
Most agent frameworks return agent steps, but lack critical observability data. We solve this with **OpenInference instrumentation** (OpenTelemetry instrumentation support coming soon) that automatically captures:
|
|
183
|
+
|
|
184
|
+
- Complete agent trajectories
|
|
185
|
+
- Token usage and costs
|
|
186
|
+
- Step-by-step latency
|
|
187
|
+
- Full execution context
|
|
188
|
+
|
|
189
|
+
**Works with your existing setup.** We provide OpenInference-compatible span exporters and processors that integrate seamlessly with your current observability platform - no vendor lock-in required.
|
|
190
|
+
|
|
191
|
+
To enable tracing:
|
|
192
|
+
|
|
193
|
+
```python
|
|
194
|
+
from openinference.instrumentation import TracerProvider
|
|
195
|
+
from quraite.tracing.span_exporter import QuraiteInMemorySpanExporter
|
|
196
|
+
from quraite.tracing.span_processor import QuraiteSimpleSpanProcessor
|
|
197
|
+
|
|
198
|
+
tracer_provider = TracerProvider()
|
|
199
|
+
|
|
200
|
+
# Add Quraite span exporter and processor to the tracer provider
|
|
201
|
+
quraite_span_exporter = QuraiteInMemorySpanExporter()
|
|
202
|
+
quraite_span_processor = QuraiteSimpleSpanProcessor(quraite_span_exporter)
|
|
203
|
+
tracer_provider.add_span_processor(quraite_span_processor)
|
|
204
|
+
|
|
205
|
+
# Instrument your framework with OpenInference
|
|
206
|
+
from openinference.instrumentation.langchain import LangChainInstrumentor
|
|
207
|
+
LangChainInstrumentor().instrument(tracer_provider=tracer_provider)
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Message Schema
|
|
211
|
+
|
|
212
|
+
The SDK uses a standardized message format:
|
|
213
|
+
|
|
214
|
+
```python
|
|
215
|
+
from quraite.schema.message import (
|
|
216
|
+
UserMessage,
|
|
217
|
+
AssistantMessage,
|
|
218
|
+
ToolMessage,
|
|
219
|
+
SystemMessage,
|
|
220
|
+
MessageContentText,
|
|
221
|
+
ToolCall,
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
# User message
|
|
225
|
+
user_msg = UserMessage(
|
|
226
|
+
content=[MessageContentText(text="Hello, world!")]
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
# Assistant message with tool calls
|
|
230
|
+
assistant_msg = AssistantMessage(
|
|
231
|
+
content=[MessageContentText(text="I'll calculate that for you.")],
|
|
232
|
+
tool_calls=[
|
|
233
|
+
ToolCall(
|
|
234
|
+
id="call_123",
|
|
235
|
+
name="add",
|
|
236
|
+
arguments={"a": 10, "b": 5}
|
|
237
|
+
)
|
|
238
|
+
]
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
# Tool message
|
|
242
|
+
tool_msg = ToolMessage(
|
|
243
|
+
tool_call_id="call_123",
|
|
244
|
+
content=[MessageContentText(text="15")]
|
|
245
|
+
)
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### Response Format
|
|
249
|
+
|
|
250
|
+
Agent invocations return an `AgentInvocationResponse`:
|
|
251
|
+
|
|
252
|
+
```python
|
|
253
|
+
from quraite.schema.response import AgentInvocationResponse
|
|
254
|
+
|
|
255
|
+
response: AgentInvocationResponse = await adapter.ainvoke(
|
|
256
|
+
input=[user_msg],
|
|
257
|
+
session_id="session-123"
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
# Access trajectory (list of messages)
|
|
261
|
+
trajectory = response.agent_trajectory
|
|
262
|
+
|
|
263
|
+
# Access trace
|
|
264
|
+
trace = response.agent_trace
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## Examples
|
|
268
|
+
|
|
269
|
+
The repository includes comprehensive examples for each supported framework:
|
|
270
|
+
|
|
271
|
+
- [`langchain_calculator_agent`](examples/langchain_calculator_agent/) - LangChain calculator agent
|
|
272
|
+
- [`pydantic_calculator_agent`](examples/pydantic_calculator_agent/) - Pydantic AI calculator agent
|
|
273
|
+
- [`agno_calculator_agent`](examples/agno_calculator_agent/) - Agno calculator agent
|
|
274
|
+
- [`google_adk_weather_agent`](examples/google_adk_weather_agent/) - Google ADK weather agent
|
|
275
|
+
- [`openai_flight_booking_agent`](examples/openai_flight_booking_agent/) - OpenAI Agents flight booking
|
|
276
|
+
- [`smolagents_sql_agent`](examples/smolagents_sql_agent/) - Smolagents SQL agent
|
|
277
|
+
- [`bedrock_restaurant_support_agent`](examples/bedrock_restaurant_support_agent/) - AWS Bedrock agent
|
|
278
|
+
- And more...
|
|
279
|
+
|
|
280
|
+
Each example includes:
|
|
281
|
+
|
|
282
|
+
- Agent implementation
|
|
283
|
+
- Adapter setup
|
|
284
|
+
- Local server configuration
|
|
285
|
+
- Environment variable examples
|
|
286
|
+
|
|
287
|
+
## API Reference
|
|
288
|
+
|
|
289
|
+
### BaseAdapter
|
|
290
|
+
|
|
291
|
+
All adapters inherit from `BaseAdapter`:
|
|
292
|
+
|
|
293
|
+
```python
|
|
294
|
+
from quraite.adapters.base import BaseAdapter
|
|
295
|
+
|
|
296
|
+
class MyAdapter(BaseAdapter):
|
|
297
|
+
async def ainvoke(
|
|
298
|
+
self,
|
|
299
|
+
input: List[AgentMessage],
|
|
300
|
+
session_id: str | None,
|
|
301
|
+
) -> AgentInvocationResponse:
|
|
302
|
+
# Implementation
|
|
303
|
+
pass
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### LocalAgentServer
|
|
307
|
+
|
|
308
|
+
Create a local HTTP server for your agent:
|
|
309
|
+
|
|
310
|
+
```python
|
|
311
|
+
import asyncio
|
|
312
|
+
from quraite.serve.local_agent import LocalAgentServer
|
|
313
|
+
|
|
314
|
+
server = LocalAgentServer(
|
|
315
|
+
wrapped_agent=adapter,
|
|
316
|
+
agent_id="optional-agent-id",
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
app = server.create_app(
|
|
320
|
+
port=8080,
|
|
321
|
+
host="0.0.0.0",
|
|
322
|
+
tunnel="cloudflare", # or "ngrok" or "none"
|
|
323
|
+
)
|
|
324
|
+
|
|
325
|
+
asyncio.run(server.start(host="0.0.0.0", port=8080))
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
## Development
|
|
329
|
+
|
|
330
|
+
### Setup
|
|
331
|
+
|
|
332
|
+
```bash
|
|
333
|
+
# Clone the repository
|
|
334
|
+
git clone https://github.com/innowhyte/quraite-python.git
|
|
335
|
+
cd quraite-python
|
|
336
|
+
|
|
337
|
+
# Install dependencies
|
|
338
|
+
pip install -e ".[dev,test]"
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
### Running Tests
|
|
342
|
+
|
|
343
|
+
```bash
|
|
344
|
+
pytest
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
### Building
|
|
348
|
+
|
|
349
|
+
```bash
|
|
350
|
+
make build
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
### Publishing
|
|
354
|
+
|
|
355
|
+
```bash
|
|
356
|
+
# Update version
|
|
357
|
+
make update-version v=0.4.0
|
|
358
|
+
|
|
359
|
+
# Build
|
|
360
|
+
make build
|
|
361
|
+
|
|
362
|
+
# Publish to Test PyPI
|
|
363
|
+
make publish
|
|
364
|
+
# Enter username as "__token__" and then enter your API key
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
## Requirements
|
|
368
|
+
|
|
369
|
+
- Python 3.10+
|
|
370
|
+
- See `pyproject.toml` for full dependency list
|
|
371
|
+
|
|
372
|
+
## License
|
|
373
|
+
|
|
374
|
+
See [LICENSE](LICENSE) file for details.
|
|
375
|
+
|
|
376
|
+
## Contributing
|
|
377
|
+
|
|
378
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
379
|
+
|
|
380
|
+
## Support
|
|
381
|
+
|
|
382
|
+
For issues, questions, or contributions, please visit the [Quraite platform](https://quraite.ai) or open an issue on GitHub.
|
|
383
|
+
|
|
384
|
+
## Changelog
|
|
385
|
+
|
|
386
|
+
See the repository's commit history for detailed changes.
|