notionhelper 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.
- notionhelper-0.1.0/.gitignore +10 -0
- notionhelper-0.1.0/.python-version +1 -0
- notionhelper-0.1.0/PKG-INFO +10 -0
- notionhelper-0.1.0/README.md +0 -0
- notionhelper-0.1.0/pyproject.toml +19 -0
- notionhelper-0.1.0/src/notionhelper/__init__.py +2 -0
- notionhelper-0.1.0/src/notionhelper/notionhelper.py +479 -0
- notionhelper-0.1.0/src/notionhelper/py.typed +0 -0
- notionhelper-0.1.0/uv.lock +278 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: notionhelper
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Add your description here
|
|
5
|
+
Author-email: Jan du Plessis <drjanduplessis@icloud.com>
|
|
6
|
+
Requires-Python: >=3.12
|
|
7
|
+
Requires-Dist: httpx>=0.27.0
|
|
8
|
+
Requires-Dist: mimetype>=0.1.5
|
|
9
|
+
Requires-Dist: notion-client>=2.4.0
|
|
10
|
+
Requires-Dist: pandas>=2.3.1
|
|
File without changes
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "notionhelper"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Add your description here"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
authors = [
|
|
7
|
+
{ name = "Jan du Plessis", email = "drjanduplessis@icloud.com" }
|
|
8
|
+
]
|
|
9
|
+
requires-python = ">=3.12"
|
|
10
|
+
dependencies = [
|
|
11
|
+
"mimetype>=0.1.5",
|
|
12
|
+
"notion-client>=2.4.0",
|
|
13
|
+
"pandas>=2.3.1",
|
|
14
|
+
"httpx>=0.27.0",
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
[build-system]
|
|
18
|
+
requires = ["hatchling"]
|
|
19
|
+
build-backend = "hatchling.build"
|
|
@@ -0,0 +1,479 @@
|
|
|
1
|
+
import notion_client
|
|
2
|
+
from notion_client import AsyncClient
|
|
3
|
+
import pprint
|
|
4
|
+
import pandas as pd
|
|
5
|
+
import os
|
|
6
|
+
import httpx
|
|
7
|
+
import mimetypes
|
|
8
|
+
import os
|
|
9
|
+
|
|
10
|
+
# NotionHelper can be used in conjunction with the Streamlit APP: (Notion API JSON)[https://notioinapiassistant.streamlit.app]
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class NotionHelper:
|
|
14
|
+
"""A helper class to interact with the Notion API, providing methods for database and page management,
|
|
15
|
+
as well as file uploads and attachments.
|
|
16
|
+
|
|
17
|
+
This class simplifies interactions with the Notion API by wrapping common operations
|
|
18
|
+
such as creating, querying, and updating databases and pages. It also includes functionality
|
|
19
|
+
for handling file uploads and embedding them within Notion pages or attaching them to page properties.
|
|
20
|
+
|
|
21
|
+
Parameters
|
|
22
|
+
----------
|
|
23
|
+
notion_token : str
|
|
24
|
+
The integration token for authenticating with the Notion API.
|
|
25
|
+
|
|
26
|
+
Methods
|
|
27
|
+
-------
|
|
28
|
+
get_database(database_id)
|
|
29
|
+
Retrieves the schema of a Notion database.
|
|
30
|
+
notion_search_db(database_id, query="")
|
|
31
|
+
Searches for pages in a database with a title containing the query.
|
|
32
|
+
notion_get_page(page_id)
|
|
33
|
+
Retrieves the properties and content blocks of a page.
|
|
34
|
+
create_database(parent_page_id, database_title, properties)
|
|
35
|
+
Creates a new database under a specified parent page.
|
|
36
|
+
new_page_to_db(database_id, page_properties)
|
|
37
|
+
Adds a new page to a database.
|
|
38
|
+
append_page_body(page_id, blocks)
|
|
39
|
+
Appends content blocks to a page.
|
|
40
|
+
get_all_page_ids(database_id)
|
|
41
|
+
Retrieves all page IDs from a database.
|
|
42
|
+
get_all_pages_as_json(database_id, limit=None)
|
|
43
|
+
Fetches all pages from a database as a list of JSON objects.
|
|
44
|
+
get_all_pages_as_dataframe(database_id, limit=None, include_page_ids=True)
|
|
45
|
+
Retrieves all pages from a database as a Pandas DataFrame.
|
|
46
|
+
upload_file(file_path)
|
|
47
|
+
Uploads a file to Notion's temporary storage.
|
|
48
|
+
attach_file_to_page(page_id, file_upload_id)
|
|
49
|
+
Attaches a previously uploaded file to a page body.
|
|
50
|
+
embed_image_to_page(page_id, file_upload_id)
|
|
51
|
+
Embeds a previously uploaded image into a page body.
|
|
52
|
+
attach_file_to_page_property(page_id, property_name, file_upload_id, file_name)
|
|
53
|
+
Attaches a previously uploaded file to a 'Files & Media' property of a page.
|
|
54
|
+
one_step_image_embed(page_id, file_path)
|
|
55
|
+
Uploads and embeds an image in a page in a single call.
|
|
56
|
+
one_step_file_to_page(page_id, file_path)
|
|
57
|
+
Uploads and attaches a file to a page body in a single call.
|
|
58
|
+
one_step_file_to_page_property(page_id, property_name, file_path, file_name)
|
|
59
|
+
Uploads and attaches a file to a page property in a single call.
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
def __init__(self, notion_token):
|
|
63
|
+
"""Initializes the NotionHelper instance and authenticates with the Notion API
|
|
64
|
+
using the provided token."""
|
|
65
|
+
self.notion_token = notion_token
|
|
66
|
+
self.notion = AsyncClient(auth=self.notion_token)
|
|
67
|
+
|
|
68
|
+
async def get_database(self, database_id):
|
|
69
|
+
"""Retrieves the schema of a Notion database given its database_id.
|
|
70
|
+
|
|
71
|
+
Parameters
|
|
72
|
+
----------
|
|
73
|
+
database_id : str
|
|
74
|
+
The unique identifier of the Notion database.
|
|
75
|
+
|
|
76
|
+
Returns
|
|
77
|
+
-------
|
|
78
|
+
dict
|
|
79
|
+
A dictionary representing the database schema.
|
|
80
|
+
"""
|
|
81
|
+
response = await self.notion.databases.retrieve(database_id=database_id)
|
|
82
|
+
return response
|
|
83
|
+
|
|
84
|
+
async def notion_search_db(
|
|
85
|
+
self, database_id="e18e2d110f9e401eb1adf3190e51a21b", query=""
|
|
86
|
+
):
|
|
87
|
+
"""Searches for pages in a Notion database that contain the specified query in their title."""
|
|
88
|
+
my_pages = await self.notion.databases.query(
|
|
89
|
+
database_id=database_id,
|
|
90
|
+
filter={
|
|
91
|
+
"property": "title",
|
|
92
|
+
"rich_text": {"contains": query},
|
|
93
|
+
},
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
page_title = my_pages["results"][0]["properties"]["Code / Notebook Description"]["title"][0]["plain_text"]
|
|
97
|
+
page_url = my_pages["results"][0]["url"]
|
|
98
|
+
|
|
99
|
+
page_list = my_pages["results"]
|
|
100
|
+
count = 1
|
|
101
|
+
for page in page_list:
|
|
102
|
+
try:
|
|
103
|
+
print(
|
|
104
|
+
count,
|
|
105
|
+
page["properties"]["Code / Notebook Description"]["title"][0]["plain_text"],
|
|
106
|
+
)
|
|
107
|
+
except IndexError:
|
|
108
|
+
print("No results found.")
|
|
109
|
+
|
|
110
|
+
print(page["url"])
|
|
111
|
+
print()
|
|
112
|
+
count += 1
|
|
113
|
+
|
|
114
|
+
# pprint.pprint(page)
|
|
115
|
+
|
|
116
|
+
async def notion_get_page(self, page_id):
|
|
117
|
+
"""Retrieves the JSON of the page properties and an array of blocks on a Notion page given its page_id."""
|
|
118
|
+
|
|
119
|
+
# Retrieve the page and block data
|
|
120
|
+
page = await self.notion.pages.retrieve(page_id)
|
|
121
|
+
blocks = await self.notion.blocks.children.list(page_id)
|
|
122
|
+
|
|
123
|
+
# Extract all properties as a JSON object
|
|
124
|
+
properties = page.get("properties", {})
|
|
125
|
+
content = [block for block in blocks["results"]]
|
|
126
|
+
|
|
127
|
+
# Print the full JSON of the properties
|
|
128
|
+
print(properties)
|
|
129
|
+
|
|
130
|
+
# Return the properties JSON and blocks content
|
|
131
|
+
return {"properties": properties, "content": content}
|
|
132
|
+
|
|
133
|
+
async def create_database(self, parent_page_id, database_title, properties):
|
|
134
|
+
"""Creates a new database in Notion.
|
|
135
|
+
|
|
136
|
+
This method creates a new database under a specified parent page with the provided title and property definitions.
|
|
137
|
+
|
|
138
|
+
Parameters:
|
|
139
|
+
parent_page_id (str): The unique identifier of the parent page.
|
|
140
|
+
database_title (str): The title for the new database.
|
|
141
|
+
properties (dict): A dictionary defining the property schema for the database.
|
|
142
|
+
|
|
143
|
+
Returns:
|
|
144
|
+
dict: The JSON response from the Notion API containing details about the created database.
|
|
145
|
+
"""
|
|
146
|
+
|
|
147
|
+
# Define the properties for the database
|
|
148
|
+
new_database = {
|
|
149
|
+
"parent": {"type": "page_id", "page_id": parent_page_id},
|
|
150
|
+
"title": [{"type": "text", "text": {"content": database_title}}],
|
|
151
|
+
"properties": properties,
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
response = await self.notion.databases.create(**new_database)
|
|
155
|
+
return response
|
|
156
|
+
|
|
157
|
+
async def new_page_to_db(self, database_id, page_properties):
|
|
158
|
+
"""Adds a new page to a Notion database."""
|
|
159
|
+
|
|
160
|
+
new_page = {
|
|
161
|
+
"parent": {"database_id": database_id},
|
|
162
|
+
"properties": page_properties,
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
response = await self.notion.pages.create(**new_page)
|
|
166
|
+
return response
|
|
167
|
+
|
|
168
|
+
async def append_page_body(self, page_id, blocks):
|
|
169
|
+
"""Appends blocks of text to the body of a Notion page."""
|
|
170
|
+
|
|
171
|
+
new_blocks = {"children": blocks}
|
|
172
|
+
|
|
173
|
+
response = await self.notion.blocks.children.append(block_id=page_id, **new_blocks)
|
|
174
|
+
return response
|
|
175
|
+
|
|
176
|
+
async def get_all_page_ids(self, database_id):
|
|
177
|
+
"""Returns the IDs of all pages in a given database."""
|
|
178
|
+
|
|
179
|
+
my_pages = await self.notion.databases.query(database_id=database_id)
|
|
180
|
+
page_ids = [page["id"] for page in my_pages["results"]]
|
|
181
|
+
return page_ids
|
|
182
|
+
|
|
183
|
+
async def get_all_pages_as_json(self, database_id, limit=None):
|
|
184
|
+
"""Returns a list of JSON objects representing all pages in the given database, with all properties.
|
|
185
|
+
You can specify the number of entries to be loaded using the `limit` parameter.
|
|
186
|
+
"""
|
|
187
|
+
|
|
188
|
+
# Use pagination to remove any limits on number of entries, optionally limited by `limit` argument
|
|
189
|
+
pages_json = []
|
|
190
|
+
has_more = True
|
|
191
|
+
start_cursor = None
|
|
192
|
+
count = 0
|
|
193
|
+
|
|
194
|
+
while has_more:
|
|
195
|
+
my_pages = await self.notion.databases.query(
|
|
196
|
+
**{
|
|
197
|
+
"database_id": database_id,
|
|
198
|
+
"start_cursor": start_cursor,
|
|
199
|
+
}
|
|
200
|
+
)
|
|
201
|
+
pages_json.extend([page["properties"] for page in my_pages["results"]])
|
|
202
|
+
has_more = my_pages.get("has_more", False)
|
|
203
|
+
start_cursor = my_pages.get("next_cursor", None)
|
|
204
|
+
count += len(my_pages["results"])
|
|
205
|
+
|
|
206
|
+
if limit is not None and count >= limit:
|
|
207
|
+
pages_json = pages_json[:limit]
|
|
208
|
+
break
|
|
209
|
+
|
|
210
|
+
return pages_json
|
|
211
|
+
|
|
212
|
+
async def get_all_pages_as_dataframe(self, database_id, limit=None, include_page_ids=True):
|
|
213
|
+
"""Retrieves all pages from a Notion database and returns them as a Pandas DataFrame.
|
|
214
|
+
|
|
215
|
+
This method collects pages from the specified Notion database, optionally including the page IDs,
|
|
216
|
+
and extracts a predefined set of allowed properties from each page to form a structured DataFrame.
|
|
217
|
+
Numeric values are formatted to avoid scientific notation.
|
|
218
|
+
|
|
219
|
+
Parameters:
|
|
220
|
+
database_id (str): The identifier of the Notion database.
|
|
221
|
+
limit (int, optional): Maximum number of page entries to include. If None, all pages are retrieved.
|
|
222
|
+
include_page_ids (bool, optional): If True, includes an additional column 'notion_page_id' in the DataFrame.
|
|
223
|
+
Defaults to True.
|
|
224
|
+
|
|
225
|
+
Returns:
|
|
226
|
+
pandas.DataFrame: A DataFrame where each row represents a page with columns corresponding to page properties.
|
|
227
|
+
If include_page_ids is True, an additional column 'notion_page_id' is included.
|
|
228
|
+
"""
|
|
229
|
+
# Retrieve pages with or without page IDs based on the flag
|
|
230
|
+
if include_page_ids:
|
|
231
|
+
pages_json = []
|
|
232
|
+
has_more = True
|
|
233
|
+
start_cursor = None
|
|
234
|
+
count = 0
|
|
235
|
+
# Retrieve pages with pagination including the page ID in properties
|
|
236
|
+
while has_more:
|
|
237
|
+
my_pages = await self.notion.databases.query(
|
|
238
|
+
database_id=database_id,
|
|
239
|
+
start_cursor=start_cursor,
|
|
240
|
+
)
|
|
241
|
+
for page in my_pages["results"]:
|
|
242
|
+
props = page["properties"]
|
|
243
|
+
props["notion_page_id"] = page.get("id", "")
|
|
244
|
+
pages_json.append(props)
|
|
245
|
+
has_more = my_pages.get("has_more", False)
|
|
246
|
+
start_cursor = my_pages.get("next_cursor", None)
|
|
247
|
+
count += len(my_pages["results"])
|
|
248
|
+
if limit is not None and count >= limit:
|
|
249
|
+
pages_json = pages_json[:limit]
|
|
250
|
+
break
|
|
251
|
+
else:
|
|
252
|
+
pages_json = await self.get_all_pages_as_json(database_id, limit=limit)
|
|
253
|
+
|
|
254
|
+
data = []
|
|
255
|
+
# Define the list of allowed property types that we want to extract
|
|
256
|
+
allowed_properties = [
|
|
257
|
+
"title",
|
|
258
|
+
"status",
|
|
259
|
+
"number",
|
|
260
|
+
"date",
|
|
261
|
+
"url",
|
|
262
|
+
"checkbox",
|
|
263
|
+
"rich_text",
|
|
264
|
+
"email",
|
|
265
|
+
"select",
|
|
266
|
+
"people",
|
|
267
|
+
"phone_number",
|
|
268
|
+
"multi_select",
|
|
269
|
+
"created_time",
|
|
270
|
+
"created_by",
|
|
271
|
+
"rollup",
|
|
272
|
+
"relation",
|
|
273
|
+
"last_edited_by",
|
|
274
|
+
"last_edited_time",
|
|
275
|
+
"formula",
|
|
276
|
+
"file",
|
|
277
|
+
]
|
|
278
|
+
if include_page_ids:
|
|
279
|
+
allowed_properties.append("notion_page_id")
|
|
280
|
+
|
|
281
|
+
for page in pages_json:
|
|
282
|
+
row = {}
|
|
283
|
+
for key, value in page.items():
|
|
284
|
+
if key == "notion_page_id":
|
|
285
|
+
row[key] = value
|
|
286
|
+
continue
|
|
287
|
+
property_type = value.get("type", "")
|
|
288
|
+
if property_type in allowed_properties:
|
|
289
|
+
if property_type == "title":
|
|
290
|
+
row[key] = value.get("title", [{}])[0].get("plain_text", "")
|
|
291
|
+
elif property_type == "status":
|
|
292
|
+
row[key] = value.get("status", {}).get("name", "")
|
|
293
|
+
elif property_type == "number":
|
|
294
|
+
number_value = value.get("number", None)
|
|
295
|
+
row[key] = float(number_value) if isinstance(number_value, (int, float)) else None
|
|
296
|
+
elif property_type == "date":
|
|
297
|
+
date_field = value.get("date", {})
|
|
298
|
+
row[key] = date_field.get("start", "") if date_field else ""
|
|
299
|
+
elif property_type == "url":
|
|
300
|
+
row[key] = value.get("url", "")
|
|
301
|
+
elif property_type == "checkbox":
|
|
302
|
+
row[key] = value.get("checkbox", False)
|
|
303
|
+
elif property_type == "rich_text":
|
|
304
|
+
rich_text_field = value.get("rich_text", [])
|
|
305
|
+
row[key] = rich_text_field[0].get("plain_text", "") if rich_text_field else ""
|
|
306
|
+
elif property_type == "email":
|
|
307
|
+
row[key] = value.get("email", "")
|
|
308
|
+
elif property_type == "select":
|
|
309
|
+
select_field = value.get("select", {})
|
|
310
|
+
row[key] = select_field.get("name", "") if select_field else ""
|
|
311
|
+
elif property_type == "people":
|
|
312
|
+
people_list = value.get("people", [])
|
|
313
|
+
if people_list:
|
|
314
|
+
person = people_list[0]
|
|
315
|
+
row[key] = {"name": person.get("name", ""), "email": person.get("person", {}).get("email", "")}
|
|
316
|
+
elif property_type == "phone_number":
|
|
317
|
+
row[key] = value.get("phone_number", "")
|
|
318
|
+
elif property_type == "multi_select":
|
|
319
|
+
multi_select_field = value.get("multi_select", [])
|
|
320
|
+
row[key] = [item.get("name", "") for item in multi_select_field]
|
|
321
|
+
elif property_type == "created_time":
|
|
322
|
+
row[key] = value.get("created_time", "")
|
|
323
|
+
elif property_type == "created_by":
|
|
324
|
+
created_by = value.get("created_by", {})
|
|
325
|
+
row[key] = created_by.get("name", "")
|
|
326
|
+
elif property_type == "rollup":
|
|
327
|
+
rollup_field = value.get("rollup", {}).get("array", [])
|
|
328
|
+
row[key] = [item.get("date", {}).get("start", "") for item in rollup_field]
|
|
329
|
+
elif property_type == "relation":
|
|
330
|
+
relation_list = value.get("relation", [])
|
|
331
|
+
row[key] = [relation.get("id", "") for relation in relation_list]
|
|
332
|
+
elif property_type == "last_edited_by":
|
|
333
|
+
last_edited_by = value.get("last_edited_by", {})
|
|
334
|
+
row[key] = last_edited_by.get("name", "")
|
|
335
|
+
elif property_type == "last_edited_time":
|
|
336
|
+
row[key] = value.get("last_edited_time", "")
|
|
337
|
+
elif property_type == "formula":
|
|
338
|
+
formula_value = value.get("formula", {})
|
|
339
|
+
row[key] = formula_value.get(formula_value.get("type", ""), "")
|
|
340
|
+
elif property_type == "file":
|
|
341
|
+
files = value.get("files", [])
|
|
342
|
+
row[key] = [file.get("name", "") for file in files]
|
|
343
|
+
data.append(row)
|
|
344
|
+
|
|
345
|
+
df = pd.DataFrame(data)
|
|
346
|
+
pd.options.display.float_format = "{:.3f}".format
|
|
347
|
+
return df
|
|
348
|
+
|
|
349
|
+
async def upload_file(self, file_path):
|
|
350
|
+
"""Uploads a file to Notion and returns the file upload object."""
|
|
351
|
+
async with httpx.AsyncClient() as client:
|
|
352
|
+
# Step 1: Create a File Upload object
|
|
353
|
+
create_upload_url = "https://api.notion.com/v1/file_uploads"
|
|
354
|
+
headers = {
|
|
355
|
+
"Authorization": f"Bearer {self.notion_token}",
|
|
356
|
+
"Content-Type": "application/json",
|
|
357
|
+
"Notion-Version": "2022-06-28",
|
|
358
|
+
}
|
|
359
|
+
response = await client.post(create_upload_url, headers=headers, json={})
|
|
360
|
+
upload_data = response.json()
|
|
361
|
+
upload_url = upload_data["upload_url"]
|
|
362
|
+
|
|
363
|
+
# Step 2: Upload file contents
|
|
364
|
+
with open(file_path, "rb") as f:
|
|
365
|
+
upload_headers = {
|
|
366
|
+
"Authorization": f"Bearer {self.notion_token}",
|
|
367
|
+
"Notion-Version": "2022-06-28",
|
|
368
|
+
}
|
|
369
|
+
files = {'file': (os.path.basename(file_path), f, mimetypes.guess_type(file_path)[0] or 'application/octet-stream')}
|
|
370
|
+
upload_response = await client.post(upload_url, headers=upload_headers, files=files)
|
|
371
|
+
|
|
372
|
+
return upload_response.json()
|
|
373
|
+
|
|
374
|
+
async def attach_file_to_page(self, page_id, file_upload_id):
|
|
375
|
+
"""Attaches an uploaded file to a specific page."""
|
|
376
|
+
attach_url = f"https://api.notion.com/v1/blocks/{page_id}/children"
|
|
377
|
+
headers = {
|
|
378
|
+
"Authorization": f"Bearer {self.notion_token}",
|
|
379
|
+
"Content-Type": "application/json",
|
|
380
|
+
"Notion-Version": "2022-06-28",
|
|
381
|
+
}
|
|
382
|
+
data = {
|
|
383
|
+
"children": [
|
|
384
|
+
{
|
|
385
|
+
"type": "file",
|
|
386
|
+
"file": {
|
|
387
|
+
"type": "file_upload",
|
|
388
|
+
"file_upload": {
|
|
389
|
+
"id": file_upload_id
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
]
|
|
394
|
+
}
|
|
395
|
+
async with httpx.AsyncClient() as client:
|
|
396
|
+
response = await client.patch(attach_url, headers=headers, json=data)
|
|
397
|
+
return response.json()
|
|
398
|
+
|
|
399
|
+
async def embed_image_to_page(self, page_id, file_upload_id):
|
|
400
|
+
"""Embeds an uploaded image to a specific page."""
|
|
401
|
+
attach_url = f"https://api.notion.com/v1/blocks/{page_id}/children"
|
|
402
|
+
headers = {
|
|
403
|
+
"Authorization": f"Bearer {self.notion_token}",
|
|
404
|
+
"Content-Type": "application/json",
|
|
405
|
+
"Notion-Version": "2022-06-28",
|
|
406
|
+
}
|
|
407
|
+
data = {
|
|
408
|
+
"children": [
|
|
409
|
+
{
|
|
410
|
+
"type": "image",
|
|
411
|
+
"image": {
|
|
412
|
+
"type": "file_upload",
|
|
413
|
+
"file_upload": {
|
|
414
|
+
"id": file_upload_id
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
]
|
|
419
|
+
}
|
|
420
|
+
async with httpx.AsyncClient() as client:
|
|
421
|
+
response = await client.patch(attach_url, headers=headers, json=data)
|
|
422
|
+
return response.json()
|
|
423
|
+
|
|
424
|
+
async def attach_file_to_page_property(
|
|
425
|
+
self, page_id, property_name, file_upload_id, file_name
|
|
426
|
+
):
|
|
427
|
+
"""Attaches a file to a Files & Media property on a specific page."""
|
|
428
|
+
update_url = f"https://api.notion.com/v1/pages/{page_id}"
|
|
429
|
+
headers = {
|
|
430
|
+
"Authorization": f"Bearer {self.notion_token}",
|
|
431
|
+
"Content-Type": "application/json",
|
|
432
|
+
"Notion-Version": "2022-06-28",
|
|
433
|
+
}
|
|
434
|
+
data = {
|
|
435
|
+
"properties": {
|
|
436
|
+
property_name: {
|
|
437
|
+
"files": [
|
|
438
|
+
{
|
|
439
|
+
"type": "file_upload",
|
|
440
|
+
"file_upload": {"id": file_upload_id},
|
|
441
|
+
"name": file_name,
|
|
442
|
+
}
|
|
443
|
+
]
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
async with httpx.AsyncClient() as client:
|
|
448
|
+
response = await client.patch(update_url, headers=headers, json=data)
|
|
449
|
+
return response.json()
|
|
450
|
+
|
|
451
|
+
async def one_step_image_embed(self, page_id, file_path):
|
|
452
|
+
"""Uploads an image and embeds it in a Notion page in one step."""
|
|
453
|
+
|
|
454
|
+
# Upload the file
|
|
455
|
+
file_upload = await self.upload_file(file_path)
|
|
456
|
+
file_upload_id = file_upload["id"]
|
|
457
|
+
|
|
458
|
+
# Embed the image in the page
|
|
459
|
+
return await self.embed_image_to_page(page_id, file_upload_id)
|
|
460
|
+
|
|
461
|
+
async def one_step_file_to_page(self, page_id, file_path):
|
|
462
|
+
"""Uploads a file and attaches it to a Notion page in one step."""
|
|
463
|
+
|
|
464
|
+
# Upload the file
|
|
465
|
+
file_upload = await self.upload_file(file_path)
|
|
466
|
+
file_upload_id = file_upload["id"]
|
|
467
|
+
|
|
468
|
+
# Attach the file to the page
|
|
469
|
+
return await self.attach_file_to_page(page_id, file_upload_id)
|
|
470
|
+
|
|
471
|
+
async def one_step_file_to_page_property(self, page_id, property_name, file_path, file_name):
|
|
472
|
+
"""Uploads a file and attaches it to a Notion page property in one step."""
|
|
473
|
+
|
|
474
|
+
# Upload the file
|
|
475
|
+
file_upload = await self.upload_file(file_path)
|
|
476
|
+
file_upload_id = file_upload["id"]
|
|
477
|
+
|
|
478
|
+
# Attach the file to the page property
|
|
479
|
+
return await self.attach_file_to_page_property(page_id, property_name, file_upload_id, file_name)
|
|
File without changes
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
version = 1
|
|
2
|
+
revision = 2
|
|
3
|
+
requires-python = ">=3.12"
|
|
4
|
+
|
|
5
|
+
[[package]]
|
|
6
|
+
name = "anyio"
|
|
7
|
+
version = "4.9.0"
|
|
8
|
+
source = { registry = "https://pypi.org/simple" }
|
|
9
|
+
dependencies = [
|
|
10
|
+
{ name = "idna" },
|
|
11
|
+
{ name = "sniffio" },
|
|
12
|
+
{ name = "typing-extensions", marker = "python_full_version < '3.13'" },
|
|
13
|
+
]
|
|
14
|
+
sdist = { url = "https://files.pythonhosted.org/packages/95/7d/4c1bd541d4dffa1b52bd83fb8527089e097a106fc90b467a7313b105f840/anyio-4.9.0.tar.gz", hash = "sha256:673c0c244e15788651a4ff38710fea9675823028a6f08a5eda409e0c9840a028", size = 190949, upload-time = "2025-03-17T00:02:54.77Z" }
|
|
15
|
+
wheels = [
|
|
16
|
+
{ url = "https://files.pythonhosted.org/packages/a1/ee/48ca1a7c89ffec8b6a0c5d02b89c305671d5ffd8d3c94acf8b8c408575bb/anyio-4.9.0-py3-none-any.whl", hash = "sha256:9f76d541cad6e36af7beb62e978876f3b41e3e04f2c1fbf0884604c0a9c4d93c", size = 100916, upload-time = "2025-03-17T00:02:52.713Z" },
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
[[package]]
|
|
20
|
+
name = "cassidy"
|
|
21
|
+
version = "0.1.4"
|
|
22
|
+
source = { registry = "https://pypi.org/simple" }
|
|
23
|
+
sdist = { url = "https://files.pythonhosted.org/packages/18/d0/4fa91fdcbfdbc05062023be347a6fb08c8e13433d8db7658c1e9b8cb49bb/cassidy-0.1.4.tar.gz", hash = "sha256:d51a0f4210a614f6b092e25fe29c981de0d9b769c42129b43708e8f847e22bee", size = 4325, upload-time = "2021-10-29T15:14:49.963Z" }
|
|
24
|
+
wheels = [
|
|
25
|
+
{ url = "https://files.pythonhosted.org/packages/d0/92/c29e704ce0f9c37ccb20338d1ae00e7b31a064779c3a83a67ddd3375833c/cassidy-0.1.4-py3-none-any.whl", hash = "sha256:9e6fdfff81accd7766f9b3e6665a1c0a914fd7b23c6da16d9face886bc1fb7d8", size = 6219, upload-time = "2021-10-29T15:14:48.684Z" },
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
[[package]]
|
|
29
|
+
name = "certifi"
|
|
30
|
+
version = "2025.7.14"
|
|
31
|
+
source = { registry = "https://pypi.org/simple" }
|
|
32
|
+
sdist = { url = "https://files.pythonhosted.org/packages/b3/76/52c535bcebe74590f296d6c77c86dabf761c41980e1347a2422e4aa2ae41/certifi-2025.7.14.tar.gz", hash = "sha256:8ea99dbdfaaf2ba2f9bac77b9249ef62ec5218e7c2b2e903378ed5fccf765995", size = 163981, upload-time = "2025-07-14T03:29:28.449Z" }
|
|
33
|
+
wheels = [
|
|
34
|
+
{ url = "https://files.pythonhosted.org/packages/4f/52/34c6cf5bb9285074dc3531c437b3919e825d976fde097a7a73f79e726d03/certifi-2025.7.14-py3-none-any.whl", hash = "sha256:6b31f564a415d79ee77df69d757bb49a5bb53bd9f756cbbe24394ffd6fc1f4b2", size = 162722, upload-time = "2025-07-14T03:29:26.863Z" },
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
[[package]]
|
|
38
|
+
name = "enumb"
|
|
39
|
+
version = "0.1.5"
|
|
40
|
+
source = { registry = "https://pypi.org/simple" }
|
|
41
|
+
dependencies = [
|
|
42
|
+
{ name = "cassidy" },
|
|
43
|
+
{ name = "expo" },
|
|
44
|
+
]
|
|
45
|
+
sdist = { url = "https://files.pythonhosted.org/packages/4d/dd/f19ba71555f477165d44fc5e9403b398ca374504ac9db2ed7e2fec8268b4/enumb-0.1.5.tar.gz", hash = "sha256:02a6eda94322ae06a52754e46be6d89310b21e0751a9fc5c9546e977b4fa1884", size = 3165, upload-time = "2021-11-10T20:57:17.057Z" }
|
|
46
|
+
wheels = [
|
|
47
|
+
{ url = "https://files.pythonhosted.org/packages/e5/79/28cbc2ff3ef8ed3c0a3c2ad797de40e227735abc6a1fe57782b7531e8bfb/enumb-0.1.5-py3-none-any.whl", hash = "sha256:1fd798bc347eecb598de9f95bc71cedd96baea3d4ad95601bfc9e18700b1e097", size = 4611, upload-time = "2021-11-10T20:57:15.443Z" },
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
[[package]]
|
|
51
|
+
name = "expo"
|
|
52
|
+
version = "0.1.2"
|
|
53
|
+
source = { registry = "https://pypi.org/simple" }
|
|
54
|
+
sdist = { url = "https://files.pythonhosted.org/packages/3c/fb/6a0b80dc50de4b02406a06e5bab80a881e2275e7f247f133fb2da904ce2b/expo-0.1.2.tar.gz", hash = "sha256:df9042d9d73307bf987e89791b6e36744c5fa99f7464210e956e76d7fe3e84bd", size = 1901, upload-time = "2021-10-29T15:15:23.557Z" }
|
|
55
|
+
wheels = [
|
|
56
|
+
{ url = "https://files.pythonhosted.org/packages/0a/f6/1ce363356dc85bb970c153df35ad2bb49468bc119c4896ca106731373e2e/expo-0.1.2-py3-none-any.whl", hash = "sha256:a36d64c6954de353ee67491351362b04c1b3281acb69afa8534b41279ecd2306", size = 2472, upload-time = "2021-10-29T15:15:22.283Z" },
|
|
57
|
+
]
|
|
58
|
+
|
|
59
|
+
[[package]]
|
|
60
|
+
name = "h11"
|
|
61
|
+
version = "0.16.0"
|
|
62
|
+
source = { registry = "https://pypi.org/simple" }
|
|
63
|
+
sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" }
|
|
64
|
+
wheels = [
|
|
65
|
+
{ url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" },
|
|
66
|
+
]
|
|
67
|
+
|
|
68
|
+
[[package]]
|
|
69
|
+
name = "httpcore"
|
|
70
|
+
version = "1.0.9"
|
|
71
|
+
source = { registry = "https://pypi.org/simple" }
|
|
72
|
+
dependencies = [
|
|
73
|
+
{ name = "certifi" },
|
|
74
|
+
{ name = "h11" },
|
|
75
|
+
]
|
|
76
|
+
sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" }
|
|
77
|
+
wheels = [
|
|
78
|
+
{ url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" },
|
|
79
|
+
]
|
|
80
|
+
|
|
81
|
+
[[package]]
|
|
82
|
+
name = "httpx"
|
|
83
|
+
version = "0.28.1"
|
|
84
|
+
source = { registry = "https://pypi.org/simple" }
|
|
85
|
+
dependencies = [
|
|
86
|
+
{ name = "anyio" },
|
|
87
|
+
{ name = "certifi" },
|
|
88
|
+
{ name = "httpcore" },
|
|
89
|
+
{ name = "idna" },
|
|
90
|
+
]
|
|
91
|
+
sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" }
|
|
92
|
+
wheels = [
|
|
93
|
+
{ url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" },
|
|
94
|
+
]
|
|
95
|
+
|
|
96
|
+
[[package]]
|
|
97
|
+
name = "idna"
|
|
98
|
+
version = "3.10"
|
|
99
|
+
source = { registry = "https://pypi.org/simple" }
|
|
100
|
+
sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload-time = "2024-09-15T18:07:39.745Z" }
|
|
101
|
+
wheels = [
|
|
102
|
+
{ url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" },
|
|
103
|
+
]
|
|
104
|
+
|
|
105
|
+
[[package]]
|
|
106
|
+
name = "mimetype"
|
|
107
|
+
version = "0.1.5"
|
|
108
|
+
source = { registry = "https://pypi.org/simple" }
|
|
109
|
+
dependencies = [
|
|
110
|
+
{ name = "enumb" },
|
|
111
|
+
]
|
|
112
|
+
sdist = { url = "https://files.pythonhosted.org/packages/59/0c/184d0bc85babf00534d5c8adbf008dd5e0f79b7b43f8962e3cca2d90721c/mimetype-0.1.5.tar.gz", hash = "sha256:0ccae479eb36d3ff0553480e9df7738f2789529e5388560ad364ca06eecaa297", size = 28519, upload-time = "2021-10-29T18:33:15.205Z" }
|
|
113
|
+
wheels = [
|
|
114
|
+
{ url = "https://files.pythonhosted.org/packages/a1/c7/96f2728f13e996fb311a8f940ef7693ae5eb131c37f66a4b7992ff8f7340/mimetype-0.1.5-py3-none-any.whl", hash = "sha256:e59720b6249761acef63b0eca246d3ae43a8d3a04f1964136a02d8a8c08d8cbb", size = 29752, upload-time = "2021-10-29T18:33:13.372Z" },
|
|
115
|
+
]
|
|
116
|
+
|
|
117
|
+
[[package]]
|
|
118
|
+
name = "notion-client"
|
|
119
|
+
version = "2.4.0"
|
|
120
|
+
source = { registry = "https://pypi.org/simple" }
|
|
121
|
+
dependencies = [
|
|
122
|
+
{ name = "httpx" },
|
|
123
|
+
]
|
|
124
|
+
sdist = { url = "https://files.pythonhosted.org/packages/6d/49/d6a8ac78256113ff70aa24e2e1c1f5efc86034ad6a2e6415f1d56a3035aa/notion_client-2.4.0.tar.gz", hash = "sha256:e7ff32f733fdbe0f18a37f5d98ff665681e5b3c4dcf2faa6e602bb1b16a3b15d", size = 18655, upload-time = "2025-06-17T10:59:20.868Z" }
|
|
125
|
+
wheels = [
|
|
126
|
+
{ url = "https://files.pythonhosted.org/packages/84/3c/27fa2772e0c6b64e732ba7549559d0eaf90808508a091474568f23d72900/notion_client-2.4.0-py2.py3-none-any.whl", hash = "sha256:89f47c0a5eedc08f1170c04e85f422091ce3e095f20b69a3877152e875f0094f", size = 13835, upload-time = "2025-06-17T10:59:19.993Z" },
|
|
127
|
+
]
|
|
128
|
+
|
|
129
|
+
[[package]]
|
|
130
|
+
name = "notionhelper"
|
|
131
|
+
version = "0.1.0"
|
|
132
|
+
source = { editable = "." }
|
|
133
|
+
dependencies = [
|
|
134
|
+
{ name = "httpx" },
|
|
135
|
+
{ name = "mimetype" },
|
|
136
|
+
{ name = "notion-client" },
|
|
137
|
+
{ name = "pandas" },
|
|
138
|
+
]
|
|
139
|
+
|
|
140
|
+
[package.metadata]
|
|
141
|
+
requires-dist = [
|
|
142
|
+
{ name = "httpx", specifier = ">=0.27.0" },
|
|
143
|
+
{ name = "mimetype", specifier = ">=0.1.5" },
|
|
144
|
+
{ name = "notion-client", specifier = ">=2.4.0" },
|
|
145
|
+
{ name = "pandas", specifier = ">=2.3.1" },
|
|
146
|
+
]
|
|
147
|
+
|
|
148
|
+
[[package]]
|
|
149
|
+
name = "numpy"
|
|
150
|
+
version = "2.3.1"
|
|
151
|
+
source = { registry = "https://pypi.org/simple" }
|
|
152
|
+
sdist = { url = "https://files.pythonhosted.org/packages/2e/19/d7c972dfe90a353dbd3efbbe1d14a5951de80c99c9dc1b93cd998d51dc0f/numpy-2.3.1.tar.gz", hash = "sha256:1ec9ae20a4226da374362cca3c62cd753faf2f951440b0e3b98e93c235441d2b", size = 20390372, upload-time = "2025-06-21T12:28:33.469Z" }
|
|
153
|
+
wheels = [
|
|
154
|
+
{ url = "https://files.pythonhosted.org/packages/c6/56/71ad5022e2f63cfe0ca93559403d0edef14aea70a841d640bd13cdba578e/numpy-2.3.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2959d8f268f3d8ee402b04a9ec4bb7604555aeacf78b360dc4ec27f1d508177d", size = 20896664, upload-time = "2025-06-21T12:15:30.845Z" },
|
|
155
|
+
{ url = "https://files.pythonhosted.org/packages/25/65/2db52ba049813670f7f987cc5db6dac9be7cd95e923cc6832b3d32d87cef/numpy-2.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:762e0c0c6b56bdedfef9a8e1d4538556438288c4276901ea008ae44091954e29", size = 14131078, upload-time = "2025-06-21T12:15:52.23Z" },
|
|
156
|
+
{ url = "https://files.pythonhosted.org/packages/57/dd/28fa3c17b0e751047ac928c1e1b6990238faad76e9b147e585b573d9d1bd/numpy-2.3.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:867ef172a0976aaa1f1d1b63cf2090de8b636a7674607d514505fb7276ab08fc", size = 5112554, upload-time = "2025-06-21T12:16:01.434Z" },
|
|
157
|
+
{ url = "https://files.pythonhosted.org/packages/c9/fc/84ea0cba8e760c4644b708b6819d91784c290288c27aca916115e3311d17/numpy-2.3.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:4e602e1b8682c2b833af89ba641ad4176053aaa50f5cacda1a27004352dde943", size = 6646560, upload-time = "2025-06-21T12:16:11.895Z" },
|
|
158
|
+
{ url = "https://files.pythonhosted.org/packages/61/b2/512b0c2ddec985ad1e496b0bd853eeb572315c0f07cd6997473ced8f15e2/numpy-2.3.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:8e333040d069eba1652fb08962ec5b76af7f2c7bce1df7e1418c8055cf776f25", size = 14260638, upload-time = "2025-06-21T12:16:32.611Z" },
|
|
159
|
+
{ url = "https://files.pythonhosted.org/packages/6e/45/c51cb248e679a6c6ab14b7a8e3ead3f4a3fe7425fc7a6f98b3f147bec532/numpy-2.3.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:e7cbf5a5eafd8d230a3ce356d892512185230e4781a361229bd902ff403bc660", size = 16632729, upload-time = "2025-06-21T12:16:57.439Z" },
|
|
160
|
+
{ url = "https://files.pythonhosted.org/packages/e4/ff/feb4be2e5c09a3da161b412019caf47183099cbea1132fd98061808c2df2/numpy-2.3.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5f1b8f26d1086835f442286c1d9b64bb3974b0b1e41bb105358fd07d20872952", size = 15565330, upload-time = "2025-06-21T12:17:20.638Z" },
|
|
161
|
+
{ url = "https://files.pythonhosted.org/packages/bc/6d/ceafe87587101e9ab0d370e4f6e5f3f3a85b9a697f2318738e5e7e176ce3/numpy-2.3.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ee8340cb48c9b7a5899d1149eece41ca535513a9698098edbade2a8e7a84da77", size = 18361734, upload-time = "2025-06-21T12:17:47.938Z" },
|
|
162
|
+
{ url = "https://files.pythonhosted.org/packages/2b/19/0fb49a3ea088be691f040c9bf1817e4669a339d6e98579f91859b902c636/numpy-2.3.1-cp312-cp312-win32.whl", hash = "sha256:e772dda20a6002ef7061713dc1e2585bc1b534e7909b2030b5a46dae8ff077ab", size = 6320411, upload-time = "2025-06-21T12:17:58.475Z" },
|
|
163
|
+
{ url = "https://files.pythonhosted.org/packages/b1/3e/e28f4c1dd9e042eb57a3eb652f200225e311b608632bc727ae378623d4f8/numpy-2.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:cfecc7822543abdea6de08758091da655ea2210b8ffa1faf116b940693d3df76", size = 12734973, upload-time = "2025-06-21T12:18:17.601Z" },
|
|
164
|
+
{ url = "https://files.pythonhosted.org/packages/04/a8/8a5e9079dc722acf53522b8f8842e79541ea81835e9b5483388701421073/numpy-2.3.1-cp312-cp312-win_arm64.whl", hash = "sha256:7be91b2239af2658653c5bb6f1b8bccafaf08226a258caf78ce44710a0160d30", size = 10191491, upload-time = "2025-06-21T12:18:33.585Z" },
|
|
165
|
+
{ url = "https://files.pythonhosted.org/packages/d4/bd/35ad97006d8abff8631293f8ea6adf07b0108ce6fec68da3c3fcca1197f2/numpy-2.3.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:25a1992b0a3fdcdaec9f552ef10d8103186f5397ab45e2d25f8ac51b1a6b97e8", size = 20889381, upload-time = "2025-06-21T12:19:04.103Z" },
|
|
166
|
+
{ url = "https://files.pythonhosted.org/packages/f1/4f/df5923874d8095b6062495b39729178eef4a922119cee32a12ee1bd4664c/numpy-2.3.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7dea630156d39b02a63c18f508f85010230409db5b2927ba59c8ba4ab3e8272e", size = 14152726, upload-time = "2025-06-21T12:19:25.599Z" },
|
|
167
|
+
{ url = "https://files.pythonhosted.org/packages/8c/0f/a1f269b125806212a876f7efb049b06c6f8772cf0121139f97774cd95626/numpy-2.3.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:bada6058dd886061f10ea15f230ccf7dfff40572e99fef440a4a857c8728c9c0", size = 5105145, upload-time = "2025-06-21T12:19:34.782Z" },
|
|
168
|
+
{ url = "https://files.pythonhosted.org/packages/6d/63/a7f7fd5f375b0361682f6ffbf686787e82b7bbd561268e4f30afad2bb3c0/numpy-2.3.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:a894f3816eb17b29e4783e5873f92faf55b710c2519e5c351767c51f79d8526d", size = 6639409, upload-time = "2025-06-21T12:19:45.228Z" },
|
|
169
|
+
{ url = "https://files.pythonhosted.org/packages/bf/0d/1854a4121af895aab383f4aa233748f1df4671ef331d898e32426756a8a6/numpy-2.3.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:18703df6c4a4fee55fd3d6e5a253d01c5d33a295409b03fda0c86b3ca2ff41a1", size = 14257630, upload-time = "2025-06-21T12:20:06.544Z" },
|
|
170
|
+
{ url = "https://files.pythonhosted.org/packages/50/30/af1b277b443f2fb08acf1c55ce9d68ee540043f158630d62cef012750f9f/numpy-2.3.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:5902660491bd7a48b2ec16c23ccb9124b8abfd9583c5fdfa123fe6b421e03de1", size = 16627546, upload-time = "2025-06-21T12:20:31.002Z" },
|
|
171
|
+
{ url = "https://files.pythonhosted.org/packages/6e/ec/3b68220c277e463095342d254c61be8144c31208db18d3fd8ef02712bcd6/numpy-2.3.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:36890eb9e9d2081137bd78d29050ba63b8dab95dff7912eadf1185e80074b2a0", size = 15562538, upload-time = "2025-06-21T12:20:54.322Z" },
|
|
172
|
+
{ url = "https://files.pythonhosted.org/packages/77/2b/4014f2bcc4404484021c74d4c5ee8eb3de7e3f7ac75f06672f8dcf85140a/numpy-2.3.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a780033466159c2270531e2b8ac063704592a0bc62ec4a1b991c7c40705eb0e8", size = 18360327, upload-time = "2025-06-21T12:21:21.053Z" },
|
|
173
|
+
{ url = "https://files.pythonhosted.org/packages/40/8d/2ddd6c9b30fcf920837b8672f6c65590c7d92e43084c25fc65edc22e93ca/numpy-2.3.1-cp313-cp313-win32.whl", hash = "sha256:39bff12c076812595c3a306f22bfe49919c5513aa1e0e70fac756a0be7c2a2b8", size = 6312330, upload-time = "2025-06-21T12:25:07.447Z" },
|
|
174
|
+
{ url = "https://files.pythonhosted.org/packages/dd/c8/beaba449925988d415efccb45bf977ff8327a02f655090627318f6398c7b/numpy-2.3.1-cp313-cp313-win_amd64.whl", hash = "sha256:8d5ee6eec45f08ce507a6570e06f2f879b374a552087a4179ea7838edbcbfa42", size = 12731565, upload-time = "2025-06-21T12:25:26.444Z" },
|
|
175
|
+
{ url = "https://files.pythonhosted.org/packages/0b/c3/5c0c575d7ec78c1126998071f58facfc124006635da75b090805e642c62e/numpy-2.3.1-cp313-cp313-win_arm64.whl", hash = "sha256:0c4d9e0a8368db90f93bd192bfa771ace63137c3488d198ee21dfb8e7771916e", size = 10190262, upload-time = "2025-06-21T12:25:42.196Z" },
|
|
176
|
+
{ url = "https://files.pythonhosted.org/packages/ea/19/a029cd335cf72f79d2644dcfc22d90f09caa86265cbbde3b5702ccef6890/numpy-2.3.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:b0b5397374f32ec0649dd98c652a1798192042e715df918c20672c62fb52d4b8", size = 20987593, upload-time = "2025-06-21T12:21:51.664Z" },
|
|
177
|
+
{ url = "https://files.pythonhosted.org/packages/25/91/8ea8894406209107d9ce19b66314194675d31761fe2cb3c84fe2eeae2f37/numpy-2.3.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:c5bdf2015ccfcee8253fb8be695516ac4457c743473a43290fd36eba6a1777eb", size = 14300523, upload-time = "2025-06-21T12:22:13.583Z" },
|
|
178
|
+
{ url = "https://files.pythonhosted.org/packages/a6/7f/06187b0066eefc9e7ce77d5f2ddb4e314a55220ad62dd0bfc9f2c44bac14/numpy-2.3.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d70f20df7f08b90a2062c1f07737dd340adccf2068d0f1b9b3d56e2038979fee", size = 5227993, upload-time = "2025-06-21T12:22:22.53Z" },
|
|
179
|
+
{ url = "https://files.pythonhosted.org/packages/e8/ec/a926c293c605fa75e9cfb09f1e4840098ed46d2edaa6e2152ee35dc01ed3/numpy-2.3.1-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:2fb86b7e58f9ac50e1e9dd1290154107e47d1eef23a0ae9145ded06ea606f992", size = 6736652, upload-time = "2025-06-21T12:22:33.629Z" },
|
|
180
|
+
{ url = "https://files.pythonhosted.org/packages/e3/62/d68e52fb6fde5586650d4c0ce0b05ff3a48ad4df4ffd1b8866479d1d671d/numpy-2.3.1-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:23ab05b2d241f76cb883ce8b9a93a680752fbfcbd51c50eff0b88b979e471d8c", size = 14331561, upload-time = "2025-06-21T12:22:55.056Z" },
|
|
181
|
+
{ url = "https://files.pythonhosted.org/packages/fc/ec/b74d3f2430960044bdad6900d9f5edc2dc0fb8bf5a0be0f65287bf2cbe27/numpy-2.3.1-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:ce2ce9e5de4703a673e705183f64fd5da5bf36e7beddcb63a25ee2286e71ca48", size = 16693349, upload-time = "2025-06-21T12:23:20.53Z" },
|
|
182
|
+
{ url = "https://files.pythonhosted.org/packages/0d/15/def96774b9d7eb198ddadfcbd20281b20ebb510580419197e225f5c55c3e/numpy-2.3.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c4913079974eeb5c16ccfd2b1f09354b8fed7e0d6f2cab933104a09a6419b1ee", size = 15642053, upload-time = "2025-06-21T12:23:43.697Z" },
|
|
183
|
+
{ url = "https://files.pythonhosted.org/packages/2b/57/c3203974762a759540c6ae71d0ea2341c1fa41d84e4971a8e76d7141678a/numpy-2.3.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:010ce9b4f00d5c036053ca684c77441f2f2c934fd23bee058b4d6f196efd8280", size = 18434184, upload-time = "2025-06-21T12:24:10.708Z" },
|
|
184
|
+
{ url = "https://files.pythonhosted.org/packages/22/8a/ccdf201457ed8ac6245187850aff4ca56a79edbea4829f4e9f14d46fa9a5/numpy-2.3.1-cp313-cp313t-win32.whl", hash = "sha256:6269b9edfe32912584ec496d91b00b6d34282ca1d07eb10e82dfc780907d6c2e", size = 6440678, upload-time = "2025-06-21T12:24:21.596Z" },
|
|
185
|
+
{ url = "https://files.pythonhosted.org/packages/f1/7e/7f431d8bd8eb7e03d79294aed238b1b0b174b3148570d03a8a8a8f6a0da9/numpy-2.3.1-cp313-cp313t-win_amd64.whl", hash = "sha256:2a809637460e88a113e186e87f228d74ae2852a2e0c44de275263376f17b5bdc", size = 12870697, upload-time = "2025-06-21T12:24:40.644Z" },
|
|
186
|
+
{ url = "https://files.pythonhosted.org/packages/d4/ca/af82bf0fad4c3e573c6930ed743b5308492ff19917c7caaf2f9b6f9e2e98/numpy-2.3.1-cp313-cp313t-win_arm64.whl", hash = "sha256:eccb9a159db9aed60800187bc47a6d3451553f0e1b08b068d8b277ddfbb9b244", size = 10260376, upload-time = "2025-06-21T12:24:56.884Z" },
|
|
187
|
+
]
|
|
188
|
+
|
|
189
|
+
[[package]]
|
|
190
|
+
name = "pandas"
|
|
191
|
+
version = "2.3.1"
|
|
192
|
+
source = { registry = "https://pypi.org/simple" }
|
|
193
|
+
dependencies = [
|
|
194
|
+
{ name = "numpy" },
|
|
195
|
+
{ name = "python-dateutil" },
|
|
196
|
+
{ name = "pytz" },
|
|
197
|
+
{ name = "tzdata" },
|
|
198
|
+
]
|
|
199
|
+
sdist = { url = "https://files.pythonhosted.org/packages/d1/6f/75aa71f8a14267117adeeed5d21b204770189c0a0025acbdc03c337b28fc/pandas-2.3.1.tar.gz", hash = "sha256:0a95b9ac964fe83ce317827f80304d37388ea77616b1425f0ae41c9d2d0d7bb2", size = 4487493, upload-time = "2025-07-07T19:20:04.079Z" }
|
|
200
|
+
wheels = [
|
|
201
|
+
{ url = "https://files.pythonhosted.org/packages/46/de/b8445e0f5d217a99fe0eeb2f4988070908979bec3587c0633e5428ab596c/pandas-2.3.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:689968e841136f9e542020698ee1c4fbe9caa2ed2213ae2388dc7b81721510d3", size = 11588172, upload-time = "2025-07-07T19:18:52.054Z" },
|
|
202
|
+
{ url = "https://files.pythonhosted.org/packages/1e/e0/801cdb3564e65a5ac041ab99ea6f1d802a6c325bb6e58c79c06a3f1cd010/pandas-2.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:025e92411c16cbe5bb2a4abc99732a6b132f439b8aab23a59fa593eb00704232", size = 10717365, upload-time = "2025-07-07T19:18:54.785Z" },
|
|
203
|
+
{ url = "https://files.pythonhosted.org/packages/51/a5/c76a8311833c24ae61a376dbf360eb1b1c9247a5d9c1e8b356563b31b80c/pandas-2.3.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b7ff55f31c4fcb3e316e8f7fa194566b286d6ac430afec0d461163312c5841e", size = 11280411, upload-time = "2025-07-07T19:18:57.045Z" },
|
|
204
|
+
{ url = "https://files.pythonhosted.org/packages/da/01/e383018feba0a1ead6cf5fe8728e5d767fee02f06a3d800e82c489e5daaf/pandas-2.3.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7dcb79bf373a47d2a40cf7232928eb7540155abbc460925c2c96d2d30b006eb4", size = 11988013, upload-time = "2025-07-07T19:18:59.771Z" },
|
|
205
|
+
{ url = "https://files.pythonhosted.org/packages/5b/14/cec7760d7c9507f11c97d64f29022e12a6cc4fc03ac694535e89f88ad2ec/pandas-2.3.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:56a342b231e8862c96bdb6ab97170e203ce511f4d0429589c8ede1ee8ece48b8", size = 12767210, upload-time = "2025-07-07T19:19:02.944Z" },
|
|
206
|
+
{ url = "https://files.pythonhosted.org/packages/50/b9/6e2d2c6728ed29fb3d4d4d302504fb66f1a543e37eb2e43f352a86365cdf/pandas-2.3.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ca7ed14832bce68baef331f4d7f294411bed8efd032f8109d690df45e00c4679", size = 13440571, upload-time = "2025-07-07T19:19:06.82Z" },
|
|
207
|
+
{ url = "https://files.pythonhosted.org/packages/80/a5/3a92893e7399a691bad7664d977cb5e7c81cf666c81f89ea76ba2bff483d/pandas-2.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:ac942bfd0aca577bef61f2bc8da8147c4ef6879965ef883d8e8d5d2dc3e744b8", size = 10987601, upload-time = "2025-07-07T19:19:09.589Z" },
|
|
208
|
+
{ url = "https://files.pythonhosted.org/packages/32/ed/ff0a67a2c5505e1854e6715586ac6693dd860fbf52ef9f81edee200266e7/pandas-2.3.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9026bd4a80108fac2239294a15ef9003c4ee191a0f64b90f170b40cfb7cf2d22", size = 11531393, upload-time = "2025-07-07T19:19:12.245Z" },
|
|
209
|
+
{ url = "https://files.pythonhosted.org/packages/c7/db/d8f24a7cc9fb0972adab0cc80b6817e8bef888cfd0024eeb5a21c0bb5c4a/pandas-2.3.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6de8547d4fdb12421e2d047a2c446c623ff4c11f47fddb6b9169eb98ffba485a", size = 10668750, upload-time = "2025-07-07T19:19:14.612Z" },
|
|
210
|
+
{ url = "https://files.pythonhosted.org/packages/0f/b0/80f6ec783313f1e2356b28b4fd8d2148c378370045da918c73145e6aab50/pandas-2.3.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:782647ddc63c83133b2506912cc6b108140a38a37292102aaa19c81c83db2928", size = 11342004, upload-time = "2025-07-07T19:19:16.857Z" },
|
|
211
|
+
{ url = "https://files.pythonhosted.org/packages/e9/e2/20a317688435470872885e7fc8f95109ae9683dec7c50be29b56911515a5/pandas-2.3.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ba6aff74075311fc88504b1db890187a3cd0f887a5b10f5525f8e2ef55bfdb9", size = 12050869, upload-time = "2025-07-07T19:19:19.265Z" },
|
|
212
|
+
{ url = "https://files.pythonhosted.org/packages/55/79/20d746b0a96c67203a5bee5fb4e00ac49c3e8009a39e1f78de264ecc5729/pandas-2.3.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e5635178b387bd2ba4ac040f82bc2ef6e6b500483975c4ebacd34bec945fda12", size = 12750218, upload-time = "2025-07-07T19:19:21.547Z" },
|
|
213
|
+
{ url = "https://files.pythonhosted.org/packages/7c/0f/145c8b41e48dbf03dd18fdd7f24f8ba95b8254a97a3379048378f33e7838/pandas-2.3.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6f3bf5ec947526106399a9e1d26d40ee2b259c66422efdf4de63c848492d91bb", size = 13416763, upload-time = "2025-07-07T19:19:23.939Z" },
|
|
214
|
+
{ url = "https://files.pythonhosted.org/packages/b2/c0/54415af59db5cdd86a3d3bf79863e8cc3fa9ed265f0745254061ac09d5f2/pandas-2.3.1-cp313-cp313-win_amd64.whl", hash = "sha256:1c78cf43c8fde236342a1cb2c34bcff89564a7bfed7e474ed2fffa6aed03a956", size = 10987482, upload-time = "2025-07-07T19:19:42.699Z" },
|
|
215
|
+
{ url = "https://files.pythonhosted.org/packages/48/64/2fd2e400073a1230e13b8cd604c9bc95d9e3b962e5d44088ead2e8f0cfec/pandas-2.3.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8dfc17328e8da77be3cf9f47509e5637ba8f137148ed0e9b5241e1baf526e20a", size = 12029159, upload-time = "2025-07-07T19:19:26.362Z" },
|
|
216
|
+
{ url = "https://files.pythonhosted.org/packages/d8/0a/d84fd79b0293b7ef88c760d7dca69828d867c89b6d9bc52d6a27e4d87316/pandas-2.3.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:ec6c851509364c59a5344458ab935e6451b31b818be467eb24b0fe89bd05b6b9", size = 11393287, upload-time = "2025-07-07T19:19:29.157Z" },
|
|
217
|
+
{ url = "https://files.pythonhosted.org/packages/50/ae/ff885d2b6e88f3c7520bb74ba319268b42f05d7e583b5dded9837da2723f/pandas-2.3.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:911580460fc4884d9b05254b38a6bfadddfcc6aaef856fb5859e7ca202e45275", size = 11309381, upload-time = "2025-07-07T19:19:31.436Z" },
|
|
218
|
+
{ url = "https://files.pythonhosted.org/packages/85/86/1fa345fc17caf5d7780d2699985c03dbe186c68fee00b526813939062bb0/pandas-2.3.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f4d6feeba91744872a600e6edbbd5b033005b431d5ae8379abee5bcfa479fab", size = 11883998, upload-time = "2025-07-07T19:19:34.267Z" },
|
|
219
|
+
{ url = "https://files.pythonhosted.org/packages/81/aa/e58541a49b5e6310d89474333e994ee57fea97c8aaa8fc7f00b873059bbf/pandas-2.3.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:fe37e757f462d31a9cd7580236a82f353f5713a80e059a29753cf938c6775d96", size = 12704705, upload-time = "2025-07-07T19:19:36.856Z" },
|
|
220
|
+
{ url = "https://files.pythonhosted.org/packages/d5/f9/07086f5b0f2a19872554abeea7658200824f5835c58a106fa8f2ae96a46c/pandas-2.3.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:5db9637dbc24b631ff3707269ae4559bce4b7fd75c1c4d7e13f40edc42df4444", size = 13189044, upload-time = "2025-07-07T19:19:39.999Z" },
|
|
221
|
+
]
|
|
222
|
+
|
|
223
|
+
[[package]]
|
|
224
|
+
name = "python-dateutil"
|
|
225
|
+
version = "2.9.0.post0"
|
|
226
|
+
source = { registry = "https://pypi.org/simple" }
|
|
227
|
+
dependencies = [
|
|
228
|
+
{ name = "six" },
|
|
229
|
+
]
|
|
230
|
+
sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" }
|
|
231
|
+
wheels = [
|
|
232
|
+
{ url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" },
|
|
233
|
+
]
|
|
234
|
+
|
|
235
|
+
[[package]]
|
|
236
|
+
name = "pytz"
|
|
237
|
+
version = "2025.2"
|
|
238
|
+
source = { registry = "https://pypi.org/simple" }
|
|
239
|
+
sdist = { url = "https://files.pythonhosted.org/packages/f8/bf/abbd3cdfb8fbc7fb3d4d38d320f2441b1e7cbe29be4f23797b4a2b5d8aac/pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3", size = 320884, upload-time = "2025-03-25T02:25:00.538Z" }
|
|
240
|
+
wheels = [
|
|
241
|
+
{ url = "https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00", size = 509225, upload-time = "2025-03-25T02:24:58.468Z" },
|
|
242
|
+
]
|
|
243
|
+
|
|
244
|
+
[[package]]
|
|
245
|
+
name = "six"
|
|
246
|
+
version = "1.17.0"
|
|
247
|
+
source = { registry = "https://pypi.org/simple" }
|
|
248
|
+
sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" }
|
|
249
|
+
wheels = [
|
|
250
|
+
{ url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" },
|
|
251
|
+
]
|
|
252
|
+
|
|
253
|
+
[[package]]
|
|
254
|
+
name = "sniffio"
|
|
255
|
+
version = "1.3.1"
|
|
256
|
+
source = { registry = "https://pypi.org/simple" }
|
|
257
|
+
sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload-time = "2024-02-25T23:20:04.057Z" }
|
|
258
|
+
wheels = [
|
|
259
|
+
{ url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" },
|
|
260
|
+
]
|
|
261
|
+
|
|
262
|
+
[[package]]
|
|
263
|
+
name = "typing-extensions"
|
|
264
|
+
version = "4.14.1"
|
|
265
|
+
source = { registry = "https://pypi.org/simple" }
|
|
266
|
+
sdist = { url = "https://files.pythonhosted.org/packages/98/5a/da40306b885cc8c09109dc2e1abd358d5684b1425678151cdaed4731c822/typing_extensions-4.14.1.tar.gz", hash = "sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36", size = 107673, upload-time = "2025-07-04T13:28:34.16Z" }
|
|
267
|
+
wheels = [
|
|
268
|
+
{ url = "https://files.pythonhosted.org/packages/b5/00/d631e67a838026495268c2f6884f3711a15a9a2a96cd244fdaea53b823fb/typing_extensions-4.14.1-py3-none-any.whl", hash = "sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76", size = 43906, upload-time = "2025-07-04T13:28:32.743Z" },
|
|
269
|
+
]
|
|
270
|
+
|
|
271
|
+
[[package]]
|
|
272
|
+
name = "tzdata"
|
|
273
|
+
version = "2025.2"
|
|
274
|
+
source = { registry = "https://pypi.org/simple" }
|
|
275
|
+
sdist = { url = "https://files.pythonhosted.org/packages/95/32/1a225d6164441be760d75c2c42e2780dc0873fe382da3e98a2e1e48361e5/tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9", size = 196380, upload-time = "2025-03-23T13:54:43.652Z" }
|
|
276
|
+
wheels = [
|
|
277
|
+
{ url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839, upload-time = "2025-03-23T13:54:41.845Z" },
|
|
278
|
+
]
|