chellow 1726510224.0.0__py3-none-any.whl → 1726664509.0.0__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 chellow might be problematic. Click here for more details.

@@ -217,7 +217,7 @@ def _handle_0860(headers, pre_record, record):
217
217
 
218
218
  def _handle_1455(headers, pre_record, record):
219
219
  parts = _chop_record(
220
- record, ccl_kwh=13, unknown_1=8, ccl_rate=15, ccl_gbp=12, unkown_2=8
220
+ record, ccl_kwh=13, unknown_1=10, ccl_rate=13, ccl_gbp=12, unkown_2=8
221
221
  )
222
222
  bd = headers["breakdown"]
223
223
  bd["ccl-kwh"] += Decimal(parts["ccl_kwh"])
chellow/e/hh_importer.py CHANGED
@@ -8,7 +8,7 @@ import traceback
8
8
  from collections import defaultdict, deque
9
9
  from datetime import datetime as Datetime, timedelta as Timedelta
10
10
  from decimal import Decimal
11
- from io import StringIO, TextIOWrapper
11
+ from io import StringIO
12
12
  from pathlib import Path
13
13
 
14
14
  import jinja2
@@ -40,7 +40,7 @@ from chellow.utils import (
40
40
  processes = defaultdict(list)
41
41
  tasks = {}
42
42
 
43
- extensions = [".df2", ".simple.csv", ".bg.csv"]
43
+ extensions = [".df2", ".simple.csv", ".bg.csv", ".vital.xlsx"]
44
44
 
45
45
 
46
46
  class HhDataImportProcess(threading.Thread):
@@ -277,7 +277,7 @@ class HhImportTask(threading.Thread):
277
277
  self.log(f"File size is {fsize} bytes.")
278
278
  self.log(f"Treating files as type {file_type}")
279
279
  self.importer = HhDataImportProcess(
280
- self.contract_id, 0, TextIOWrapper(f, "utf8"), fpath + file_type, fsize
280
+ self.contract_id, 0, f, fpath + file_type, fsize
281
281
  )
282
282
 
283
283
  self.importer.run()
@@ -412,7 +412,7 @@ class HhImportTask(threading.Thread):
412
412
  self.log(f"File size is {fsize} bytes.")
413
413
  self.log(f"Treating files as type {file_type}")
414
414
  self.importer = HhDataImportProcess(
415
- self.contract_id, 0, TextIOWrapper(f, "utf8"), fpath + file_type, fsize
415
+ self.contract_id, 0, f, fpath + file_type, fsize
416
416
  )
417
417
 
418
418
  self.importer.run()
@@ -1,5 +1,6 @@
1
1
  import decimal
2
2
  import itertools
3
+ from codecs import iterdecode
3
4
 
4
5
  from werkzeug.exceptions import BadRequest
5
6
 
@@ -13,7 +14,7 @@ def create_parser(reader, mpan_map, messages):
13
14
  class StarkDf2HhParser:
14
15
  def __init__(self, reader, mpan_map, messages):
15
16
  self.line = self.line_number = None
16
- self.reader = zip(itertools.count(1), reader)
17
+ self.reader = zip(itertools.count(1), iterdecode(reader, "utf-8"))
17
18
 
18
19
  self.line_number, self.line = next(self.reader)
19
20
  if self.line.strip().upper() != "#F2":
@@ -1,5 +1,6 @@
1
1
  import csv
2
2
  import itertools
3
+ from codecs import iterdecode
3
4
  from datetime import datetime as Datetime
4
5
  from decimal import Decimal
5
6
 
@@ -14,7 +15,8 @@ def create_parser(reader, mpan_map, messages):
14
15
 
15
16
  class HhParserCsvSimple:
16
17
  def __init__(self, reader, mpan_map, messages):
17
- self.shredder = zip(itertools.count(1), csv.reader(reader))
18
+ s = iterdecode(reader, "utf-8")
19
+ self.shredder = zip(itertools.count(1), csv.reader(s))
18
20
  next(self.shredder) # skip the title line
19
21
  self.values = None
20
22
 
@@ -0,0 +1,132 @@
1
+ from datetime import datetime as Datetime
2
+
3
+ from decimal import Decimal, InvalidOperation
4
+ from openpyxl import load_workbook
5
+
6
+ from werkzeug.exceptions import BadRequest
7
+
8
+ from chellow.utils import HH, ct_datetime, hh_before, hh_range, to_utc
9
+
10
+
11
+ def create_parser(input_stream, mpan_map, messages):
12
+ return HhParserVital(input_stream, mpan_map, messages)
13
+
14
+
15
+ def get_cell(sheet, col, row):
16
+ try:
17
+ coordinates = f"{col}{row}"
18
+ return sheet[coordinates]
19
+ except IndexError:
20
+ raise BadRequest(f"Can't find the cell {coordinates} on sheet {sheet}.")
21
+
22
+
23
+ def get_date(sheet, col, row):
24
+ cell = get_cell(sheet, col, row)
25
+ val = cell.value
26
+ if not isinstance(val, Datetime):
27
+ raise BadRequest(
28
+ f"Problem reading {val} (of type {type(val)}) as a timestamp at "
29
+ f"{cell.coordinate}."
30
+ )
31
+ return val
32
+
33
+
34
+ def get_str(sheet, col, row):
35
+ return get_cell(sheet, col, row).value.strip()
36
+
37
+
38
+ def get_dec(sheet, col, row):
39
+ return get_dec_from_cell(get_cell(sheet, col, row))
40
+
41
+
42
+ def get_dec_from_cell(cell):
43
+ try:
44
+ return Decimal(str(cell.value))
45
+ except InvalidOperation as e:
46
+ raise BadRequest(f"Problem parsing the number at {cell.coordinate}. {e}")
47
+
48
+
49
+ def get_int(sheet, col, row):
50
+ return int(get_cell(sheet, col, row).value)
51
+
52
+
53
+ def find_hhs(sheet, imp_mpan, exp_mpan):
54
+ row = pres_readings = pres_ts = None
55
+ caches = {}
56
+ try:
57
+ for row in range(2, len(sheet["A"]) + 1):
58
+ imp_read_cell = get_cell(sheet, "H", row)
59
+ imp_read_val = imp_read_cell.value
60
+ if imp_read_val is None or imp_read_val == "":
61
+ break
62
+
63
+ exp_read_cell = get_cell(sheet, "I", row)
64
+ exp_read_val = exp_read_cell.value
65
+ if exp_read_val is None or exp_read_val == "":
66
+ break
67
+
68
+ # '16/09/2024 14:45:00
69
+ ts_str = get_str(sheet, "A", row)
70
+ ts_naive = Datetime.strptime(ts_str, "%d/%m/%Y %H:%M:%S")
71
+ ts_ct = ct_datetime(
72
+ ts_naive.year,
73
+ ts_naive.month,
74
+ ts_naive.day,
75
+ ts_naive.hour,
76
+ ts_naive.minute,
77
+ )
78
+
79
+ imp_read = get_dec_from_cell(imp_read_cell)
80
+ exp_read = get_dec_from_cell(exp_read_cell)
81
+ ts = to_utc(ts_ct)
82
+
83
+ if ts_naive.minute in (0, 30) and hh_before(ts, pres_ts):
84
+ if pres_readings is not None:
85
+ pres_imp_read, pres_exp_read = pres_readings
86
+ hhs = hh_range(caches, ts, pres_ts - HH)
87
+ num_hhs = len(hhs)
88
+ val_imp = (pres_imp_read - imp_read) / num_hhs
89
+ val_exp = (pres_exp_read - exp_read) / num_hhs
90
+ for hh in hhs:
91
+
92
+ yield {
93
+ "mpan_core": imp_mpan,
94
+ "channel_type": "ACTIVE",
95
+ "start_date": hh,
96
+ "value": val_imp,
97
+ "status": "A",
98
+ }
99
+ yield {
100
+ "mpan_core": exp_mpan,
101
+ "channel_type": "ACTIVE",
102
+ "start_date": hh,
103
+ "value": val_exp,
104
+ "status": "A",
105
+ }
106
+
107
+ pres_readings = imp_read, exp_read
108
+ pres_ts = ts
109
+
110
+ except BadRequest as e:
111
+ e.description = (f"Problem at row: {row}: {e.description}",)
112
+ raise e
113
+
114
+
115
+ class HhParserVital:
116
+ def __init__(self, input_stream, mpan_map, messages):
117
+ book = load_workbook(input_stream, data_only=True)
118
+ sheet = book.worksheets[0]
119
+ imp_name = get_str(sheet, "H", 1).strip()
120
+ imp_mpan = mpan_map[imp_name]
121
+ exp_name = get_str(sheet, "I", 1).strip()
122
+ exp_mpan = mpan_map[exp_name]
123
+ self.data = iter(find_hhs(sheet, imp_mpan, exp_mpan))
124
+
125
+ def __iter__(self):
126
+ return self
127
+
128
+ def __next__(self):
129
+ return next(self.data)
130
+
131
+ def close(self):
132
+ pass
chellow/e/views.py CHANGED
@@ -3,7 +3,7 @@ import os
3
3
  import threading
4
4
  from collections import defaultdict
5
5
  from datetime import datetime as Datetime
6
- from io import StringIO
6
+ from io import BytesIO, StringIO
7
7
  from itertools import chain, islice
8
8
  from random import random
9
9
 
@@ -1233,7 +1233,7 @@ def dc_contracts_hh_imports_post(contract_id):
1233
1233
  contract = Contract.get_dc_by_id(g.sess, contract_id)
1234
1234
 
1235
1235
  file_item = req_file("import_file")
1236
- f = StringIO(str(file_item.stream.read(), "utf-8"))
1236
+ f = BytesIO(file_item.stream.read())
1237
1237
  f.seek(0, os.SEEK_END)
1238
1238
  file_size = f.tell()
1239
1239
  f.seek(0)
@@ -110,10 +110,10 @@ def _process_CCD2(elements, headers):
110
110
  units_billed = to_decimal(nuct) / units_divisor
111
111
  breakdown[key] += units_billed
112
112
 
113
- if "start_date" not in headers:
113
+ if tpref == "standing" or "start_date" not in headers:
114
114
  headers["start_date"] = to_date(csdt[0])
115
115
 
116
- if "finish_date" not in headers:
116
+ if tpref == "standing" or "finish_date" not in headers:
117
117
  headers["finish_date"] = _to_finish_date(cedt[0])
118
118
 
119
119
  if "mprn" not in headers:
@@ -2,7 +2,7 @@ import csv
2
2
  import sys
3
3
  import threading
4
4
  import traceback
5
- from collections import OrderedDict, defaultdict
5
+ from collections import defaultdict
6
6
  from datetime import datetime as Datetime
7
7
  from decimal import Decimal
8
8
  from itertools import combinations
@@ -11,7 +11,7 @@ from dateutil.relativedelta import relativedelta
11
11
 
12
12
  from flask import g, request
13
13
 
14
- from sqlalchemy import or_
14
+ from sqlalchemy import or_, select
15
15
  from sqlalchemy.orm import joinedload, subqueryload
16
16
  from sqlalchemy.sql.expression import null, true
17
17
 
@@ -27,7 +27,6 @@ from chellow.models import (
27
27
  Contract,
28
28
  Era,
29
29
  Llfc,
30
- MarketRole,
31
30
  MtcParticipant,
32
31
  RSession,
33
32
  RegisterRead,
@@ -380,19 +379,19 @@ def _process_supply(
380
379
  while enlarged:
381
380
  enlarged = False
382
381
  covered_elems = find_elements(bill)
383
- covered_bills = OrderedDict(
382
+ covered_bills = dict(
384
383
  (b.id, b)
385
- for b in sess.query(Bill)
386
- .join(Batch)
387
- .join(Contract)
388
- .join(MarketRole)
389
- .filter(
390
- Bill.supply == supply,
391
- Bill.start_date <= covered_finish,
392
- Bill.finish_date >= covered_start,
393
- MarketRole.code == market_role_code,
384
+ for b in sess.scalars(
385
+ select(Bill)
386
+ .join(Batch)
387
+ .where(
388
+ Bill.supply == supply,
389
+ Bill.start_date <= covered_finish,
390
+ Bill.finish_date >= covered_start,
391
+ Batch.contract == contract,
392
+ )
393
+ .order_by(Bill.start_date, Bill.issue_date)
394
394
  )
395
- .order_by(Bill.start_date, Bill.issue_date)
396
395
  )
397
396
  while True:
398
397
  to_del = None
@@ -21,15 +21,16 @@
21
21
  Reached line number {{process.converter.line_number}}.
22
22
  {% endif %}
23
23
  </p>
24
- {% elif process.messages|length == 0 %}
24
+ {% elif process.error is none %}
25
25
  <p>The import has completed successfully.</p>
26
26
  {% else %}
27
- <p>The import failed:</p>
28
- <ul>
29
- {% for message in process.messages %}
30
- <li>{{message}}</li>
31
- {% endfor %}
32
- </ul>
27
+ <p>The import failed. {{process.error}}</p>
33
28
  {% endif %}
29
+
30
+ <ul>
31
+ {% for message in process.messages %}
32
+ <li>{{message}}</li>
33
+ {% endfor %}
34
+ </ul>
34
35
 
35
36
  {% endblock %}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: chellow
3
- Version: 1726510224.0.0
3
+ Version: 1726664509.0.0
4
4
  Summary: Web Application for checking UK energy bills.
5
5
  Project-URL: Homepage, https://github.com/WessexWater/chellow
6
6
  Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
@@ -24,10 +24,11 @@ chellow/e/dno_rate_parser.py,sha256=A5TP6KjyfT5lVWh7dX4SiXRi6wnf2lGv-H_T4Sod8CI,
24
24
  chellow/e/duos.py,sha256=nwviRjz-qIt3GxIMHk0hItIT4dtKsxOWq9TUC1z-hO8,30864
25
25
  chellow/e/elexon.py,sha256=ALhXS9Es7PV0z9ukPbIramn3cf3iLyFi-PMWPSm5iOs,5487
26
26
  chellow/e/energy_management.py,sha256=aXC2qlGt3FAODlNl_frWzVYAQrJLP8FFOiNX3m-QE_Y,12388
27
- chellow/e/hh_importer.py,sha256=-jvJaex756NpygSapsWxXl6RK0Z4ymkz3QA6ETrdnac,21476
27
+ chellow/e/hh_importer.py,sha256=vD2PRMSBhxmsyJ4xEq2N7Ib5Ohmf1FmQk8-APw8vBEs,21430
28
28
  chellow/e/hh_parser_bg_csv.py,sha256=W5SU2MSpa8BGA0VJw1JXF-IwbCNLFy8fe35yxLZ7gEw,2453
29
- chellow/e/hh_parser_df2.py,sha256=7gaVidyIqeqprm3zYPtHvRLLn08nph04N0cKlveNTV0,4279
30
- chellow/e/hh_parser_simple_csv.py,sha256=RN4QOLvTQeoPrpvXvQ9hkOBZnR5piybLfjCiSJdjpjs,2112
29
+ chellow/e/hh_parser_df2.py,sha256=tRAoVUUoJDlfPopm6usEBnhJz7dXMc2_KEWbkW9Gyq4,4330
30
+ chellow/e/hh_parser_simple_csv.py,sha256=lJx9tw9BWFSoBmns1Cws_vY-OIn90LPt2yvIN_CFcTE,2177
31
+ chellow/e/hh_parser_vital_xlsx.py,sha256=g9-CElfH1PPfwpuUcVvD6WQpBlNxCo8j9pq_0Yza0ZM,4125
31
32
  chellow/e/laf_import.py,sha256=aqkcbjnvfBPszBLSNg6getP7iW1uWiTVHy6N5Z5x39U,5514
32
33
  chellow/e/lcc.py,sha256=OkpynN8_iAdHRlu-yyU6BhRUqYYOZsUnl0HbHULYo_4,4670
33
34
  chellow/e/mdd_importer.py,sha256=NugJr2JhuzkPTsEMl_5UdQuw5K2p8lVJ-hyz4MK6Hfg,35762
@@ -38,7 +39,7 @@ chellow/e/system_price.py,sha256=6w5J7bzwFAZubE2zdOFRiS8IIrVP8hkoIOaG2yCt-Ic,623
38
39
  chellow/e/tlms.py,sha256=M33D6YpMixu2KkwSCzDRM3kThLgShg8exp63Obo75l8,8905
39
40
  chellow/e/tnuos.py,sha256=XseYztPUsQXNKuBmystO2kzzwAG9ehCZgpGBTdgSk-A,4313
40
41
  chellow/e/triad.py,sha256=lIQj7EdUrcFwEqleuHZXYU_bfzIwNOqUVVxB3NPQt4A,13710
41
- chellow/e/views.py,sha256=aljiDbLvO_rUl00ohDDxs-3-xPmsuguaOyo69lcXcBA,220624
42
+ chellow/e/views.py,sha256=LG9KeYfXDkOvd7GrywuQPG1qDnpFvKe1oa95H0wRlqY,220618
42
43
  chellow/e/bill_parsers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
43
44
  chellow/e/bill_parsers/activity_mop_stark_xlsx.py,sha256=UgWXDPzQkQghyj_lfgBqoSJpHB-t-qOdSaB8qY6GLog,4071
44
45
  chellow/e/bill_parsers/annual_mop_stark_xlsx.py,sha256=-HMoIfa_utXYKA44RuC0Xqv3vd2HLeQU_4P0iBUd3WA,4219
@@ -52,7 +53,7 @@ chellow/e/bill_parsers/gdf_csv.py,sha256=ZfK3Oc6oP28p_P9DIevLNB_zW2WLcEJ3Lvb1gL3
52
53
  chellow/e/bill_parsers/haven_csv.py,sha256=0uENq8IgVNqdxfBQMBxLTSZWCOuDHXZC0xzk52SbfyE,13652
53
54
  chellow/e/bill_parsers/haven_edi.py,sha256=YGPHRxPOhje9s32jqPHHELni2tooOYj3cMC_qaZVPq4,16107
54
55
  chellow/e/bill_parsers/haven_edi_tprs.py,sha256=ZVX9CCqUybsot_Z0BEOJPvl9x5kSr7fEWyuJXvZDcz4,11841
55
- chellow/e/bill_parsers/mm.py,sha256=W_n7xlXrSH6QewkCnNQpMAxWUocXctIHo7XR-t95Aas,9543
56
+ chellow/e/bill_parsers/mm.py,sha256=mXghmH_gLx82O20CUMBnUysAJqh-OMkR_-CGEcKrzhs,9544
56
57
  chellow/e/bill_parsers/nonsettlement_dc_stark_xlsx.py,sha256=yogXTuQHGRL7IiqvRWr2C9V24ez1j9Yx0128UygPE_k,4723
57
58
  chellow/e/bill_parsers/settlement_dc_stark_xlsx.py,sha256=PlEqCZuJ9DfQXeeYQ64jtf3ML7sUt_tt61QOOTnkE5c,6380
58
59
  chellow/e/bill_parsers/sse_edi.py,sha256=L85DOfNkqexeEIEr8pCBn_2sHJI-zEaw6cogpE3YyYM,15204
@@ -60,7 +61,7 @@ chellow/e/bill_parsers/sww_xls.py,sha256=QEjiuvwvr5FuWCfqqVw8LaA_vZyAKsvRAS5fw3x
60
61
  chellow/gas/bill_import.py,sha256=w0lPgK_Drzh8rtnEBQe3qFuxrgzZ6qQSgpaGrrGznMU,6549
61
62
  chellow/gas/bill_parser_csv.py,sha256=Ecdy-apFT-mWAxddAsM4k1s-9-FpIaOfjP0oFc0rdQg,5557
62
63
  chellow/gas/bill_parser_engie_edi.py,sha256=Ko0vZP-QdVQ1uuhS_5cdrii60_cM4b_LFJMoY0pZqnk,8950
63
- chellow/gas/bill_parser_total_edi.py,sha256=hbjvahC8mQ0RuyIEQVJu18XNqq7T_htnV-OYg6NSuiE,7379
64
+ chellow/gas/bill_parser_total_edi.py,sha256=HdX2ctKvqIA5saf8VkpWmYWfqaZsdB-sAEcMSZjTgE4,7425
64
65
  chellow/gas/ccl.py,sha256=DMlcPUELZi00CaDekVJINYk3GgH5apFrImVdmkbyba0,2913
65
66
  chellow/gas/cv.py,sha256=4cdYYQ8Qak6NeYdBCB4YaQ0jX8-UkaydIIdibCQuXxM,7344
66
67
  chellow/gas/dn_rate_parser.py,sha256=Mq8rAcUEUxIQOks59bsCKl8GrefvoHbrTCHqon9N0z0,11340
@@ -69,7 +70,7 @@ chellow/gas/transportation.py,sha256=Bkg8TWOs-v0ES-4qqwbleiOhqbE_t2KauUx9JYMZELM
69
70
  chellow/gas/views.py,sha256=zOlJnL6eVq7Tag-0NMabzCPQk5AoTrclEz-923pbwAE,57851
70
71
  chellow/reports/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
71
72
  chellow/reports/report_109.py,sha256=FmRWG8wQC97cj0nqQH7mrfbYesRIKWXQLh6ERHvtHrU,11212
72
- chellow/reports/report_111.py,sha256=AlYjvCDpGNe1qBuzW52EONWDsFaIVElug0Vpe9qm1PY,28169
73
+ chellow/reports/report_111.py,sha256=rgwoOPfvbfwIC_IjBqs2e8umF_YTtpyejLrX_uCgyHE,28145
73
74
  chellow/reports/report_169.py,sha256=tnTiHmhigcgZ7E8rUSfgzsVYUCW947xBZZq04-KqfK8,9287
74
75
  chellow/reports/report_181.py,sha256=mCL6vXfrj8r0kL-LilDS0SnSu5tJOzCq7eMJVx9zpEw,4999
75
76
  chellow/reports/report_183.py,sha256=DZX-hHJPl_Tbgkt31C_cuLZg_5L2b6iCPQ5foOZizR0,8817
@@ -187,7 +188,7 @@ chellow/templates/e/dc_bill_import.html,sha256=NHjMSoFizvFQIaPWuVE3nTCtMDTzJB0Xm
187
188
  chellow/templates/e/dc_bill_imports.html,sha256=lCaUR47r9KPr0VrQhEvVEaKexM5R_nmkxtzgpWZ0e9s,2135
188
189
  chellow/templates/e/dc_contract.html,sha256=b6DLDrGdzN9Rri56pFvfpE7QZKYXGHib2veYAztuHlg,2352
189
190
  chellow/templates/e/dc_contract_edit.html,sha256=IObmbHQmeZ_LSpnYgabmhoSNUR3aPmm-Jk5nJLM_u74,1706
190
- chellow/templates/e/dc_contract_hh_import.html,sha256=UODiBFNohb60MjH1w-9JW1JE0O9GR2uKPGw-lD7Da5g,848
191
+ chellow/templates/e/dc_contract_hh_import.html,sha256=JncR3L6cOK4jghsGyr-itEqlIemXBXt3kL09wpqnQSE,856
191
192
  chellow/templates/e/dc_contract_hh_imports.html,sha256=eXFDGyzSgag4JRism81_p5yTzQOjCIXaVkQ8tl3dDcM,8172
192
193
  chellow/templates/e/dc_contract_properties.html,sha256=2EmA91gYWZcTOHQ3PxXQrpTOb8dm0OGjwRWsW6qNI9s,455
193
194
  chellow/templates/e/dc_contract_properties_edit.html,sha256=TGYcHTlWbk5WmjZPkdbHhRVZcOpEfhowCp2penZcGiE,1704
@@ -365,6 +366,6 @@ chellow/templates/g/supply_note_edit.html,sha256=b8mB6_ucBwoljp03iy6AgVaZUhGw3-1
365
366
  chellow/templates/g/supply_notes.html,sha256=6epNmZ3NKdXZz27fvmRUGeffg_oc1kmwuBeyRzQe3Rg,854
366
367
  chellow/templates/g/unit.html,sha256=KouNVU0-i84afANkLQ_heJ0uDfJ9H5A05PuLqb8iCN8,438
367
368
  chellow/templates/g/units.html,sha256=p5Nd-lAIboKPEOO6N451hx1bcKxMg4BDODnZ-43MmJc,441
368
- chellow-1726510224.0.0.dist-info/METADATA,sha256=5yHyg_hOusHvyLO5578hobk7B9yosB2-EFVHM94oE7U,12204
369
- chellow-1726510224.0.0.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
370
- chellow-1726510224.0.0.dist-info/RECORD,,
369
+ chellow-1726664509.0.0.dist-info/METADATA,sha256=PhQBcuYRWYyJltXJBei7Jl22-HKANq4qi5Nae4hRNhs,12204
370
+ chellow-1726664509.0.0.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
371
+ chellow-1726664509.0.0.dist-info/RECORD,,