nebu 0.1.121__py3-none-any.whl → 0.1.123__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.
- nebu/processors/consumer.py +8 -8
- nebu/processors/consumer_health_worker.py +78 -69
- {nebu-0.1.121.dist-info → nebu-0.1.123.dist-info}/METADATA +1 -1
- {nebu-0.1.121.dist-info → nebu-0.1.123.dist-info}/RECORD +7 -7
- {nebu-0.1.121.dist-info → nebu-0.1.123.dist-info}/WHEEL +0 -0
- {nebu-0.1.121.dist-info → nebu-0.1.123.dist-info}/licenses/LICENSE +0 -0
- {nebu-0.1.121.dist-info → nebu-0.1.123.dist-info}/top_level.txt +0 -0
nebu/processors/consumer.py
CHANGED
@@ -471,10 +471,10 @@ def check_health_subprocess() -> bool:
|
|
471
471
|
"""Check if the health subprocess is still running and restart if needed."""
|
472
472
|
global health_subprocess
|
473
473
|
|
474
|
-
print(f"[DEBUG] check_health_subprocess called")
|
474
|
+
# print(f"[DEBUG] check_health_subprocess called")
|
475
475
|
|
476
476
|
if health_subprocess is None:
|
477
|
-
print(f"[DEBUG] health_subprocess is None")
|
477
|
+
# print(f"[DEBUG] health_subprocess is None")
|
478
478
|
return False
|
479
479
|
|
480
480
|
# Cat the health subprocess log file
|
@@ -503,7 +503,7 @@ def check_health_subprocess() -> bool:
|
|
503
503
|
|
504
504
|
# Check if process is still running
|
505
505
|
poll_result = health_subprocess.poll()
|
506
|
-
print(f"[DEBUG] health_subprocess.poll() returned: {poll_result}")
|
506
|
+
# print(f"[DEBUG] health_subprocess.poll() returned: {poll_result}")
|
507
507
|
|
508
508
|
if poll_result is None:
|
509
509
|
print(f"[DEBUG] Health subprocess still running (PID {health_subprocess.pid})")
|
@@ -511,29 +511,29 @@ def check_health_subprocess() -> bool:
|
|
511
511
|
|
512
512
|
# Process has exited
|
513
513
|
exit_code = health_subprocess.returncode
|
514
|
-
print(f"[DEBUG] Health subprocess exited with code {exit_code}")
|
514
|
+
# print(f"[DEBUG] Health subprocess exited with code {exit_code}")
|
515
515
|
logger.warning(
|
516
516
|
f"[Consumer] Health subprocess exited with code {exit_code}. Restarting..."
|
517
517
|
)
|
518
518
|
|
519
519
|
# Start a new health subprocess
|
520
|
-
print(f"[DEBUG] Attempting to restart health subprocess...")
|
520
|
+
# print(f"[DEBUG] Attempting to restart health subprocess...")
|
521
521
|
health_subprocess = start_health_check_subprocess()
|
522
522
|
|
523
523
|
if health_subprocess:
|
524
|
-
print(f"[DEBUG] Health subprocess restarted successfully")
|
524
|
+
# print(f"[DEBUG] Health subprocess restarted successfully")
|
525
525
|
# Start monitoring thread for the new subprocess
|
526
526
|
monitor_thread = threading.Thread(
|
527
527
|
target=monitor_health_subprocess, args=(health_subprocess,), daemon=True
|
528
528
|
)
|
529
529
|
monitor_thread.start()
|
530
|
-
print(f"[DEBUG] Monitor thread started for health subprocess")
|
530
|
+
# print(f"[DEBUG] Monitor thread started for health subprocess")
|
531
531
|
logger.info(
|
532
532
|
"[Consumer] Health subprocess restarted and monitoring thread started."
|
533
533
|
)
|
534
534
|
return True
|
535
535
|
else:
|
536
|
-
print(f"[DEBUG] Failed to restart health subprocess")
|
536
|
+
# print(f"[DEBUG] Failed to restart health subprocess")
|
537
537
|
logger.error("[Consumer] Failed to restart health subprocess.")
|
538
538
|
return False
|
539
539
|
|
@@ -31,9 +31,7 @@ def setup_health_logging():
|
|
31
31
|
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
32
32
|
handlers=[
|
33
33
|
logging.FileHandler(log_file),
|
34
|
-
|
35
|
-
sys.stdout
|
36
|
-
), # Also log to stdout for subprocess monitoring
|
34
|
+
# Removed StreamHandler to prevent health logs from appearing in main logs
|
37
35
|
],
|
38
36
|
)
|
39
37
|
|
@@ -51,11 +49,11 @@ def process_health_check_message(
|
|
51
49
|
health_group: str,
|
52
50
|
) -> None:
|
53
51
|
"""Processes a single health check message."""
|
54
|
-
print(f"[HEALTH DEBUG] === PROCESSING HEALTH CHECK MESSAGE ===")
|
55
|
-
print(f"[HEALTH DEBUG] Message ID: {message_id}")
|
56
|
-
print(f"[HEALTH DEBUG] Message data: {message_data}")
|
57
|
-
print(f"[HEALTH DEBUG] Health stream: {health_stream}")
|
58
|
-
print(f"[HEALTH DEBUG] Health group: {health_group}")
|
52
|
+
# print(f"[HEALTH DEBUG] === PROCESSING HEALTH CHECK MESSAGE ===")
|
53
|
+
# print(f"[HEALTH DEBUG] Message ID: {message_id}")
|
54
|
+
# print(f"[HEALTH DEBUG] Message data: {message_data}")
|
55
|
+
# print(f"[HEALTH DEBUG] Health stream: {health_stream}")
|
56
|
+
# print(f"[HEALTH DEBUG] Health group: {health_group}")
|
59
57
|
|
60
58
|
logger.info(f"Processing health check message {message_id}: {message_data}")
|
61
59
|
|
@@ -64,33 +62,33 @@ def process_health_check_message(
|
|
64
62
|
details: Optional[Dict[str, Any]] = None
|
65
63
|
return_stream: Optional[str] = None
|
66
64
|
original_message_id: Optional[str] = None
|
67
|
-
user_id: Optional[str] = None
|
65
|
+
# user_id: Optional[str] = None
|
68
66
|
|
69
67
|
try:
|
70
68
|
if "data" in message_data:
|
71
|
-
print(f"[HEALTH DEBUG] Found 'data' field in message")
|
69
|
+
# print(f"[HEALTH DEBUG] Found 'data' field in message")
|
72
70
|
data_str = message_data["data"]
|
73
71
|
print(f"[HEALTH DEBUG] Raw data string: {data_str}")
|
74
72
|
|
75
73
|
data = json.loads(data_str)
|
76
|
-
print(f"[HEALTH DEBUG] Parsed data: {json.dumps(data, indent=2)}")
|
74
|
+
# print(f"[HEALTH DEBUG] Parsed data: {json.dumps(data, indent=2)}")
|
77
75
|
logger.info(f"Health check data: {data}")
|
78
76
|
|
79
77
|
# Extract important fields from the forwarded message
|
80
78
|
return_stream = data.get("return_stream")
|
81
79
|
original_message_id = data.get("original_message_id")
|
82
|
-
user_id = data.get("user_id")
|
83
|
-
inner_kind = data.get("kind")
|
80
|
+
# user_id = data.get("user_id")
|
81
|
+
# inner_kind = data.get("kind")
|
84
82
|
inner_id = data.get("id")
|
85
83
|
content = data.get("content")
|
86
84
|
|
87
|
-
print(f"[HEALTH DEBUG] Extracted fields:")
|
88
|
-
print(f"[HEALTH DEBUG] return_stream: {return_stream}")
|
89
|
-
print(f"[HEALTH DEBUG] original_message_id: {original_message_id}")
|
90
|
-
print(f"[HEALTH DEBUG] user_id: {user_id}")
|
91
|
-
print(f"[HEALTH DEBUG] inner_kind: {inner_kind}")
|
92
|
-
print(f"[HEALTH DEBUG] inner_id: {inner_id}")
|
93
|
-
print(f"[HEALTH DEBUG] content: {content}")
|
85
|
+
# print(f"[HEALTH DEBUG] Extracted fields:")
|
86
|
+
# print(f"[HEALTH DEBUG] return_stream: {return_stream}")
|
87
|
+
# print(f"[HEALTH DEBUG] original_message_id: {original_message_id}")
|
88
|
+
# print(f"[HEALTH DEBUG] user_id: {user_id}")
|
89
|
+
# print(f"[HEALTH DEBUG] inner_kind: {inner_kind}")
|
90
|
+
# print(f"[HEALTH DEBUG] inner_id: {inner_id}")
|
91
|
+
# print(f"[HEALTH DEBUG] content: {content}")
|
94
92
|
|
95
93
|
# Update details with health check info
|
96
94
|
details = {
|
@@ -101,12 +99,13 @@ def process_health_check_message(
|
|
101
99
|
|
102
100
|
if content and isinstance(content, dict):
|
103
101
|
details.update({"check_content": content})
|
104
|
-
print(f"[HEALTH DEBUG] Added check_content to details")
|
102
|
+
# print(f"[HEALTH DEBUG] Added check_content to details")
|
105
103
|
else:
|
106
|
-
print(f"[HEALTH DEBUG] No 'data' field found in message_data")
|
104
|
+
# print(f"[HEALTH DEBUG] No 'data' field found in message_data")
|
105
|
+
pass
|
107
106
|
|
108
107
|
except (json.JSONDecodeError, KeyError) as e:
|
109
|
-
print(f"[HEALTH DEBUG] ERROR parsing message data: {e}")
|
108
|
+
# print(f"[HEALTH DEBUG] ERROR parsing message data: {e}")
|
110
109
|
logger.warning(f"Could not parse health check message data: {e}")
|
111
110
|
health_status = "error"
|
112
111
|
health_message = f"Failed to parse health check message data: {e}"
|
@@ -126,16 +125,16 @@ def process_health_check_message(
|
|
126
125
|
|
127
126
|
# Send the response to the return stream in the format expected by the system
|
128
127
|
if return_stream:
|
129
|
-
print(
|
130
|
-
|
131
|
-
)
|
128
|
+
# print(
|
129
|
+
# f"[HEALTH DEBUG] Sending V1ProcessorHealthResponse to return_stream: {return_stream}"
|
130
|
+
# )
|
132
131
|
try:
|
133
132
|
# Send the V1ProcessorHealthResponse directly (not wrapped in StreamResponseMessage)
|
134
133
|
response_data = health_response.model_dump()
|
135
134
|
|
136
|
-
print(
|
137
|
-
|
138
|
-
)
|
135
|
+
# print(
|
136
|
+
# f"[HEALTH DEBUG] Sending V1ProcessorHealthResponse directly: {json.dumps(response_data, indent=2)}"
|
137
|
+
# )
|
139
138
|
|
140
139
|
# Send to return stream
|
141
140
|
redis_conn.xadd(
|
@@ -144,38 +143,39 @@ def process_health_check_message(
|
|
144
143
|
maxlen=1000,
|
145
144
|
approximate=True,
|
146
145
|
)
|
147
|
-
print(
|
148
|
-
|
149
|
-
)
|
146
|
+
# print(
|
147
|
+
# f"[HEALTH DEBUG] V1ProcessorHealthResponse sent successfully to {return_stream}"
|
148
|
+
# )
|
150
149
|
logger.info(
|
151
150
|
f"Sent health response for {message_id} to stream: {return_stream}"
|
152
151
|
)
|
153
152
|
except Exception as e_resp_send:
|
154
|
-
print(f"[HEALTH DEBUG] ERROR sending response: {e_resp_send}")
|
153
|
+
# print(f"[HEALTH DEBUG] ERROR sending response: {e_resp_send}")
|
155
154
|
logger.error(
|
156
155
|
f"Failed to send health response for {message_id} to stream {return_stream}: {e_resp_send}"
|
157
156
|
)
|
158
157
|
else:
|
159
|
-
print(f"[HEALTH DEBUG] No return_stream specified, not sending response")
|
158
|
+
# print(f"[HEALTH DEBUG] No return_stream specified, not sending response")
|
159
|
+
pass
|
160
160
|
|
161
161
|
# Acknowledge the health check message
|
162
|
-
print(f"[HEALTH DEBUG] Acknowledging message {message_id}")
|
162
|
+
# print(f"[HEALTH DEBUG] Acknowledging message {message_id}")
|
163
163
|
try:
|
164
164
|
redis_conn.xack(health_stream, health_group, message_id)
|
165
|
-
print(f"[HEALTH DEBUG] Message {message_id} acknowledged successfully")
|
165
|
+
# print(f"[HEALTH DEBUG] Message {message_id} acknowledged successfully")
|
166
166
|
logger.info(f"Acknowledged health check message {message_id}")
|
167
167
|
except Exception as e_ack:
|
168
|
-
print(f"[HEALTH DEBUG] ERROR acknowledging message: {e_ack}")
|
168
|
+
# print(f"[HEALTH DEBUG] ERROR acknowledging message: {e_ack}")
|
169
169
|
logger.error(
|
170
170
|
f"Failed to acknowledge health check message {message_id}: {e_ack}"
|
171
171
|
)
|
172
172
|
|
173
|
-
print(f"[HEALTH DEBUG] === FINISHED PROCESSING HEALTH CHECK MESSAGE ===")
|
173
|
+
# print(f"[HEALTH DEBUG] === FINISHED PROCESSING HEALTH CHECK MESSAGE ===")
|
174
174
|
|
175
175
|
|
176
176
|
def main():
|
177
177
|
"""Main function for the health check consumer subprocess."""
|
178
|
-
print(f"[HEALTH DEBUG] === HEALTH WORKER STARTING ===")
|
178
|
+
# print(f"[HEALTH DEBUG] === HEALTH WORKER STARTING ===")
|
179
179
|
logger = setup_health_logging()
|
180
180
|
|
181
181
|
# Get environment variables
|
@@ -183,10 +183,10 @@ def main():
|
|
183
183
|
health_stream = os.environ.get("REDIS_HEALTH_STREAM")
|
184
184
|
health_group = os.environ.get("REDIS_HEALTH_CONSUMER_GROUP")
|
185
185
|
|
186
|
-
print(f"[HEALTH DEBUG] Environment variables:")
|
187
|
-
print(f"[HEALTH DEBUG] REDIS_URL: {redis_url}")
|
188
|
-
print(f"[HEALTH DEBUG] REDIS_HEALTH_STREAM: {health_stream}")
|
189
|
-
print(f"[HEALTH DEBUG] REDIS_HEALTH_CONSUMER_GROUP: {health_group}")
|
186
|
+
# print(f"[HEALTH DEBUG] Environment variables:")
|
187
|
+
# print(f"[HEALTH DEBUG] REDIS_URL: {redis_url}")
|
188
|
+
# print(f"[HEALTH DEBUG] REDIS_HEALTH_STREAM: {health_stream}")
|
189
|
+
# print(f"[HEALTH DEBUG] REDIS_HEALTH_CONSUMER_GROUP: {health_group}")
|
190
190
|
|
191
191
|
if not all([redis_url, health_stream, health_group]):
|
192
192
|
print(f"[HEALTH DEBUG] ERROR: Missing required environment variables")
|
@@ -208,56 +208,58 @@ def main():
|
|
208
208
|
)
|
209
209
|
|
210
210
|
# Configure SOCKS proxy
|
211
|
-
print(f"[HEALTH DEBUG] Configuring SOCKS proxy...")
|
211
|
+
# print(f"[HEALTH DEBUG] Configuring SOCKS proxy...")
|
212
212
|
socks.set_default_proxy(socks.SOCKS5, "localhost", 1055)
|
213
213
|
socket.socket = socks.socksocket
|
214
214
|
logger.info("Configured SOCKS5 proxy for socket connections via localhost:1055")
|
215
215
|
|
216
216
|
health_redis_conn: Optional[redis.Redis] = None
|
217
217
|
health_consumer_name = f"health-consumer-{os.getpid()}-{socket.gethostname()}"
|
218
|
-
print(f"[HEALTH DEBUG] Health consumer name: {health_consumer_name}")
|
218
|
+
# print(f"[HEALTH DEBUG] Health consumer name: {health_consumer_name}")
|
219
219
|
|
220
|
-
print(f"[HEALTH DEBUG] === ENTERING MAIN LOOP ===")
|
220
|
+
# print(f"[HEALTH DEBUG] === ENTERING MAIN LOOP ===")
|
221
221
|
while True:
|
222
222
|
try:
|
223
223
|
if health_redis_conn is None:
|
224
|
-
print(f"[HEALTH DEBUG] Connecting to Redis for health stream...")
|
224
|
+
# print(f"[HEALTH DEBUG] Connecting to Redis for health stream...")
|
225
225
|
logger.info("Connecting to Redis for health stream...")
|
226
|
+
|
226
227
|
health_redis_conn = redis.from_url(redis_url, decode_responses=True)
|
227
228
|
health_redis_conn.ping()
|
228
|
-
print(f"[HEALTH DEBUG] Connected to Redis successfully")
|
229
|
+
# print(f"[HEALTH DEBUG] Connected to Redis successfully")
|
229
230
|
logger.info("Connected to Redis for health stream.")
|
230
231
|
|
231
232
|
# Create health consumer group if it doesn't exist
|
232
|
-
print(f"[HEALTH DEBUG] Creating/checking consumer group...")
|
233
|
+
# print(f"[HEALTH DEBUG] Creating/checking consumer group...")
|
234
|
+
logger.info("Creating/checking consumer group...")
|
233
235
|
try:
|
234
236
|
health_redis_conn.xgroup_create(
|
235
237
|
health_stream, health_group, id="0", mkstream=True
|
236
238
|
)
|
237
|
-
print(
|
238
|
-
|
239
|
-
)
|
239
|
+
# print(
|
240
|
+
# f"[HEALTH DEBUG] Created consumer group {health_group} for stream {health_stream}"
|
241
|
+
# )
|
240
242
|
logger.info(
|
241
243
|
f"Created consumer group {health_group} for stream {health_stream}"
|
242
244
|
)
|
243
245
|
except ResponseError as e_group:
|
244
246
|
if "BUSYGROUP" in str(e_group):
|
245
|
-
print(
|
246
|
-
|
247
|
-
)
|
247
|
+
# print(
|
248
|
+
# f"[HEALTH DEBUG] Consumer group {health_group} already exists"
|
249
|
+
# )
|
248
250
|
logger.info(f"Consumer group {health_group} already exists.")
|
249
251
|
else:
|
250
|
-
print(
|
251
|
-
|
252
|
-
)
|
252
|
+
# print(
|
253
|
+
# f"[HEALTH DEBUG] ERROR creating health consumer group: {e_group}"
|
254
|
+
# )
|
253
255
|
logger.error(f"Error creating health consumer group: {e_group}")
|
254
256
|
time.sleep(5)
|
255
257
|
health_redis_conn = None
|
256
258
|
continue
|
257
259
|
except Exception as e_group_other:
|
258
|
-
print(
|
259
|
-
|
260
|
-
)
|
260
|
+
# print(
|
261
|
+
# f"[HEALTH DEBUG] UNEXPECTED ERROR creating health consumer group: {e_group_other}"
|
262
|
+
# )
|
261
263
|
logger.error(
|
262
264
|
f"Unexpected error creating health consumer group: {e_group_other}"
|
263
265
|
)
|
@@ -268,7 +270,8 @@ def main():
|
|
268
270
|
# Read from health stream
|
269
271
|
assert health_redis_conn is not None
|
270
272
|
|
271
|
-
print(f"[HEALTH DEBUG] Reading from health stream {health_stream}...")
|
273
|
+
# print(f"[HEALTH DEBUG] Reading from health stream {health_stream}...")
|
274
|
+
logger.info(f"Reading from health stream {health_stream}...")
|
272
275
|
health_streams_arg: Dict[str, object] = {health_stream: ">"}
|
273
276
|
raw_messages = health_redis_conn.xreadgroup(
|
274
277
|
health_group,
|
@@ -278,21 +281,26 @@ def main():
|
|
278
281
|
block=5000, # Block for 5 seconds
|
279
282
|
)
|
280
283
|
|
281
|
-
print(f"[HEALTH DEBUG] xreadgroup returned: {raw_messages}")
|
282
|
-
print(f"[HEALTH DEBUG] Messages type: {type(raw_messages)}")
|
284
|
+
# print(f"[HEALTH DEBUG] xreadgroup returned: {raw_messages}")
|
285
|
+
# print(f"[HEALTH DEBUG] Messages type: {type(raw_messages)}")
|
283
286
|
|
284
287
|
if raw_messages:
|
285
|
-
print(f"[HEALTH DEBUG] Found messages to process")
|
288
|
+
# print(f"[HEALTH DEBUG] Found messages to process")
|
289
|
+
logger.info("Found messages to process")
|
286
290
|
# Cast to expected type for decode_responses=True
|
287
291
|
messages = cast(
|
288
292
|
List[Tuple[str, List[Tuple[str, Dict[str, str]]]]], raw_messages
|
289
293
|
)
|
290
294
|
for stream_name, stream_messages in messages:
|
291
|
-
print(
|
292
|
-
|
295
|
+
# print(
|
296
|
+
# f"[HEALTH DEBUG] Processing stream: {stream_name} with {len(stream_messages)} message(s)"
|
297
|
+
# )
|
298
|
+
logger.info(
|
299
|
+
f"Processing stream: {stream_name} with {len(stream_messages)} message(s)"
|
293
300
|
)
|
294
301
|
for message_id, message_data in stream_messages:
|
295
|
-
print(f"[HEALTH DEBUG] Processing message {message_id}")
|
302
|
+
# print(f"[HEALTH DEBUG] Processing message {message_id}")
|
303
|
+
logger.info(f"Processing message {message_id}")
|
296
304
|
process_health_check_message(
|
297
305
|
message_id,
|
298
306
|
message_data,
|
@@ -302,7 +310,8 @@ def main():
|
|
302
310
|
health_group,
|
303
311
|
)
|
304
312
|
else:
|
305
|
-
print(f"[HEALTH DEBUG] No messages received (timeout)")
|
313
|
+
# print(f"[HEALTH DEBUG] No messages received (timeout)")
|
314
|
+
logger.info("No messages received (timeout)")
|
306
315
|
|
307
316
|
except (ConnectionError, RedisTimeoutError, TimeoutError) as e_conn:
|
308
317
|
logger.error(f"Redis connection error: {e_conn}. Reconnecting in 5s...")
|
@@ -13,8 +13,8 @@ nebu/containers/container.py,sha256=Mrh_gvMsTvDkj3CwpqIPzJ72IMw0gQIg64y548vq0yg,
|
|
13
13
|
nebu/containers/models.py,sha256=0j6NGy4yto-enRDh_4JH_ZTbHrLdSpuMOqNQPnIrwC4,6815
|
14
14
|
nebu/namespaces/models.py,sha256=EqUOpzhVBhvJw2P92ONDUbIgC31M9jMmcaG5vyOrsWg,497
|
15
15
|
nebu/namespaces/namespace.py,sha256=oeZyGqsIGIrppyjif1ZONsdTmqRgd9oSLFE1BChXTTE,5247
|
16
|
-
nebu/processors/consumer.py,sha256=
|
17
|
-
nebu/processors/consumer_health_worker.py,sha256=
|
16
|
+
nebu/processors/consumer.py,sha256=RoQqpE8ee7-dV68dYLZTX3c7W373txNs7qsJF-NK8Oo,78541
|
17
|
+
nebu/processors/consumer_health_worker.py,sha256=XJaLNNBxkHmkBap_XeQrxFV9JKcXp21ATudV25r3l7g,15096
|
18
18
|
nebu/processors/consumer_process_worker.py,sha256=h--eNFKaLbUayxn88mB8oGGdrU2liE1dnwm_TPlewX8,36960
|
19
19
|
nebu/processors/decorate.py,sha256=5p9pQrk_H8-Fj0UjsgSVCYx7Jk7KFuhMZtNhkKvpmkQ,61306
|
20
20
|
nebu/processors/default.py,sha256=cy4ETMdbdRGkrvbYec1o60h7mGDlGN5JsuUph0ENtDU,364
|
@@ -22,8 +22,8 @@ nebu/processors/models.py,sha256=8-TmKha2_QAnPlXcZxYjrCSPDCX7FFcMDMcHK77jK0U,422
|
|
22
22
|
nebu/processors/processor.py,sha256=wos5BkNZUVaY5ifT7yeDLbJkdfeloJ7hRuK9P18LU7U,26155
|
23
23
|
nebu/redis/models.py,sha256=coPovAcVXnOU1Xh_fpJL4PO3QctgK9nBe5QYoqEcnxg,1230
|
24
24
|
nebu/services/service.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
25
|
-
nebu-0.1.
|
26
|
-
nebu-0.1.
|
27
|
-
nebu-0.1.
|
28
|
-
nebu-0.1.
|
29
|
-
nebu-0.1.
|
25
|
+
nebu-0.1.123.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
26
|
+
nebu-0.1.123.dist-info/METADATA,sha256=8L9L8vNoFhK8A4U-iWvXP9DIgeVXOW0MV324qcOhsV0,1798
|
27
|
+
nebu-0.1.123.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
28
|
+
nebu-0.1.123.dist-info/top_level.txt,sha256=uLIbEKJeGSHWOAJN5S0i5XBGwybALlF9bYoB1UhdEgQ,5
|
29
|
+
nebu-0.1.123.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|