fleet-python 0.2.65__py3-none-any.whl → 0.2.66a3__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.

Potentially problematic release.


This version of fleet-python might be problematic. Click here for more details.

@@ -374,7 +374,37 @@ class AsyncSnapshotDiff:
374
374
  )
375
375
 
376
376
  for row in report.get("added_rows", []):
377
- if not _is_change_allowed(tbl, row["row_id"], None, "__added__"):
377
+ # First, check if there's a whole-row addition spec (field=None)
378
+ whole_row_allowed = _is_change_allowed(
379
+ tbl, row["row_id"], None, "__added__"
380
+ )
381
+
382
+ if not whole_row_allowed:
383
+ # If not, check if all fields in the added row match field-level specs
384
+ # This allows users to specify expected field values for added rows
385
+ row_data = row.get("data", {})
386
+ all_fields_allowed = True
387
+ unmatched_fields = []
388
+
389
+ for field_name, field_value in row_data.items():
390
+ # Skip ignored fields
391
+ if self.ignore_config.should_ignore_field(tbl, field_name):
392
+ continue
393
+ # Skip rowid as it's internal
394
+ if field_name == "rowid":
395
+ continue
396
+
397
+ if not _is_change_allowed(
398
+ tbl, row["row_id"], field_name, field_value
399
+ ):
400
+ all_fields_allowed = False
401
+ unmatched_fields.append((field_name, field_value))
402
+
403
+ # If all non-ignored fields match specs, allow the addition
404
+ if all_fields_allowed:
405
+ continue
406
+
407
+ # Otherwise, it's an unexpected addition
378
408
  unexpected_changes.append(
379
409
  {
380
410
  "type": "insertion",
@@ -383,11 +413,64 @@ class AsyncSnapshotDiff:
383
413
  "field": None,
384
414
  "after": "__added__",
385
415
  "full_row": row,
416
+ "unmatched_fields": unmatched_fields
417
+ if unmatched_fields
418
+ else None,
386
419
  }
387
420
  )
388
421
 
389
422
  for row in report.get("removed_rows", []):
390
- if not _is_change_allowed(tbl, row["row_id"], None, "__removed__"):
423
+ # First, check if there's a whole-row deletion spec (field=None)
424
+ whole_row_allowed = _is_change_allowed(
425
+ tbl, row["row_id"], None, "__removed__"
426
+ )
427
+
428
+ if not whole_row_allowed:
429
+ # If not, check if all fields in the deleted row match field-level specs
430
+ # This allows users to specify expected field values for deleted rows
431
+ row_data = row.get("data", {})
432
+ all_fields_allowed = True
433
+ unmatched_fields = []
434
+
435
+ for field_name, field_value in row_data.items():
436
+ # Skip ignored fields
437
+ if self.ignore_config.should_ignore_field(tbl, field_name):
438
+ continue
439
+ # Skip rowid as it's internal
440
+ if field_name == "rowid":
441
+ continue
442
+
443
+ # For deletions, check if there's a field-level spec with matching "before" value
444
+ field_spec_found = False
445
+ for allowed in allowed_changes:
446
+ allowed_pk = allowed.get("pk")
447
+ pk_match = (
448
+ str(allowed_pk) == str(row["row_id"])
449
+ if allowed_pk is not None
450
+ else False
451
+ )
452
+
453
+ if (
454
+ allowed["table"] == tbl
455
+ and pk_match
456
+ and allowed.get("field") == field_name
457
+ and "before" in allowed
458
+ and _values_equivalent(
459
+ allowed.get("before"), field_value
460
+ )
461
+ ):
462
+ field_spec_found = True
463
+ break
464
+
465
+ if not field_spec_found:
466
+ all_fields_allowed = False
467
+ unmatched_fields.append((field_name, field_value))
468
+
469
+ # If all non-ignored fields match specs, allow the deletion
470
+ if all_fields_allowed:
471
+ continue
472
+
473
+ # Otherwise, it's an unexpected deletion
391
474
  unexpected_changes.append(
392
475
  {
393
476
  "type": "deletion",
@@ -396,6 +479,9 @@ class AsyncSnapshotDiff:
396
479
  "field": None,
397
480
  "after": "__removed__",
398
481
  "full_row": row,
482
+ "unmatched_fields": unmatched_fields
483
+ if unmatched_fields
484
+ else None,
399
485
  }
400
486
  )
