async-mega-py 2.4.1__tar.gz → 2.5.1__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.1}/PKG-INFO +25 -28
- {async_mega_py-2.4.1 → async_mega_py-2.5.1}/README.md +19 -21
- async_mega_py-2.5.1/pyproject.toml +136 -0
- async_mega_py-2.4.1/pyproject.toml → async_mega_py-2.5.1/pyproject.toml.orig +17 -14
- {async_mega_py-2.4.1 → async_mega_py-2.5.1}/src/mega/__init__.py +2 -0
- {async_mega_py-2.4.1 → async_mega_py-2.5.1}/src/mega/api.py +5 -3
- {async_mega_py-2.4.1 → async_mega_py-2.5.1}/LICENSE +0 -0
- {async_mega_py-2.4.1 → async_mega_py-2.5.1}/src/mega/__main__.py +0 -0
- {async_mega_py-2.4.1 → async_mega_py-2.5.1}/src/mega/auth.py +0 -0
- {async_mega_py-2.4.1 → async_mega_py-2.5.1}/src/mega/chunker.py +0 -0
- {async_mega_py-2.4.1 → async_mega_py-2.5.1}/src/mega/client.py +0 -0
- {async_mega_py-2.4.1 → async_mega_py-2.5.1}/src/mega/core.py +0 -0
- {async_mega_py-2.4.1 → async_mega_py-2.5.1}/src/mega/crypto.py +0 -0
- {async_mega_py-2.4.1 → async_mega_py-2.5.1}/src/mega/data_structures.py +0 -0
- {async_mega_py-2.4.1 → async_mega_py-2.5.1}/src/mega/download.py +0 -0
- {async_mega_py-2.4.1 → async_mega_py-2.5.1}/src/mega/env.py +0 -0
- {async_mega_py-2.4.1 → async_mega_py-2.5.1}/src/mega/errors.py +0 -0
- {async_mega_py-2.4.1 → async_mega_py-2.5.1}/src/mega/filesystem.py +0 -0
- {async_mega_py-2.4.1 → async_mega_py-2.5.1}/src/mega/progress/__init__.py +0 -0
- {async_mega_py-2.4.1 → async_mega_py-2.5.1}/src/mega/progress/rich_progress.py +0 -0
- {async_mega_py-2.4.1 → async_mega_py-2.5.1}/src/mega/py.typed +0 -0
- {async_mega_py-2.4.1 → async_mega_py-2.5.1}/src/mega/transfer_it.py +0 -0
- {async_mega_py-2.4.1 → async_mega_py-2.5.1}/src/mega/upload.py +0 -0
- {async_mega_py-2.4.1 → async_mega_py-2.5.1}/src/mega/utils.py +0 -0
- {async_mega_py-2.4.1 → async_mega_py-2.5.1}/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.1
|
|
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
|
|
@@ -12,7 +12,6 @@ Classifier: Environment :: Console
|
|
|
12
12
|
Classifier: Framework :: AsyncIO
|
|
13
13
|
Classifier: Intended Audience :: Developers
|
|
14
14
|
Classifier: Intended Audience :: End Users/Desktop
|
|
15
|
-
Classifier: License :: OSI Approved :: Apache Software License
|
|
16
15
|
Classifier: Operating System :: OS Independent
|
|
17
16
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
18
17
|
Classifier: Programming Language :: Python :: 3.11
|
|
@@ -21,11 +20,11 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
21
20
|
Classifier: Programming Language :: Python :: 3.14
|
|
22
21
|
Classifier: Programming Language :: Python :: 3.15
|
|
23
22
|
Classifier: Programming Language :: Python
|
|
24
|
-
Requires-Dist: aiohttp>=3.
|
|
25
|
-
Requires-Dist: aiolimiter>=1.
|
|
26
|
-
Requires-Dist: pycryptodome>=3.
|
|
27
|
-
Requires-Dist: cyclopts>=
|
|
28
|
-
Requires-Dist: python-dotenv>=1.2.
|
|
23
|
+
Requires-Dist: aiohttp>=3.14.0,<4.0.0
|
|
24
|
+
Requires-Dist: aiolimiter>=1.3.0
|
|
25
|
+
Requires-Dist: pycryptodome>=3.24.0
|
|
26
|
+
Requires-Dist: cyclopts>=5.2.0 ; extra == 'cli'
|
|
27
|
+
Requires-Dist: python-dotenv>=1.2.4 ; extra == 'cli'
|
|
29
28
|
Requires-Python: >=3.11
|
|
30
29
|
Project-URL: Homepage, https://github.com/NTFSvolume/mega.py
|
|
31
30
|
Provides-Extra: cli
|
|
@@ -88,7 +87,6 @@ email = "my_email@email.com"
|
|
|
88
87
|
password = "12345"
|
|
89
88
|
async with MegaNzClient() as mega:
|
|
90
89
|
await mega.login(email, password)
|
|
91
|
-
|
|
92
90
|
```
|
|
93
91
|
|
|
94
92
|
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 +96,8 @@ from mega.client import MegaNzClient
|
|
|
98
96
|
|
|
99
97
|
# Also works without using it as a context manager, but you have the responsability to close the session at the end
|
|
100
98
|
mega = MegaNzClient()
|
|
101
|
-
await mega.login()
|
|
99
|
+
await mega.login() # login using a temporary anonymous account
|
|
102
100
|
# await mega.close()
|
|
103
|
-
|
|
104
101
|
```
|
|
105
102
|
|
|
106
103
|
## Methods
|
|
@@ -126,18 +123,20 @@ contact = "test@mega.nz"
|
|
|
126
123
|
await mega.add_contact(contact)
|
|
127
124
|
await mega.remove_contact(contact)
|
|
128
125
|
|
|
126
|
+
|
|
129
127
|
async def view_paths():
|
|
130
128
|
fs = await mega.get_filesystem()
|
|
131
|
-
print
|
|
129
|
+
print(fs.paths.values())
|
|
130
|
+
|
|
132
131
|
|
|
133
132
|
# Create a folder
|
|
134
|
-
await mega.create_folder(
|
|
135
|
-
await mega.create_folder(
|
|
133
|
+
await mega.create_folder("new_folder")
|
|
134
|
+
await mega.create_folder("new_folder/sub_folder/subsub_folder")
|
|
136
135
|
await view_paths()
|
|
137
136
|
|
|
138
137
|
# Rename a file or a folder
|
|
139
|
-
folder = await mega.find(
|
|
140
|
-
await mega.rename(folder, new_name=
|
|
138
|
+
folder = await mega.find("new_folder/sub_folder/subsub_folder")
|
|
139
|
+
await mega.rename(folder, new_name="my_new_name")
|
|
141
140
|
await view_paths()
|
|
142
141
|
|
|
143
142
|
# Send this node to the trash bin (still counts towards your quota)
|
|
@@ -153,9 +152,9 @@ await view_paths()
|
|
|
153
152
|
|
|
154
153
|
```python
|
|
155
154
|
# 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)
|
|
155
|
+
my_real_file = "/home/user/myfile.doc" # Change this to a real file path!
|
|
156
|
+
uploaded_file = await mega.upload(my_real_file) # Upload returns the Node that represents the file you just uploaded
|
|
157
|
+
await mega.export(uploaded_file) # This only works with real accounts. Temp accounts can't create public links
|
|
159
158
|
|
|
160
159
|
# Download a file from your account
|
|
161
160
|
output_dir = "my downloads"
|
|
@@ -171,7 +170,7 @@ folder_url = "https://mega.nz/folder/CJ8y1SDJ#KX8YfTd526P4o_hDH02jLQ"
|
|
|
171
170
|
public_handle, public_key, selected_node = mega.parse_folder_url(folder_url)
|
|
172
171
|
results = await mega.download_public_folder(public_handle, public_key, output_dir, selected_node)
|
|
173
172
|
for node_id, result in results.items():
|
|
174
|
-
print
|
|
173
|
+
print((node_id, result))
|
|
175
174
|
|
|
176
175
|
# Import a file from URL
|
|
177
176
|
public_handle, public_key = mega.parse_file_url(file_url)
|
|
@@ -179,7 +178,7 @@ await mega.import_public_file(public_handle, public_key, dest_node_id=folder.id)
|
|
|
179
178
|
|
|
180
179
|
# How do you know if an URL is a file or folder?
|
|
181
180
|
result = mega.parse_url(url)
|
|
182
|
-
print
|
|
181
|
+
print(result.is_folder)
|
|
183
182
|
```
|
|
184
183
|
|
|
185
184
|
> [!TIP]
|
|
@@ -253,8 +252,8 @@ fs = UserFileSystem.from_dump(json.loads(dump))
|
|
|
253
252
|
# Search for nodes
|
|
254
253
|
query = "tests/script"
|
|
255
254
|
for node_id, path in fs.search(query):
|
|
256
|
-
print
|
|
257
|
-
print
|
|
255
|
+
print(node_id)
|
|
256
|
+
print(path)
|
|
258
257
|
|
|
259
258
|
# or
|
|
260
259
|
dict(fs.search(query))
|
|
@@ -274,12 +273,11 @@ The output will be:
|
|
|
274
273
|
|
|
275
274
|
```python
|
|
276
275
|
# Get the path to a node
|
|
277
|
-
fs.absolute_path("0fPFklV3")
|
|
276
|
+
fs.absolute_path("0fPFklV3") # /tests/scripts/notes.txt
|
|
278
277
|
|
|
279
278
|
# Find a node by its *exact* path
|
|
280
279
|
result = fs.find("/tests/scripts/notes.txt")
|
|
281
|
-
print
|
|
282
|
-
|
|
280
|
+
print(result.id) # "0fPFklV3"
|
|
283
281
|
```
|
|
284
282
|
|
|
285
283
|
```python
|
|
@@ -290,7 +288,6 @@ list(fs.deleted)
|
|
|
290
288
|
folder = fs.find("/tests")
|
|
291
289
|
for node in fs.iterdir(folder.id, recursive=True):
|
|
292
290
|
print(fs.absolute_path(node.id))
|
|
293
|
-
|
|
294
291
|
```
|
|
295
292
|
|
|
296
293
|
Output will be:
|
|
@@ -315,7 +312,7 @@ Output will be:
|
|
|
315
312
|
> If 2 nodes have the same path, `find` will throw an error.
|
|
316
313
|
|
|
317
314
|
```python
|
|
318
|
-
fs.find("/tests/logo.png")
|
|
315
|
+
fs.find("/tests/logo.png") # This will fail
|
|
319
316
|
# You will have to call search and choose which one you actually want
|
|
320
317
|
dict(fs.search("/tests/logo.png"))
|
|
321
318
|
```
|
|
@@ -335,7 +332,7 @@ async with TransferItClient() as client:
|
|
|
335
332
|
fs = await client.get_filesystem(transfer_id)
|
|
336
333
|
output_dir = "My downloads"
|
|
337
334
|
results = await client.download_transfer(transfer_id, output_dir)
|
|
338
|
-
print
|
|
335
|
+
print(results)
|
|
339
336
|
```
|
|
340
337
|
|
|
341
338
|
## 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
|
+
version = "2.5.1"
|
|
4
|
+
classifiers = [
|
|
5
|
+
"Development Status :: 5 - Production/Stable",
|
|
6
|
+
"Environment :: Console",
|
|
7
|
+
"Framework :: AsyncIO",
|
|
8
|
+
"Intended Audience :: Developers",
|
|
9
|
+
"Intended Audience :: End Users/Desktop",
|
|
10
|
+
"Operating System :: OS Independent",
|
|
11
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
12
|
+
"Programming Language :: Python :: 3.11",
|
|
13
|
+
"Programming Language :: Python :: 3.12",
|
|
14
|
+
"Programming Language :: Python :: 3.13",
|
|
15
|
+
"Programming Language :: Python :: 3.14",
|
|
16
|
+
"Programming Language :: Python :: 3.15",
|
|
17
|
+
"Programming Language :: Python",
|
|
18
|
+
]
|
|
19
|
+
dependencies = [
|
|
20
|
+
"aiohttp>=3.14.0,<4.0.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
|
+
|
|
37
|
+
[[project.authors]]
|
|
38
|
+
name = "NTFSvolume"
|
|
39
|
+
email = "NTFSvolume@proton.me"
|
|
40
|
+
|
|
41
|
+
[project.optional-dependencies]
|
|
42
|
+
cli = [
|
|
43
|
+
"cyclopts>=5.2.0",
|
|
44
|
+
"python-dotenv>=1.2.4",
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
[project.scripts]
|
|
48
|
+
async-mega-py = "mega.__main__:app.meta"
|
|
49
|
+
mega-py = "mega.__main__:app.meta"
|
|
50
|
+
|
|
51
|
+
[project.urls]
|
|
52
|
+
Homepage = "https://github.com/NTFSvolume/mega.py"
|
|
53
|
+
|
|
54
|
+
[tool.coverage.run]
|
|
55
|
+
omit = ["tests/*"]
|
|
56
|
+
|
|
57
|
+
[tool.pytest.ini_options]
|
|
58
|
+
addopts = "-s -v"
|
|
59
|
+
asyncio_default_fixture_loop_scope = "function"
|
|
60
|
+
asyncio_mode = "auto"
|
|
61
|
+
minversion = "9.2.0"
|
|
62
|
+
norecursedirs = [".git"]
|
|
63
|
+
|
|
64
|
+
[tool.ruff]
|
|
65
|
+
line-length = 120
|
|
66
|
+
|
|
67
|
+
[tool.ruff.lint]
|
|
68
|
+
select = [
|
|
69
|
+
"B",
|
|
70
|
+
"C4",
|
|
71
|
+
"COM8",
|
|
72
|
+
"E",
|
|
73
|
+
"F",
|
|
74
|
+
"FA102",
|
|
75
|
+
"FURB188",
|
|
76
|
+
"I",
|
|
77
|
+
"N",
|
|
78
|
+
"PLR1716",
|
|
79
|
+
"Q",
|
|
80
|
+
"RUF",
|
|
81
|
+
"T20",
|
|
82
|
+
"TC",
|
|
83
|
+
"TID",
|
|
84
|
+
"UP",
|
|
85
|
+
"W",
|
|
86
|
+
]
|
|
87
|
+
extend-safe-fixes = ["TC"]
|
|
88
|
+
ignore = [
|
|
89
|
+
"COM812",
|
|
90
|
+
"E501",
|
|
91
|
+
"N806",
|
|
92
|
+
]
|
|
93
|
+
unfixable = ["ERA"]
|
|
94
|
+
|
|
95
|
+
[tool.ruff.lint.per-file-ignores]
|
|
96
|
+
"**/{tests,docs}/*" = [
|
|
97
|
+
"E402",
|
|
98
|
+
"T20",
|
|
99
|
+
]
|
|
100
|
+
"__init__.py" = ["E402"]
|
|
101
|
+
|
|
102
|
+
[tool.ruff.lint.pydocstyle]
|
|
103
|
+
convention = "google"
|
|
104
|
+
|
|
105
|
+
[tool.tomlsort]
|
|
106
|
+
all = true
|
|
107
|
+
ignore_case = true
|
|
108
|
+
in_place = true
|
|
109
|
+
sort_first = [
|
|
110
|
+
"name",
|
|
111
|
+
"project",
|
|
112
|
+
"select",
|
|
113
|
+
"tool",
|
|
114
|
+
"version",
|
|
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.13.6"
|
|
122
|
+
|
|
123
|
+
[tool.uv.build-backend]
|
|
124
|
+
module-name = "mega"
|
|
125
|
+
|
|
126
|
+
[build-system]
|
|
127
|
+
build-backend = "uv_build"
|
|
128
|
+
requires = ["uv_build>=0.13.6,<1.0.0"]
|
|
129
|
+
|
|
130
|
+
[dependency-groups]
|
|
131
|
+
dev = [
|
|
132
|
+
"prek>=0.5.5",
|
|
133
|
+
"pytest-asyncio>=1.4.1",
|
|
134
|
+
"pytest>=9.2.0",
|
|
135
|
+
"ruff>=0.17.3,<0.18.0",
|
|
136
|
+
]
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "async-mega.py"
|
|
3
|
+
version = "2.5.1"
|
|
3
4
|
authors = [{name = "NTFSvolume", email = "NTFSvolume@proton.me"}]
|
|
4
5
|
classifiers = [
|
|
5
6
|
"Development Status :: 5 - Production/Stable",
|
|
@@ -7,7 +8,6 @@ classifiers = [
|
|
|
7
8
|
"Framework :: AsyncIO",
|
|
8
9
|
"Intended Audience :: Developers",
|
|
9
10
|
"Intended Audience :: End Users/Desktop",
|
|
10
|
-
"License :: OSI Approved :: Apache Software License",
|
|
11
11
|
"Operating System :: OS Independent",
|
|
12
12
|
"Programming Language :: Python :: 3 :: Only",
|
|
13
13
|
"Programming Language :: Python :: 3.11",
|
|
@@ -18,9 +18,9 @@ classifiers = [
|
|
|
18
18
|
"Programming Language :: Python"
|
|
19
19
|
]
|
|
20
20
|
dependencies = [
|
|
21
|
-
"aiohttp>=3.
|
|
22
|
-
"aiolimiter>=1.
|
|
23
|
-
"pycryptodome>=3.
|
|
21
|
+
"aiohttp>=3.14.0,<4.0.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,11 @@ license = "Apache-2.0"
|
|
|
34
34
|
license-files = ["LICENSE"]
|
|
35
35
|
readme = "README.md"
|
|
36
36
|
requires-python = ">=3.11"
|
|
37
|
-
version = "2.4.1"
|
|
38
37
|
|
|
39
38
|
[project.optional-dependencies]
|
|
40
39
|
cli = [
|
|
41
|
-
"cyclopts>=
|
|
42
|
-
"python-dotenv>=1.2.
|
|
40
|
+
"cyclopts>=5.2.0",
|
|
41
|
+
"python-dotenv>=1.2.4"
|
|
43
42
|
]
|
|
44
43
|
|
|
45
44
|
[project.scripts]
|
|
@@ -58,7 +57,7 @@ omit = [
|
|
|
58
57
|
addopts = "-s -v"
|
|
59
58
|
asyncio_default_fixture_loop_scope = "function"
|
|
60
59
|
asyncio_mode = "auto"
|
|
61
|
-
minversion = "
|
|
60
|
+
minversion = "9.2.0"
|
|
62
61
|
norecursedirs = [".git"]
|
|
63
62
|
|
|
64
63
|
[tool.ruff]
|
|
@@ -110,21 +109,25 @@ convention = "google"
|
|
|
110
109
|
all = true
|
|
111
110
|
ignore_case = true
|
|
112
111
|
in_place = true
|
|
113
|
-
sort_first = ["name", "project", "select", "tool"]
|
|
112
|
+
sort_first = ["name", "project", "select", "tool", "version"]
|
|
114
113
|
spaces_before_inline_comment = 2
|
|
115
114
|
spaces_indent_inline_array = 4
|
|
116
115
|
|
|
116
|
+
[tool.uv]
|
|
117
|
+
default-groups = "all"
|
|
118
|
+
required-version = ">=0.13.6"
|
|
119
|
+
|
|
117
120
|
[tool.uv.build-backend]
|
|
118
121
|
module-name = "mega"
|
|
119
122
|
|
|
120
123
|
[build-system]
|
|
121
124
|
build-backend = "uv_build"
|
|
122
|
-
requires = ["uv_build
|
|
125
|
+
requires = ["uv_build>=0.13.6,<1.0.0"]
|
|
123
126
|
|
|
124
127
|
[dependency-groups]
|
|
125
128
|
dev = [
|
|
126
|
-
"prek>=0.
|
|
127
|
-
"pytest-asyncio>=
|
|
128
|
-
"pytest>=
|
|
129
|
-
"ruff
|
|
129
|
+
"prek>=0.5.5",
|
|
130
|
+
"pytest-asyncio>=1.4.1",
|
|
131
|
+
"pytest>=9.2.0",
|
|
132
|
+
"ruff>=0.17.3,<0.18.0"
|
|
130
133
|
]
|
|
@@ -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
|