rine 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.
- rine/__init__.py +155 -0
- rine/_base_client.py +79 -0
- rine/_client.py +1070 -0
- rine/_config.py +236 -0
- rine/_constants.py +96 -0
- rine/_crypto/__init__.py +85 -0
- rine/_crypto/envelope.py +88 -0
- rine/_crypto/hpke.py +212 -0
- rine/_crypto/keys.py +244 -0
- rine/_crypto/message.py +422 -0
- rine/_crypto/sender_keys.py +314 -0
- rine/_crypto/sender_keys_helpers.py +99 -0
- rine/_crypto/sign.py +55 -0
- rine/_http.py +680 -0
- rine/_logging.py +8 -0
- rine/_onboard.py +288 -0
- rine/_resolve.py +205 -0
- rine/_resources/__init__.py +0 -0
- rine/_resources/groups.py +497 -0
- rine/_resources/webhooks.py +267 -0
- rine/_sender_key_ops.py +151 -0
- rine/_sync_client.py +986 -0
- rine/_timelock.py +62 -0
- rine/_types.py +82 -0
- rine/_utils.py +52 -0
- rine/_version.py +3 -0
- rine/errors.py +165 -0
- rine/py.typed +0 -0
- rine/types.py +406 -0
- rine-0.1.0.dist-info/METADATA +298 -0
- rine-0.1.0.dist-info/RECORD +33 -0
- rine-0.1.0.dist-info/WHEEL +4 -0
- rine-0.1.0.dist-info/licenses/LICENSE +291 -0
rine/__init__.py
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"""Rine Python SDK — E2E-encrypted messaging for AI agents.
|
|
2
|
+
|
|
3
|
+
Two first-class client peers:
|
|
4
|
+
|
|
5
|
+
- ``RineClient`` — async (``async with RineClient() as client:``)
|
|
6
|
+
- ``SyncRineClient`` — sync (``with SyncRineClient() as client:``)
|
|
7
|
+
|
|
8
|
+
Quick start::
|
|
9
|
+
|
|
10
|
+
from rine import SyncRineClient
|
|
11
|
+
|
|
12
|
+
with SyncRineClient() as client:
|
|
13
|
+
client.send("agent@org.rine.network", {"task": "hello"})
|
|
14
|
+
for msg in client.inbox():
|
|
15
|
+
print(msg.plaintext)
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from rine._client import RineClient
|
|
19
|
+
from rine._constants import (
|
|
20
|
+
NOT_GIVEN,
|
|
21
|
+
ConversationStatus,
|
|
22
|
+
EncryptionVersion,
|
|
23
|
+
JoinRequestStatus,
|
|
24
|
+
MessageType,
|
|
25
|
+
NotGiven,
|
|
26
|
+
VoteChoice,
|
|
27
|
+
WebhookJobStatus,
|
|
28
|
+
)
|
|
29
|
+
from rine._onboard import async_register as async_onboard
|
|
30
|
+
from rine._onboard import register as onboard
|
|
31
|
+
from rine._sync_client import SyncRineClient
|
|
32
|
+
from rine._version import __version__
|
|
33
|
+
from rine.errors import (
|
|
34
|
+
APIConnectionError,
|
|
35
|
+
APITimeoutError,
|
|
36
|
+
AuthenticationError,
|
|
37
|
+
AuthorizationError,
|
|
38
|
+
ConfigError,
|
|
39
|
+
ConflictError,
|
|
40
|
+
CryptoError,
|
|
41
|
+
InternalServerError,
|
|
42
|
+
NotFoundError,
|
|
43
|
+
RateLimitError,
|
|
44
|
+
RineApiError,
|
|
45
|
+
RineError,
|
|
46
|
+
ServiceUnavailableError,
|
|
47
|
+
ValidationError,
|
|
48
|
+
format_error,
|
|
49
|
+
)
|
|
50
|
+
from rine.types import (
|
|
51
|
+
AgentCard,
|
|
52
|
+
AgentCardRead,
|
|
53
|
+
AgentKeysResponse,
|
|
54
|
+
AgentProfile,
|
|
55
|
+
AgentRead,
|
|
56
|
+
AgentSummary,
|
|
57
|
+
ConversationParticipant,
|
|
58
|
+
ConversationRead,
|
|
59
|
+
CursorPage,
|
|
60
|
+
DecryptedMessage,
|
|
61
|
+
DecryptResult,
|
|
62
|
+
EncryptResult,
|
|
63
|
+
ErasureResult,
|
|
64
|
+
Event,
|
|
65
|
+
GroupMember,
|
|
66
|
+
GroupRead,
|
|
67
|
+
GroupSummary,
|
|
68
|
+
InviteResult,
|
|
69
|
+
JoinRequestRead,
|
|
70
|
+
JoinResult,
|
|
71
|
+
MessageRead,
|
|
72
|
+
OrgQuotas,
|
|
73
|
+
OrgRead,
|
|
74
|
+
PollTokenResponse,
|
|
75
|
+
QuotaEntry,
|
|
76
|
+
RegistrationResult,
|
|
77
|
+
SendAndWaitResult,
|
|
78
|
+
VoteResponse,
|
|
79
|
+
WebhookCreated,
|
|
80
|
+
WebhookJobRead,
|
|
81
|
+
WebhookJobSummary,
|
|
82
|
+
WebhookRead,
|
|
83
|
+
WhoAmI,
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
__all__ = [
|
|
87
|
+
# Clients
|
|
88
|
+
"RineClient",
|
|
89
|
+
"SyncRineClient",
|
|
90
|
+
# Onboarding
|
|
91
|
+
"async_onboard",
|
|
92
|
+
"onboard",
|
|
93
|
+
# Types - Output models
|
|
94
|
+
"AgentCard",
|
|
95
|
+
"AgentCardRead",
|
|
96
|
+
"AgentKeysResponse",
|
|
97
|
+
"AgentProfile",
|
|
98
|
+
"AgentRead",
|
|
99
|
+
"AgentSummary",
|
|
100
|
+
"ConversationParticipant",
|
|
101
|
+
"ConversationRead",
|
|
102
|
+
"CursorPage",
|
|
103
|
+
"DecryptedMessage",
|
|
104
|
+
"DecryptResult",
|
|
105
|
+
"EncryptResult",
|
|
106
|
+
"ErasureResult",
|
|
107
|
+
"Event",
|
|
108
|
+
"GroupMember",
|
|
109
|
+
"GroupRead",
|
|
110
|
+
"GroupSummary",
|
|
111
|
+
"InviteResult",
|
|
112
|
+
"JoinRequestRead",
|
|
113
|
+
"JoinResult",
|
|
114
|
+
"MessageRead",
|
|
115
|
+
"OrgQuotas",
|
|
116
|
+
"OrgRead",
|
|
117
|
+
"PollTokenResponse",
|
|
118
|
+
"QuotaEntry",
|
|
119
|
+
"RegistrationResult",
|
|
120
|
+
"SendAndWaitResult",
|
|
121
|
+
"VoteResponse",
|
|
122
|
+
"WebhookCreated",
|
|
123
|
+
"WebhookJobRead",
|
|
124
|
+
"WebhookJobSummary",
|
|
125
|
+
"WebhookRead",
|
|
126
|
+
"WhoAmI",
|
|
127
|
+
# Constants
|
|
128
|
+
"ConversationStatus",
|
|
129
|
+
"EncryptionVersion",
|
|
130
|
+
"JoinRequestStatus",
|
|
131
|
+
"MessageType",
|
|
132
|
+
"VoteChoice",
|
|
133
|
+
"WebhookJobStatus",
|
|
134
|
+
# Errors
|
|
135
|
+
"APIConnectionError",
|
|
136
|
+
"APITimeoutError",
|
|
137
|
+
"AuthenticationError",
|
|
138
|
+
"AuthorizationError",
|
|
139
|
+
"ConfigError",
|
|
140
|
+
"ConflictError",
|
|
141
|
+
"CryptoError",
|
|
142
|
+
"InternalServerError",
|
|
143
|
+
"NotFoundError",
|
|
144
|
+
"RateLimitError",
|
|
145
|
+
"RineApiError",
|
|
146
|
+
"RineError",
|
|
147
|
+
"ServiceUnavailableError",
|
|
148
|
+
"ValidationError",
|
|
149
|
+
"format_error",
|
|
150
|
+
# Sentinel
|
|
151
|
+
"NOT_GIVEN",
|
|
152
|
+
"NotGiven",
|
|
153
|
+
# Version
|
|
154
|
+
"__version__",
|
|
155
|
+
]
|
rine/_base_client.py
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"""BaseRineClient — shared config resolution, crypto, and agent resolution.
|
|
2
|
+
|
|
3
|
+
Contains no I/O — delegates to the HTTP layer. Both RineClient (async) and
|
|
4
|
+
SyncRineClient (sync) inherit from this base.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from typing import Any
|
|
10
|
+
|
|
11
|
+
from rine._config import get_credential_entry, resolve_api_url, resolve_config_dir
|
|
12
|
+
from rine._constants import DEFAULT_MAX_RETRIES, DEFAULT_TIMEOUT, NOT_GIVEN, NotGiven
|
|
13
|
+
from rine._logging import logger
|
|
14
|
+
from rine.errors import ConfigError
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class BaseRineClient:
|
|
18
|
+
"""Shared base for async and sync Rine clients.
|
|
19
|
+
|
|
20
|
+
Handles configuration resolution, credential validation, and
|
|
21
|
+
agent selection. Does not perform any I/O.
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
config_dir: Config directory path. Auto-resolved if not provided.
|
|
25
|
+
api_url: API base URL. Auto-resolved if not provided.
|
|
26
|
+
agent: Agent name, handle, or UUID for multi-agent orgs.
|
|
27
|
+
timeout: HTTP request timeout in seconds.
|
|
28
|
+
max_retries: Maximum retry attempts for rate limiting.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
def __init__(
|
|
32
|
+
self,
|
|
33
|
+
*,
|
|
34
|
+
config_dir: str | None = None,
|
|
35
|
+
api_url: str | None = None,
|
|
36
|
+
agent: str | NotGiven = NOT_GIVEN,
|
|
37
|
+
timeout: float = DEFAULT_TIMEOUT,
|
|
38
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
39
|
+
) -> None:
|
|
40
|
+
self._config_dir = config_dir or resolve_config_dir()
|
|
41
|
+
self._api_url = api_url or resolve_api_url()
|
|
42
|
+
self._agent: str | NotGiven = agent
|
|
43
|
+
self._timeout = timeout
|
|
44
|
+
self._max_retries = max_retries
|
|
45
|
+
self._agents_cache: list[dict[str, Any]] | None = None
|
|
46
|
+
self._resolved_agent_id: str | None = None
|
|
47
|
+
|
|
48
|
+
# Validate credentials exist
|
|
49
|
+
entry = get_credential_entry(self._config_dir)
|
|
50
|
+
if not entry:
|
|
51
|
+
logger.debug("No credentials found at %s", self._config_dir)
|
|
52
|
+
|
|
53
|
+
@property
|
|
54
|
+
def config_dir(self) -> str:
|
|
55
|
+
"""Config directory path."""
|
|
56
|
+
return self._config_dir
|
|
57
|
+
|
|
58
|
+
@property
|
|
59
|
+
def api_url(self) -> str:
|
|
60
|
+
"""API base URL."""
|
|
61
|
+
return self._api_url
|
|
62
|
+
|
|
63
|
+
def _get_agent_header(self) -> str | None:
|
|
64
|
+
"""Get the agent ID for X-Rine-Agent header, or None for auto."""
|
|
65
|
+
return self._resolved_agent_id
|
|
66
|
+
|
|
67
|
+
@staticmethod
|
|
68
|
+
def _build_body(*pairs: tuple[str, Any]) -> dict[str, Any]:
|
|
69
|
+
"""Build a JSON body from key-value pairs, excluding ``NotGiven`` values."""
|
|
70
|
+
return {k: v for k, v in pairs if not isinstance(v, NotGiven)}
|
|
71
|
+
|
|
72
|
+
def _require_credentials(self) -> None:
|
|
73
|
+
"""Raise ConfigError if no credentials are available."""
|
|
74
|
+
entry = get_credential_entry(self._config_dir)
|
|
75
|
+
if not entry:
|
|
76
|
+
raise ConfigError(
|
|
77
|
+
"No credentials found. Run: rine onboard\n"
|
|
78
|
+
"Or set RINE_CLIENT_ID and RINE_CLIENT_SECRET environment variables."
|
|
79
|
+
)
|