401
487
 
@@ -229,7 +229,25 @@ Remote traceback:
229
229
  ) -> "VerifiersExecuteResponse":
230
230
  """Remote execution of the verifier function that returns the full response model."""
231
231
  args_array = list(args)
232
- args_array.append({"env": env.instance_id})
232
+ # Send complete environment data for remote reconstruction
233
+ env_data = {
234
+ "instance_id": env.instance_id,
235
+ "env_key": env.env_key,
236
+ "version": env.version,
237
+ "status": env.status,
238
+ "subdomain": env.subdomain,
239
+ "created_at": env.created_at,
240
+ "updated_at": env.updated_at,
241
+ "terminated_at": env.terminated_at,
242
+ "team_id": env.team_id,
243
+ "region": env.region,
244
+ "env_variables": env.env_variables,
245
+ "data_key": env.data_key,
246
+ "data_version": env.data_version,
247
+ "urls": env.urls.model_dump() if env.urls else None,
248
+ "health": env.health,
249
+ }
250
+ args_array.append({"env": env_data})
233
251
  args = tuple(args_array)
234
252
 
235
253
  try:
fleet/resources/sqlite.py CHANGED
@@ -370,7 +370,37 @@ class SyncSnapshotDiff:
370
370
  )
371
371
 
372
372
  for row in report.get("added_rows", []):
373
- if not _is_change_allowed(tbl, row["row_id"], None, "__added__"):
373
+ # First, check if there's a whole-row addition spec (field=None)
374
+ whole_row_allowed = _is_change_allowed(
375
+ tbl, row["row_id"], None, "__added__"
376
+ )
377
+
378
+ if not whole_row_allowed:
379
+ # If not, check if all fields in the added row match field-level specs
380
+ # This allows users to specify expected field values for added rows
381
+ row_data = row.get("data", {})
382
+ all_fields_allowed = True
383
+ unmatched_fields = []
384
+
385
+ for field_name, field_value in row_data.items():
386
+ # Skip ignored fields
387
+ if self.ignore_config.should_ignore_field(tbl, field_name):
388
+ continue
389
+ # Skip rowid as it's internal
390
+ if field_name == "rowid":
391
+ continue
392
+
393
+ if not _is_change_allowed(
394
+ tbl, row["row_id"], field_name, field_value
395
+ ):
396
+ all_fields_allowed = False
397
+ unmatched_fields.append((field_name, field_value))
398
+
399
+ # If all non-ignored fields match specs, allow the addition
400
+ if all_fields_allowed:
401
+ continue
402
+
403
+ # Otherwise, it's an unexpected addition
374
404
  unexpected_changes.append(
375
405
  {
376
406
  "type": "insertion",
@@ -379,11 +409,64 @@ class SyncSnapshotDiff:
379
409
  "field": None,
380
410
  "after": "__added__",
381
411
  "full_row": row,
412
+ "unmatched_fields": unmatched_fields
413
+ if unmatched_fields
414
+ else None,
382
415
  }
383
416
  )
384
417
 
385
418
  for row in report.get("removed_rows", []):
