morphik 0.1.5__py3-none-any.whl → 0.1.6__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.
morphik/models.py CHANGED
@@ -2,7 +2,7 @@ from datetime import datetime
2
2
  from pathlib import Path
3
3
  from typing import Any, BinaryIO, Dict, List, Literal, Optional, Union
4
4
 
5
- from pydantic import BaseModel, Field, field_validator, model_validator
5
+ from pydantic import BaseModel, Field, PrivateAttr, field_validator, model_validator
6
6
 
7
7
 
8
8
  class Document(BaseModel):
@@ -285,6 +285,7 @@ class Graph(BaseModel):
285
285
  entities: List[Entity] = Field(default_factory=list, description="Entities in the graph")
286
286
  relationships: List[Relationship] = Field(default_factory=list, description="Relationships in the graph")
287
287
  metadata: Dict[str, Any] = Field(default_factory=dict, description="Graph metadata")
288
+ system_metadata: Dict[str, Any] = Field(default_factory=dict, description="System-managed metadata")
288
289
  document_ids: List[str] = Field(default_factory=list, description="Source document IDs")
289
290
  filters: Optional[Dict[str, Any]] = Field(None, description="Document filters used to create the graph")
290
291
  created_at: datetime = Field(..., description="Creation timestamp")
@@ -292,6 +293,47 @@ class Graph(BaseModel):
292
293
  owner: Dict[str, str] = Field(default_factory=dict, description="Graph owner information")
293
294
  access_control: Dict[str, List[str]] = Field(default_factory=dict, description="Access control information")
294
295
 
296
+ _client: Any | None = PrivateAttr(default=None)
297
+
298
+ # ---------------- Convenience helpers ----------------
299
+ @property
300
+ def status(self) -> str | None:
301
+ """Return processing status if available."""
302
+ return self.system_metadata.get("status") if self.system_metadata else None
303
+
304
+ @property
305
+ def is_processing(self) -> bool:
306
+ return self.status == "processing"
307
+
308
+ @property
309
+ def is_completed(self) -> bool:
310
+ return self.status == "completed"
311
+
312
+ @property
313
+ def is_failed(self) -> bool:
314
+ return self.status == "failed"
315
+
316
+ @property
317
+ def error(self) -> str | None:
318
+ return self.system_metadata.get("error") if self.system_metadata else None
319
+
320
+ def wait_for_completion(self, timeout_seconds: int = 300, check_interval_seconds: int = 5) -> "Graph":
321
+ """Poll the server until the graph processing is finished."""
322
+ import time
323
+
324
+ if not self._client:
325
+ raise RuntimeError("Graph object has no client reference for polling")
326
+
327
+ start = time.time()
328
+ while time.time() - start < timeout_seconds:
329
+ refreshed = self._client.get_graph(self.name)
330
+ if refreshed.is_completed:
331
+ return refreshed
332
+ if refreshed.is_failed:
333
+ raise RuntimeError(refreshed.error or "Graph creation failed")
334
+ time.sleep(check_interval_seconds)
335
+ raise TimeoutError("Timed out waiting for graph completion")
336
+
295
337
 
296
338
  class EntityExtractionExample(BaseModel):
297
339
  """