async-mega-py 2.4.1__tar.gz → 2.5.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.
- {async_mega_py-2.4.1 → async_mega_py-2.5.0}/PKG-INFO +26 -28
- {async_mega_py-2.4.1 → async_mega_py-2.5.0}/README.md +19 -21
- async_mega_py-2.5.0/pyproject.toml +136 -0
- async_mega_py-2.4.1/pyproject.toml → async_mega_py-2.5.0/pyproject.toml.orig +18 -14
- {async_mega_py-2.4.1 → async_mega_py-2.5.0}/src/mega/__init__.py +2 -0
- {async_mega_py-2.4.1 → async_mega_py-2.5.0}/src/mega/api.py +5 -3
- {async_mega_py-2.4.1 → async_mega_py-2.5.0}/LICENSE +0 -0
- {async_mega_py-2.4.1 → async_mega_py-2.5.0}/src/mega/__main__.py +0 -0
- {async_mega_py-2.4.1 → async_mega_py-2.5.0}/src/mega/auth.py +0 -0
- {async_mega_py-2.4.1 → async_mega_py-2.5.0}/src/mega/chunker.py +0 -0
- {async_mega_py-2.4.1 → async_mega_py-2.5.0}/src/mega/client.py +0 -0
- {async_mega_py-2.4.1 → async_mega_py-2.5.0}/src/mega/core.py +0 -0
- {async_mega_py-2.4.1 → async_mega_py-2.5.0}/src/mega/crypto.py +0 -0
- {async_mega_py-2.4.1 → async_mega_py-2.5.0}/src/mega/data_structures.py +0 -0
- {async_mega_py-2.4.1 → async_mega_py-2.5.0}/src/mega/download.py +0 -0
- {async_mega_py-2.4.1 → async_mega_py-2.5.0}/src/mega/env.py +0 -0
- {async_mega_py-2.4.1 → async_mega_py-2.5.0}/src/mega/errors.py +0 -0
- {async_mega_py-2.4.1 → async_mega_py-2.5.0}/src/mega/filesystem.py +0 -0
- {async_mega_py-2.4.1 → async_mega_py-2.5.0}/src/mega/progress/__init__.py +0 -0
- {async_mega_py-2.4.1 → async_mega_py-2.5.0}/src/mega/progress/rich_progress.py +0 -0
- {async_mega_py-2.4.1 → async_mega_py-2.5.0}/src/mega/py.typed +0 -0
- {async_mega_py-2.4.1 → async_mega_py-2.5.0}/src/mega/transfer_it.py +0 -0
- {async_mega_py-2.4.1 → async_mega_py-2.5.0}/src/mega/upload.py +0 -0
- {async_mega_py-2.4.1 → async_mega_py-2.5.0}/src/mega/utils.py +0 -0
- {async_mega_py-2.4.1 → async_mega_py-2.5.0}/src/mega/vault.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: async-mega.py
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.5.0
|
|
4
4
|
Summary: Python library for the Mega.nz and Transfer.it API
|
|
5
5
|
Keywords: api,downloader,mega,mega.nz,transfer.it
|
|
6
6
|
Author: NTFSvolume
|
|
@@ -14,18 +14,18 @@ Classifier: Intended Audience :: Developers
|
|
|
14
14
|
Classifier: Intended Audience :: End Users/Desktop
|
|
15
15
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
16
16
|
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python
|
|
17
18
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
18
19
|
Classifier: Programming Language :: Python :: 3.11
|
|
19
20
|
Classifier: Programming Language :: Python :: 3.12
|
|
20
21
|
Classifier: Programming Language :: Python :: 3.13
|
|
21
22
|
Classifier: Programming Language :: Python :: 3.14
|
|
22
23
|
Classifier: Programming Language :: Python :: 3.15
|
|
23
|
-
|
|
24
|
-
Requires-Dist:
|
|
25
|
-
Requires-Dist:
|
|
26
|
-
Requires-Dist:
|
|
27
|
-
Requires-Dist:
|
|
28
|
-
Requires-Dist: python-dotenv>=1.2.1 ; extra == 'cli'
|
|
24
|
+
Requires-Dist: aiohttp>=3.14.0
|
|
25
|
+
Requires-Dist: aiolimiter>=1.3.0
|
|
26
|
+
Requires-Dist: pycryptodome>=3.24.0
|
|
27
|
+
Requires-Dist: cyclopts>=5.2.0 ; extra == 'cli'
|
|
28
|
+
Requires-Dist: python-dotenv>=1.2.4 ; extra == 'cli'
|
|
29
29
|
Requires-Python: >=3.11
|
|
30
30
|
Project-URL: Homepage, https://github.com/NTFSvolume/mega.py
|
|
31
31
|
Provides-Extra: cli
|
|
@@ -88,7 +88,6 @@ email = "my_email@email.com"
|
|
|
88
88
|
password = "12345"
|
|
89
89
|
async with MegaNzClient() as mega:
|
|
90
90
|
await mega.login(email, password)
|
|
91
|
-
|
|
92
91
|
```
|
|
93
92
|
|
|
94
93
|
Login should always be the first thing you do. Almost all operations require a valid account. You can call `login` without params to create a temporary account:
|
|
@@ -98,9 +97,8 @@ from mega.client import MegaNzClient
|
|
|
98
97
|
|
|
99
98
|
# Also works without using it as a context manager, but you have the responsability to close the session at the end
|
|
100
99
|
mega = MegaNzClient()
|
|
101
|
-
await mega.login()
|
|
100
|
+
await mega.login() # login using a temporary anonymous account
|
|
102
101
|
# await mega.close()
|
|
103
|
-
|
|
104
102
|
```
|
|
105
103
|
|
|
106
104
|
## Methods
|
|
@@ -126,18 +124,20 @@ contact = "test@mega.nz"
|
|
|
126
124
|
await mega.add_contact(contact)
|
|
127
125
|
await mega.remove_contact(contact)
|
|
128
126
|
|
|
127
|
+
|
|
129
128
|
async def view_paths():
|
|
130
129
|
fs = await mega.get_filesystem()
|
|
131
|
-
print
|
|
130
|
+
print(fs.paths.values())
|
|
131
|
+
|
|
132
132
|
|
|
133
133
|
# Create a folder
|
|
134
|
-
await mega.create_folder(
|
|
135
|
-
await mega.create_folder(
|
|
134
|
+
await mega.create_folder("new_folder")
|
|
135
|
+
await mega.create_folder("new_folder/sub_folder/subsub_folder")
|
|
136
136
|
await view_paths()
|
|
137
137
|
|
|
138
138
|
# Rename a file or a folder
|
|
139
|
-
folder = await mega.find(
|
|
140
|
-
await mega.rename(folder, new_name=
|
|
139
|
+
folder = await mega.find("new_folder/sub_folder/subsub_folder")
|
|
140
|
+
await mega.rename(folder, new_name="my_new_name")
|
|
141
141
|
await view_paths()
|
|
142
142
|
|
|
143
143
|
# Send this node to the trash bin (still counts towards your quota)
|
|
@@ -153,9 +153,9 @@ await view_paths()
|
|
|
153
153
|
|
|
154
154
|
```python
|
|
155
155
|
# Upload a file, and get its public link
|
|
156
|
-
my_real_file =
|
|
157
|
-
uploaded_file = await mega.upload(my_real_file)
|
|
158
|
-
await mega.export(uploaded_file)
|
|
156
|
+
my_real_file = "/home/user/myfile.doc" # Change this to a real file path!
|
|
157
|
+
uploaded_file = await mega.upload(my_real_file) # Upload returns the Node that represents the file you just uploaded
|
|
158
|
+
await mega.export(uploaded_file) # This only works with real accounts. Temp accounts can't create public links
|
|
159
159
|
|
|
160
160
|
# Download a file from your account
|
|
161
161
|
output_dir = "my downloads"
|
|
@@ -171,7 +171,7 @@ folder_url = "https://mega.nz/folder/CJ8y1SDJ#KX8YfTd526P4o_hDH02jLQ"
|
|
|
171
171
|
public_handle, public_key, selected_node = mega.parse_folder_url(folder_url)
|
|
172
172
|
results = await mega.download_public_folder(public_handle, public_key, output_dir, selected_node)
|
|
173
173
|
for node_id, result in results.items():
|
|
174
|
-
print
|
|
174
|
+
print((node_id, result))
|
|
175
175
|
|
|
176
176
|
# Import a file from URL
|
|
177
177
|
public_handle, public_key = mega.parse_file_url(file_url)
|
|
@@ -179,7 +179,7 @@ await mega.import_public_file(public_handle, public_key, dest_node_id=folder.id)
|
|
|
179
179
|
|
|
180
180
|
# How do you know if an URL is a file or folder?
|
|
181
181
|
result = mega.parse_url(url)
|
|
182
|
-
print
|
|
182
|
+
print(result.is_folder)
|
|
183
183
|
```
|
|
184
184
|
|
|
185
185
|
> [!TIP]
|
|
@@ -253,8 +253,8 @@ fs = UserFileSystem.from_dump(json.loads(dump))
|
|
|
253
253
|
# Search for nodes
|
|
254
254
|
query = "tests/script"
|
|
255
255
|
for node_id, path in fs.search(query):
|
|
256
|
-
print
|
|
257
|
-
print
|
|
256
|
+
print(node_id)
|
|
257
|
+
print(path)
|
|
258
258
|
|
|
259
259
|
# or
|
|
260
260
|
dict(fs.search(query))
|
|
@@ -274,12 +274,11 @@ The output will be:
|
|
|
274
274
|
|
|
275
275
|
```python
|
|
276
276
|
# Get the path to a node
|
|
277
|
-
fs.absolute_path("0fPFklV3")
|
|
277
|
+
fs.absolute_path("0fPFklV3") # /tests/scripts/notes.txt
|
|
278
278
|
|
|
279
279
|
# Find a node by its *exact* path
|
|
280
280
|
result = fs.find("/tests/scripts/notes.txt")
|
|
281
|
-
print
|
|
282
|
-
|
|
281
|
+
print(result.id) # "0fPFklV3"
|
|
283
282
|
```
|
|
284
283
|
|
|
285
284
|
```python
|
|
@@ -290,7 +289,6 @@ list(fs.deleted)
|
|
|
290
289
|
folder = fs.find("/tests")
|
|
291
290
|
for node in fs.iterdir(folder.id, recursive=True):
|
|
292
291
|
print(fs.absolute_path(node.id))
|
|
293
|
-
|
|
294
292
|
```
|
|
295
293
|
|
|
296
294
|
Output will be:
|
|
@@ -315,7 +313,7 @@ Output will be:
|
|
|
315
313
|
> If 2 nodes have the same path, `find` will throw an error.
|
|
316
314
|
|
|
317
315
|
```python
|
|
318
|
-
fs.find("/tests/logo.png")
|
|
316
|
+
fs.find("/tests/logo.png") # This will fail
|
|
319
317
|
# You will have to call search and choose which one you actually want
|
|
320
318
|
dict(fs.search("/tests/logo.png"))
|
|
321
319
|
```
|
|
@@ -335,7 +333,7 @@ async with TransferItClient() as client:
|
|
|
335
333
|
fs = await client.get_filesystem(transfer_id)
|
|
336
334
|
output_dir = "My downloads"
|
|
337
335
|
results = await client.download_transfer(transfer_id, output_dir)
|
|
338
|
-
print
|
|
336
|
+
print(results)
|
|
339
337
|
```
|
|
340
338
|
|
|
341
339
|
## CLI
|
|
@@ -55,7 +55,6 @@ email = "my_email@email.com"
|
|
|
55
55
|
password = "12345"
|
|
56
56
|
async with MegaNzClient() as mega:
|
|
57
57
|
await mega.login(email, password)
|
|
58
|
-
|
|
59
58
|
```
|
|
60
59
|
|
|
61
60
|
Login should always be the first thing you do. Almost all operations require a valid account. You can call `login` without params to create a temporary account:
|
|
@@ -65,9 +64,8 @@ from mega.client import MegaNzClient
|
|
|
65
64
|
|
|
66
65
|
# Also works without using it as a context manager, but you have the responsability to close the session at the end
|
|
67
66
|
mega = MegaNzClient()
|
|
68
|
-
await mega.login()
|
|
67
|
+
await mega.login() # login using a temporary anonymous account
|
|
69
68
|
# await mega.close()
|
|
70
|
-
|
|
71
69
|
```
|
|
72
70
|
|
|
73
71
|
## Methods
|
|
@@ -93,18 +91,20 @@ contact = "test@mega.nz"
|
|
|
93
91
|
await mega.add_contact(contact)
|
|
94
92
|
await mega.remove_contact(contact)
|
|
95
93
|
|
|
94
|
+
|
|
96
95
|
async def view_paths():
|
|
97
96
|
fs = await mega.get_filesystem()
|
|
98
|
-
print
|
|
97
|
+
print(fs.paths.values())
|
|
98
|
+
|
|
99
99
|
|
|
100
100
|
# Create a folder
|
|
101
|
-
await mega.create_folder(
|
|
102
|
-
await mega.create_folder(
|
|
101
|
+
await mega.create_folder("new_folder")
|
|
102
|
+
await mega.create_folder("new_folder/sub_folder/subsub_folder")
|
|
103
103
|
await view_paths()
|
|
104
104
|
|
|
105
105
|
# Rename a file or a folder
|
|
106
|
-
folder = await mega.find(
|
|
107
|
-
await mega.rename(folder, new_name=
|
|
106
|
+
folder = await mega.find("new_folder/sub_folder/subsub_folder")
|
|
107
|
+
await mega.rename(folder, new_name="my_new_name")
|
|
108
108
|
await view_paths()
|
|
109
109
|
|
|
110
110
|
# Send this node to the trash bin (still counts towards your quota)
|
|
@@ -120,9 +120,9 @@ await view_paths()
|
|
|
120
120
|
|
|
121
121
|
```python
|
|
122
122
|
# Upload a file, and get its public link
|
|
123
|
-
my_real_file =
|
|
124
|
-
uploaded_file = await mega.upload(my_real_file)
|
|
125
|
-
await mega.export(uploaded_file)
|
|
123
|
+
my_real_file = "/home/user/myfile.doc" # Change this to a real file path!
|
|
124
|
+
uploaded_file = await mega.upload(my_real_file) # Upload returns the Node that represents the file you just uploaded
|
|
125
|
+
await mega.export(uploaded_file) # This only works with real accounts. Temp accounts can't create public links
|
|
126
126
|
|
|
127
127
|
# Download a file from your account
|
|
128
128
|
output_dir = "my downloads"
|
|
@@ -138,7 +138,7 @@ folder_url = "https://mega.nz/folder/CJ8y1SDJ#KX8YfTd526P4o_hDH02jLQ"
|
|
|
138
138
|
public_handle, public_key, selected_node = mega.parse_folder_url(folder_url)
|
|
139
139
|
results = await mega.download_public_folder(public_handle, public_key, output_dir, selected_node)
|
|
140
140
|
for node_id, result in results.items():
|
|
141
|
-
print
|
|
141
|
+
print((node_id, result))
|
|
142
142
|
|
|
143
143
|
# Import a file from URL
|
|
144
144
|
public_handle, public_key = mega.parse_file_url(file_url)
|
|
@@ -146,7 +146,7 @@ await mega.import_public_file(public_handle, public_key, dest_node_id=folder.id)
|
|
|
146
146
|
|
|
147
147
|
# How do you know if an URL is a file or folder?
|
|
148
148
|
result = mega.parse_url(url)
|
|
149
|
-
print
|
|
149
|
+
print(result.is_folder)
|
|
150
150
|
```
|
|
151
151
|
|
|
152
152
|
> [!TIP]
|
|
@@ -220,8 +220,8 @@ fs = UserFileSystem.from_dump(json.loads(dump))
|
|
|
220
220
|
# Search for nodes
|
|
221
221
|
query = "tests/script"
|
|
222
222
|
for node_id, path in fs.search(query):
|
|
223
|
-
print
|
|
224
|
-
print
|
|
223
|
+
print(node_id)
|
|
224
|
+
print(path)
|
|
225
225
|
|
|
226
226
|
# or
|
|
227
227
|
dict(fs.search(query))
|
|
@@ -241,12 +241,11 @@ The output will be:
|
|
|
241
241
|
|
|
242
242
|
```python
|
|
243
243
|
# Get the path to a node
|
|
244
|
-
fs.absolute_path("0fPFklV3")
|
|
244
|
+
fs.absolute_path("0fPFklV3") # /tests/scripts/notes.txt
|
|
245
245
|
|
|
246
246
|
# Find a node by its *exact* path
|
|
247
247
|
result = fs.find("/tests/scripts/notes.txt")
|
|
248
|
-
print
|
|
249
|
-
|
|
248
|
+
print(result.id) # "0fPFklV3"
|
|
250
249
|
```
|
|
251
250
|
|
|
252
251
|
```python
|
|
@@ -257,7 +256,6 @@ list(fs.deleted)
|
|
|
257
256
|
folder = fs.find("/tests")
|
|
258
257
|
for node in fs.iterdir(folder.id, recursive=True):
|
|
259
258
|
print(fs.absolute_path(node.id))
|
|
260
|
-
|
|
261
259
|
```
|
|
262
260
|
|
|
263
261
|
Output will be:
|
|
@@ -282,7 +280,7 @@ Output will be:
|
|
|
282
280
|
> If 2 nodes have the same path, `find` will throw an error.
|
|
283
281
|
|
|
284
282
|
```python
|
|
285
|
-
fs.find("/tests/logo.png")
|
|
283
|
+
fs.find("/tests/logo.png") # This will fail
|
|
286
284
|
# You will have to call search and choose which one you actually want
|
|
287
285
|
dict(fs.search("/tests/logo.png"))
|
|
288
286
|
```
|
|
@@ -302,7 +300,7 @@ async with TransferItClient() as client:
|
|
|
302
300
|
fs = await client.get_filesystem(transfer_id)
|
|
303
301
|
output_dir = "My downloads"
|
|
304
302
|
results = await client.download_transfer(transfer_id, output_dir)
|
|
305
|
-
print
|
|
303
|
+
print(results)
|
|
306
304
|
```
|
|
307
305
|
|
|
308
306
|
## CLI
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "async-mega.py"
|
|
3
|
+
classifiers = [
|
|
4
|
+
"Development Status :: 5 - Production/Stable",
|
|
5
|
+
"Environment :: Console",
|
|
6
|
+
"Framework :: AsyncIO",
|
|
7
|
+
"Intended Audience :: Developers",
|
|
8
|
+
"Intended Audience :: End Users/Desktop",
|
|
9
|
+
"License :: OSI Approved :: Apache Software License",
|
|
10
|
+
"Operating System :: OS Independent",
|
|
11
|
+
"Programming Language :: Python",
|
|
12
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
13
|
+
"Programming Language :: Python :: 3.11",
|
|
14
|
+
"Programming Language :: Python :: 3.12",
|
|
15
|
+
"Programming Language :: Python :: 3.13",
|
|
16
|
+
"Programming Language :: Python :: 3.14",
|
|
17
|
+
"Programming Language :: Python :: 3.15",
|
|
18
|
+
]
|
|
19
|
+
dependencies = [
|
|
20
|
+
"aiohttp>=3.14.0",
|
|
21
|
+
"aiolimiter>=1.3.0",
|
|
22
|
+
"pycryptodome>=3.24.0",
|
|
23
|
+
]
|
|
24
|
+
description = "Python library for the Mega.nz and Transfer.it API"
|
|
25
|
+
keywords = [
|
|
26
|
+
"api",
|
|
27
|
+
"downloader",
|
|
28
|
+
"mega",
|
|
29
|
+
"mega.nz",
|
|
30
|
+
"transfer.it",
|
|
31
|
+
]
|
|
32
|
+
license = "Apache-2.0"
|
|
33
|
+
license-files = ["LICENSE"]
|
|
34
|
+
readme = "README.md"
|
|
35
|
+
requires-python = ">=3.11"
|
|
36
|
+
version = "2.5.0"
|
|
37
|
+
|
|
38
|
+
[[project.authors]]
|
|
39
|
+
name = "NTFSvolume"
|
|
40
|
+
email = "NTFSvolume@proton.me"
|
|
41
|
+
|
|
42
|
+
[project.optional-dependencies]
|
|
43
|
+
cli = [
|
|
44
|
+
"cyclopts>=5.2.0",
|
|
45
|
+
"python-dotenv>=1.2.4",
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
[project.scripts]
|
|
49
|
+
async-mega-py = "mega.__main__:app.meta"
|
|
50
|
+
mega-py = "mega.__main__:app.meta"
|
|
51
|
+
|
|
52
|
+
[project.urls]
|
|
53
|
+
Homepage = "https://github.com/NTFSvolume/mega.py"
|
|
54
|
+
|
|
55
|
+
[tool.coverage.run]
|
|
56
|
+
omit = ["tests/*"]
|
|
57
|
+
|
|
58
|
+
[tool.pytest.ini_options]
|
|
59
|
+
addopts = "-s -v"
|
|
60
|
+
asyncio_default_fixture_loop_scope = "function"
|
|
61
|
+
asyncio_mode = "auto"
|
|
62
|
+
minversion = "8.3"
|
|
63
|
+
norecursedirs = [".git"]
|
|
64
|
+
|
|
65
|
+
[tool.ruff]
|
|
66
|
+
line-length = 120
|
|
67
|
+
|
|
68
|
+
[tool.ruff.lint]
|
|
69
|
+
select = [
|
|
70
|
+
"B",
|
|
71
|
+
"C4",
|
|
72
|
+
"COM8",
|
|
73
|
+
"E",
|
|
74
|
+
"F",
|
|
75
|
+
"FA102",
|
|
76
|
+
"FURB188",
|
|
77
|
+
"I",
|
|
78
|
+
"N",
|
|
79
|
+
"PLR1716",
|
|
80
|
+
"Q",
|
|
81
|
+
"RUF",
|
|
82
|
+
"T20",
|
|
83
|
+
"TC",
|
|
84
|
+
"TID",
|
|
85
|
+
"UP",
|
|
86
|
+
"W",
|
|
87
|
+
]
|
|
88
|
+
extend-safe-fixes = ["TC"]
|
|
89
|
+
ignore = [
|
|
90
|
+
"COM812",
|
|
91
|
+
"E501",
|
|
92
|
+
"N806",
|
|
93
|
+
]
|
|
94
|
+
unfixable = ["ERA"]
|
|
95
|
+
|
|
96
|
+
[tool.ruff.lint.per-file-ignores]
|
|
97
|
+
"**/{tests,docs}/*" = [
|
|
98
|
+
"E402",
|
|
99
|
+
"T20",
|
|
100
|
+
]
|
|
101
|
+
"__init__.py" = ["E402"]
|
|
102
|
+
|
|
103
|
+
[tool.ruff.lint.pydocstyle]
|
|
104
|
+
convention = "google"
|
|
105
|
+
|
|
106
|
+
[tool.tomlsort]
|
|
107
|
+
all = true
|
|
108
|
+
ignore_case = true
|
|
109
|
+
in_place = true
|
|
110
|
+
sort_first = [
|
|
111
|
+
"name",
|
|
112
|
+
"project",
|
|
113
|
+
"select",
|
|
114
|
+
"tool",
|
|
115
|
+
]
|
|
116
|
+
spaces_before_inline_comment = 2
|
|
117
|
+
spaces_indent_inline_array = 4
|
|
118
|
+
|
|
119
|
+
[tool.uv]
|
|
120
|
+
default-groups = "all"
|
|
121
|
+
required-version = ">=0.12.24"
|
|
122
|
+
|
|
123
|
+
[tool.uv.build-backend]
|
|
124
|
+
module-name = "mega"
|
|
125
|
+
|
|
126
|
+
[build-system]
|
|
127
|
+
build-backend = "uv_build"
|
|
128
|
+
requires = ["uv_build>=0.12.24,<0.13.0"]
|
|
129
|
+
|
|
130
|
+
[dependency-groups]
|
|
131
|
+
dev = [
|
|
132
|
+
"prek>=0.5.5",
|
|
133
|
+
"pytest-asyncio>=1.4.0",
|
|
134
|
+
"pytest>=9.1.1",
|
|
135
|
+
"ruff>=0.16.10,<0.17.0",
|
|
136
|
+
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "async-mega.py"
|
|
3
|
-
authors = [{name = "NTFSvolume", email = "NTFSvolume@proton.me"}]
|
|
3
|
+
authors = [{ name = "NTFSvolume", email = "NTFSvolume@proton.me" }]
|
|
4
4
|
classifiers = [
|
|
5
5
|
"Development Status :: 5 - Production/Stable",
|
|
6
6
|
"Environment :: Console",
|
|
@@ -9,18 +9,18 @@ classifiers = [
|
|
|
9
9
|
"Intended Audience :: End Users/Desktop",
|
|
10
10
|
"License :: OSI Approved :: Apache Software License",
|
|
11
11
|
"Operating System :: OS Independent",
|
|
12
|
+
"Programming Language :: Python",
|
|
12
13
|
"Programming Language :: Python :: 3 :: Only",
|
|
13
14
|
"Programming Language :: Python :: 3.11",
|
|
14
15
|
"Programming Language :: Python :: 3.12",
|
|
15
16
|
"Programming Language :: Python :: 3.13",
|
|
16
17
|
"Programming Language :: Python :: 3.14",
|
|
17
|
-
"Programming Language :: Python :: 3.15"
|
|
18
|
-
"Programming Language :: Python"
|
|
18
|
+
"Programming Language :: Python :: 3.15"
|
|
19
19
|
]
|
|
20
20
|
dependencies = [
|
|
21
|
-
"aiohttp>=3.
|
|
22
|
-
"aiolimiter>=1.
|
|
23
|
-
"pycryptodome>=3.
|
|
21
|
+
"aiohttp>=3.14.0",
|
|
22
|
+
"aiolimiter>=1.3.0",
|
|
23
|
+
"pycryptodome>=3.24.0"
|
|
24
24
|
]
|
|
25
25
|
description = "Python library for the Mega.nz and Transfer.it API"
|
|
26
26
|
keywords = [
|
|
@@ -34,12 +34,12 @@ license = "Apache-2.0"
|
|
|
34
34
|
license-files = ["LICENSE"]
|
|
35
35
|
readme = "README.md"
|
|
36
36
|
requires-python = ">=3.11"
|
|
37
|
-
version = "2.
|
|
37
|
+
version = "2.5.0"
|
|
38
38
|
|
|
39
39
|
[project.optional-dependencies]
|
|
40
40
|
cli = [
|
|
41
|
-
"cyclopts>=
|
|
42
|
-
"python-dotenv>=1.2.
|
|
41
|
+
"cyclopts>=5.2.0",
|
|
42
|
+
"python-dotenv>=1.2.4"
|
|
43
43
|
]
|
|
44
44
|
|
|
45
45
|
[project.scripts]
|
|
@@ -114,17 +114,21 @@ sort_first = ["name", "project", "select", "tool"]
|
|
|
114
114
|
spaces_before_inline_comment = 2
|
|
115
115
|
spaces_indent_inline_array = 4
|
|
116
116
|
|
|
117
|
+
[tool.uv]
|
|
118
|
+
default-groups = "all"
|
|
119
|
+
required-version = ">=0.12.24"
|
|
120
|
+
|
|
117
121
|
[tool.uv.build-backend]
|
|
118
122
|
module-name = "mega"
|
|
119
123
|
|
|
120
124
|
[build-system]
|
|
121
125
|
build-backend = "uv_build"
|
|
122
|
-
requires = ["uv_build
|
|
126
|
+
requires = ["uv_build>=0.12.24,<0.13.0"]
|
|
123
127
|
|
|
124
128
|
[dependency-groups]
|
|
125
129
|
dev = [
|
|
126
|
-
"prek>=0.
|
|
127
|
-
"pytest-asyncio>=
|
|
128
|
-
"pytest>=
|
|
129
|
-
"ruff
|
|
130
|
+
"prek>=0.5.5",
|
|
131
|
+
"pytest-asyncio>=1.4.0",
|
|
132
|
+
"pytest>=9.1.1",
|
|
133
|
+
"ruff>=0.16.10,<0.17.0"
|
|
130
134
|
]
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import importlib.metadata
|
|
2
|
+
import logging
|
|
2
3
|
from contextvars import ContextVar
|
|
3
4
|
|
|
4
5
|
_package_name_ = "async-mega-py"
|
|
@@ -6,3 +7,4 @@ __version__ = importlib.metadata.version(_package_name_)
|
|
|
6
7
|
|
|
7
8
|
LOG_FILE_PROGRESS: ContextVar[bool] = ContextVar("LOG_FILE_PROGRESS", default=True)
|
|
8
9
|
LOG_HTTP_TRAFFIC: ContextVar[bool] = ContextVar("LOG_HTTP_TRAFFIC", default=False)
|
|
10
|
+
LOG_HTTP_TRAFFIC_LEVEL: ContextVar[int] = ContextVar("LOG_HTTP_TRAFFIC_LEVEL", default=logging.DEBUG)
|
|
@@ -14,7 +14,7 @@ import aiohttp
|
|
|
14
14
|
import yarl
|
|
15
15
|
from aiolimiter import AsyncLimiter
|
|
16
16
|
|
|
17
|
-
from mega import LOG_HTTP_TRAFFIC, __version__, _package_name_
|
|
17
|
+
from mega import LOG_HTTP_TRAFFIC, LOG_HTTP_TRAFFIC_LEVEL, __version__, _package_name_
|
|
18
18
|
from mega.crypto import generate_hashcash
|
|
19
19
|
from mega.errors import RequestError, RetryRequestError
|
|
20
20
|
from mega.utils import random_id, random_u32int
|
|
@@ -161,7 +161,8 @@ class MegaAPI:
|
|
|
161
161
|
kwargs["headers"] = {"User-Agent": self.user_agent, **(headers or {})}
|
|
162
162
|
request_id = str(uuid.uuid4())
|
|
163
163
|
if LOG_HTTP_TRAFFIC.get():
|
|
164
|
-
logger.
|
|
164
|
+
logger.log(
|
|
165
|
+
LOG_HTTP_TRAFFIC_LEVEL.get(),
|
|
165
166
|
"Starting %s request [id=%s] to %s \n%s",
|
|
166
167
|
method,
|
|
167
168
|
request_id,
|
|
@@ -181,7 +182,8 @@ class MegaAPI:
|
|
|
181
182
|
raise
|
|
182
183
|
finally:
|
|
183
184
|
if resp and LOG_HTTP_TRAFFIC.get():
|
|
184
|
-
logger.
|
|
185
|
+
logger.log(
|
|
186
|
+
LOG_HTTP_TRAFFIC_LEVEL.get(),
|
|
185
187
|
"Finished %s request [id=%s]\n%s",
|
|
186
188
|
method,
|
|
187
189
|
request_id,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|