386
- if not _is_change_allowed(tbl, row["row_id"], None, "__removed__"):
419
+ # First, check if there's a whole-row deletion spec (field=None)
420
+ whole_row_allowed = _is_change_allowed(
421
+ tbl, row["row_id"], None, "__removed__"
422
+ )
423
+
424
+ if not whole_row_allowed:
425
+ # If not, check if all fields in the deleted row match field-level specs
426
+ # This allows users to specify expected field values for deleted rows
427
+ row_data = row.get("data", {})
428
+ all_fields_allowed = True
429
+ unmatched_fields = []
430
+
431
+ for field_name, field_value in row_data.items():
432
+ # Skip ignored fields
433
+ if self.ignore_config.should_ignore_field(tbl, field_name):
434
+ continue
435
+ # Skip rowid as it's internal
436
+ if field_name == "rowid":
437
+ continue
438
+
439
+ # For deletions, check if there's a field-level spec with matching "before" value
440
+ field_spec_found = False
441
+ for allowed in allowed_changes:
442
+ allowed_pk = allowed.get("pk")
443
+ pk_match = (
444
+ str(allowed_pk) == str(row["row_id"])
445
+ if allowed_pk is not None
446
+ else False
447
+ )
448
+
449
+ if (
450
+ allowed["table"] == tbl
451
+ and pk_match
452
+ and allowed.get("field") == field_name
453
+ and "before" in allowed
454
+ and _values_equivalent(
455
+ allowed.get("before"), field_value
456
+ )
457
+ ):
458
+ field_spec_found = True
459
+ break
460
+
461
+ if not field_spec_found:
462
+ all_fields_allowed = False
463
+ unmatched_fields.append((field_name, field_value))
464
+
465
+ # If all non-ignored fields match specs, allow the deletion
466
+ if all_fields_allowed:
467
+ continue
468
+
469
+ # Otherwise, it's an unexpected deletion
387
470
  unexpected_changes.append(
388
471
  {
389
472
  "type": "deletion",
@@ -392,6 +475,9 @@ class SyncSnapshotDiff:
392
475
  "field": None,
393
476
  "after": "__removed__",
394
477
  "full_row": row,
478
+ "unmatched_fields": unmatched_fields
479
+ if unmatched_fields
480
+ else None,
395
481
  }
396
482
  )
397
483
 
fleet/verifiers/db.py CHANGED
@@ -502,7 +502,50 @@ class SnapshotDiff:
502
502
  )
503
503
 
504
504
  for row in report.get("added_rows", []):
505
- if not _is_change_allowed(tbl, row["row_id"], None, "__added__"):
505
+ # Check if there are any field-level specs DEFINED for this row (not whether they match)
506
+ row_data = row.get("data", {})
507
+ has_field_specs = False
508
+ for allowed in allowed_changes:
509
+ allowed_pk = allowed.get("pk")
510
+ pk_match = (
511
+ str(allowed_pk) == str(row["row_id"])
512
+ if allowed_pk is not None
513
+ else False
514
+ )
515
+ # Check if this is a field-level spec (not whole-row)
516
+ if (
517
+ allowed["table"] == tbl
518
+ and pk_match
519
+ and allowed.get("field")
520
+ is not None # field-level, not whole-row
521
+ ):
522
+ has_field_specs = True
523
+ break
524
+
525
+ # If field-level specs exist, validate them (field-level takes precedence)
526
+ if has_field_specs:
527
+ all_fields_allowed = True
528
+ unmatched_fields = []
529
+
530
+ for field_name, field_value in row_data.items():
531
+ # Skip ignored fields
532
+ if self.ignore_config.should_ignore_field(tbl, field_name):
533
+ continue
534
+ # Skip rowid as it's internal
535
+ if field_name == "rowid":
536
+ continue
537
+
538
+ if not _is_change_allowed(
539
+ tbl, row["row_id"], field_name, field_value
540
+ ):
541
+ all_fields_allowed = False
542
+ unmatched_fields.append((field_name, field_value))
543
+
544
+ # If all non-ignored fields match specs, allow the addition
545
+ if all_fields_allowed:
546
+ continue
547
+
548
+ # Otherwise, it's an unexpected addition
506
549
  unexpected_changes.append(
507
550
  {
508
551
  "type": "insertion",
@@ -511,11 +554,102 @@ class SnapshotDiff:
511
554
  "field": None,
512
555
  "after": "__added__",
513
556
  "full_row": row,
557
+ "unmatched_fields": unmatched_fields
558
+ if unmatched_fields
559
+ else None,
514
560
  }
515
561
  )
562
+ else:
563
+ # No field-level specs, check for whole-row spec (backward compatible)
564
+ whole_row_allowed = _is_change_allowed(
565
+ tbl, row["row_id"], None, "__added__"
566
+ )
567
+
568
+ if not whole_row_allowed:
569
+ # Neither field-level nor whole-row spec found
570
+ unexpected_changes.append(
571
+ {
572
+ "type": "insertion",
573
+ "table": tbl,
574
+ "row_id": row["row_id"],
575
+ "field": None,
576
+ "after": "__added__",
577
+ "full_row": row,
578
+ }
579
+ )
516
580
 
517
581
  for row in report.get("removed_rows", []):
