zipcode-features 0.0.8__tar.gz → 0.1.0__tar.gz

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.
Files changed (18) hide show
  1. {zipcode_features-0.0.8 → zipcode_features-0.1.0}/PKG-INFO +1 -1
  2. {zipcode_features-0.0.8 → zipcode_features-0.1.0}/pyproject.toml +1 -1
  3. {zipcode_features-0.0.8 → zipcode_features-0.1.0}/setup.py +1 -1
  4. zipcode_features-0.1.0/src/zipcode_features/__init__.py +290 -0
  5. {zipcode_features-0.0.8 → zipcode_features-0.1.0}/uv.lock +17 -1
  6. zipcode_features-0.0.8/src/zipcode_features/__init__.py +0 -91
  7. {zipcode_features-0.0.8 → zipcode_features-0.1.0}/LICENSE +0 -0
  8. {zipcode_features-0.0.8 → zipcode_features-0.1.0}/README.md +0 -0
  9. {zipcode_features-0.0.8 → zipcode_features-0.1.0}/azure-pipelines.yml +0 -0
  10. {zipcode_features-0.0.8 → zipcode_features-0.1.0}/clean_install.sh +0 -0
  11. {zipcode_features-0.0.8 → zipcode_features-0.1.0}/requirements.txt +0 -0
  12. {zipcode_features-0.0.8 → zipcode_features-0.1.0}/src/zipcode_features/data/CBSA_ZIP_122025.csv +0 -0
  13. {zipcode_features-0.0.8 → zipcode_features-0.1.0}/src/zipcode_features/data/ZIP_COUNTY_122025.csv +0 -0
  14. {zipcode_features-0.0.8 → zipcode_features-0.1.0}/src/zipcode_features/data/bls_2025_quarter_four.csv +0 -0
  15. {zipcode_features-0.0.8 → zipcode_features-0.1.0}/src/zipcode_features/data/bls_2025_quarter_one.csv +0 -0
  16. {zipcode_features-0.0.8 → zipcode_features-0.1.0}/src/zipcode_features/data/bls_2025_quarter_three.csv +0 -0
  17. {zipcode_features-0.0.8 → zipcode_features-0.1.0}/src/zipcode_features/data/bls_2025_quarter_two.csv +0 -0
  18. {zipcode_features-0.0.8 → zipcode_features-0.1.0}/src/zipcode_features/data/cbsa_codes.json +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: zipcode-features
3
- Version: 0.0.8
3
+ Version: 0.1.0
4
4
  Summary: A Python package to process and extract features from zipcode data.
5
5
  Project-URL: Homepage, https://github.com/EricSchles/zipcode_features
6
6
  Author-email: Eric Schles <your.email@example.com>
@@ -5,7 +5,7 @@ build-backend = "hatchling.build"
5
5
 
6
6
  [project]
7
7
  name = "zipcode-features"
8
- version = "0.0.8"
8
+ version = "0.1.0"
9
9
  description = "A Python package to process and extract features from zipcode data."
10
10
  readme = "README.md"
11
11
  requires-python = ">=3.10"
@@ -10,7 +10,7 @@ README = (HERE / "README.md").read_text()
10
10
  # This call to setup() does all the work
