orgo 0.0.29__py3-none-any.whl → 0.0.30__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.
orgo/computer.py
CHANGED
|
@@ -1,333 +1,183 @@
|
|
|
1
|
-
"""
|
|
2
|
-
|
|
3
|
-
import base64
|
|
4
|
-
import logging
|
|
5
|
-
import uuid
|
|
6
|
-
import io
|
|
7
|
-
from typing import Dict, List, Any, Optional, Callable, Literal, Union
|
|
8
|
-
from PIL import Image
|
|
1
|
+
"""API client for Orgo service"""
|
|
2
|
+
|
|
9
3
|
import requests
|
|
10
|
-
from
|
|
4
|
+
from typing import Dict, Any, Optional, List
|
|
5
|
+
import logging
|
|
11
6
|
|
|
12
|
-
from .
|
|
13
|
-
from .prompt import get_provider
|
|
7
|
+
from orgo.utils.auth import get_api_key
|
|
14
8
|
|
|
15
9
|
logger = logging.getLogger(__name__)
|
|
16
10
|
|
|
17
|
-
class
|
|
18
|
-
def __init__(self,
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
""
|
|
30
|
-
Initialize an Orgo virtual computer.
|
|
31
|
-
|
|
32
|
-
Args:
|
|
33
|
-
project: Project name (str) or Project instance. If not provided, creates a new project.
|
|
34
|
-
name: Computer name within the project (optional, auto-generated if not provided)
|
|
35
|
-
computer_id: Existing computer ID to connect to (optional)
|
|
36
|
-
api_key: Orgo API key (defaults to ORGO_API_KEY env var)
|
|
37
|
-
base_api_url: Custom API URL (optional)
|
|
38
|
-
ram/memory: RAM in GB (1, 2, 4, 8, 16, 32, or 64) - only used when creating
|
|
39
|
-
cpu: CPU cores (1, 2, 4, 8, or 16) - only used when creating
|
|
40
|
-
os: Operating system ("linux" or "windows") - only used when creating
|
|
41
|
-
gpu: GPU type - only used when creating
|
|
42
|
-
|
|
43
|
-
Examples:
|
|
44
|
-
# Create computer in new project
|
|
45
|
-
computer = Computer(ram=4, cpu=2)
|
|
46
|
-
|
|
47
|
-
# Create computer in existing project
|
|
48
|
-
computer = Computer(project="manus", ram=4, cpu=2)
|
|
49
|
-
|
|
50
|
-
# Connect to existing computer in project
|
|
51
|
-
computer = Computer(project="manus")
|
|
52
|
-
"""
|
|
53
|
-
self.api_key = api_key or operating_system.environ.get("ORGO_API_KEY")
|
|
54
|
-
self.base_api_url = base_api_url
|
|
55
|
-
self.api = ApiClient(self.api_key, self.base_api_url)
|
|
56
|
-
|
|
57
|
-
# Handle memory parameter as an alias for ram
|
|
58
|
-
if ram is None and memory is not None:
|
|
59
|
-
ram = memory
|
|
60
|
-
|
|
61
|
-
# Store configuration
|
|
62
|
-
self.os = os or "linux"
|
|
63
|
-
self.ram = ram or 2
|
|
64
|
-
self.cpu = cpu or 2
|
|
65
|
-
self.gpu = gpu or "none"
|
|
11
|
+
class ApiClient:
|
|
12
|
+
def __init__(self, api_key: Optional[str] = None, base_url: Optional[str] = None):
|
|
13
|
+
self.api_key = get_api_key(api_key)
|
|
14
|
+
self.base_url = base_url or "https://www.orgo.ai/api"
|
|
15
|
+
self.session = requests.Session()
|
|
16
|
+
self.session.headers.update({
|
|
17
|
+
"Authorization": f"Bearer {self.api_key}",
|
|
18
|
+
"Content-Type": "application/json",
|
|
19
|
+
"Accept": "application/json"
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
def _request(self, method: str, endpoint: str, data: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
|
|
23
|
+
url = f"{self.base_url}/{endpoint}"
|
|
66
24
|
|
|
67
|
-
if computer_id:
|
|
68
|
-
# Connect to existing computer by ID
|
|
69
|
-
self._connect_by_id(computer_id)
|
|
70
|
-
elif project:
|
|
71
|
-
# Work with specified project
|
|
72
|
-
if isinstance(project, str):
|
|
73
|
-
# Project name provided
|
|
74
|
-
self.project_name = project
|
|
75
|
-
self._initialize_with_project_name(project, name)
|
|
76
|
-
else:
|
|
77
|
-
# Project instance provided
|
|
78
|
-
from .project import Project as ProjectClass
|
|
79
|
-
if isinstance(project, ProjectClass):
|
|
80
|
-
self.project_name = project.name
|
|
81
|
-
self.project_id = project.id
|
|
82
|
-
self._initialize_with_project_instance(project, name)
|
|
83
|
-
else:
|
|
84
|
-
raise ValueError("project must be a string (project name) or Project instance")
|
|
85
|
-
else:
|
|
86
|
-
# No project specified, create a new one
|
|
87
|
-
self._create_new_project_and_computer(name)
|
|
88
|
-
|
|
89
|
-
def _connect_by_id(self, computer_id: str):
|
|
90
|
-
"""Connect to existing computer by ID"""
|
|
91
|
-
self.computer_id = computer_id
|
|
92
|
-
self._info = self.api.get_computer(computer_id)
|
|
93
|
-
self.project_id = self._info.get("project_id")
|
|
94
|
-
self.name = self._info.get("name")
|
|
95
|
-
# Get project name
|
|
96
|
-
if self.project_id:
|
|
97
|
-
project = self.api.get_project(self.project_id)
|
|
98
|
-
self.project_name = project.get("name")
|
|
99
|
-
|
|
100
|
-
def _initialize_with_project_name(self, project_name: str, computer_name: Optional[str]):
|
|
101
|
-
"""Initialize with a project name (create project if needed)"""
|
|
102
25
|
try:
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
26
|
+
if method.upper() == "GET":
|
|
27
|
+
response = self.session.get(url, params=data)
|
|
28
|
+
else:
|
|
29
|
+
response = self.session.request(method, url, json=data)
|
|
106
30
|
|
|
107
|
-
|
|
108
|
-
|
|
31
|
+
response.raise_for_status()
|
|
32
|
+
return response.json()
|
|
33
|
+
except requests.exceptions.RequestException as e:
|
|
34
|
+
# Log the full error for debugging
|
|
35
|
+
logger.debug(f"API request failed: {method} {url}", exc_info=True)
|
|
109
36
|
|
|
110
|
-
if
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
"
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
"""Create a new
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
""
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
def
|
|
172
|
-
"""
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
self.
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
def
|
|
219
|
-
""
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
return self.
|
|
225
|
-
|
|
226
|
-
def
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
def
|
|
232
|
-
"""
|
|
233
|
-
return self.
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
return self.api.key_press(self.computer_id, key)
|
|
243
|
-
|
|
244
|
-
# View methods
|
|
245
|
-
def screenshot(self) -> Image.Image:
|
|
246
|
-
"""Capture screenshot and return as PIL Image"""
|
|
247
|
-
response = self.api.get_screenshot(self.computer_id)
|
|
248
|
-
image_data = response.get("image", "")
|
|
249
|
-
|
|
250
|
-
if image_data.startswith(('http://', 'https://')):
|
|
251
|
-
img_response = requests.get(image_data)
|
|
252
|
-
img_response.raise_for_status()
|
|
253
|
-
return Image.open(io.BytesIO(img_response.content))
|
|
254
|
-
else:
|
|
255
|
-
img_data = base64.b64decode(image_data)
|
|
256
|
-
return Image.open(io.BytesIO(img_data))
|
|
257
|
-
|
|
258
|
-
def screenshot_base64(self) -> str:
|
|
259
|
-
"""Capture screenshot and return as base64 string"""
|
|
260
|
-
response = self.api.get_screenshot(self.computer_id)
|
|
261
|
-
image_data = response.get("image", "")
|
|
262
|
-
|
|
263
|
-
if image_data.startswith(('http://', 'https://')):
|
|
264
|
-
img_response = requests.get(image_data)
|
|
265
|
-
img_response.raise_for_status()
|
|
266
|
-
return base64.b64encode(img_response.content).decode('utf-8')
|
|
267
|
-
else:
|
|
268
|
-
return image_data
|
|
269
|
-
|
|
270
|
-
# Execution methods
|
|
271
|
-
def bash(self, command: str) -> str:
|
|
272
|
-
"""Execute a bash command and return output"""
|
|
273
|
-
response = self.api.execute_bash(self.computer_id, command)
|
|
274
|
-
return response.get("output", "")
|
|
275
|
-
|
|
276
|
-
def exec(self, code: str, timeout: int = 10) -> Dict[str, Any]:
|
|
277
|
-
"""Execute Python code on the remote computer"""
|
|
278
|
-
response = self.api.execute_python(self.computer_id, code, timeout)
|
|
279
|
-
return response
|
|
280
|
-
|
|
281
|
-
def wait(self, seconds: float) -> Dict[str, Any]:
|
|
282
|
-
"""Wait for specified number of seconds"""
|
|
283
|
-
return self.api.wait(self.computer_id, seconds)
|
|
37
|
+
if hasattr(e, 'response') and e.response is not None:
|
|
38
|
+
try:
|
|
39
|
+
error_data = e.response.json()
|
|
40
|
+
if 'error' in error_data:
|
|
41
|
+
raise Exception(error_data['error']) from None
|
|
42
|
+
except (ValueError, KeyError):
|
|
43
|
+
pass
|
|
44
|
+
raise Exception(f"Request failed with status {e.response.status_code}") from None
|
|
45
|
+
|
|
46
|
+
# Generic error message without exposing internal details
|
|
47
|
+
raise Exception("Failed to connect to Orgo service. Please check your connection and try again.") from None
|
|
48
|
+
|
|
49
|
+
# Project methods
|
|
50
|
+
def create_project(self, name: str) -> Dict[str, Any]:
|
|
51
|
+
"""Create a new named project"""
|
|
52
|
+
return self._request("POST", "projects", {"name": name})
|
|
53
|
+
|
|
54
|
+
def get_project_by_name(self, name: str) -> Dict[str, Any]:
|
|
55
|
+
"""Get project details by name"""
|
|
56
|
+
projects = self.list_projects()
|
|
57
|
+
for project in projects:
|
|
58
|
+
if project.get("name") == name:
|
|
59
|
+
return project
|
|
60
|
+
raise Exception(f"Project '{name}' not found") from None
|
|
61
|
+
|
|
62
|
+
def get_project(self, project_id: str) -> Dict[str, Any]:
|
|
63
|
+
"""Get project details by ID"""
|
|
64
|
+
return self._request("GET", f"projects/{project_id}")
|
|
65
|
+
|
|
66
|
+
def list_projects(self) -> List[Dict[str, Any]]:
|
|
67
|
+
"""List all projects"""
|
|
68
|
+
response = self._request("GET", "projects")
|
|
69
|
+
return response.get("projects", [])
|
|
70
|
+
|
|
71
|
+
def delete_project(self, project_id: str) -> Dict[str, Any]:
|
|
72
|
+
"""Delete a project and all its computers"""
|
|
73
|
+
return self._request("DELETE", f"projects/{project_id}")
|
|
74
|
+
|
|
75
|
+
# Computer methods
|
|
76
|
+
def create_computer(self, project_id: str, computer_name: str,
|
|
77
|
+
os: str = "linux", ram: int = 2, cpu: int = 2,
|
|
78
|
+
gpu: str = "none") -> Dict[str, Any]:
|
|
79
|
+
"""Create a new computer within a project"""
|
|
80
|
+
return self._request("POST", "computers", {
|
|
81
|
+
"project_id": project_id,
|
|
82
|
+
"name": computer_name,
|
|
83
|
+
"os": os,
|
|
84
|
+
"ram": ram,
|
|
85
|
+
"cpu": cpu,
|
|
86
|
+
"gpu": gpu
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
def list_computers(self, project_id: str) -> List[Dict[str, Any]]:
|
|
90
|
+
"""List all computers in a project"""
|
|
91
|
+
project = self.get_project(project_id)
|
|
92
|
+
return project.get("desktops", [])
|
|
93
|
+
|
|
94
|
+
def get_computer(self, computer_id: str) -> Dict[str, Any]:
|
|
95
|
+
"""Get computer details"""
|
|
96
|
+
return self._request("GET", f"computers/{computer_id}")
|
|
97
|
+
|
|
98
|
+
def delete_computer(self, computer_id: str) -> Dict[str, Any]:
|
|
99
|
+
"""Delete a computer"""
|
|
100
|
+
return self._request("DELETE", f"computers/{computer_id}")
|
|
101
|
+
|
|
102
|
+
def restart_computer(self, computer_id: str) -> Dict[str, Any]:
|
|
103
|
+
"""Restart a computer"""
|
|
104
|
+
return self._request("POST", f"computers/{computer_id}/restart")
|
|
105
|
+
|
|
106
|
+
# Computer control methods
|
|
107
|
+
def left_click(self, computer_id: str, x: int, y: int) -> Dict[str, Any]:
|
|
108
|
+
return self._request("POST", f"computers/{computer_id}/click", {
|
|
109
|
+
"button": "left", "x": x, "y": y
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
def right_click(self, computer_id: str, x: int, y: int) -> Dict[str, Any]:
|
|
113
|
+
return self._request("POST", f"computers/{computer_id}/click", {
|
|
114
|
+
"button": "right", "x": x, "y": y
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
def double_click(self, computer_id: str, x: int, y: int) -> Dict[str, Any]:
|
|
118
|
+
return self._request("POST", f"computers/{computer_id}/click", {
|
|
119
|
+
"button": "left", "x": x, "y": y, "double": True
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
def drag(self, computer_id: str, start_x: int, start_y: int,
|
|
123
|
+
end_x: int, end_y: int, button: str = "left",
|
|
124
|
+
duration: float = 0.5) -> Dict[str, Any]:
|
|
125
|
+
"""Perform a drag operation from start to end coordinates"""
|
|
126
|
+
return self._request("POST", f"computers/{computer_id}/drag", {
|
|
127
|
+
"start_x": start_x,
|
|
128
|
+
"start_y": start_y,
|
|
129
|
+
"end_x": end_x,
|
|
130
|
+
"end_y": end_y,
|
|
131
|
+
"button": button,
|
|
132
|
+
"duration": duration
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
def scroll(self, computer_id: str, direction: str, amount: int = 3) -> Dict[str, Any]:
|
|
136
|
+
return self._request("POST", f"computers/{computer_id}/scroll", {
|
|
137
|
+
"direction": direction, "amount": amount
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
def type_text(self, computer_id: str, text: str) -> Dict[str, Any]:
|
|
141
|
+
return self._request("POST", f"computers/{computer_id}/type", {
|
|
142
|
+
"text": text
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
def key_press(self, computer_id: str, key: str) -> Dict[str, Any]:
|
|
146
|
+
return self._request("POST", f"computers/{computer_id}/key", {
|
|
147
|
+
"key": key
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
def get_screenshot(self, computer_id: str) -> Dict[str, Any]:
|
|
151
|
+
return self._request("GET", f"computers/{computer_id}/screenshot")
|
|
152
|
+
|
|
153
|
+
def execute_bash(self, computer_id: str, command: str) -> Dict[str, Any]:
|
|
154
|
+
return self._request("POST", f"computers/{computer_id}/bash", {
|
|
155
|
+
"command": command
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
def execute_python(self, computer_id: str, code: str, timeout: int = 10) -> Dict[str, Any]:
|
|
159
|
+
"""Execute Python code on the computer"""
|
|
160
|
+
return self._request("POST", f"computers/{computer_id}/exec", {
|
|
161
|
+
"code": code,
|
|
162
|
+
"timeout": timeout
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
def wait(self, computer_id: str, duration: float) -> Dict[str, Any]:
|
|
166
|
+
return self._request("POST", f"computers/{computer_id}/wait", {
|
|
167
|
+
"duration": duration
|
|
168
|
+
})
|
|
284
169
|
|
|
285
170
|
# Streaming methods
|
|
286
|
-
def start_stream(self,
|
|
287
|
-
"""Start streaming
|
|
288
|
-
return self.
|
|
171
|
+
def start_stream(self, computer_id: str, connection_name: str) -> Dict[str, Any]:
|
|
172
|
+
"""Start streaming to a configured RTMP connection"""
|
|
173
|
+
return self._request("POST", f"computers/{computer_id}/stream/start", {
|
|
174
|
+
"connection_name": connection_name
|
|
175
|
+
})
|
|
289
176
|
|
|
290
|
-
def stop_stream(self) -> Dict[str, Any]:
|
|
177
|
+
def stop_stream(self, computer_id: str) -> Dict[str, Any]:
|
|
291
178
|
"""Stop the active stream"""
|
|
292
|
-
return self.
|
|
293
|
-
|
|
294
|
-
def stream_status(self) -> Dict[str, Any]:
|
|
295
|
-
"""Get the current streaming status"""
|
|
296
|
-
return self.api.get_stream_status(self.computer_id)
|
|
297
|
-
|
|
298
|
-
# AI control method
|
|
299
|
-
def prompt(self,
|
|
300
|
-
instruction: str,
|
|
301
|
-
provider: str = "anthropic",
|
|
302
|
-
model: str = "claude-3-7-sonnet-20250219",
|
|
303
|
-
display_width: int = 1024,
|
|
304
|
-
display_height: int = 768,
|
|
305
|
-
callback: Optional[Callable[[str, Any], None]] = None,
|
|
306
|
-
thinking_enabled: bool = False,
|
|
307
|
-
thinking_budget: int = 1024,
|
|
308
|
-
max_tokens: int = 4096,
|
|
309
|
-
max_iterations: int = 20,
|
|
310
|
-
max_saved_screenshots: int = 5,
|
|
311
|
-
api_key: Optional[str] = None) -> List[Dict[str, Any]]:
|
|
312
|
-
"""Control the computer with natural language instructions using an AI assistant"""
|
|
313
|
-
provider_instance = get_provider(provider)
|
|
314
|
-
|
|
315
|
-
return provider_instance.execute(
|
|
316
|
-
computer_id=self.computer_id,
|
|
317
|
-
instruction=instruction,
|
|
318
|
-
callback=callback,
|
|
319
|
-
api_key=api_key,
|
|
320
|
-
model=model,
|
|
321
|
-
display_width=display_width,
|
|
322
|
-
display_height=display_height,
|
|
323
|
-
thinking_enabled=thinking_enabled,
|
|
324
|
-
thinking_budget=thinking_budget,
|
|
325
|
-
max_tokens=max_tokens,
|
|
326
|
-
max_iterations=max_iterations,
|
|
327
|
-
max_saved_screenshots=max_saved_screenshots,
|
|
328
|
-
orgo_api_key=self.api_key,
|
|
329
|
-
orgo_base_url=self.base_api_url
|
|
330
|
-
)
|
|
179
|
+
return self._request("POST", f"computers/{computer_id}/stream/stop")
|
|
331
180
|
|
|
332
|
-
def
|
|
333
|
-
|
|
181
|
+
def get_stream_status(self, computer_id: str) -> Dict[str, Any]:
|
|
182
|
+
"""Get current stream status"""
|
|
183
|
+
return self._request("GET", f"computers/{computer_id}/stream/status")
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
orgo/__init__.py,sha256=aw3BM7-Wy8jk-mvIWRG2gC4-nsc74s6ZFm1U21NyGeM,171
|
|
2
|
-
orgo/computer.py,sha256=
|
|
2
|
+
orgo/computer.py,sha256=apny7V3IYJTyDwn5utukzyECLWT65oo-1EmFRwHL--E,7544
|
|
3
3
|
orgo/project.py,sha256=uVDFa8iyn5OaHzTzjGQhxnF_nVzwkqkqUShiV3M0AWU,3150
|
|
4
4
|
orgo/prompt.py,sha256=ynblwXPTDp_aF1MbGBsY0PIEr9naklDaKFcfSE_EZ6E,19781
|
|
5
5
|
orgo/api/__init__.py,sha256=9Tzb_OPJ5DH7Cg7OrHzpZZUT4ip05alpa9RLDYmnId8,113
|
|
6
6
|
orgo/api/client.py,sha256=sBvX1e1BSY_BB7N4Cnb7mhBt1JBn-EpIYc5KO5sf6m4,7406
|
|
7
7
|
orgo/utils/__init__.py,sha256=W4G_nwGBf_7jy0w_mfcrkllurYHSRU4B5cMTVYH_uCc,123
|
|
8
8
|
orgo/utils/auth.py,sha256=tPLBJY-6gdBQWLUjUbwIwxHphC3KoRT_XgP3Iykw3Mw,509
|
|
9
|
-
orgo-0.0.
|
|
10
|
-
orgo-0.0.
|
|
11
|
-
orgo-0.0.
|
|
12
|
-
orgo-0.0.
|
|
9
|
+
orgo-0.0.30.dist-info/METADATA,sha256=piWp5WsPjKfXfJPjDKxtq9YBE2Io4FAH_JLASnoeJVg,822
|
|
10
|
+
orgo-0.0.30.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
11
|
+
orgo-0.0.30.dist-info/top_level.txt,sha256=q0rYtFji8GbYuhFW8A5Ab9e0j27761IKPhnL0E9xow4,5
|
|
12
|
+
orgo-0.0.30.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|