518
- if not _is_change_allowed(tbl, row["row_id"], None, "__removed__"):
582
+ # Check if there are any field-level specs with "before" values for this row
583
+ row_data = row.get("data", {})
584
+ has_field_specs = False
585
+ for field_name, field_value in row_data.items():
586
+ if field_name == "rowid" or self.ignore_config.should_ignore_field(
587
+ tbl, field_name
588
+ ):
589
+ continue
590
+ # For deletions, look for specs with "before" key
591
+ for allowed in allowed_changes:
592
+ allowed_pk = allowed.get("pk")
593
+ pk_match = (
594
+ str(allowed_pk) == str(row["row_id"])
595
+ if allowed_pk is not None
596
+ else False
597
+ )
598
+ if (
599
+ allowed["table"] == tbl
600
+ and pk_match
601
+ and allowed.get("field") == field_name
602
+ and "before" in allowed
603
+ ):
604
+ has_field_specs = True
605
+ break
606
+ if has_field_specs:
607
+ break
608
+
609
+ # If field-level specs exist, validate them (field-level takes precedence)
610
+ if has_field_specs:
611
+ all_fields_allowed = True
612
+ unmatched_fields = []
613
+
614
+ for field_name, field_value in row_data.items():
615
+ # Skip ignored fields
616
+ if self.ignore_config.should_ignore_field(tbl, field_name):
617
+ continue
618
+ # Skip rowid as it's internal
619
+ if field_name == "rowid":
620
+ continue
621
+
622
+ # For deletions, check if there's a field-level spec with matching "before" value
623
+ field_spec_found = False
624
+ for allowed in allowed_changes:
625
+ allowed_pk = allowed.get("pk")
626
+ pk_match = (
627
+ str(allowed_pk) == str(row["row_id"])
628
+ if allowed_pk is not None
629
+ else False
630
+ )
631
+
632
+ if (
633
+ allowed["table"] == tbl
634
+ and pk_match
635
+ and allowed.get("field") == field_name
636
+ and "before" in allowed
637
+ and _values_equivalent(
638
+ allowed.get("before"), field_value
639
+ )
640
+ ):
641
+ field_spec_found = True
642
+ break
643
+
644
+ if not field_spec_found:
645
+ all_fields_allowed = False
646
+ unmatched_fields.append((field_name, field_value))
647
+
648
+ # If all non-ignored fields match specs, allow the deletion
649
+ if all_fields_allowed:
650
+ continue
651
+
652
+ # Otherwise, it's an unexpected deletion
519
653
  unexpected_changes.append(
520
654
  {
521
655
  "type": "deletion",
@@ -524,8 +658,29 @@ class SnapshotDiff:
524
658
  "field": None,
525
659
  "after": "__removed__",
526
660
  "full_row": row,
661
+ "unmatched_fields": unmatched_fields
662
+ if unmatched_fields
663
+ else None,
527
664
  }
528
665
  )
666
+ else:
667
+ # No field-level specs, check for whole-row spec (backward compatible)
668
+ whole_row_allowed = _is_change_allowed(
669
+ tbl, row["row_id"], None, "__removed__"
670
+ )
671
+
672
+ if not whole_row_allowed:
673
+ # Neither field-level nor whole-row spec found
674
+ unexpected_changes.append(
675
+ {
676
+ "type": "deletion",
677
+ "table": tbl,
678
+ "row_id": row["row_id"],
679
+ "field": None,
680
+ "after": "__removed__",
681
+ "full_row": row,
682
+ }
683
+ )
529
684
 
530
685
  if unexpected_changes:
531
686
  # Build comprehensive error message
@@ -611,7 +766,7 @@ class SnapshotDiff:
611
766
  diff = self._collect()
612
767
  for tbl, report in diff.items():
613
768
  for row in report.get("modified_rows", []):
614
- for f in row["changed"].keys():
769
+ for f in row["changes"].keys():
615
770
  if self.ignore_config.should_ignore_field(tbl, f):
616
771
  continue
617
772
  key = (tbl, f)
@@ -240,7 +240,25 @@ Remote traceback:
240
240
  ) -> "VerifiersExecuteResponse":
241
241
  """Remote execution of the verifier function that returns the full response model."""
242
242
  args_array = list(args)
