deeprails 0.2.1__py3-none-any.whl → 0.3.1__py3-none-any.whl

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.

Potentially problematic release.


This version of deeprails might be problematic. Click here for more details.

deeprails/client.py CHANGED
@@ -8,6 +8,7 @@ class DeepRails:
8
8
  """
9
9
  Python SDK client for the DeepRails API.
10
10
  """
11
+
11
12
  def __init__(self, token: str, base_url: str = "https://api.deeprails.com"):
12
13
  """
13
14
  Initializes the DeepRails client.
@@ -23,10 +24,11 @@ class DeepRails:
23
24
  self._headers = {
24
25
  "Authorization": f"Bearer {token}",
25
26
  "Content-Type": "application/json",
26
- "User-Agent": "deeprails-python-sdk/0.2.0"
27
+ "User-Agent": "deeprails-python-sdk/0.3.0"
27
28
  }
28
29
  self._client = httpx.Client(base_url=self._base_url, headers=self._headers, timeout=30.0)
29
30
 
31
+
30
32
  def _request(self, method: str, endpoint: str, **kwargs) -> httpx.Response:
31
33
  """Helper method to make requests and handle API errors."""
32
34
  try:
@@ -43,6 +45,7 @@ class DeepRails:
43
45
  except httpx.RequestError as e:
44
46
  raise DeepRailsAPIError(status_code=500, error_detail=f"Request failed: {e}") from e
45
47
 
48
+
46
49
  def create_evaluation(
47
50
  self,
48
51
  *,
@@ -87,6 +90,7 @@ class DeepRails:
87
90
  response = self._request("POST", "/evaluate", json=json_payload)
88
91
  return EvaluationResponse.parse_obj(response.json())
89
92
 
93
+
90
94
  def get_evaluation(self, eval_id: str) -> EvaluationResponse:
91
95
  """
92
96
  Retrieves the status and results of a specific evaluation.
@@ -98,4 +102,184 @@ class DeepRails:
98
102
  An EvaluationResponse object with the full, up-to-date details of the evaluation.
