setta 0.0.3.dev8__py3-none-any.whl → 0.0.3.dev9__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- setta/__init__.py +1 -1
- setta/routers/interactive.py +7 -8
- setta/static/constants/constants.json +1 -0
- setta/static/frontend/assets/{index-8204c872.js → index-d7ede6b5.js} +145 -145
- setta/static/frontend/index.html +1 -1
- setta/tasks/tasks.py +74 -23
- setta/tasks/utils.py +48 -26
- {setta-0.0.3.dev8.dist-info → setta-0.0.3.dev9.dist-info}/METADATA +1 -1
- {setta-0.0.3.dev8.dist-info → setta-0.0.3.dev9.dist-info}/RECORD +13 -13
- {setta-0.0.3.dev8.dist-info → setta-0.0.3.dev9.dist-info}/LICENSE +0 -0
- {setta-0.0.3.dev8.dist-info → setta-0.0.3.dev9.dist-info}/WHEEL +0 -0
- {setta-0.0.3.dev8.dist-info → setta-0.0.3.dev9.dist-info}/entry_points.txt +0 -0
- {setta-0.0.3.dev8.dist-info → setta-0.0.3.dev9.dist-info}/top_level.txt +0 -0
setta/static/frontend/index.html
CHANGED
@@ -15,7 +15,7 @@
|
|
15
15
|
|
16
16
|
|
17
17
|
<title>setta.dev</title>
|
18
|
-
<script type="module" crossorigin src="/static/assets/index-
|
18
|
+
<script type="module" crossorigin src="/static/assets/index-d7ede6b5.js"></script>
|
19
19
|
<link rel="stylesheet" href="/static/assets/index-af271c9f.css">
|
20
20
|
</head>
|
21
21
|
<body>
|
setta/tasks/tasks.py
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
import asyncio
|
2
|
+
import copy
|
2
3
|
import logging
|
4
|
+
import time
|
3
5
|
from typing import Dict
|
4
6
|
|
5
7
|
from setta.database.utils import create_new_id
|
@@ -63,12 +65,12 @@ class Tasks:
|
|
63
65
|
tasks = []
|
64
66
|
results = []
|
65
67
|
|
66
|
-
for sp_info in self.in_memory_subprocesses.
|
67
|
-
for fn_name,
|
68
|
+
for sp_key, sp_info in self.in_memory_subprocesses.items():
|
69
|
+
for fn_name, fnInfo in sp_info["fnInfo"].items():
|
68
70
|
if (
|
69
71
|
call_all
|
70
|
-
or None in dependencies
|
71
|
-
or any(k in dependencies for k in message.content.keys())
|
72
|
+
or None in fnInfo["dependencies"]
|
73
|
+
or any(k in fnInfo["dependencies"] for k in message.content.keys())
|
72
74
|
):
|
73
75
|
# Send message to subprocess
|
74
76
|
sp_info["subprocess"].parent_conn.send(
|
@@ -78,6 +80,8 @@ class Tasks:
|
|
78
80
|
# Create task for receiving response
|
79
81
|
task = asyncio.create_task(
|
80
82
|
self._handle_subprocess_response(
|
83
|
+
sp_key,
|
84
|
+
fn_name,
|
81
85
|
message.id,
|
82
86
|
sp_info["subprocess"].parent_conn.recv,
|
83
87
|
websocket_manager,
|
@@ -100,30 +104,40 @@ class Tasks:
|
|
100
104
|
return {"content": content, "messageType": C.WS_IN_MEMORY_FN_RETURN}
|
101
105
|
|
102
106
|
async def _handle_subprocess_response(
|
103
|
-
self, msg_id, recv_fn, websocket_manager, results
|
107
|
+
self, subprocess_key, fn_name, msg_id, recv_fn, websocket_manager, results
|
104
108
|
):
|
105
109
|
# Run the receive function in a thread
|
110
|
+
start_time = time.perf_counter()
|
106
111
|
result = await self.task_runner.run(recv_fn, [], RunType.THREAD)
|
112
|
+
elapsed_time = time.perf_counter() - start_time
|
107
113
|
if result["status"] == "success":
|
108
|
-
|
109
|
-
|
110
|
-
|
114
|
+
self.update_average_subprocess_fn_time(
|
115
|
+
subprocess_key, fn_name, elapsed_time
|
116
|
+
)
|
117
|
+
if websocket_manager is not None:
|
118
|
+
if result["content"]:
|
119
|
+
await websocket_manager.send_message_to_requester(
|
120
|
+
msg_id, result["content"], result["messageType"]
|
121
|
+
)
|
122
|
+
await self.maybe_send_latest_run_time_info(
|
123
|
+
subprocess_key, fn_name, msg_id, websocket_manager
|
111
124
|
)
|
112
|
-
|
113
|
-
|
125
|
+
else:
|
126
|
+
results.append(result)
|
114
127
|
|
115
128
|
async def add_custom_fns(self, code_graph, to_cache):
|
116
129
|
for c in code_graph:
|
117
130
|
subprocess_key = c["subprocess_key"]
|
118
131
|
module_name = c["module_name"]
|
119
132
|
sp = self.in_memory_subprocesses.get(subprocess_key, {}).get("subprocess")
|
120
|
-
if
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
}
|
133
|
+
if sp:
|
134
|
+
sp.close()
|
135
|
+
logger.debug(f"Creating new subprocess for {module_name}")
|
136
|
+
sp = SettaInMemoryFnSubprocess(self.stop_event, self.websockets)
|
137
|
+
self.in_memory_subprocesses[subprocess_key] = {
|
138
|
+
"subprocess": sp,
|
139
|
+
"fnInfo": {},
|
140
|
+
}
|
127
141
|
|
128
142
|
sp.parent_conn.send(
|
129
143
|
{
|
@@ -134,17 +148,22 @@ class Tasks:
|
|
134
148
|
}
|
135
149
|
)
|
136
150
|
result = await self.task_runner.run(sp.parent_conn.recv, [], RunType.THREAD)
|
137
|
-
|
151
|
+
fnInfo = self.in_memory_subprocesses[subprocess_key]["fnInfo"]
|
138
152
|
|
139
153
|
if result["status"] == "success":
|
140
|
-
|
154
|
+
for k, v in result["content"].items():
|
155
|
+
if k not in fnInfo:
|
156
|
+
fnInfo[k] = {
|
157
|
+
"dependencies": set(),
|
158
|
+
"averageRunTime": None,
|
159
|
+
"callCount": 0,
|
160
|
+
"lastStatsUpdate": time.time(),
|
161
|
+
}
|
162
|
+
fnInfo[k]["dependencies"].update(v)
|
141
163
|
else:
|
142
164
|
# TODO: store error message and display on frontend?
|
143
165
|
pass
|
144
166
|
|
145
|
-
all_dependencies = set()
|
146
|
-
for d in sp_info["dependencies"].values():
|
147
|
-
all_dependencies.update(d)
|
148
167
|
initial_result = await self.call_in_memory_subprocess_fn(
|
149
168
|
TaskMessage(id=create_new_id(), content={}), call_all=True
|
150
169
|
)
|
@@ -153,9 +172,41 @@ class Tasks:
|
|
153
172
|
f"self.in_memory_subprocesses keys: {self.in_memory_subprocesses.keys()}"
|
154
173
|
)
|
155
174
|
|
156
|
-
return
|
175
|
+
return initial_result["content"]
|
157
176
|
|
158
177
|
def close(self):
|
159
178
|
self.stop_event.set()
|
160
179
|
for v in self.in_memory_subprocesses.values():
|
161
180
|
v["subprocess"].close()
|
181
|
+
|
182
|
+
def update_average_subprocess_fn_time(self, subprocess_key, fn_name, new_time):
|
183
|
+
fnInfo = self.in_memory_subprocesses[subprocess_key]["fnInfo"][fn_name]
|
184
|
+
current_avg = fnInfo["averageRunTime"]
|
185
|
+
new_avg = (
|
186
|
+
new_time
|
187
|
+
if current_avg is None
|
188
|
+
else ((0.9) * current_avg) + (0.1 * new_time)
|
189
|
+
)
|
190
|
+
fnInfo["averageRunTime"] = new_avg
|
191
|
+
fnInfo["callCount"] += 1
|
192
|
+
fnInfo["lastStatsUpdate"] = time.time()
|
193
|
+
|
194
|
+
async def maybe_send_latest_run_time_info(
|
195
|
+
self, subprocess_key, fn_name, msg_id, websocket_manager
|
196
|
+
):
|
197
|
+
fnInfo = self.in_memory_subprocesses[subprocess_key]["fnInfo"][fn_name]
|
198
|
+
if fnInfo["callCount"] % 10 == 0 or (
|
199
|
+
fnInfo["lastStatsUpdate"] and (time.time() - fnInfo["lastStatsUpdate"]) > 10
|
200
|
+
):
|
201
|
+
newInfo = self.getInMemorySubprocessInfo()
|
202
|
+
await websocket_manager.send_message_to_requester(
|
203
|
+
msg_id, newInfo, C.WS_IN_MEMORY_FN_AVG_RUN_TIME
|
204
|
+
)
|
205
|
+
|
206
|
+
def getInMemorySubprocessInfo(self):
|
207
|
+
output = {}
|
208
|
+
for sp_key, sp_info in self.in_memory_subprocesses.items():
|
209
|
+
output[sp_key] = {"fnInfo": copy.deepcopy(sp_info["fnInfo"])}
|
210
|
+
for fnInfo in output[sp_key]["fnInfo"].values():
|
211
|
+
fnInfo["dependencies"] = list(fnInfo["dependencies"])
|
212
|
+
return output
|
setta/tasks/utils.py
CHANGED
@@ -53,7 +53,8 @@ class SettaInMemoryFnSubprocess:
|
|
53
53
|
self.process.daemon = True # Ensure process dies with parent
|
54
54
|
self.process.start()
|
55
55
|
|
56
|
-
self.stop_event =
|
56
|
+
self.stop_event = asyncio.Event()
|
57
|
+
self.tasks_stop_event = stop_event
|
57
58
|
self.websockets = websockets
|
58
59
|
self.stdout_queue = queue.Queue()
|
59
60
|
self.stdout_processor_task = None
|
@@ -99,15 +100,15 @@ class SettaInMemoryFnSubprocess:
|
|
99
100
|
# Import and store module
|
100
101
|
module = import_code_from_string(code, module_name)
|
101
102
|
added_fn_names = add_fns_from_module(fns_dict, module, module_name)
|
102
|
-
|
103
|
+
dependencies = {}
|
103
104
|
for k in added_fn_names:
|
104
105
|
cache[k] = msg["to_cache"]
|
105
|
-
|
106
|
+
dependencies[k] = get_task_metadata(fns_dict[k], cache[k])
|
106
107
|
|
107
108
|
self.child_conn.send(
|
108
109
|
{
|
109
110
|
"status": "success",
|
110
|
-
"content":
|
111
|
+
"content": dependencies,
|
111
112
|
}
|
112
113
|
)
|
113
114
|
|
@@ -138,22 +139,34 @@ class SettaInMemoryFnSubprocess:
|
|
138
139
|
|
139
140
|
def close(self):
|
140
141
|
try:
|
142
|
+
logger.debug("Initiating shutdown sequence")
|
141
143
|
self.parent_conn.send({"type": "shutdown"})
|
142
|
-
self.process.join(timeout=
|
143
|
-
except:
|
144
|
-
pass
|
144
|
+
self.process.join(timeout=2) # Add timeout to process join
|
145
145
|
|
146
|
-
|
147
|
-
|
148
|
-
|
146
|
+
if self.process.is_alive():
|
147
|
+
logger.debug("Process still alive after timeout, forcing termination")
|
148
|
+
self.process.terminate()
|
149
|
+
self.process.join(timeout=1)
|
150
|
+
except Exception as e:
|
151
|
+
logger.debug(f"Error during process shutdown: {e}")
|
149
152
|
|
150
|
-
#
|
151
|
-
self.
|
152
|
-
|
153
|
-
|
154
|
-
|
153
|
+
# Set stop event before closing pipes
|
154
|
+
self.stop_event.set()
|
155
|
+
|
156
|
+
# Close all connections
|
157
|
+
for conn in [
|
158
|
+
self.parent_conn,
|
159
|
+
self.child_conn,
|
160
|
+
self.stdout_parent_conn,
|
161
|
+
self.stdout_child_conn,
|
162
|
+
]:
|
163
|
+
conn.close()
|
164
|
+
|
165
|
+
self.stdout_thread.join(timeout=2) # Add timeout to thread join
|
166
|
+
|
167
|
+
if self.stdout_thread.is_alive():
|
168
|
+
logger.debug("Stdout thread failed to terminate within timeout")
|
155
169
|
|
156
|
-
self.stdout_thread.join()
|
157
170
|
if self.stdout_processor_task:
|
158
171
|
self.stdout_processor_task.cancel()
|
159
172
|
|
@@ -183,9 +196,9 @@ class SettaInMemoryFnSubprocess:
|
|
183
196
|
self.stdout_processor_task = None
|
184
197
|
|
185
198
|
async def process_stdout_queue(self):
|
186
|
-
while not self.
|
199
|
+
while not self.should_stop():
|
187
200
|
try:
|
188
|
-
if self.
|
201
|
+
if self.should_stop():
|
189
202
|
break
|
190
203
|
if len(self.websockets) > 0:
|
191
204
|
stdout_data = self.stdout_queue.get_nowait()
|
@@ -198,19 +211,28 @@ class SettaInMemoryFnSubprocess:
|
|
198
211
|
except asyncio.CancelledError:
|
199
212
|
break
|
200
213
|
except Exception as e:
|
201
|
-
if self.
|
214
|
+
if self.should_stop():
|
202
215
|
break
|
203
216
|
logger.debug(f"Error processing stdout: {e}")
|
204
217
|
|
205
218
|
def stdout_listener(self):
|
206
|
-
while not self.
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
219
|
+
while not self.should_stop():
|
220
|
+
if self.stdout_parent_conn.poll(0.1): # Check for data with timeout
|
221
|
+
try:
|
222
|
+
stdout_data = self.stdout_parent_conn.recv()
|
223
|
+
self.stdout_queue.put(stdout_data)
|
224
|
+
except EOFError: # Pipe was closed
|
225
|
+
break
|
226
|
+
except Exception as e:
|
227
|
+
logger.debug(f"Error in stdout listener: {e}")
|
228
|
+
if self.should_stop():
|
229
|
+
break
|
230
|
+
else: # No data available within timeout
|
231
|
+
if self.should_stop():
|
212
232
|
break
|
213
|
-
|
233
|
+
|
234
|
+
def should_stop(self):
|
235
|
+
return self.stop_event.is_set() or self.tasks_stop_event.is_set()
|
214
236
|
|
215
237
|
|
216
238
|
def add_fns_from_module(fns_dict, module, module_name=None):
|
@@ -1,4 +1,4 @@
|
|
1
|
-
setta/__init__.py,sha256=
|
1
|
+
setta/__init__.py,sha256=mRKlQs_lYaraYvOzYlGQDMNDPQsRu2O-zNqzBFCdPLA,27
|
2
2
|
setta/server.py,sha256=P78BMFvcCokVhjnVlNIKcmpCSvmzSqt-33bx4bhOe6Y,4626
|
3
3
|
setta/start.py,sha256=jEeSiocLeBitvg48fa6k1CpLnPI63JHkQ8O-WVM6ch8,3078
|
4
4
|
setta/cli/__init__.py,sha256=UxZG_VOMuF6lEBT3teUgTS9ulsK3wt3Gu3BbAQiAmt8,47
|
@@ -87,7 +87,7 @@ setta/routers/artifact.py,sha256=9wHdreg5DsLshhET-6gEDw2Apw_-r8bRF1x3-_dD9mU,266
|
|
87
87
|
setta/routers/code_info.py,sha256=rDBLkr5VQOlktap3hWA73ls0VrBi5y4mc_SfWzw9ad0,857
|
88
88
|
setta/routers/dependencies.py,sha256=lQDZFcXw-jUXK1q8yglUg3jY9dKoE-xvVcWckKqmOr4,1126
|
89
89
|
setta/routers/in_memory_fn_stdout_websocket.py,sha256=T2BpLzh6PwYQP0qIkFS4r_VfEKBlwl4gkwIaq6r6Phs,604
|
90
|
-
setta/routers/interactive.py,sha256=
|
90
|
+
setta/routers/interactive.py,sha256=V68ooA_C2rSqyXeARHifvr_17iCfLrWPERLSrrb_PIU,4316
|
91
91
|
setta/routers/lsp.py,sha256=DAZqdiRKDWJ9ikjwQetV4_8s9U-EDC91ToJA3u57qnU,385
|
92
92
|
setta/routers/projects.py,sha256=p3zPD3jobYOxBGJSSIYS1Aqu1w-PrJCcEN6dPJ0DT6E,5255
|
93
93
|
setta/routers/reference_renaming.py,sha256=Ec1hz2Nz_hYqk8GyGmUcWKvXo-lVEDbIIK2YbX-wi00,3598
|
@@ -97,7 +97,7 @@ setta/routers/terminals.py,sha256=91I3tVUPJtLyCD_-E_qBQ_k8uuNUrcXl5P7sCTQuDQE,24
|
|
97
97
|
setta/routers/websocket.py,sha256=6fSROv9C5PobPXppUWwNLDDO0p8VADYaf2KcgIuTQp4,1121
|
98
98
|
setta/static/constants/BaseUITypes.json,sha256=S08qzaNwjclRKuC9U3J0_PpmDTw5aQFwKQcUb0SiiR4,3873
|
99
99
|
setta/static/constants/Settings.json,sha256=-cpSDnjJ9s86z_hfC69xq7A4kxqphKXqssMUUhTN4BQ,3444
|
100
|
-
setta/static/constants/constants.json,sha256=
|
100
|
+
setta/static/constants/constants.json,sha256=ICVe1HiGoUlSyiuNptfLX7rimHJk_7SfN38MWJEL62c,5151
|
101
101
|
setta/static/constants/db_init.sql,sha256=eSYQrcEEqNPcshOHJEOpSGGkoN_FJwMfZqJFrbnX_8U,8416
|
102
102
|
setta/static/constants/defaultValues.json,sha256=7S8wabxk7CIM23H0FcXdLaIhhldsFUfN8lrzWAIU5pQ,2948
|
103
103
|
setta/static/constants/settingsProject.json,sha256=yfSIQpu2zUcFnUp2JimAkZ0ispvMv8lMPUUTx4AWSi4,10006
|
@@ -108,7 +108,7 @@ setta/static/frontend/browserconfig.xml,sha256=w0iw1t89kA7-965LTfyLYrFzewTQnUWE_
|
|
108
108
|
setta/static/frontend/favicon-16x16.png,sha256=q67Crpy8s3wryu7Y3kffPeysN99Lt4XeFygXhPKize8,740
|
109
109
|
setta/static/frontend/favicon-32x32.png,sha256=4NKXYticYdMrRHmVveHjxqnBU1HWgBT5JyJG8lx3BNE,1027
|
110
110
|
setta/static/frontend/favicon.ico,sha256=02qhEBLsvsgBTZX6dcZElMyivlvrR7Yr6wB8ItEZFsc,15086
|
111
|
-
setta/static/frontend/index.html,sha256=
|
111
|
+
setta/static/frontend/index.html,sha256=C5t7lfzDhTvNFweX0ISsHGNyj8TkHAz8uv-VwByWtlY,1296
|
112
112
|
setta/static/frontend/manifest.json,sha256=ULPYw5A68_eNhxuUVXqxT045yhkurKPSz6hjyGcnmhQ,492
|
113
113
|
setta/static/frontend/mstile-144x144.png,sha256=wQqckmRWre2NCCevevI3rv4j0tcduVMkpYr2tPj73cs,2692
|
114
114
|
setta/static/frontend/mstile-150x150.png,sha256=FUwy6PipTofnhmJB5CdXWYgwy-2inq_sIOdOwdDklcY,2674
|
@@ -184,8 +184,8 @@ setta/static/frontend/assets/cormorant-garamond-latin-700-italic-0bc53e12.woff2,
|
|
184
184
|
setta/static/frontend/assets/cormorant-garamond-latin-ext-700-italic-525738e0.woff2,sha256=Ulc44CPXdUiI5dY86W76HLk7801Fm9_QywCV-8GRtFU,17240
|
185
185
|
setta/static/frontend/assets/cormorant-garamond-vietnamese-700-italic-99563037.woff2,sha256=mVYwN54qI0RLXqyrDGPUNpBHWSJDKjgUyBRWa2FJ_ao,5248
|
186
186
|
setta/static/frontend/assets/erase-5e0448ea.svg,sha256=XgRI6pChr392LJ-pGbwqqkN8OWcJMEtRGX-Gv-90qjw,872
|
187
|
-
setta/static/frontend/assets/index-8204c872.js,sha256=3vVnv6_MeYW0qxkfUH5ecJwXxeb4lJevbvhWT60vXxQ,2847453
|
188
187
|
setta/static/frontend/assets/index-af271c9f.css,sha256=ryccn_uul30_aMdIhgzMlq6GcE0D6x8fyfneCdgaY9o,232608
|
188
|
+
setta/static/frontend/assets/index-d7ede6b5.js,sha256=giu4kQ9aQjEAt6f0_j7KZXnM0XNGtAXSIdOXAO3q_40,2848353
|
189
189
|
setta/static/frontend/assets/inter-all-400-normal-054f12d0.woff,sha256=BU8S0GmcIMyYte4ESEdQJO-WvL2Rb-38m1n0ujdbYxI,128624
|
190
190
|
setta/static/frontend/assets/inter-all-600-normal-c03769e5.woff,sha256=wDdp5VNyQL_IbxcPThD2qI-ETg_QKj7AmCwMCjqDfLE,139072
|
191
191
|
setta/static/frontend/assets/inter-all-800-normal-15dc6e4b.woff,sha256=FdxuS9xuVumB5nbVcCXyt3IWqzS4Z75qiRz_0FV5al0,139120
|
@@ -232,8 +232,8 @@ setta/static/seed/.DS_Store,sha256=ENxJvDQd7Te_U8gExcXtHE-mAeBUYOHELRfDWgN1NmA,6
|
|
232
232
|
setta/static/seed/examples/.DS_Store,sha256=1lFlJ5EFymdzGAUAaI30vcaaLHt3F1LwpG7xILf9jsM,6148
|
233
233
|
setta/tasks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
234
234
|
setta/tasks/task_runner.py,sha256=gMXpfZWFMQbix2MfrHVCKB7BxQCjO8JH2P8cxUmt1ms,849
|
235
|
-
setta/tasks/tasks.py,sha256=
|
236
|
-
setta/tasks/utils.py,sha256=
|
235
|
+
setta/tasks/tasks.py,sha256=0VYL2P9bOV5b82OHEuIIIhixBit9qcoK817x5JZdpQE,8126
|
236
|
+
setta/tasks/utils.py,sha256=9XfSoqYsUf9rBWorZTEqGXfU6J6-nDztIkkgRo1ndhQ,9509
|
237
237
|
setta/tasks/fns/__init__.py,sha256=JhGzzQGaT9BWtF3pOmguh6pzIF9kdG3jdDNLyYZ2w7g,461
|
238
238
|
setta/tasks/fns/codeAreaAutocomplete.py,sha256=gJ5JbjkWDyTothr-UF-YlOxrbVzj2iyOVK7XD3lfhSQ,6416
|
239
239
|
setta/tasks/fns/codeAreaFindTemplateVars.py,sha256=vD9rY8VNPavv6VKa1bnxRPPRDNvFQy6mPIZRl-_3GnY,3708
|
@@ -254,9 +254,9 @@ setta/utils/generate_new_filename.py,sha256=KBLX6paDmTvXR-027TpqQkfijIXc7mCfhen-
|
|
254
254
|
setta/utils/section_contents.py,sha256=V2HQPik6DfSXw4j7IalbP5AZ3OEGCbtL5ub3xL-Q_Qo,4141
|
255
255
|
setta/utils/utils.py,sha256=KjzcvgM3Ab3IcE8vaWYtgBpwzPLKg0LmblnHLoYZJHM,9164
|
256
256
|
setta/utils/websocket_manager.py,sha256=S2lEGZsc2OhW0yKLW9VEcH7wi7ppzTfDMQa_hxf3ovc,3772
|
257
|
-
setta-0.0.3.
|
258
|
-
setta-0.0.3.
|
259
|
-
setta-0.0.3.
|
260
|
-
setta-0.0.3.
|
261
|
-
setta-0.0.3.
|
262
|
-
setta-0.0.3.
|
257
|
+
setta-0.0.3.dev9.dist-info/LICENSE,sha256=us9fuCq9wmiZVzayjKxNZ2iJYF6dROe0Qp57ToCO7XU,11361
|
258
|
+
setta-0.0.3.dev9.dist-info/METADATA,sha256=OXk3_WwJkRIycDIw9YOQFDWJpYQlWXv5TQLznCHNd_g,829
|
259
|
+
setta-0.0.3.dev9.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
260
|
+
setta-0.0.3.dev9.dist-info/entry_points.txt,sha256=P0qCESy9fWF2q1EQ9JufGldCSnPHplDPn8J6Bgk5hB0,42
|
261
|
+
setta-0.0.3.dev9.dist-info/top_level.txt,sha256=8G4lmRzVOnJ11_DescPVHE6MQZH-o06A0nGsDDV2ngY,6
|
262
|
+
setta-0.0.3.dev9.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|