243
- args_array.append({"env": env.instance_id})
243
+ # Send complete environment data for remote reconstruction
244
+ env_data = {
245
+ "instance_id": env.instance_id,
246
+ "env_key": env.env_key,
247
+ "version": env.version,
248
+ "status": env.status,
249
+ "subdomain": env.subdomain,
250
+ "created_at": env.created_at,
251
+ "updated_at": env.updated_at,
252
+ "terminated_at": env.terminated_at,
253
+ "team_id": env.team_id,
254
+ "region": env.region,
255
+ "env_variables": env.env_variables,
256
+ "data_key": env.data_key,
257
+ "data_version": env.data_version,
258
+ "urls": env.urls.model_dump() if env.urls else None,
259
+ "health": env.health,
260
+ }
261
+ args_array.append({"env": env_data})
244
262
  args = tuple(args_array)
245
263
 
246
264
  try:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fleet-python
3
- Version: 0.2.65
3
+ Version: 0.2.66a3
4
4
  Summary: Python SDK for Fleet environments
5
5
  Author-email: Fleet AI <nic@fleet.so>
6
6
  License: Apache-2.0
@@ -51,6 +51,20 @@ Install the Fleet SDK using pip:
51
51
  pip install fleet-python
52
52
  ```
53
53
 
54
+ ### Alpha/Pre-release Versions
55
+
56
+ To install the latest alpha or pre-release version:
57
+
58
+ ```bash
59
+ pip install --pre fleet-python
60
+ ```
61
+
62
+ To install a specific alpha version:
63
+
64
+ ```bash
65
+ pip install fleet-python==0.2.64-alpha1
66
+ ```
67
+
54
68
  ## API Key Setup
55
69
 
56
70
  Fleet requires an API key for authentication. You can obtain one from the [Fleet Platform](https://fleetai.com/dashboard/api-keys).
@@ -46,10 +46,10 @@ fleet/_async/resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
46
46
  fleet/_async/resources/base.py,sha256=UfrenxUqcpL8SgYGOo8o8HgRvv2-ZO5G2Cdo91ofEdg,664
47
47
  fleet/_async/resources/browser.py,sha256=oldoSiymJ1lJkADhpUG81ViOBDNyppX1jSoEwe9-W94,1369
48
48
  fleet/_async/resources/mcp.py,sha256=TLEsLiFhfVfZFs0Fu_uDPm-h4FPdvqgQblYqs-PTHhc,1720
49
- fleet/_async/resources/sqlite.py,sha256=up_umepfyX9PDFsnmEMJLjsj7bLa6a3wizZOgMGkK1Q,27409
49
+ fleet/_async/resources/sqlite.py,sha256=bVlNG1e4A3ygZBpaSxo_oKpu2Au1bLFFNT0hKiWj7yY,31425
50
50
  fleet/_async/verifiers/__init__.py,sha256=1WTlCNq4tIFbbXaQu5Bf2WppZq0A8suhtZbxMTSOwxI,465
51
51
  fleet/_async/verifiers/bundler.py,sha256=Sq0KkqEhM5Ng2x8R6Z4puXvQ8FMlEO7D3-ldBLktPi4,26205
52
- fleet/_async/verifiers/verifier.py,sha256=IiHX028s6ux0kb2FR0Z5zJangl_IDh6cemXsUN2ktUU,14152
52
+ fleet/_async/verifiers/verifier.py,sha256=vr7s11qQE2WmnLBrrxyM6UIpJbvWEubxZIt0G1CbLww,14866
53
53
  fleet/env/__init__.py,sha256=cS9zCYobM5jypppDMZIQMYd6hOg5f4sgqRXEQ67pckk,676
54
54
  fleet/env/client.py,sha256=Lu0pGia3Rcull83BFhB1nccAHXbUEGFKl3BUSkoKbr4,1143
55
55
  fleet/instance/__init__.py,sha256=CyWUkbGAK-DBPw4DC4AnCW-MqqheGhZMA5QSRVu-ws4,479
@@ -60,21 +60,22 @@ fleet/resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
60
60
  fleet/resources/base.py,sha256=AXZzT0_yWHkT497q3yekfr0xsD4cPGMCC6y7C43TIkk,663
61
61
  fleet/resources/browser.py,sha256=hRNM0YMsVQUAraZGNi_B-KXxLpuddy4ntoEDFSw7czU,1295
62
62
  fleet/resources/mcp.py,sha256=c6O4vVJnXANuHMGMe4IPxgp4zBEbFaGm6_d9e6j8Myc,1695
63
- fleet/resources/sqlite.py,sha256=bR6d1zYQ4cMAlmZIJ7jqmY9-N-GokXaDhUyGKTWHsfY,26811
63
+ fleet/resources/sqlite.py,sha256=k7XVGruUbLOD6CQrWWiRw43r5064oVvlo1MJlQ23WuM,30827
64
64
  fleet/verifiers/__init__.py,sha256=GntS8qc3xv8mm-cku1t3xjvOll5jcc5FuiVqQgR4Y6Q,458
65
65
  fleet/verifiers/bundler.py,sha256=Sq0KkqEhM5Ng2x8R6Z4puXvQ8FMlEO7D3-ldBLktPi4,26205
66
66
  fleet/verifiers/code.py,sha256=A1i_UabZspbyj1awzKVQ_HRxgMO3fU7NbkxYyTrp7So,48
67
- fleet/verifiers/db.py,sha256=LAh1HambBInH_D9q9E2Z41YNkCOI9JJfpWPFqztjpfQ,27922
67
+ fleet/verifiers/db.py,sha256=yZEv1VQS1JM2N86V6bVy5VBo-ratV7k53FufQ6z6690,34998
68
68
  fleet/verifiers/decorator.py,sha256=nAP3O8szXu7md_kpwpz91hGSUNEVLYjwZQZTkQlV1DM,3260
69
69
  fleet/verifiers/parse.py,sha256=qz9AfJrTbjlg-LU-lE8Ciqi7Yt2a8-cs17FdpjTLhMk,8550
70
70
  fleet/verifiers/sql_differ.py,sha256=TqTLWyK3uOyLbitT6HYzYEzuSFC39wcyhgk3rcm__k8,6525
71
- fleet/verifiers/verifier.py,sha256=_lcxXVm8e0xRrK2gNJy9up7pW1zOkPRY5n5lQ85S8jg,14197
72
- fleet_python-0.2.65.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
71
+ fleet/verifiers/verifier.py,sha256=d0YEmL_eUH9Tgx28_UnW5g0Q1Ow_HT4RZ9HimZdF5FE,14911
72
+ fleet_python-0.2.66a3.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
73
73
  scripts/fix_sync_imports.py,sha256=X9fWLTpiPGkSHsjyQUDepOJkxOqw1DPj7nd8wFlFqLQ,8368
74
74
  scripts/unasync.py,sha256=vWVQxRWX8SRZO5cmzEhpvnG_REhCWXpidIGIpWmEcvI,696
75
75
  tests/__init__.py,sha256=Re1SdyxH8NfyL1kjhi7SQkGP1mYeWB-D6UALqdIMd8I,35
76
+ tests/test_expect_only.py,sha256=TiJCrIupu6y5PtYIpQRD41p8PDwvHR92oCMiXjUQUVg,40013
76
77
  tests/test_verifier_from_string.py,sha256=Lxi3TpFHFb-hG4-UhLKZJkqo84ax9YJY8G6beO-1erM,13581
77
- fleet_python-0.2.65.dist-info/METADATA,sha256=8S11v3oWKIXvxy_7pj2nBfj8RUSmKRUX1dDa33iO10Q,3304
78
- fleet_python-0.2.65.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
79
- fleet_python-0.2.65.dist-info/top_level.txt,sha256=qb1zIbtEktyhRFZdqVytwg54l64qtoZL0wjHB4bUg3c,29
80
- fleet_python-0.2.65.dist-info/RECORD,,
78
+ fleet_python-0.2.66a3.dist-info/METADATA,sha256=qUZ4kFGzkuXz4VG8p13KUSwcteSswIovSfYFo5bKeBc,3526
79
+ fleet_python-0.2.66a3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
80
+ fleet_python-0.2.66a3.dist-info/top_level.txt,sha256=qb1zIbtEktyhRFZdqVytwg54l64qtoZL0wjHB4bUg3c,29
81
+ fleet_python-0.2.66a3.dist-info/RECORD,,