99
103
  """
100
104
  response = self._request("GET", f"/evaluate/{eval_id}")
101
- return EvaluationResponse.parse_obj(response.json())
105
+ return EvaluationResponse.parse_obj(response.json())
106
+
107
+
108
+ def create_monitor(
109
+ self,
110
+ *,
111
+ name: str,
112
+ description: Optional[str] = None
113
+ ) -> MonitorResponse:
114
+ """
115
+ Creates a new monitor for tracking AI responses.
116
+
117
+ Args:
118
+ name: A name for the monitor.
119
+ description: Optional description of the monitor's purpose.
120
+
121
+ Returns:
122
+ A MonitorResponse object with the details of the created monitor.
123
+ """
124
+ payload = {
125
+ "name": name,
126
+ "description": description
127
+ }
128
+
129
+ # Remove None values
130
+ json_payload = {k: v for k, v in payload.items() if v is not None}
131
+
132
+ response = self._request("POST", "/monitor", json=json_payload)
133
+ response_json = response.json()
134
+
135
+ # Handle DeepRails API response structure
136
+ if "data" in response_json:
137
+ return MonitorResponse.parse_obj(response_json["data"])
138
+ else:
139
+ return MonitorResponse.parse_obj(response_json)
140
+
141
+ def get_monitor(self, monitor_id: str) -> MonitorResponse:
142
+ """
143
+ Get details of a specific monitor.
144
+
145
+ Args:
146
+ monitor_id: The ID of the monitor to retrieve.
147
+
148
+ Returns:
149
+ A MonitorResponse object with the monitor details.
150
+ """
151
+ response = self._request("GET", f"/monitor/{monitor_id}")
152
+ response_json = response.json()
153
+
154
+ # Handle DeepRails API response structure
155
+ if "data" in response_json:
156
+ return MonitorResponse.parse_obj(response_json["data"])
157
+ else:
158
+ return MonitorResponse.parse_obj(response_json)
159
+
160
+ def create_monitor_event(
161
+ self,
162
+ *,
163
+ monitor_id: str,
164
+ model_input: Dict[str, Any],
165
+ model_output: str,
166
+ guardrail_metrics: List[str],
167
+ model_used: Optional[str] = None,
168
+ run_mode: Optional[str] = None,
169
+ nametag: Optional[str] = None,
170
+ webhook: Optional[str] = None
171
+ ) -> MonitorEventResponse:
172
+ """
173
+ Creates a new event for a monitor.
174
+
175
+ Args:
176
+ monitor_id: The ID of the monitor to create an event for.
177
+ model_input: A dictionary containing the inputs for the model.
178
+ model_output: The response generated by the model you are evaluating.
179
+ guardrail_metrics: A list of metrics to evaluate.
180
+ model_used: The name or identifier of the model being evaluated.
181
+ run_mode: The evaluation mode (e.g., "smart", "dev").
182
+ nametag: A user-defined name or tag for the event.
183
+ webhook: A URL to send a POST request to upon evaluation completion.
184
+
185
+ Returns:
186
+ A MonitorEventResponse object with the details of the created event.
187
+ """
188
+ payload = {
189
+ "model_input": model_input,
190
+ "model_output": model_output,
191
+ "model_used": model_used,
192
+ "run_mode": run_mode,
193
+ "guardrail_metrics": guardrail_metrics,
194
+ "nametag": nametag,
195
+ "webhook": webhook,
196
+ }
197
+
198
+ # Remove None values
199
+ json_payload = {k: v for k, v in payload.items() if v is not None}
200
+
201
+ response = self._request("POST", f"/monitor/{monitor_id}/events", json=json_payload)
202
+ response_json = response.json()
203
+
204
+ # Handle DeepRails API response structure
205
+ if "data" in response_json:
206
+ return MonitorEventResponse.parse_obj(response_json["data"])
207
+ else:
208
+ return MonitorEventResponse.parse_obj(response_json)
209
+
210
+ def get_monitor_events(
211
+ self,
212
+ monitor_id: str,
213
+ limit: int = 10,
214
+ offset: int = 0
215
+ ) -> List[MonitorEventResponse]:
216
+ """
217
+ Retrieves events for a specific monitor.
218
+
219
+ Args:
220
+ monitor_id: The ID of the monitor to get events for.
221
+ limit: Maximum number of events to return (default: 10).
222
+ offset: Offset for pagination (default: 0).
223
+
224
+ Returns:
225
+ A list of MonitorEventResponse objects with details of the monitor events.
226
+ """
227
+ params = {
228
+ "limit": limit,
229
+ "offset": offset
230
+ }
231
+
232
+ response = self._request("GET", f"/monitor/{monitor_id}/events", params=params)
233
+ response_json = response.json()
234
+
235
+ # Handle DeepRails API response structure
236
+ if "data" in response_json and isinstance(response_json["data"], list):
237
+ return [MonitorEventResponse.parse_obj(event) for event in response_json["data"]]
238
+ else:
239
+ # Fallback if the response structure is unexpected
240
+ return []
241
+
242
+ def get_monitors(
243
+ self,
244
+ *,
245
+ page: int = 1,
246
+ limit: int = 20,
247
+ search: Optional[List[str]] = None,
248
+ monitor_status: Optional[List[str]] = None,
249
+ date_from: Optional[str] = None,
250
+ date_to: Optional[str] = None,
251
+ sort_by: str = "created_at",
252
+ sort_order: str = "desc"
253
+ ) -> MonitorListResponse:
254
+ """
255
+ Get a paginated list of monitors with optional filtering.
256
+
257
+ Args:
258
+ page: Page number for pagination (default: 1)
259
+ limit: Number of items per page (default: 20, max: 100)
260
+ search: Optional list of free-text search terms
261
+ monitor_status: Optional list of monitor statuses ("active", "inactive", "all")
262
+ date_from: Optional filter for monitors from this date (ISO format)
263
+ date_to: Optional filter for monitors to this date (ISO format)
264
+ sort_by: Field to sort by (default: "created_at")
265
+ sort_order: Sort order (default: "desc")
266
+
267
+ Returns:
268
+ A MonitorListResponse object containing monitors, pagination info, and applied filters.
269
+ """
270
+ params = {
271
+ "page": page,
272
+ "limit": limit,
273
+ "sort_by": sort_by,
274
+ "sort_order": sort_order,
275
+ "search": search,
276
+ "monitor_status": monitor_status,
277
+ "date_from": date_from,
278
+ "date_to": date_to
279
+ }
280
+
281
+ # Remove None values
282
+ params = {k: v for k, v in params.items() if v is not None}
283
+
284
+ response = self._request("GET", "/monitor", params=params)
285
+ return MonitorListResponse.parse_obj(response.json())
deeprails/schemas.py CHANGED
@@ -27,4 +27,66 @@ class EvaluationResponse(BaseModel):
27
27
  modified_at: Optional[datetime] = None
28
28
 
29
29
  class Config:
30
- extra = 'ignore'
30
+ extra = 'ignore'
31
+
32
+ class MonitorResponse(BaseModel):
33
+ """Represents a monitor from the DeepRails API."""
34
+ monitor_id: str
35
+ user_id: str
36
+ name: str
37
+ description: Optional[str] = None
38
+ monitor_status: str
39
+ created_at: str
40
+ updated_at: str
41
+
42
+ class Config:
43
+ extra = 'ignore'
44
+
45
+ class MonitorEventCreate(BaseModel):
46
+ """Model for creating a new monitor event."""
47
+ model_input: Dict[str, Any]
48
+ model_output: str
49
+ model_used: Optional[str] = None
50
+ run_mode: Optional[str] = None
51
+ guardrail_metrics: List[str]
52
+ nametag: Optional[str] = None
53
+ webhook: Optional[str] = None
54
+
55
+ class MonitorEventResponse(BaseModel):
56
+ """Response model for a monitor event."""
57
+ event_id: str
58
+ monitor_id: str
59
+ evaluation_id: str
60
+ created_at: str
61
+
62
+ class Config:
63
+ extra = 'ignore'
64
+
65
+ class PaginationInfo(BaseModel):
66
+ """Pagination information for list responses."""
67
+ page: int
68
+ limit: int
69
+ total_pages: int
70
+ total_count: int
71
+ has_next: bool
72
+ has_previous: bool
73
+
74
+ class MonitorFiltersApplied(BaseModel):
75
+ """Information about which filters were applied to the monitor query."""
76
+ search: Optional[List[str]] = None
77
+ status: Optional[List[str]] = None
78
+ date_from: Optional[str] = None
79
+ date_to: Optional[str] = None
80
+ sort_by: Optional[str] = None
81
+ sort_order: Optional[str] = None
82
+
83
+ class MonitorWithEventCountResponse(MonitorResponse):
84
+ """Monitor response with event count information."""
85
+ event_count: int
86
+ latest_event_modified_at: Optional[str] = None
87
+
88
+ class MonitorListResponse(BaseModel):
89
+ """Response model for a paginated list of monitors."""
90
+ monitors: List[MonitorWithEventCountResponse]
91
+ pagination: PaginationInfo
92
+ filters_applied: MonitorFiltersApplied
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deeprails
3
- Version: 0.2.1
3
+ Version: 0.3.1
4
4
  Summary: Python SDK for interacting with the DeepRails API
5
5
  Project-URL: Homepage, https://deeprails.com
6
6
  Project-URL: Documentation, https://docs.deeprails.com
@@ -35,7 +35,9 @@ Description-Content-Type: text/markdown
35
35
 
36
36
  # DeepRails Python SDK
37
37
 
38
- A lightweight, intuitive Python SDK for interacting with the DeepRails API. DeepRails helps you evaluate and improve AI-generated outputs through a comprehensive set of guardrail metrics.
38
+ Official Python SDK for interacting with the DeepRails API. [DeepRails](https://deeprails.com) is a powerful developer tool with a comprehesive set of adaptive guardrails to protect against LLM hallucinations - deploy our Evaluate, Monitor, and Defend APIs in <15 mins for the best out-of-the-box guardrails in the market.
39
+
40
+ Supports DeepRails API Version v2.0
39
41
 
40
42
  ## Installation
41
43
 
@@ -55,12 +57,17 @@ client = DeepRails(token="YOUR_API_KEY")
55
57
  evaluation = client.create_evaluation(
56
58
  model_input={"user_prompt": "Prompt used to generate completion"},
57
59
  model_output="Generated output",
58
- model_used="gpt-4o-mini (LLM used to generate completion)",
60
+ model_used="gpt-4o-mini",
59
61
  guardrail_metrics=["correctness", "completeness"]
60
62
  )
61
-
62
- # Print evaluation ID
63
63
  print(f"Evaluation created with ID: {evaluation.eval_id}")
64
+
65
+ # Create a monitor
66
+ monitor = client.create_monitor(
67
+ name="Production Assistant Monitor",
68
+ description="Tracking our production assistant quality"
69
+ )
70
+ print(f"Monitor created with ID: {monitor.monitor_id}")
64
71
  ```
65
72
 
66
73
  ## Features
@@ -69,6 +76,7 @@ print(f"Evaluation created with ID: {evaluation.eval_id}")
69
76
  - **Comprehensive Metrics**: Evaluate outputs on correctness, completeness, and more
70
77
  - **Real-time Progress**: Track evaluation progress in real-time
71
78
  - **Detailed Results**: Get detailed scores and rationales for each metric
79
+ - **Continuous Monitoring**: Create monitors to track AI system performance over time
72
80
 
73
81
  ## Authentication
74
82
 
@@ -81,14 +89,16 @@ token = os.environ.get("DEEPRAILS_API_KEY")
81
89
  client = DeepRails(token=token)
82
90
  ```
83
91
 
84
- ## Creating Evaluations
92
+ ## Evaluation Service
93
+
94
+ ### Creating Evaluations
85
95
 
86
96
  ```python
87
97
  try:
88
98
  evaluation = client.create_evaluation(
89
99
  model_input={"user_prompt": "Prompt used to generate completion"},
90
100
  model_output="Generated output",
91
- model_used="gpt-4o-mini (LLM used to generate completion)",
101
+ model_used="gpt-4o-mini",
92
102
  guardrail_metrics=["correctness", "completeness"]
93
103
  )
94
104
  print(f"ID: {evaluation.eval_id}")
@@ -98,7 +108,7 @@ except Exception as e:
98
108
  print(f"Error: {e}")
99
109
  ```
100
110
 
101
- ### Parameters
111
+ #### Parameters
102
112
 
103
113
  - `model_input`: Dictionary containing the prompt and any context (must include `user_prompt`)
104
114
  - `model_output`: The generated output to evaluate
@@ -108,7 +118,7 @@ except Exception as e:
108
118
  - `nametag`: (Optional) Custom identifier for this evaluation
109
119
  - `webhook`: (Optional) URL to receive completion notifications
110
120
 
111
- ## Retrieving Evaluations
121
+ ### Retrieving Evaluations
112
122
 
113
123
  ```python
114
124
  try:
@@ -126,6 +136,76 @@ except Exception as e:
126
136
  print(f"Error: {e}")
127
137
  ```
128
138
 
139
+ ## Monitor Service
140
+
141
+ ### Creating Monitors
142
+
143
+ ```python
144
+ try:
145
+ # Create a monitor
146
+ monitor = client.create_monitor(
147
+ name="Production Chat Assistant Monitor",
148
+ description="Monitoring our production chatbot responses"
149
+ )
150
+
151
+ print(f"Monitor created with ID: {monitor.monitor_id}")
152
+ except Exception as e:
153
+ print(f"Error: {e}")
154
+ ```
155
+
156
+ ### Logging Monitor Events
157
+
158
+ ```python
159
+ try:
160
+ # Add an event to the monitor
161
+ event = client.create_monitor_event(
162
+ monitor_id="mon-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
163
+ model_input={"user_prompt": "Tell me about renewable energy"},
164
+ model_output="Renewable energy comes from natural sources...",
165
+ model_used="gpt-4o-mini",
166
+ guardrail_metrics=["correctness", "completeness", "comprehensive_safety"]
167
+ )
168
+
169
+ print(f"Monitor event created with ID: {event.event_id}")
170
+ print(f"Associated evaluation ID: {event.evaluation_id}")
171
+ except Exception as e:
172
+ print(f"Error: {e}")
173
+ ```
174
+
175
+ ### Retrieving Monitor Data
176
+
177
+ ```python
178
+ try:
179
+ # Get monitor details
180
+ monitor = client.get_monitor("mon-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")
181
+ print(f"Monitor name: {monitor.name}")
182
+ print(f"Status: {monitor.monitor_status}")
183
+
184
+ # Get monitor events
185
+ events = client.get_monitor_events(
186
+ monitor_id="mon-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
187
+ limit=10
188
+ )
189
+
190
+ for event in events:
191
+ print(f"Event ID: {event.event_id}")
192
+ print(f"Evaluation ID: {event.evaluation_id}")
193
+
194
+ # List all monitors with filtering
195
+ monitors = client.get_monitors(
196
+ limit=5,
197
+ monitor_status=["active"],
198
+ sort_by="created_at",
199
+ sort_order="desc"
200
+ )
201
+
202
+ print(f"Total monitors: {monitors.pagination.total_count}")
203
+ for m in monitors.monitors:
204
+ print(f"{m.name}: {m.event_count} events")
205
+ except Exception as e:
206
+ print(f"Error: {e}")
207
+ ```
208
+
129
209
  ## Available Metrics
130
210
 
131
211
  - `correctness`: Measures factual accuracy by evaluating whether each claim in the output is true and verifiable.
@@ -135,7 +215,6 @@ except Exception as e:
135
215
  - `ground_truth_adherence`: Measures how closely the output matches a known correct answer (gold standard).
136
216
  - `comprehensive_safety`: Detects and categorizes safety violations across areas like PII, CBRN, hate speech, self-harm, and more.
137
217
 
138
-
139
218
  ## Error Handling
140
219
 
141
220
  The SDK throws `DeepRailsAPIError` for API-related errors, with status code and detailed message.
@@ -0,0 +1,8 @@
1
+ deeprails/__init__.py,sha256=7ccTz1heYcCd3DIH3wmHc67FD6CUzM8_J4WmDeq0RZ0,29
2
+ deeprails/client.py,sha256=Jv4Z4LR3g_eYO4L86sabOAibHJGV9p8naDOl1Yw-2L0,10406
3
+ deeprails/exceptions.py,sha256=ipwFq4lROv7XpcBC5h9cGqPf6f68zeOMEyKPVy7H0co,405
4
+ deeprails/schemas.py,sha256=XqBUFNEW4nwxm53YIUWVk4fEPsDGC6gzzXGL9lPuRAU,2870
5
+ deeprails-0.3.1.dist-info/METADATA,sha256=uPQ35AwbQiucWBX5STCIUw76PsVksQskx5F_1fPvp3A,8538
6
+ deeprails-0.3.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
7
+ deeprails-0.3.1.dist-info/licenses/LICENSE,sha256=GsV7lN6fihCcDgkJbfs0rq1q9d6IyB0TFQ8HLKUpSXM,1077
8
+ deeprails-0.3.1.dist-info/RECORD,,
@@ -1,8 +0,0 @@
1
- deeprails/__init__.py,sha256=7ccTz1heYcCd3DIH3wmHc67FD6CUzM8_J4WmDeq0RZ0,29
2
- deeprails/client.py,sha256=gm3aq5FQj7qpLbWeyKkew3gbRI0l9QyGhvk7m0N7JxU,4004
3
- deeprails/exceptions.py,sha256=ipwFq4lROv7XpcBC5h9cGqPf6f68zeOMEyKPVy7H0co,405
4
- deeprails/schemas.py,sha256=pqZ-J7mIVdYe-q8sPSw07fe3H4YFCYb-PrshA_qU8RU,1113
5
- deeprails-0.2.1.dist-info/METADATA,sha256=Ha9Aa6LpmLYOgdNOupfDECI-47kpH_QMQZpc4ZJZHhg,6222
6
- deeprails-0.2.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
7
- deeprails-0.2.1.dist-info/licenses/LICENSE,sha256=GsV7lN6fihCcDgkJbfs0rq1q9d6IyB0TFQ8HLKUpSXM,1077
8
- deeprails-0.2.1.dist-info/RECORD,,