11
11
  setup(
12
12
  name="zipcode_features",
13
- version="0.0.4",
13
+ version="0.0.9",
14
14
  description="A tool to get features based on census data from zipcodes",
15
15
  long_description=README,
16
16
  long_description_content_type="text/markdown",
@@ -0,0 +1,290 @@
1
+ __version__ = '0.1.0'
2
+
3
+ import zipcodes
4
+ from zipcode3.search import SearchEngine
5
+ from importlib import resources
6
+ import pandas as pd
7
+ import json
8
+
9
+ zip_to_fips = {
10
+ '00544': '36103', # Suffolk County
11
+ '10015': '36061', # New York County (Manhattan)
12
+ '10046': '36061', # New York County
13
+ '10047': '36061', # New York County
14
+ '10048': '36061', # New York County
15
+ '10060': '36061', # New York County
16
+ '10072': '36061', # New York County
17
+ '10079': '36061', # New York County
18
+ '10082': '36061', # New York County
19
+ '10087': '36061', # New York County
20
+ '10090': '36061', # New York County
21
+ '10094': '36061', # New York County
22
+ '10095': '36061', # New York County
23
+ '10096': '36061', # New York County
24
+ '10098': '36061', # New York County
25
+ '10099': '36061', # New York County
26
+ '10102': '36061', # New York County
27
+ '10109': '36061', # New York County
28
+ '10114': '36061', # New York County
29
+ '10130': '36061', # New York County
30
+ '10132': '36061', # New York County
31
+ '10149': '36061', # New York County
32
+ '10161': '36061', # New York County
33
+ '10184': '36061', # New York County
34
+ '10196': '36061', # New York County
35
+ '10197': '36061', # New York County
36
+ '10200': '36061', # New York County
37
+ '10242': '36061', # New York County
38
+ '10249': '36061', # New York County
39
+ '10256': '36061', # New York County
40
+ '10257': '36061', # New York County
41
+ '10259': '36061', # New York County
42
+ '10260': '36061', # New York County
43
+ '10261': '36061', # New York County
44
+ '10265': '36061', # New York County
45
+ '10270': '36061', # New York County
46
+ '10273': '36061', # New York County
47
+ '10286': '36061', # New York County
48
+ '10292': '36061', # New York County
49
+ '10499': '36005', # Bronx County
50
+ '10521': '36119', # Westchester County
51
+ '10557': '36119', # Westchester County
52
+ '10558': '36119', # Westchester County
53
+ '10571': '36119', # Westchester County
54
+ '10572': '36119', # Westchester County
55
+ '10943': '36071', # Orange County
56
+ '10997': '36071', # Orange County
57
+ '11025': '36059', # Nassau County
58
+ '11026': '36059', # Nassau County
59
+ '11027': '36059', # Nassau County
60
+ '11041': '36059', # Nassau County
61
+ '11043': '36059', # Nassau County
62
+ '11044': '36059', # Nassau County
63
+ '11051': '36059', # Nassau County
64
+ '11052': '36059', # Nassau County
65
+ '11053': '36059', # Nassau County
66
+ '11054': '36059', # Nassau County
67
+ '11055': '36059', # Nassau County
68
+ '11099': '36059', # Nassau County
69
+ '11120': '36081', # Queens County
70
+ '11240': '36047', # Kings County (Brooklyn)
71
+ '11244': '36047', # Kings County
72
+ '11248': '36047', # Kings County
73
+ '11254': '36047', # Kings County
74
+ '11255': '36047', # Kings County
75
+ '11381': '36081', # Queens County
76
+ '11390': '36081', # Queens County
77
+ '11535': '36059', # Nassau County
78
+ '11536': '36059', # Nassau County
79
+ '11555': '36059', # Nassau County
80
+ '11592': '36059', # Nassau County
81
+ '11594': '36059', # Nassau County
82
+ '11595': '36059', # Nassau County
83
+ '11597': '36059', # Nassau County
84
+ '11690': '36081', # Queens County
85
+ '11695': '36081', # Queens County
86
+ '11707': '36103', # Suffolk County
87
+ '11708': '36103', # Suffolk County
88
+ '11736': '36103', # Suffolk County
89
+ '11737': '36103', # Suffolk County
90
+ '11750': '36103', # Suffolk County
91
+ '11760': '36103', # Suffolk County
92
+ '11774': '36059', # Nassau County
93
+ '11775': '36059', # Nassau County
94
+ '11819': '36059', # Nassau County
95
+ '11853': '36059', # Nassau County
96
+ '11854': '36059', # Nassau County
97
+ '11855': '36059', # Nassau County
98
+ '12016': '36057', # Montgomery County
99
+ '12214': '36001', # Albany County
100
+ '12225': '36001', # Albany County
101
+ '12228': '36001', # Albany County
102
+ '12229': '36001', # Albany County
103
+ '12230': '36001', # Albany County
104
+ '12231': '36001', # Albany County
105
+ '12238': '36001', # Albany County
106
+ '12241': '36001', # Albany County
107
+ '12242': '36001', # Albany County
108
+ '12243': '36001', # Albany County
109
+ '12244': '36001', # Albany County
110
+ '12250': '36001', # Albany County
111
+ '12252': '36001', # Albany County
112
+ '12256': '36001', # Albany County
113
+ '12261': '36001', # Albany County
114
+ '12325': '36093', # Schenectady County
115
+ '12593': '36027', # Dutchess County
116
+ '12727': '36105', # Sullivan County
117
+ '13056': '36053', # Madison County
118
+ '13107': '36075', # Oswego County
119
+ '13221': '36067', # Onondaga County
120
+ '13250': '36067', # Onondaga County
121
+ '13251': '36067', # Onondaga County
122
+ '13449': '36065', # Oneida County
123
+ '13465': '36065', # Oneida County
124
+ '13599': '36065', # Oneida County
125
+ '13627': '36045', # Jefferson County
126
+ '13657': '36049', # Lewis County
127
+ '13763': '36025', # Delaware County
128
+ '13837': '36025', # Delaware County
129
+ '14133': '36063', # Niagara County
130
+ '14261': '36029', # Erie County
131
+ '14264': '36029', # Erie County
132
+ '14267': '36029', # Erie County
133
+ '14443': '36069', # Ontario County
134
+ '14644': '36055', # Monroe County
135
+ '14645': '36055', # Monroe County
136
+ '14650': '36055', # Monroe County
137
+ '14664': '36055', # Monroe County
138
+ '14673': '36055', # Monroe County
139
+ '14683': '36055', # Monroe County
140
+ '14694': '36055', # Monroe County
141
+ '14756': '36013', # Chautauqua County
142
+ '14925': '36015', # Chemung County
143
+ }
144
+
145
+ def zipcode_mapper(x):
146
+ if x["ZIP_len"] == 3:
147
+ return "00" + x["ZIP"]
148
+ elif x["ZIP_len"] == 4:
149
+ return "0" + x["ZIP"]
150
+ else:
151
+ return x["ZIP"]
152
+
153
+ def _get_zip_to_cbsa_code() -> dict:
154
+ """
155
+ This method gets a mapping from zipcode to cbsa code
156
+ mapping is of the form:
157
+ {"zip code": "cbsa code"}
158
+ """
159
+ with resources.path("zipcode_features.data", "CBSA_ZIP_122025.csv") as csv_path:
160
+ df = pd.read_csv(csv_path, dtype={'ZIP': str, "CBSA": str})
161
+ df["ZIP_len"] = df["ZIP"].apply(lambda x: len(x))
162
+ df["ZIP"] = df.apply(zipcode_mapper, axis=1)
163
+ return df.set_index('ZIP')['CBSA'].to_dict()
164
+
165
+
166
+ def _get_cbsa_code_to_cbsa_name() -> dict:
167
+ """
168
+ This method gets a mapping from cbsa code to name
169
+ {cbsa code: cbsa name}
170
+ """
171
+ with resources.path("zipcode_features.data", "cbsa_codes.json") as json_path:
172
+ code_to_name = json.load(open(json_path))
173
+ df = pd.DataFrame(columns=["code", "name"])
174
+ df["name"] = code_to_name.values()
175
+ df["code"] = code_to_name.keys()
176
+ df["name"] = df["name"].str.replace(" -", "-")
177
+ df["name"] = df["name"].str.split().str.join(' ')
178
+ return df.to_dict()
179
+
180
+ def _get_zip_to_fips_code() -> dict:
181
+ with resources.path("zipcode_features.data", "ZIP_COUNTY_122025.csv") as csv_path:
182
+ df = pd.read_csv(csv_path, dtype={'ZIP': str, "COUNTY": str})
183
+ df["ZIP_len"] = df["ZIP"].apply(lambda x: len(x))
184
+ df["ZIP"] = df.apply(zipcode_mapper, axis=1)
185
+ df = df[["ZIP", "COUNTY"]]
186
+ zip_to_county = df.set_index('ZIP')['COUNTY'].to_dict()
187
+ zip_to_county.update(zip_to_fips)
188
+ return zip_to_county
189
+
190
+ def _get_bls_data() -> pd.DataFrame:
191
+ csvs = [
192
+ "bls_2025_quarter_four.csv",
193
+ "bls_2025_quarter_one.csv",
194
+ "bls_2025_quarter_three.csv",
195
+ "bls_2025_quarter_two.csv"
196
+ ]
197
+ cols_to_drop = [
198
+ "industry_code",
199
+ "size_code",
200
+ "disclosure_code",
201
+ 'lq_disclosure_code',
202
+ 'lq_qtrly_estabs',
203
+ 'lq_month1_emplvl',
204
+ 'lq_month2_emplvl',
205
+ 'lq_month3_emplvl',
206
+ 'lq_total_qtrly_wages',
207
+ 'lq_taxable_qtrly_wages',
208
+ 'lq_qtrly_contributions',
209
+ 'lq_avg_wkly_wage',
210
+ 'oty_disclosure_code',
211
+ 'oty_qtrly_estabs_chg',
212
+ 'oty_qtrly_estabs_pct_chg',
213
+ 'oty_month1_emplvl_chg',
214
+ 'oty_month1_emplvl_pct_chg',
215
+ 'oty_month2_emplvl_chg',
216
+ 'oty_month2_emplvl_pct_chg',
217
+ 'oty_month3_emplvl_chg',
218
+ 'oty_month3_emplvl_pct_chg',
219
+ 'oty_total_qtrly_wages_chg',
220
+ 'oty_total_qtrly_wages_pct_chg',
221
+ 'oty_taxable_qtrly_wages_chg',
222
+ 'oty_taxable_qtrly_wages_pct_chg',
223
+ 'oty_qtrly_contributions_chg',
224
+ 'oty_qtrly_contributions_pct_chg',
225
+ 'oty_avg_wkly_wage_chg',
226
+ 'oty_avg_wkly_wage_pct_chg'
227
+ ]
228
+ final_df = pd.DataFrame()
229
+ for csv in csvs:
230
+ with resources.path("zipcode_features.data", csv) as csv_path:
231
+ df = pd.read_csv(csv_path)
232
+ df = df.drop(cols_to_drop, axis=1)
233
+ final_df = pd.concat([final_df, df], ignore_index=True)
234
+ final_df = final_df.rename({"area_fips": "fips_code"}, axis=1)
235
+ final_df["fips_code"] = final_df["fips_code"].astype(str)
236
+ return final_df
237
+
238
+
239
+ def us_get_demographics(state: str, city: str = None, zip_list: list = None) -> pd.DataFrame:
240
+ """
241
+ This gets demographic information for associated with zipcodes in the United States of America.
242
+
243
+ Parameters
244
+ ----------
245
+ * state : str - the US state
246
+ * city : str [Optional] - the US city
247
+ * zip_list : list [Optional] - a zip list is the query results from the zipcodes library.
248
+ Found here: https://github.com/seanpianka/zipcodes
249
+ If you use zip_list state and city will be ignored.
250
+
251
+ Returns
252
+ -------
253
+ A pandas dataframe with zipcode and everything typically returned by
254
+ https://github.com/EricSchles/uszipcode-project
255
+ """
256
+ search = SearchEngine()
257
+ if city is None:
258
+ payload = {
259
+ "state": state
260
+ }
261
+ else:
262
+ payload = {
263
+ "state": state,
264
+ "city": city
265
+ }
266
+ if zip_list is None:
267
+ zipcode_and_demo = [
268
+ [zipcode["zip_code"], search.by_zipcode(zipcode["zip_code"])]
269
+ for zipcode in zipcodes.filter_by(**payload)
270
+ ]
271
+ else:
272
+ zipcode_and_demo = zip_list[:]
273
+ demographics = []
274
+ for info in zipcode_and_demo:
275
+ if info[1] is None:
276
+ continue
277
+ tmp_dict = info[1].to_dict()
278
+ tmp_dict["zip_code"] = info[0]
279
+ demographics.append(tmp_dict)
280
+ df = pd.DataFrame(demographics)
281
+ zip_to_cbsa = _get_zip_to_cbsa_code()
282
+ df["cbsa"] = df["zip_code"].map(zip_to_cbsa)
283
+ cbsa_code_to_name = _get_cbsa_code_to_cbsa_name()
284
+ df["cbsa_name"] = df["cbsa"].map(cbsa_code_to_name)
285
+ zip_code_to_fips_code = _get_zip_to_fips_code()
286
+ df["fips_code"] = df["zip_code"].map(zip_code_to_fips_code)
287
+ bls_data = _get_bls_data()
288
+ return pd.merge(df, bls_data, how="inner", on="fips_code")
289
+
290
+
@@ -172,14 +172,18 @@ wheels = [
172
172
  { url = "https://files.pythonhosted.org/packages/f5/a1/1f7f0c555f5858fd2906fe9f7b0a3554fddb85cb70df7a6aaec41dc292c2/greenlet-3.5.3-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:c180d22d325fb613956b443c3c6f4406eb70e6defc70d3974da2a7b59e06f48c", size = 285838, upload-time = "2026-06-26T18:21:05.167Z" },
173
173
  { url = "https://files.pythonhosted.org/packages/0a/29/be9f43ed61677a5759b38c8a9389248133c8c731bbfc0574ecdff66c99fc/greenlet-3.5.3-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:483d08c11181c83a6ce1a7a61df0f624a208ec40817a3bb2302714592eee4f04", size = 602342, upload-time = "2026-06-26T19:07:06.908Z" },
174
174
  { url = "https://files.pythonhosted.org/packages/b9/42/ba41c97ec36aa4b3ec25e5aa691d79561254805fad7f2f826dd6770587e2/greenlet-3.5.3-cp310-cp310-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1dae6e0091eae084317e411f047f0b7cb241c6db570f7c45fd6b900a274914ce", size = 615541, upload-time = "2026-06-26T19:10:04.909Z" },
175
+ { url = "https://files.pythonhosted.org/packages/2e/8c/231ca675b0df779816950ca66b40b1fa14dbff4a0ed9814a9a29ec399140/greenlet-3.5.3-cp310-cp310-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0f6ff50ff8dbd51fae9b37f4101648b04ea0df19b3f50ab2beb5061e7716a5c8", size = 622473, upload-time = "2026-06-26T19:24:12.786Z" },
175
176
  { url = "https://files.pythonhosted.org/packages/f5/c7/28747042e1df8a9cd120a1ebe15529fc4be3b486e13e8d551ff307a82412/greenlet-3.5.3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9bcd2d72ccd70a1ec68ba6ef93e7fbb4420ef9997dabc7010d893bd4015e0bec", size = 615675, upload-time = "2026-06-26T18:32:14.444Z" },
177
+ { url = "https://files.pythonhosted.org/packages/81/fe/dd97c483a3ff82849196ccd07851600edd3ac9de74669ca8a6022ada9ea1/greenlet-3.5.3-cp310-cp310-manylinux_2_39_riscv64.whl", hash = "sha256:37bf9c538f5ae6e63d643f88dec37c0c83bdf0e2ebc62961dedcf458822f7b71", size = 418421, upload-time = "2026-06-26T19:25:34.503Z" },
176
178
  { url = "https://files.pythonhosted.org/packages/cc/a8/b85525a6c8fba9f009a5f7c8df1545de8fb0f0bf3e0179194ef4e500317f/greenlet-3.5.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:73f152c895e09907e0dbe24f6c2db37beb085cd63db91c3825a0fcd0064124a8", size = 1575057, upload-time = "2026-06-26T19:09:00.264Z" },
177
179
  { url = "https://files.pythonhosted.org/packages/03/79/fb76edb218fe6735ab0edeba176c7ab80df9618f7c02ce4208979f3ae7db/greenlet-3.5.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8bdb43e1a1d1873721acab2be99c5befd4d2044ddfd52e4d610801019880a702", size = 1641692, upload-time = "2026-06-26T18:31:41.454Z" },
178
180
  { url = "https://files.pythonhosted.org/packages/6b/79/86fe3ee50ed55d9b3907eecd3208b5c3fe8a79515519aae98b4753c3fa1d/greenlet-3.5.3-cp310-cp310-win_amd64.whl", hash = "sha256:0909f9355a9f24845d3299f3112e266a06afb68302041989fd26bd68894933db", size = 238742, upload-time = "2026-06-26T18:20:40.758Z" },
179
181
  { url = "https://files.pythonhosted.org/packages/51/58/5404031044f55afad7aad1aff8be3f22b1bed03e237cfeabbc7e5c8cfde0/greenlet-3.5.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:aca9b4ce85b152b5524ef7d88170efdff80dc0032aa8b75f9aaf7f3479ea95b4", size = 287424, upload-time = "2026-06-26T18:20:31.469Z" },
180
182
  { url = "https://files.pythonhosted.org/packages/b4/bf/1c65e9b94a54d547068fa5b5a8a06f221f3316b48908e08668d29c77cb50/greenlet-3.5.3-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f71be4920368fe1fabeeaa53d1e3548337e2b223d9565f8ad5e392a75ba23fc", size = 606523, upload-time = "2026-06-26T19:07:08.859Z" },
181
183
  { url = "https://files.pythonhosted.org/packages/b8/c7/b66baacc95775ad511287acb0137b95574a9ce5491902372b7564799d790/greenlet-3.5.3-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4d77e67f65f98449e3fb83f795b5d0a8437aead2f874ca89c96576caf4be3af6", size = 618315, upload-time = "2026-06-26T19:10:06.055Z" },
184
+ { url = "https://files.pythonhosted.org/packages/b0/a0/68afd1ebad40db87dac0a28ffa120726b98bf9c7c40c481b0f63c105d298/greenlet-3.5.3-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e18619ba655ac05d78d80fc83cac4ba892bd6927b99e3b8237aee861aaacc8bb", size = 626155, upload-time = "2026-06-26T19:24:14.44Z" },
182
185
  { url = "https://files.pythonhosted.org/packages/78/2b/28ed29463522fdbe4c15b1f63922041626a7478316b34ab4adda3f0a4aba/greenlet-3.5.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8540f1e6205bd13ca0ce685581037219ca54a1b41a0a15d228c6c9b8ad5903d7", size = 617381, upload-time = "2026-06-26T18:32:16.077Z" },
186
+ { url = "https://files.pythonhosted.org/packages/07/7f/e327d912239ec4b3b49999e3967389bcf1ee8722b9ee9194d2752ecd558a/greenlet-3.5.3-cp311-cp311-manylinux_2_39_riscv64.whl", hash = "sha256:d27c0c653a60d9535f690226474a5cc1036a8b0d7b57504d1c4f89c44a07a80c", size = 421083, upload-time = "2026-06-26T19:25:35.804Z" },
183
187
  { url = "https://files.pythonhosted.org/packages/2a/7b/ad04e9d1337fc04965dc9fc616b6a72cb65a24b800a014c011ec812f5489/greenlet-3.5.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7ef56fe650f50575bf843acde967b9c567687f3c22340941a899b7bc56e956a8", size = 1577771, upload-time = "2026-06-26T19:09:01.537Z" },
184
188
  { url = "https://files.pythonhosted.org/packages/d8/33/6c87ab7ba663f70ca21f3022aad1ffe56d3f3e0521e836c2415e13abcc3c/greenlet-3.5.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5121af01cf911e70056c00d4b46d5e9b5d1415550038573d744138bacb59e6b8", size = 1644048, upload-time = "2026-06-26T18:31:42.996Z" },
185
189
  { url = "https://files.pythonhosted.org/packages/1c/35/f0d8ee998b422cf8693b270f098e55d8d4ec8006b061b333f54f177d28d9/greenlet-3.5.3-cp311-cp311-win_amd64.whl", hash = "sha256:0f41e4a05a3c0cb31b17023eff28dd111e1d16bf7d7d00406cd7df23f31398a7", size = 239137, upload-time = "2026-06-26T18:23:21.664Z" },
@@ -187,7 +191,9 @@ wheels = [
187
191
  { url = "https://files.pythonhosted.org/packages/5d/6e/4c37d51a2b7f82d2ff11bb6b5f7d766d9a011726624af255e843727627a3/greenlet-3.5.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:719757059f5a53fd0dde23f78cffeafcdd97b21c850ddb7ca684a3c1a1f122e2", size = 288685, upload-time = "2026-06-26T18:22:08.977Z" },
188
192
  { url = "https://files.pythonhosted.org/packages/7a/73/815dd90131c1b71ebdf53dbc7c276cafec2a1173b97559f97aba72724a87/greenlet-3.5.3-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:efa9f765dd09f9d0cdac651ffdf631ee59ec5dc6ee7a73e0c012ba9c52fbdf5b", size = 604761, upload-time = "2026-06-26T19:07:10.114Z" },
189
193
  { url = "https://files.pythonhosted.org/packages/9f/57/079cfe76bcef36b153b25607ee91c6fcb58f17f8b23c86bbbeabe0c88d72/greenlet-3.5.3-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7faba15ac005376e02a0384504e0243be3370ce010296a44a820feb342b505ab", size = 617044, upload-time = "2026-06-26T19:10:07.25Z" },
194
+ { url = "https://files.pythonhosted.org/packages/fb/fb/d97dc261209c80744b7c8132693a30d70ec6e7315e632cb0a10b3fec94dd/greenlet-3.5.3-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5795cd1101371140551c645f2d408b8d3c01a5a29cf8a9bce6e759c983682d23", size = 622351, upload-time = "2026-06-26T19:24:16.32Z" },
190
195
  { url = "https://files.pythonhosted.org/packages/37/87/b4d095775a3fb1bcafbb483fc206b27ebb785724c83051447737085dc54e/greenlet-3.5.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:87142215824be6ac05e2e8e2786eec307ccbc27c36723c3881959df654af6861", size = 614244, upload-time = "2026-06-26T18:32:17.594Z" },
196
+ { url = "https://files.pythonhosted.org/packages/8e/ac/e5fee13cbbd0e8de312d9a146584b8a51891c68847330ef9dc8b5109d23f/greenlet-3.5.3-cp312-cp312-manylinux_2_39_riscv64.whl", hash = "sha256:af4923b3096e26a36d7e9cf24ab88083a20f97d191e3b97f253731ce9b41b28c", size = 425395, upload-time = "2026-06-26T19:25:37.144Z" },
191
197
  { url = "https://files.pythonhosted.org/packages/8a/70/7559b609683650fa2b95b8ab84b4ab0b26556a635d19675e12aa832d826d/greenlet-3.5.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:215275b1b49320987352e6c1b054acca0064f965a2c66992bed9a6f7d913f149", size = 1574210, upload-time = "2026-06-26T19:09:03.077Z" },
192
198
  { url = "https://files.pythonhosted.org/packages/ae/73/be55392074c60fc37655ca40fa6022457bfbf6718e9e342a7b0b41f96dd2/greenlet-3.5.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6b1b0eed82364b0e32c4ea0f221452d33e6bb17ae094d9f72aed9851812747ea", size = 1638627, upload-time = "2026-06-26T18:31:44.748Z" },
193
199
  { url = "https://files.pythonhosted.org/packages/14/40/c57489acf8e37d74e2913d4eff63aa0dba17acccc4bdeef874dde2dbbec9/greenlet-3.5.3-cp312-cp312-win_amd64.whl", hash = "sha256:cde8adafa2365676f74a979744629589999093bc86e2484214f58e61df08902c", size = 239882, upload-time = "2026-06-26T18:23:27.518Z" },
@@ -195,7 +201,9 @@ wheels = [
195
201
  { url = "https://files.pythonhosted.org/packages/9b/ff/a620267401db30a50cc8450ee90730e2d4a85658c055c0e760d4ed47fb13/greenlet-3.5.3-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:c8d87c2134d871df96ecdea9cec7cbaab286dadab0f56476e57aaf9e8ac11550", size = 287609, upload-time = "2026-06-26T18:21:14.724Z" },
196
202
  { url = "https://files.pythonhosted.org/packages/d6/fa/5401ac78021c826a25b6dde0c705e0a8f29b617509f9185a31dac15fbe1b/greenlet-3.5.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a2d185dd1621757e70c3861cceffd5317ab4e7ed7eb09c82994828468527ade5", size = 607435, upload-time = "2026-06-26T19:07:11.412Z" },
197
203
  { url = "https://files.pythonhosted.org/packages/e9/76/1dc144a2e56e65d36405078ed774224375ea520a1870a6e46e08bb4ac7bf/greenlet-3.5.3-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1c514a468149bf8fbbab874188a3535cd8a48a3e353eb53a3d424296f8dbacd3", size = 619787, upload-time = "2026-06-26T19:10:08.396Z" },
204
+ { url = "https://files.pythonhosted.org/packages/57/61/2f5b1adf256d039f5dab8005de8d3d7ad2b0070a3219c0e036b3fbfeb440/greenlet-3.5.3-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:9ad04dd75458c6300b047c61b8639092433d205a25a14e310d6582a480efcca1", size = 625580, upload-time = "2026-06-26T19:24:18.344Z" },
198
205
  { url = "https://files.pythonhosted.org/packages/bf/87/c298cee62df1de4ad7fec32abda73526cff347fd143a6ed4ac369246668a/greenlet-3.5.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:915f887cf2682b66419b879423a2e072634aa7b7dce6f3ada4957cfced3f1e9a", size = 616786, upload-time = "2026-06-26T18:32:19.128Z" },
206
+ { url = "https://files.pythonhosted.org/packages/3e/d9/ab7fc9e543e44d6879b0a6ef9a4b2188940fd180cc65d6f646883ddf7201/greenlet-3.5.3-cp313-cp313-manylinux_2_39_riscv64.whl", hash = "sha256:afaabdd554cd7ae9bbb3ca070b0d7fdfd207dbf1d16865f7233837709d354bda", size = 427933, upload-time = "2026-06-26T19:25:38.219Z" },
199
207
  { url = "https://files.pythonhosted.org/packages/9e/2e/e6f009885ed0705ccf33fe0583c117cfd03cde77e31a596dd5785a30762b/greenlet-3.5.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:766cfd421c13e450feb340cd472a3ed9957d438727b7b4593ad7c76c5d2b0deb", size = 1574316, upload-time = "2026-06-26T19:09:04.273Z" },
200
208
  { url = "https://files.pythonhosted.org/packages/ef/fe/43fd110b01e40da0adb7c90ac7ea744bef2d43dca00de5095fd2351c2a68/greenlet-3.5.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2ecda9ec22edf38fa389369eaed8c3d37c05f3c54e69f69438dbb2cc1de1458b", size = 1638614, upload-time = "2026-06-26T18:31:46.297Z" },
201
209
  { url = "https://files.pythonhosted.org/packages/0f/7c/062447147a61f8b4337b156fe70d32a165fcf2f89d7ca6255e572806705c/greenlet-3.5.3-cp313-cp313-win_amd64.whl", hash = "sha256:c82304750f057167ff60d188df1d0cc1764ce9567eadf03e6a7443bcedd0b30b", size = 239850, upload-time = "2026-06-26T18:21:54.613Z" },
@@ -203,7 +211,9 @@ wheels = [
203
211
  { url = "https://files.pythonhosted.org/packages/c3/93/43e116ee114b28737ba7e12952a0d4e2f55944d0f84e42bc91ba7192a3c9/greenlet-3.5.3-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:fd2e02fa07485778536a036222d616ab957b1d533f36b3ed98ce725d9c9d3117", size = 288202, upload-time = "2026-06-26T18:23:49.604Z" },
204
212
  { url = "https://files.pythonhosted.org/packages/82/2f/146d218299046a43d1f029fd544b3d110d0f175a09c715c7e8da4a4a345d/greenlet-3.5.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:df0a0628d1597eb0897b62f55d1343f772405fd25f3b2a796c76874b0c2e22e8", size = 654096, upload-time = "2026-06-26T19:07:12.71Z" },
205
213
  { url = "https://files.pythonhosted.org/packages/a0/cc/04738cafb3f45fa991ea44f9de94c47dcec964f5a972300988a6751f49d9/greenlet-3.5.3-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ebd933a6adabc298bab47731a130fe6bfb888bd934eee37810f151159544540d", size = 666304, upload-time = "2026-06-26T19:10:09.503Z" },
214
+ { url = "https://files.pythonhosted.org/packages/86/a9/73fa62893d5b84b4205544e6b673c654cc43aa5b9899bac00f04d64af73d/greenlet-3.5.3-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8d19fe6c39ebff9259f07bcc685d3290f8fa4ea2278e51dd0008e4d6b0f2d814", size = 670657, upload-time = "2026-06-26T19:24:19.967Z" },
206
215
  { url = "https://files.pythonhosted.org/packages/ce/aa/4e0dad5e605c270c784ab911c43da6adb136ccd4d81180f763ca429a723d/greenlet-3.5.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4b9d501b40e80b70e32323c799dd9b420a5577a9601469d362ae1ffb690f3a7c", size = 663635, upload-time = "2026-06-26T18:32:20.802Z" },
216
+ { url = "https://files.pythonhosted.org/packages/29/7e/2ffce64929fb3cab7b65d5a0b20aaf9764e227681d731b041077fc9a525a/greenlet-3.5.3-cp314-cp314-manylinux_2_39_riscv64.whl", hash = "sha256:962c5df2db8cb446da51edf1ca5296c389d93b99c9d8aa2ee4c7d0d8f1218260", size = 473497, upload-time = "2026-06-26T19:25:39.421Z" },
207
217
  { url = "https://files.pythonhosted.org/packages/d1/50/13efdbea246fe3d3b735e191fec08fb50809f53cd2383ebe123d0809e44b/greenlet-3.5.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a1fad1d11e7d6aab184107baa8e4ece11ccba3ec9599cd7efa5ff4d70d43256a", size = 1621252, upload-time = "2026-06-26T19:09:05.647Z" },
208
218
  { url = "https://files.pythonhosted.org/packages/f7/22/c0a336ae4a1410fd5f5121098e5bfbf1865f64c5ef80b4b5412886c4a332/greenlet-3.5.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:fad5aec764399f1b5cc347ad250a59660f20c8f8888ea6bae1f93b769cce1154", size = 1684824, upload-time = "2026-06-26T18:31:47.738Z" },
209
219
  { url = "https://files.pythonhosted.org/packages/7a/94/91aec0030bea75c4b3244251d0de60a1f3432d1ecb53ab6c437fb5c3ba61/greenlet-3.5.3-cp314-cp314-win_amd64.whl", hash = "sha256:7669aa24cf2a1041d6f7899575b494a3ab4cf68bfcc8609b1dc0be7272db835e", size = 240754, upload-time = "2026-06-26T18:22:15.669Z" },
@@ -211,14 +221,18 @@ wheels = [
211
221
  { url = "https://files.pythonhosted.org/packages/91/95/3e161213d7f1d378d15aa9e792093e9bfe01844680d04b7fd6e0107c9098/greenlet-3.5.3-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:271a8ea7c1024e8a0d7dd2be66dd66dda8a07193f41a17b9e924f7600f5b62be", size = 296389, upload-time = "2026-06-26T18:22:20.657Z" },
212
222
  { url = "https://files.pythonhosted.org/packages/00/92/715c44721abe2b4d1ae9abde4179411868a5bff312479f54e105d372f131/greenlet-3.5.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:19131729ae0ddc3c2e1ef85e650169b5e37ee32e400f215f78b94d7b0d567310", size = 653382, upload-time = "2026-06-26T19:07:14.209Z" },
213
223
  { url = "https://files.pythonhosted.org/packages/a0/83/37a10372a1090a6624cca8e74c12df1a36c2dc36429ed0255b7fb1aeee23/greenlet-3.5.3-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1540dd8e5fc2a5aec40fbb98ef8e149fa47c89a4b4a1cf2575a14d3d1869d7a8", size = 659401, upload-time = "2026-06-26T19:10:10.876Z" },
224
+ { url = "https://files.pythonhosted.org/packages/cb/73/8faec206b851c22b1733545fda900829a1f3f5b1c78ae7e0fb3dba57d9f4/greenlet-3.5.3-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b897d97759425953f69a9c0fac67f8fe333ec0ce7377ef186fb2b0c3ad5e354d", size = 659582, upload-time = "2026-06-26T19:24:21.357Z" },
214
225
  { url = "https://files.pythonhosted.org/packages/db/e2/d1509cad4207da559cc42986ecdd8fc67ad0d1bba2bf03023c467fd5e0f3/greenlet-3.5.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e81fa194a1d20967877bdf9c7794db2bc99063e5be36aee710c08f04c5bb087f", size = 656969, upload-time = "2026-06-26T18:32:22.272Z" },
226
+ { url = "https://files.pythonhosted.org/packages/b4/55/50c19e49f8045834ada71ef12f8ad048eba8517c6aa41161bed676328fae/greenlet-3.5.3-cp314-cp314t-manylinux_2_39_riscv64.whl", hash = "sha256:3236754d423955ea08e9bb5f6c04a7895f9e22c290b66aa7653fcb922d839eb0", size = 491037, upload-time = "2026-06-26T19:25:40.672Z" },
215
227
  { url = "https://files.pythonhosted.org/packages/86/7d/eaf70de20aadca3a5884aec58362861c64ce45e7b277f47ed026926a3b89/greenlet-3.5.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:55cf4d777485d43110e47133cbba6d74a8885a87ec1227ef0267f9ee80c5aa21", size = 1617822, upload-time = "2026-06-26T19:09:06.893Z" },
216
228
  { url = "https://files.pythonhosted.org/packages/8a/f9/414d38fc400ae4350d4185eaad1827676f7cf5287b9136e0ed1cbbe20a7f/greenlet-3.5.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:12a248ba75f6a9a236375f52296c498c89ff1d8badf32deb9eca7abd5853f7da", size = 1677983, upload-time = "2026-06-26T18:31:49.396Z" },
217
229
  { url = "https://files.pythonhosted.org/packages/e4/15/7edb977e08f9bff702fe42d6c902702786ff6b9694058b4e6a2a6ac90e57/greenlet-3.5.3-cp314-cp314t-win_amd64.whl", hash = "sha256:efc6bd60ea02e085862c74a3ef64b147ffc6f1a5ea7d9f26e7a939943f68c1e3", size = 243626, upload-time = "2026-06-26T18:24:41.485Z" },
218
230
  { url = "https://files.pythonhosted.org/packages/2c/8a/93928dce91e6b3598b5e779e8d1fd6576a504640c58e78627077f6a7a91a/greenlet-3.5.3-cp315-cp315-macosx_11_0_universal2.whl", hash = "sha256:ea03f2f04367845d6b58eeed276e1e56e51f0b97d8ad5a88a7d20a91dc9056cc", size = 288860, upload-time = "2026-06-26T18:22:48.07Z" },
219
231
  { url = "https://files.pythonhosted.org/packages/4f/ca/69db42d447a1378043e2c8f19c09cbbd1263371505053c496b49066d3d16/greenlet-3.5.3-cp315-cp315-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:78dbef602fda6d97d957eb7937f70c9ce9e9527330347f8f6b6f9e554a9e7a47", size = 659747, upload-time = "2026-06-26T19:07:15.565Z" },
220
232
  { url = "https://files.pythonhosted.org/packages/a8/0b/af7ac2ef8dd41e3da1a40dda6305c23b9a03e13ba975ec916357b50f8575/greenlet-3.5.3-cp315-cp315-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6f73857adb8fee13fa56c172bd11262f888c0c648f9fea113e777bb2c7904a81", size = 670419, upload-time = "2026-06-26T19:10:12.293Z" },
233
+ { url = "https://files.pythonhosted.org/packages/25/aa/952cf28c2ff949a8c971134fb43854dd7eaa737218723aaef758f8c9aead/greenlet-3.5.3-cp315-cp315-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:cefa9cef4b371f9844c6053db71f1138bc6807bab1578b0dae5149c1f1141357", size = 674261, upload-time = "2026-06-26T19:24:22.79Z" },
221
234
  { url = "https://files.pythonhosted.org/packages/51/1e/1d51640cacbfc455dbe9f9a9f594c49e4e244f63b9971a2f4764e46cc53d/greenlet-3.5.3-cp315-cp315-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:232fec92e823addaf02d9472cf7381e24a1d046a6ced1103c5caa4c21b9dfc1d", size = 668787, upload-time = "2026-06-26T18:32:24.298Z" },
235
+ { url = "https://files.pythonhosted.org/packages/dc/f2/b00d6f5e63e531a93562b2ec1a4c320fbee91f580fc42e6417af69d706e5/greenlet-3.5.3-cp315-cp315-manylinux_2_39_riscv64.whl", hash = "sha256:6219b6d04dbf6ba6084d77dc609e8473060dc55f759cbf626d512122781fa128", size = 480322, upload-time = "2026-06-26T19:25:41.852Z" },
222
236
  { url = "https://files.pythonhosted.org/packages/21/66/4030d5b0b5894500023f003bb054d9bb354dfbd1e186c3a296759172f5f5/greenlet-3.5.3-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:2421c3564da9429d5586d46ca31ebb26516b5498a802cf65c041a8e8a8980d34", size = 1626305, upload-time = "2026-06-26T19:09:08.281Z" },
223
237
  { url = "https://files.pythonhosted.org/packages/0e/50/5221371c7550108dfa3c378debc41d032aa9c78e89abb01d8011cfc93289/greenlet-3.5.3-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:e0f0d160f0b2e558e6c75f7930967183255dc9735e5f5b8cae58ee09c9576d8b", size = 1688631, upload-time = "2026-06-26T18:31:51.278Z" },
224
238
  { url = "https://files.pythonhosted.org/packages/68/5d/00d469daae3c65d2bf620b10eee82eb022127d483c6bc8c69fae6f3fbf17/greenlet-3.5.3-cp315-cp315-win_amd64.whl", hash = "sha256:dd99329bbc15ca78dcc583dba05d0b1b0bae01ab6c2174989f5aaee3e41ac930", size = 241027, upload-time = "2026-06-26T18:22:38.203Z" },
@@ -226,7 +240,9 @@ wheels = [
226
240
  { url = "https://files.pythonhosted.org/packages/1c/da/4f4a8450962fad137c1c8981a3f1b8919d06c829993d4d476f9c525d5173/greenlet-3.5.3-cp315-cp315t-macosx_11_0_universal2.whl", hash = "sha256:176bc16a721fa5fc294d70b87b4dfa5fbdd251b3da5d5372735ecef9bd7d6d0c", size = 297221, upload-time = "2026-06-26T18:23:27.176Z" },
227
241
  { url = "https://files.pythonhosted.org/packages/57/66/b3bfae3e220a9b63ea539a0eea681800c69ab1aada757eae8789f183e7ce/greenlet-3.5.3-cp315-cp315t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:629b614d2b786e89c50440e246f33eea78f58a962d0bdbbcc809e6d13605903f", size = 657221, upload-time = "2026-06-26T19:07:16.973Z" },
228
242
  { url = "https://files.pythonhosted.org/packages/7b/81/b6d4d73a709684fc77e7fa034d7c2fe82cffa9fc920fadcaa659c2626213/greenlet-3.5.3-cp315-cp315t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2b2e857ae16f5f72142edf75f9f176fe7526ba19a2841df1420516f83831c9f2", size = 663226, upload-time = "2026-06-26T19:10:13.723Z" },
243
+ { url = "https://files.pythonhosted.org/packages/e9/39/0e0938a75115b939d42733a2a12e1d349653c9531fe6fe563e8a681f04e6/greenlet-3.5.3-cp315-cp315t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:16d192579ed281051396dddd7f7754dac6259e6b1fb26378c87b66622f8e3f91", size = 663706, upload-time = "2026-06-26T19:24:24.312Z" },
229
244
  { url = "https://files.pythonhosted.org/packages/f5/07/e210b02b589f16e74ff48b730690e4a34ffe984219fce4f3c1a0e7ec8545/greenlet-3.5.3-cp315-cp315t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e515757e2e36bcbf1fad09a46e1557e8b1ae1797d4b44d09da7deed88ad28608", size = 660802, upload-time = "2026-06-26T18:32:26.081Z" },
245
+ { url = "https://files.pythonhosted.org/packages/5b/41/35d1c678cdb3c3b9e6bee691728e563cfb294202b23c7a4c3c2ccc343589/greenlet-3.5.3-cp315-cp315t-manylinux_2_39_riscv64.whl", hash = "sha256:4399eb8d041f20b68d943918bc55502a93d6fdc0a37c14da7881c04139acee9d", size = 498803, upload-time = "2026-06-26T19:25:43.063Z" },
230
246
  { url = "https://files.pythonhosted.org/packages/eb/2e/5303eb3fa06bca089060f479707182a93e360683bc252acf846c3090d34e/greenlet-3.5.3-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:b363d46ed1ea431825fdb01471bb024fc08399bad1572a616e853c7684415adb", size = 1622157, upload-time = "2026-06-26T19:09:09.527Z" },
231
247
  { url = "https://files.pythonhosted.org/packages/54/70/50de47a488f14df260b50ae34fb5d56016e308b098eab02c878b5223c26a/greenlet-3.5.3-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:e44da2f5bbdaabaf7d80b73dbb430c7035771e9f244e3c8b769715c9d8fa0a16", size = 1681159, upload-time = "2026-06-26T18:31:52.986Z" },
232
248
  { url = "https://files.pythonhosted.org/packages/a7/13/1055e1dda7882073eda533e2b96c62e55bbd2db7fda6d5ece992febc7071/greenlet-3.5.3-cp315-cp315t-win_amd64.whl", hash = "sha256:8ff8bed3e3baa20a3ea261ce00526f1898ad4801d4886fd2220580ee0ad8fadf", size = 244007, upload-time = "2026-06-26T18:22:04.353Z" },
@@ -718,7 +734,7 @@ wheels = [
718
734
 
719
735
  [[package]]
720
736
  name = "zipcode-features"
721
- version = "0.0.7"
737
+ version = "0.0.9"
722
738
  source = { editable = "." }
723
739
  dependencies = [
724
740
  { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" },
@@ -1,91 +0,0 @@
1
- __version__ = '0.0.7'
2
-
3
- import zipcodes
4
- from zipcode3.search import SearchEngine
5
- from importlib import resources
6
- import pandas as pd
7
- import json
8
-
9
- def zipcode_mapper(x):
10
- if x["ZIP_len"] == 3:
11
- return "00" + x["ZIP"]
12
- elif x["ZIP_len"] == 4:
13
- return "0" + x["ZIP"]
14
- else:
15
- return x["ZIP"]
16
-
17
- def _get_zip_to_cbsa_code() -> dict:
18
- """
19
- This method gets a mapping from zipcode to cbsa code
20
- mapping is of the form:
21
- {"zip code": "cbsa code"}
22
- """
23
- with resources.path("zipcode_features.data", "CBSA_ZIP_122025.csv") as csv_path:
24
- df = pd.read_csv(csv_path, dtype={'ZIP': str, "CBSA": str})
25
- df["ZIP_len"] = df["ZIP"].apply(lambda x: len(x))
26
- df["ZIP"] = df.apply(zipcode_mapper, axis=1)
27
- return df[["ZIP", "CBSA"]].to_dict()
28
-
29
- def _get_cbsa_code_to_cbsa_name() -> dict:
30
- """
31
- This method gets a mapping from cbsa code to name
32
- {cbsa code: cbsa name}
33
- """
34
- with resources.path("zipcode_features.data", "cbsa_codes.json") as json_path:
35
- code_to_name = json.load(open(json_path))
36
- df = pd.DataFrame(columns=["code", "name"])
37
- df["name"] = code_to_name.values()
38
- df["code"] = code_to_name.keys()
39
- df["name"] = df["name"].str.replace(" -", "-")
40
- df["name"] = df["name"].str.split().str.join(' ')
41
- return df.to_dict()
42
-
43
-
44
- def us_get_demographics(state: str, city: str = None, zip_list: list = None) -> pd.DataFrame:
45
- """
46
- This gets demographic information for associated with zipcodes in the United States of America.
47
-
48
- Parameters
49
- ----------
50
- * state : str - the US state
51
- * city : str [Optional] - the US city
52
- * zip_list : list [Optional] - a zip list is the query results from the zipcodes library.
53
- Found here: https://github.com/seanpianka/zipcodes
54
- If you use zip_list state and city will be ignored.
55
-
56
- Returns
57
- -------
58
- A pandas dataframe with zipcode and everything typically returned by
59
- https://github.com/EricSchles/uszipcode-project
60
- """
61
- search = SearchEngine()
62
- if city is None:
63
- payload = {
64
- "state": state
65
- }
66
- else:
67
- payload = {
68
- "state": state,
69
- "city": city
70
- }
71
- if zip_list is None:
72
- zipcode_and_demo = [
73
- [zipcode["zip_code"], search.by_zipcode(zipcode["zip_code"])]
74
- for zipcode in zipcodes.filter_by(**payload)
75
- ]
76
- else:
77
- zipcode_and_demo = zip_list[:]
78
- demographics = []
79
- for info in zipcode_and_demo:
80
- if info[1] is None:
81
- continue
82
- tmp_dict = info[1].to_dict()
83
- tmp_dict["zip_code"] = info[0]
84
- demographics.append(tmp_dict)
85
- df = pd.DataFrame(demographics)
86
- zip_to_cbsa = _get_zip_to_cbsa_code()
87
- df["cbsa"] = df["zip_code"].map(zip_to_cbsa)
88
- cbsa_code_to_name = _get_cbsa_code_to_cbsa_name()
89
- df["cbsa_name"] = df["cbsa"].map(cbsa_code_to_name)
90
- return df
91
-