sinas 0.1.0__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.
sinas/state.py ADDED
@@ -0,0 +1,164 @@
1
+ """Runtime State API."""
2
+
3
+ from typing import TYPE_CHECKING, Any, Dict, List, Optional
4
+
5
+ if TYPE_CHECKING:
6
+ from sinas.client import SinasClient
7
+
8
+
9
+ class StateAPI:
10
+ """Runtime State API methods."""
11
+
12
+ def __init__(self, client: "SinasClient") -> None:
13
+ self._client = client
14
+
15
+ def set(
16
+ self,
17
+ namespace: str,
18
+ key: str,
19
+ value: Any,
20
+ visibility: str = "private",
21
+ group_id: Optional[str] = None,
22
+ assistant_id: Optional[str] = None,
23
+ description: Optional[str] = None,
24
+ tags: Optional[List[str]] = None,
25
+ relevance_score: Optional[float] = None,
26
+ expires_at: Optional[str] = None,
27
+ ) -> Dict[str, Any]:
28
+ """Create a new state entry.
29
+
30
+ Args:
31
+ namespace: State namespace.
32
+ key: State key.
33
+ value: State value (JSON-serializable).
34
+ visibility: Visibility level ("private", "group", "public"). Defaults to "private".
35
+ group_id: Group ID (required if visibility is "group").
36
+ assistant_id: Optional assistant ID.
37
+ description: Optional description.
38
+ tags: Optional list of tags.
39
+ relevance_score: Optional relevance score (0-1).
40
+ expires_at: Optional expiration datetime (ISO 8601 format).
41
+
42
+ Returns:
43
+ Created state entry.
44
+ """
45
+ data: Dict[str, Any] = {
46
+ "namespace": namespace,
47
+ "key": key,
48
+ "value": value,
49
+ "visibility": visibility,
50
+ }
51
+ if group_id is not None:
52
+ data["group_id"] = group_id
53
+ if assistant_id is not None:
54
+ data["assistant_id"] = assistant_id
55
+ if description is not None:
56
+ data["description"] = description
57
+ if tags is not None:
58
+ data["tags"] = tags
59
+ if relevance_score is not None:
60
+ data["relevance_score"] = relevance_score
61
+ if expires_at is not None:
62
+ data["expires_at"] = expires_at
63
+
64
+ return self._client._request("POST", "/states", json=data)
65
+
66
+ def get(self, state_id: str) -> Dict[str, Any]:
67
+ """Get a specific state entry.
68
+
69
+ Args:
70
+ state_id: State ID (UUID).
71
+
72
+ Returns:
73
+ State entry.
74
+ """
75
+ return self._client._request("GET", f"/states/{state_id}")
76
+
77
+ def list(
78
+ self,
79
+ namespace: Optional[str] = None,
80
+ visibility: Optional[str] = None,
81
+ assistant_id: Optional[str] = None,
82
+ tags: Optional[str] = None,
83
+ search: Optional[str] = None,
84
+ skip: int = 0,
85
+ limit: int = 100,
86
+ ) -> List[Dict[str, Any]]:
87
+ """List state entries accessible to the current user.
88
+
89
+ Args:
90
+ namespace: Filter by namespace.
91
+ visibility: Filter by visibility ("private", "group", "public").
92
+ assistant_id: Filter by assistant ID.
93
+ tags: Comma-separated list of tags to filter by.
94
+ search: Search in keys and descriptions.
95
+ skip: Number of entries to skip (pagination).
96
+ limit: Maximum number of entries to return (1-1000).
97
+
98
+ Returns:
99
+ List of state entries.
100
+ """
101
+ params: Dict[str, Any] = {"skip": skip, "limit": limit}
102
+ if namespace is not None:
103
+ params["namespace"] = namespace
104
+ if visibility is not None:
105
+ params["visibility"] = visibility
106
+ if assistant_id is not None:
107
+ params["assistant_id"] = assistant_id
108
+ if tags is not None:
109
+ params["tags"] = tags
110
+ if search is not None:
111
+ params["search"] = search
112
+
113
+ return self._client._request("GET", "/states", params=params)
114
+
115
+ def update(
116
+ self,
117
+ state_id: str,
118
+ value: Optional[Any] = None,
119
+ description: Optional[str] = None,
120
+ tags: Optional[List[str]] = None,
121
+ relevance_score: Optional[float] = None,
122
+ expires_at: Optional[str] = None,
123
+ visibility: Optional[str] = None,
124
+ ) -> Dict[str, Any]:
125
+ """Update a state entry.
126
+
127
+ Args:
128
+ state_id: State ID (UUID).
129
+ value: New value.
130
+ description: New description.
131
+ tags: New list of tags.
132
+ relevance_score: New relevance score.
133
+ expires_at: New expiration datetime.
134
+ visibility: New visibility level.
135
+
136
+ Returns:
137
+ Updated state entry.
138
+ """
139
+ data: Dict[str, Any] = {}
140
+ if value is not None:
141
+ data["value"] = value
142
+ if description is not None:
143
+ data["description"] = description
144
+ if tags is not None:
145
+ data["tags"] = tags
146
+ if relevance_score is not None:
147
+ data["relevance_score"] = relevance_score
148
+ if expires_at is not None:
149
+ data["expires_at"] = expires_at
150
+ if visibility is not None:
151
+ data["visibility"] = visibility
152
+
153
+ return self._client._request("PUT", f"/states/{state_id}", json=data)
154
+
155
+ def delete(self, state_id: str) -> Dict[str, Any]:
156
+ """Delete a state entry.
157
+
158
+ Args:
159
+ state_id: State ID (UUID).
160
+
161
+ Returns:
162
+ Deletion confirmation message.
163
+ """
164
+ return self._client._request("DELETE", f"/states/{state_id}")
sinas/webhooks.py ADDED
@@ -0,0 +1,57 @@
1
+ """Runtime Webhooks API."""
2
+
3
+ from typing import TYPE_CHECKING, Any, Dict, Optional
4
+
5
+ if TYPE_CHECKING:
6
+ from sinas.client import SinasClient
7
+
8
+
9
+ class WebhooksAPI:
10
+ """Runtime Webhooks API methods."""
11
+
12
+ def __init__(self, client: "SinasClient") -> None:
13
+ self._client = client
14
+
15
+ def run(
16
+ self,
17
+ path: str,
18
+ method: str = "POST",
19
+ body: Optional[Dict[str, Any]] = None,
20
+ headers: Optional[Dict[str, str]] = None,
21
+ query: Optional[Dict[str, str]] = None,
22
+ ) -> Dict[str, Any]:
23
+ """Execute a webhook by path and HTTP method.
24
+
25
+ Args:
26
+ path: Webhook path (without /webhooks/ prefix).
27
+ method: HTTP method (GET, POST, PUT, DELETE, PATCH). Defaults to POST.
28
+ body: Optional request body (for POST/PUT/PATCH).
29
+ headers: Optional custom headers.
30
+ query: Optional query parameters.
31
+
32
+ Returns:
33
+ Webhook execution result with execution_id and result.
34
+ """
35
+ # Construct the full webhook URL
36
+ url = f"/webhooks/{path}"
37
+
38
+ # Merge custom headers with default headers
39
+ request_headers = self._client._get_headers()
40
+ if headers:
41
+ request_headers.update(headers)
42
+
43
+ # Make request with specified method
44
+ response = self._client._client.request(
45
+ method=method.upper(),
46
+ url=f"{self._client.base_url}{url}",
47
+ json=body,
48
+ params=query,
49
+ headers=request_headers,
50
+ )
51
+
52
+ self._client._handle_response(response)
53
+
54
+ if response.status_code == 204:
55
+ return {}
56
+
57
+ return response.json()