proly 1.0.0__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.
proly-1.0.0/PKG-INFO ADDED
@@ -0,0 +1,82 @@
1
+ Metadata-Version: 2.4
2
+ Name: proly
3
+ Version: 1.0.0
4
+ Summary: Proly Agent SDK — build marketplace agents that call platform tools securely from E2B sandboxes
5
+ Home-page: https://proly.co.uk/developers
6
+ License: MIT
7
+ Project-URL: Source, https://github.com/proly/proly-runtime/tree/main/pkg/sdk/python
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Requires-Python: >=3.10
16
+ Description-Content-Type: text/markdown
17
+ Dynamic: classifier
18
+ Dynamic: description
19
+ Dynamic: description-content-type
20
+ Dynamic: home-page
21
+ Dynamic: license
22
+ Dynamic: project-url
23
+ Dynamic: requires-python
24
+ Dynamic: summary
25
+
26
+ # proly
27
+
28
+ Build marketplace agents for the Proly platform.
29
+
30
+ ## Install
31
+
32
+ ```bash
33
+ pip install proly
34
+ ```
35
+
36
+ ## Usage
37
+
38
+ ```python
39
+ from proly import Proly
40
+
41
+ def run():
42
+ proly = Proly()
43
+
44
+ # Fetch a web page
45
+ result = proly.web_fetch(url='https://example.com')
46
+ print(result['content'])
47
+
48
+ # Search the web
49
+ results = proly.web_search(query='best deals UK')
50
+
51
+ # Send a notification to the user
52
+ proly.call_tool('messaging_notify', {
53
+ 'title': 'Deal found!',
54
+ 'body': 'Nike trainers 30% off at JD Sports',
55
+ })
56
+
57
+ if __name__ == '__main__':
58
+ run()
59
+ ```
60
+
61
+ ## Environment Variables
62
+
63
+ The SDK reads these automatically when running inside a Proly sandbox:
64
+
65
+ - `PROLY_TOOL_API_URL` — Tool API endpoint
66
+ - `PROLY_SANDBOX_TOKEN` — Scoped authentication token
67
+ - `PROLY_AGENT_ID` — Agent instance ID
68
+ - `PROLY_USER_ID` — User ID
69
+ - `PROLY_TASK_ID` — Current task ID
70
+ - `PROLY_CONFIG` — Agent configuration JSON
71
+
72
+ ## Local Development
73
+
74
+ Use `claw dev` to test locally:
75
+
76
+ ```bash
77
+ claw dev --api-key your_api_key
78
+ ```
79
+
80
+ ## Docs
81
+
82
+ https://proly.co.uk/developers
proly-1.0.0/README.md ADDED
@@ -0,0 +1,57 @@
1
+ # proly
2
+
3
+ Build marketplace agents for the Proly platform.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pip install proly
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```python
14
+ from proly import Proly
15
+
16
+ def run():
17
+ proly = Proly()
18
+
19
+ # Fetch a web page
20
+ result = proly.web_fetch(url='https://example.com')
21
+ print(result['content'])
22
+
23
+ # Search the web
24
+ results = proly.web_search(query='best deals UK')
25
+
26
+ # Send a notification to the user
27
+ proly.call_tool('messaging_notify', {
28
+ 'title': 'Deal found!',
29
+ 'body': 'Nike trainers 30% off at JD Sports',
30
+ })
31
+
32
+ if __name__ == '__main__':
33
+ run()
34
+ ```
35
+
36
+ ## Environment Variables
37
+
38
+ The SDK reads these automatically when running inside a Proly sandbox:
39
+
40
+ - `PROLY_TOOL_API_URL` — Tool API endpoint
41
+ - `PROLY_SANDBOX_TOKEN` — Scoped authentication token
42
+ - `PROLY_AGENT_ID` — Agent instance ID
43
+ - `PROLY_USER_ID` — User ID
44
+ - `PROLY_TASK_ID` — Current task ID
45
+ - `PROLY_CONFIG` — Agent configuration JSON
46
+
47
+ ## Local Development
48
+
49
+ Use `claw dev` to test locally:
50
+
51
+ ```bash
52
+ claw dev --api-key your_api_key
53
+ ```
54
+
55
+ ## Docs
56
+
57
+ https://proly.co.uk/developers
@@ -0,0 +1,258 @@
1
+ """
2
+ Proly SDK for marketplace agent developers.
3
+
4
+ Usage:
5
+ from proly import Proly
6
+
7
+ platform = Proly()
8
+ emails = platform.read_emails(unread_only=True)
9
+
10
+ The SDK reads environment variables injected by the Proly runtime
11
+ automatically. Developer code never manages tokens or URLs directly.
12
+ """
13
+
14
+ import json
15
+ import os
16
+ from urllib.request import Request, urlopen
17
+ from urllib.error import URLError, HTTPError
18
+
19
+ __version__ = "0.1.0"
20
+ __all__ = ["Proly"]
21
+
22
+
23
+ class Proly:
24
+ """Client for the Proly Tool API.
25
+
26
+ Reads connection details from environment variables injected by the
27
+ runtime into E2B sandboxes. Does NOT raise if env vars are missing;
28
+ fails gracefully on the first tool call with a clear error message.
29
+ """
30
+
31
+ def __init__(self):
32
+ self._tool_api_url = os.environ.get("PROLY_TOOL_API_URL")
33
+ self._token = os.environ.get("PROLY_SANDBOX_TOKEN")
34
+ self._agent_id = os.environ.get("PROLY_AGENT_ID")
35
+ self._user_id = os.environ.get("PROLY_USER_ID")
36
+ self._task_id = os.environ.get("PROLY_TASK_ID")
37
+ self._goal = os.environ.get("PROLY_GOAL")
38
+
39
+ config_raw = os.environ.get("PROLY_CONFIG", "{}")
40
+ try:
41
+ self._config = json.loads(config_raw)
42
+ except (json.JSONDecodeError, TypeError):
43
+ self._config = {}
44
+
45
+ # ------------------------------------------------------------------
46
+ # Properties
47
+ # ------------------------------------------------------------------
48
+
49
+ @property
50
+ def agent_id(self):
51
+ """The agent UUID, or None if not set."""
52
+ return self._agent_id
53
+
54
+ @property
55
+ def user_id(self):
56
+ """The user UUID, or None if not set."""
57
+ return self._user_id
58
+
59
+ @property
60
+ def task_id(self):
61
+ """The task UUID, or None if not set."""
62
+ return self._task_id
63
+
64
+ @property
65
+ def goal(self):
66
+ """The task goal string, or None if not set."""
67
+ return self._goal
68
+
69
+ @property
70
+ def config(self):
71
+ """User-provided agent configuration dict."""
72
+ return self._config
73
+
74
+ # ------------------------------------------------------------------
75
+ # Core tool execution
76
+ # ------------------------------------------------------------------
77
+
78
+ def call_tool(self, tool_name, input_data=None):
79
+ """Execute any platform tool by name.
80
+
81
+ Args:
82
+ tool_name: The tool identifier (e.g. 'email_read', 'web_search').
83
+ input_data: Tool-specific input parameters as a dict.
84
+
85
+ Returns:
86
+ The tool's output payload (parsed from JSON).
87
+
88
+ Raises:
89
+ RuntimeError: If env vars are missing, the request fails, or
90
+ the Tool API returns an error.
91
+ """
92
+ if input_data is None:
93
+ input_data = {}
94
+
95
+ if not self._tool_api_url:
96
+ raise RuntimeError(
97
+ "Proly SDK: PROLY_TOOL_API_URL is not set. "
98
+ "This SDK must run inside a Proly sandbox."
99
+ )
100
+ if not self._token:
101
+ raise RuntimeError(
102
+ "Proly SDK: PROLY_SANDBOX_TOKEN is not set. "
103
+ "This SDK must run inside a Proly sandbox."
104
+ )
105
+
106
+ url = self._tool_api_url.rstrip("/") + "/tools/execute"
107
+ payload = json.dumps({"tool": tool_name, "input": input_data}).encode("utf-8")
108
+
109
+ req = Request(
110
+ url,
111
+ data=payload,
112
+ headers={
113
+ "Content-Type": "application/json",
114
+ "Authorization": "Bearer " + self._token,
115
+ },
116
+ method="POST",
117
+ )
118
+
119
+ try:
120
+ with urlopen(req) as resp:
121
+ body = resp.read().decode("utf-8")
122
+ except HTTPError as exc:
123
+ # The Tool API returns JSON error bodies on 4xx/5xx
124
+ try:
125
+ body = exc.read().decode("utf-8")
126
+ except Exception:
127
+ raise RuntimeError(
128
+ "Proly SDK: Tool API returned HTTP %d for tool '%s'"
129
+ % (exc.code, tool_name)
130
+ ) from exc
131
+ except URLError as exc:
132
+ raise RuntimeError(
133
+ "Proly SDK: failed to reach Tool API at %s: %s"
134
+ % (url, exc.reason)
135
+ ) from exc
136
+
137
+ try:
138
+ data = json.loads(body)
139
+ except (json.JSONDecodeError, TypeError) as exc:
140
+ raise RuntimeError(
141
+ "Proly SDK: Tool API returned non-JSON response"
142
+ ) from exc
143
+
144
+ if not data.get("success"):
145
+ error_msg = data.get("error", "unknown error")
146
+ raise RuntimeError(
147
+ "Proly SDK: tool '%s' failed: %s" % (tool_name, error_msg)
148
+ )
149
+
150
+ return data.get("output")
151
+
152
+ # ------------------------------------------------------------------
153
+ # Convenience methods
154
+ # ------------------------------------------------------------------
155
+
156
+ def read_emails(self, **options):
157
+ """Read emails from the user's inbox.
158
+
159
+ Keyword Args:
160
+ unread_only (bool): Only return unread emails.
161
+ max_results (int): Maximum number of emails to return.
162
+ labels (list): Gmail labels to filter by.
163
+ """
164
+ return self.call_tool("email_read", options)
165
+
166
+ def send_email(self, to, subject, body, **options):
167
+ """Send an email.
168
+
169
+ Args:
170
+ to: Recipient email address.
171
+ subject: Email subject line.
172
+ body: Email body (plain text or HTML).
173
+
174
+ Keyword Args:
175
+ cc (str): CC recipients.
176
+ bcc (str): BCC recipients.
177
+ reply_to (str): Message ID to reply to.
178
+ """
179
+ return self.call_tool("email_send", {"to": to, "subject": subject, "body": body, **options})
180
+
181
+ def delete_email(self, message_id, **options):
182
+ """Delete an email by message ID.
183
+
184
+ Args:
185
+ message_id: The email message ID to delete.
186
+ """
187
+ return self.call_tool("email_delete", {"message_id": message_id, **options})
188
+
189
+ def read_calendar(self, **options):
190
+ """Read calendar events.
191
+
192
+ Keyword Args:
193
+ start_date (str): Start of date range (e.g. '2026-03-25').
194
+ end_date (str): End of date range.
195
+ max_results (int): Maximum number of events to return.
196
+ """
197
+ return self.call_tool("calendar_read", options)
198
+
199
+ def create_event(self, title, date, start_time, **options):
200
+ """Create a calendar event.
201
+
202
+ Args:
203
+ title: Event title.
204
+ date: Event date (e.g. '2026-03-25').
205
+ start_time: Start time (e.g. '09:00').
206
+
207
+ Keyword Args:
208
+ end_time (str): End time.
209
+ description (str): Event description.
210
+ location (str): Event location.
211
+ """
212
+ return self.call_tool("calendar_write", {
213
+ "title": title, "date": date, "start_time": start_time, **options
214
+ })
215
+
216
+ def send_whatsapp(self, to, message):
217
+ """Send a WhatsApp message.
218
+
219
+ Args:
220
+ to: Recipient phone number (with country code, e.g. '+447700900000').
221
+ message: Message text.
222
+ """
223
+ return self.call_tool("whatsapp_send", {"to": to, "message": message})
224
+
225
+ def web_search(self, query, **options):
226
+ """Perform a web search.
227
+
228
+ Args:
229
+ query: Search query string.
230
+
231
+ Keyword Args:
232
+ max_results (int): Maximum number of results to return.
233
+ """
234
+ return self.call_tool("web_search", {"query": query, **options})
235
+
236
+ def use_browser(self, action, **options):
237
+ """Interact with a cloud browser session.
238
+
239
+ Args:
240
+ action: Browser action ('navigate', 'click', 'fill', 'read', 'screenshot').
241
+
242
+ Keyword Args:
243
+ Varies by action (e.g. url, selector, text).
244
+ """
245
+ return self.call_tool("browser_use", {"action": action, **options})
246
+
247
+ def http_fetch(self, url, **options):
248
+ """Fetch a URL via HTTP.
249
+
250
+ Args:
251
+ url: The URL to fetch.
252
+
253
+ Keyword Args:
254
+ method (str): HTTP method (default 'GET').
255
+ headers (dict): Request headers.
256
+ body (str): Request body.
257
+ """
258
+ return self.call_tool("http_fetch", {"url": url, **options})
@@ -0,0 +1,82 @@
1
+ Metadata-Version: 2.4
2
+ Name: proly
3
+ Version: 1.0.0
4
+ Summary: Proly Agent SDK — build marketplace agents that call platform tools securely from E2B sandboxes
5
+ Home-page: https://proly.co.uk/developers
6
+ License: MIT
7
+ Project-URL: Source, https://github.com/proly/proly-runtime/tree/main/pkg/sdk/python
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Requires-Python: >=3.10
16
+ Description-Content-Type: text/markdown
17
+ Dynamic: classifier
18
+ Dynamic: description
19
+ Dynamic: description-content-type
20
+ Dynamic: home-page
21
+ Dynamic: license
22
+ Dynamic: project-url
23
+ Dynamic: requires-python
24
+ Dynamic: summary
25
+
26
+ # proly
27
+
28
+ Build marketplace agents for the Proly platform.
29
+
30
+ ## Install
31
+
32
+ ```bash
33
+ pip install proly
34
+ ```
35
+
36
+ ## Usage
37
+
38
+ ```python
39
+ from proly import Proly
40
+
41
+ def run():
42
+ proly = Proly()
43
+
44
+ # Fetch a web page
45
+ result = proly.web_fetch(url='https://example.com')
46
+ print(result['content'])
47
+
48
+ # Search the web
49
+ results = proly.web_search(query='best deals UK')
50
+
51
+ # Send a notification to the user
52
+ proly.call_tool('messaging_notify', {
53
+ 'title': 'Deal found!',
54
+ 'body': 'Nike trainers 30% off at JD Sports',
55
+ })
56
+
57
+ if __name__ == '__main__':
58
+ run()
59
+ ```
60
+
61
+ ## Environment Variables
62
+
63
+ The SDK reads these automatically when running inside a Proly sandbox:
64
+
65
+ - `PROLY_TOOL_API_URL` — Tool API endpoint
66
+ - `PROLY_SANDBOX_TOKEN` — Scoped authentication token
67
+ - `PROLY_AGENT_ID` — Agent instance ID
68
+ - `PROLY_USER_ID` — User ID
69
+ - `PROLY_TASK_ID` — Current task ID
70
+ - `PROLY_CONFIG` — Agent configuration JSON
71
+
72
+ ## Local Development
73
+
74
+ Use `claw dev` to test locally:
75
+
76
+ ```bash
77
+ claw dev --api-key your_api_key
78
+ ```
79
+
80
+ ## Docs
81
+
82
+ https://proly.co.uk/developers
@@ -0,0 +1,7 @@
1
+ README.md
2
+ setup.py
3
+ proly/__init__.py
4
+ proly.egg-info/PKG-INFO
5
+ proly.egg-info/SOURCES.txt
6
+ proly.egg-info/dependency_links.txt
7
+ proly.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ proly
proly-1.0.0/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
proly-1.0.0/setup.py ADDED
@@ -0,0 +1,25 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ setup(
4
+ name='proly',
5
+ version='1.0.0',
6
+ description='Proly Agent SDK — build marketplace agents that call platform tools securely from E2B sandboxes',
7
+ long_description=open('README.md').read() if __import__('os').path.exists('README.md') else '',
8
+ long_description_content_type='text/markdown',
9
+ url='https://proly.co.uk/developers',
10
+ project_urls={
11
+ 'Source': 'https://github.com/proly/proly-runtime/tree/main/pkg/sdk/python',
12
+ },
13
+ packages=find_packages(),
14
+ python_requires='>=3.10',
15
+ license='MIT',
16
+ classifiers=[
17
+ 'Development Status :: 4 - Beta',
18
+ 'Intended Audience :: Developers',
19
+ 'License :: OSI Approved :: MIT License',
20
+ 'Programming Language :: Python :: 3',
21
+ 'Programming Language :: Python :: 3.10',
22
+ 'Programming Language :: Python :: 3.11',
23
+ 'Programming Language :: Python :: 3.12',
24
+ ],
25
+ )