pinarkive-sdk 2.0.0__py3-none-any.whl → 2.1.46__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pinarkive_client.py +153 -11
- pinarkive_sdk-2.1.46.dist-info/METADATA +455 -0
- pinarkive_sdk-2.1.46.dist-info/RECORD +5 -0
- pinarkive_sdk-2.0.0.dist-info/METADATA +0 -44
- pinarkive_sdk-2.0.0.dist-info/RECORD +0 -5
- {pinarkive_sdk-2.0.0.dist-info → pinarkive_sdk-2.1.46.dist-info}/WHEEL +0 -0
- {pinarkive_sdk-2.0.0.dist-info → pinarkive_sdk-2.1.46.dist-info}/top_level.txt +0 -0
pinarkive_client.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
import requests
|
2
|
-
from typing import Optional, Dict, Any, List
|
2
|
+
from typing import Optional, Dict, Any, List, Union, BinaryIO
|
3
|
+
import os
|
3
4
|
|
4
5
|
class PinarkiveClient:
|
5
6
|
def __init__(self, token: Optional[str] = None, api_key: Optional[str] = None, base_url: str = 'https://api.pinarkive.com/api/v2'):
|
@@ -13,7 +14,7 @@ class PinarkiveClient:
|
|
13
14
|
if self.token:
|
14
15
|
headers['Authorization'] = f'Bearer {self.token}'
|
15
16
|
elif self.api_key:
|
16
|
-
headers['
|
17
|
+
headers['Authorization'] = f'Bearer {self.api_key}'
|
17
18
|
return headers
|
18
19
|
|
19
20
|
# --- Authentication ---
|
@@ -58,12 +59,138 @@ class PinarkiveClient:
|
|
58
59
|
headers=self._headers()
|
59
60
|
)
|
60
61
|
|
62
|
+
# New: Directory DAG upload
|
63
|
+
def upload_directory_dag(self, files_dict: Dict[str, Any], dir_name: Optional[str] = None) -> Any:
|
64
|
+
"""
|
65
|
+
Upload directory structure as DAG (Directed Acyclic Graph).
|
66
|
+
|
67
|
+
Args:
|
68
|
+
files_dict: Dictionary with file paths as keys and file content as values
|
69
|
+
dir_name: Optional directory name for the DAG
|
70
|
+
|
71
|
+
Returns:
|
72
|
+
API response with DAG CID and file information
|
73
|
+
"""
|
74
|
+
files = []
|
75
|
+
for path, content in files_dict.items():
|
76
|
+
if isinstance(content, str):
|
77
|
+
# If content is a string, treat it as file content
|
78
|
+
files.append(('files', (path, content, 'text/plain')))
|
79
|
+
elif isinstance(content, (bytes, BinaryIO)):
|
80
|
+
# If content is bytes or file-like object
|
81
|
+
files.append(('files', (path, content, 'application/octet-stream')))
|
82
|
+
else:
|
83
|
+
# Try to convert to string
|
84
|
+
files.append(('files', (path, str(content), 'text/plain')))
|
85
|
+
|
86
|
+
data = {}
|
87
|
+
if dir_name:
|
88
|
+
data['dirName'] = dir_name
|
89
|
+
|
90
|
+
return self.session.post(
|
91
|
+
f'{self.base_url}/files/directory-dag',
|
92
|
+
files=files,
|
93
|
+
data=data,
|
94
|
+
headers=self._headers()
|
95
|
+
)
|
96
|
+
|
97
|
+
# New: Directory cluster upload
|
98
|
+
def upload_directory_cluster(self, files: List[Dict[str, Any]]) -> Any:
|
99
|
+
"""
|
100
|
+
Upload directory using cluster-based approach.
|
101
|
+
|
102
|
+
Args:
|
103
|
+
files: List of dictionaries with 'path' and 'content' keys
|
104
|
+
|
105
|
+
Returns:
|
106
|
+
API response with cluster CID
|
107
|
+
"""
|
108
|
+
files_data = []
|
109
|
+
for file_info in files:
|
110
|
+
path = file_info.get('path')
|
111
|
+
content = file_info.get('content')
|
112
|
+
if path and content is not None:
|
113
|
+
if isinstance(content, str):
|
114
|
+
files_data.append(('files', (path, content, 'text/plain')))
|
115
|
+
elif isinstance(content, (bytes, BinaryIO)):
|
116
|
+
files_data.append(('files', (path, content, 'application/octet-stream')))
|
117
|
+
else:
|
118
|
+
files_data.append(('files', (path, str(content), 'text/plain')))
|
119
|
+
|
120
|
+
return self.session.post(
|
121
|
+
f'{self.base_url}/files/directory-cluster',
|
122
|
+
files=files_data,
|
123
|
+
headers=self._headers()
|
124
|
+
)
|
125
|
+
|
126
|
+
# New: Upload file to existing directory
|
127
|
+
def upload_file_to_directory(self, file_path: str, dir_path: str) -> Any:
|
128
|
+
"""
|
129
|
+
Upload a file to an existing directory.
|
130
|
+
|
131
|
+
Args:
|
132
|
+
file_path: Path to the file to upload
|
133
|
+
dir_path: Path of the existing directory
|
134
|
+
|
135
|
+
Returns:
|
136
|
+
API response with file CID
|
137
|
+
"""
|
138
|
+
with open(file_path, 'rb') as f:
|
139
|
+
files = {'file': f}
|
140
|
+
data = {'dirPath': dir_path}
|
141
|
+
return self.session.post(
|
142
|
+
f'{self.base_url}/files/directory-files',
|
143
|
+
files=files,
|
144
|
+
data=data,
|
145
|
+
headers=self._headers()
|
146
|
+
)
|
147
|
+
|
148
|
+
# New: Rename file
|
149
|
+
def rename_file(self, upload_id: str, new_name: str) -> Any:
|
150
|
+
"""
|
151
|
+
Rename an uploaded file.
|
152
|
+
|
153
|
+
Args:
|
154
|
+
upload_id: ID of the uploaded file
|
155
|
+
new_name: New name for the file
|
156
|
+
|
157
|
+
Returns:
|
158
|
+
API response with rename status
|
159
|
+
"""
|
160
|
+
return self.session.put(
|
161
|
+
f'{self.base_url}/files/rename/{upload_id}',
|
162
|
+
json={'newName': new_name},
|
163
|
+
headers=self._headers()
|
164
|
+
)
|
165
|
+
|
61
166
|
def pin_cid(self, cid: str) -> Any:
|
62
167
|
return self.session.post(
|
63
168
|
f'{self.base_url}/files/pin/{cid}',
|
64
169
|
headers=self._headers()
|
65
170
|
)
|
66
171
|
|
172
|
+
# New: Pin CID with custom name
|
173
|
+
def pin_cid_with_name(self, cid: str, custom_name: Optional[str] = None) -> Any:
|
174
|
+
"""
|
175
|
+
Pin a CID with an optional custom name.
|
176
|
+
|
177
|
+
Args:
|
178
|
+
cid: IPFS CID to pin
|
179
|
+
custom_name: Optional custom name for the pinned content
|
180
|
+
|
181
|
+
Returns:
|
182
|
+
API response with pin status
|
183
|
+
"""
|
184
|
+
data = {}
|
185
|
+
if custom_name:
|
186
|
+
data['customName'] = custom_name
|
187
|
+
|
188
|
+
return self.session.post(
|
189
|
+
f'{self.base_url}/files/pin/{cid}',
|
190
|
+
json=data,
|
191
|
+
headers=self._headers()
|
192
|
+
)
|
193
|
+
|
67
194
|
def remove_file(self, cid: str) -> Any:
|
68
195
|
return self.session.delete(
|
69
196
|
f'{self.base_url}/files/remove/{cid}',
|
@@ -91,11 +218,6 @@ class PinarkiveClient:
|
|
91
218
|
headers=self._headers()
|
92
219
|
)
|
93
220
|
|
94
|
-
def delete_upload(self, cid: str) -> Any:
|
95
|
-
return self.session.delete(
|
96
|
-
f'{self.base_url}/users/me/uploads/{cid}',
|
97
|
-
headers=self._headers()
|
98
|
-
)
|
99
221
|
|
100
222
|
def get_referrals(self) -> Any:
|
101
223
|
return self.session.get(
|
@@ -104,10 +226,30 @@ class PinarkiveClient:
|
|
104
226
|
)
|
105
227
|
|
106
228
|
# --- Token Management ---
|
107
|
-
def generate_token(self, name: str,
|
108
|
-
|
109
|
-
|
110
|
-
|
229
|
+
def generate_token(self, name: str, options: Optional[Dict[str, Any]] = None) -> Any:
|
230
|
+
"""
|
231
|
+
Generate an API token with enhanced options.
|
232
|
+
|
233
|
+
Args:
|
234
|
+
name: Name for the token
|
235
|
+
options: Optional dictionary with:
|
236
|
+
- permissions: List of permissions
|
237
|
+
- expires_in_days: Number of days until expiration
|
238
|
+
- ip_allowlist: List of allowed IP addresses
|
239
|
+
|
240
|
+
Returns:
|
241
|
+
API response with token information
|
242
|
+
"""
|
243
|
+
data = {'name': name}
|
244
|
+
|
245
|
+
if options:
|
246
|
+
if 'permissions' in options:
|
247
|
+
data['permissions'] = options['permissions']
|
248
|
+
if 'expires_in_days' in options:
|
249
|
+
data['expiresInDays'] = options['expires_in_days']
|
250
|
+
if 'ip_allowlist' in options:
|
251
|
+
data['ipAllowlist'] = options['ip_allowlist']
|
252
|
+
|
111
253
|
return self.session.post(
|
112
254
|
f'{self.base_url}/tokens/generate',
|
113
255
|
json=data,
|
@@ -0,0 +1,455 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: pinarkive-sdk
|
3
|
+
Version: 2.1.46
|
4
|
+
Summary: Python SDK for the Pinarkive API v2.1 - Easy IPFS file management with directory DAG uploads, file renaming, and enhanced API key management. Includes type hints for better IDE support.
|
5
|
+
Author: ITCS VIP, Joel_da
|
6
|
+
License: MIT
|
7
|
+
Project-URL: Homepage, https://github.com/pinarkive/pinarkive-sdk
|
8
|
+
Project-URL: Repository, https://github.com/pinarkive/pinarkive-sdk.git
|
9
|
+
Requires-Python: >=3.7
|
10
|
+
Description-Content-Type: text/markdown
|
11
|
+
Requires-Dist: requests>=2.31.0
|
12
|
+
|
13
|
+
# Pinarkive Python SDK
|
14
|
+
|
15
|
+
Python client for the Pinarkive API v2.1. Easy IPFS file management with directory DAG uploads, file renaming, and enhanced API key management. Includes type hints for better IDE support and Pythonic usage patterns.
|
16
|
+
|
17
|
+
## Installation
|
18
|
+
|
19
|
+
```bash
|
20
|
+
pip install pinarkive-sdk
|
21
|
+
```
|
22
|
+
|
23
|
+
## Quick Start
|
24
|
+
|
25
|
+
```python
|
26
|
+
from pinarkive_client import PinarkiveClient
|
27
|
+
|
28
|
+
# Initialize with API key
|
29
|
+
client = PinarkiveClient(api_key="your-api-key-here")
|
30
|
+
|
31
|
+
# Upload a file
|
32
|
+
result = client.upload_file("document.pdf")
|
33
|
+
print(f"File uploaded: {result.json()['cid']}")
|
34
|
+
|
35
|
+
# Generate API key
|
36
|
+
token = client.generate_token("my-app", {
|
37
|
+
"expires_in_days": 30
|
38
|
+
})
|
39
|
+
print(f"New API key: {token.json()['token']}")
|
40
|
+
```
|
41
|
+
|
42
|
+
## Authentication
|
43
|
+
|
44
|
+
The SDK supports two authentication methods:
|
45
|
+
|
46
|
+
### API Key Authentication (Recommended)
|
47
|
+
```python
|
48
|
+
client = PinarkiveClient(api_key="your-api-key-here")
|
49
|
+
```
|
50
|
+
**Note:** The SDK automatically sends the API key using the `Authorization: Bearer` header format, not `X-API-Key`.
|
51
|
+
|
52
|
+
### JWT Token Authentication
|
53
|
+
```python
|
54
|
+
client = PinarkiveClient(token="your-jwt-token-here")
|
55
|
+
```
|
56
|
+
|
57
|
+
## Basic Usage
|
58
|
+
|
59
|
+
### File Upload
|
60
|
+
```python
|
61
|
+
# Upload single file
|
62
|
+
result = client.upload_file("document.pdf")
|
63
|
+
response_data = result.json()
|
64
|
+
print(f"CID: {response_data['cid']}")
|
65
|
+
print(f"Status: {response_data['status']}")
|
66
|
+
```
|
67
|
+
|
68
|
+
### Directory Upload
|
69
|
+
```python
|
70
|
+
# Upload directory from local path
|
71
|
+
result = client.upload_directory("/path/to/directory")
|
72
|
+
print(f"Directory CID: {result.json()['cid']}")
|
73
|
+
```
|
74
|
+
|
75
|
+
### List Uploads
|
76
|
+
```python
|
77
|
+
# List all uploaded files with pagination
|
78
|
+
result = client.list_uploads(page=1, limit=20)
|
79
|
+
response_data = result.json()
|
80
|
+
print(f"Uploads: {response_data['uploads']}")
|
81
|
+
print(f"Total: {response_data['pagination']['total']}")
|
82
|
+
```
|
83
|
+
|
84
|
+
## Advanced Features
|
85
|
+
|
86
|
+
### Directory DAG Upload
|
87
|
+
Upload entire directory structures as DAG (Directed Acyclic Graph):
|
88
|
+
|
89
|
+
```python
|
90
|
+
# Create project structure
|
91
|
+
project_files = {
|
92
|
+
"src/index.py": "print('Hello World')",
|
93
|
+
"src/utils.py": "def utils(): pass",
|
94
|
+
"requirements.txt": "requests>=2.31.0",
|
95
|
+
"README.md": "# My Project\n\nThis is my project."
|
96
|
+
}
|
97
|
+
|
98
|
+
# Upload as DAG
|
99
|
+
result = client.upload_directory_dag(project_files, dir_name="my-project")
|
100
|
+
response_data = result.json()
|
101
|
+
print(f"DAG CID: {response_data['dagCid']}")
|
102
|
+
print(f"Files: {response_data['files']}")
|
103
|
+
```
|
104
|
+
|
105
|
+
### Directory Cluster Upload
|
106
|
+
```python
|
107
|
+
# Upload using cluster-based approach
|
108
|
+
files = [
|
109
|
+
{"path": "file1.txt", "content": "Content 1"},
|
110
|
+
{"path": "file2.txt", "content": "Content 2"}
|
111
|
+
]
|
112
|
+
|
113
|
+
result = client.upload_directory_cluster(files)
|
114
|
+
print(f"Cluster CID: {result.json()['cid']}")
|
115
|
+
```
|
116
|
+
|
117
|
+
### Upload File to Existing Directory
|
118
|
+
```python
|
119
|
+
# Add file to existing directory
|
120
|
+
result = client.upload_file_to_directory("new-file.txt", "existing-directory-path")
|
121
|
+
print(f"File added to directory: {result.json()['cid']}")
|
122
|
+
```
|
123
|
+
|
124
|
+
### File Renaming
|
125
|
+
```python
|
126
|
+
# Rename an uploaded file
|
127
|
+
result = client.rename_file("upload-id-here", "new-file-name.pdf")
|
128
|
+
print(f"File renamed: {result.json()['updated']}")
|
129
|
+
```
|
130
|
+
|
131
|
+
### Pinning Operations
|
132
|
+
|
133
|
+
#### Basic CID Pinning
|
134
|
+
```python
|
135
|
+
result = client.pin_cid("QmYourCIDHere")
|
136
|
+
print(f"CID pinned: {result.json()['pinned']}")
|
137
|
+
```
|
138
|
+
|
139
|
+
#### Pin with Custom Name
|
140
|
+
```python
|
141
|
+
result = client.pin_cid_with_name("QmYourCIDHere", "my-important-file")
|
142
|
+
print(f"CID pinned with name: {result.json()['pinned']}")
|
143
|
+
```
|
144
|
+
|
145
|
+
### API Key Management
|
146
|
+
|
147
|
+
#### Generate API Key
|
148
|
+
```python
|
149
|
+
# Basic token generation
|
150
|
+
token = client.generate_token("my-app")
|
151
|
+
|
152
|
+
# Advanced token with options
|
153
|
+
token = client.generate_token("my-app", {
|
154
|
+
"expires_in_days": 30,
|
155
|
+
"ip_allowlist": ["192.168.1.1", "10.0.0.1"],
|
156
|
+
"permissions": ["upload", "pin"]
|
157
|
+
})
|
158
|
+
print(f"New API key: {token.json()['token']}")
|
159
|
+
```
|
160
|
+
|
161
|
+
#### List API Keys
|
162
|
+
```python
|
163
|
+
tokens = client.list_tokens()
|
164
|
+
print(f"API Keys: {tokens.json()['tokens']}")
|
165
|
+
```
|
166
|
+
|
167
|
+
#### Revoke API Key
|
168
|
+
```python
|
169
|
+
result = client.revoke_token("my-app")
|
170
|
+
print(f"Token revoked: {result.json()['revoked']}")
|
171
|
+
```
|
172
|
+
|
173
|
+
## Type Hints Support
|
174
|
+
|
175
|
+
The SDK includes comprehensive type hints for better IDE support:
|
176
|
+
|
177
|
+
```python
|
178
|
+
from typing import Dict, Any, Optional
|
179
|
+
from pinarkive_client import PinarkiveClient
|
180
|
+
|
181
|
+
# Type hints provide better autocomplete and error checking
|
182
|
+
client = PinarkiveClient(api_key="your-key")
|
183
|
+
|
184
|
+
# IDE will show parameter types and return types
|
185
|
+
def upload_project_files(files: Dict[str, str]) -> Any:
|
186
|
+
return client.upload_directory_dag(files, dir_name="project")
|
187
|
+
|
188
|
+
# Type hints for options
|
189
|
+
token_options: Dict[str, Any] = {
|
190
|
+
"expires_in_days": 30,
|
191
|
+
"ip_allowlist": ["192.168.1.1"]
|
192
|
+
}
|
193
|
+
token = client.generate_token("my-app", token_options)
|
194
|
+
```
|
195
|
+
|
196
|
+
## Error Handling
|
197
|
+
|
198
|
+
```python
|
199
|
+
import requests
|
200
|
+
|
201
|
+
try:
|
202
|
+
result = client.upload_file("document.pdf")
|
203
|
+
print("Success:", result.json())
|
204
|
+
except requests.exceptions.RequestException as e:
|
205
|
+
if hasattr(e, 'response') and e.response is not None:
|
206
|
+
print(f"API Error: {e.response.status_code}")
|
207
|
+
print(f"Response: {e.response.json()}")
|
208
|
+
else:
|
209
|
+
print(f"Network Error: {e}")
|
210
|
+
```
|
211
|
+
|
212
|
+
## Integration Examples
|
213
|
+
|
214
|
+
### Django Integration
|
215
|
+
```python
|
216
|
+
# views.py
|
217
|
+
from django.http import JsonResponse
|
218
|
+
from django.views.decorators.csrf import csrf_exempt
|
219
|
+
from pinarkive_client import PinarkiveClient
|
220
|
+
import json
|
221
|
+
|
222
|
+
@csrf_exempt
|
223
|
+
def upload_file(request):
|
224
|
+
if request.method == 'POST':
|
225
|
+
client = PinarkiveClient(api_key=settings.PINARKIVE_API_KEY)
|
226
|
+
|
227
|
+
uploaded_file = request.FILES['file']
|
228
|
+
# Save temporarily
|
229
|
+
with open(f'/tmp/{uploaded_file.name}', 'wb+') as destination:
|
230
|
+
for chunk in uploaded_file.chunks():
|
231
|
+
destination.write(chunk)
|
232
|
+
|
233
|
+
try:
|
234
|
+
result = client.upload_file(f'/tmp/{uploaded_file.name}')
|
235
|
+
return JsonResponse(result.json())
|
236
|
+
except Exception as e:
|
237
|
+
return JsonResponse({'error': str(e)}, status=500)
|
238
|
+
|
239
|
+
return JsonResponse({'error': 'Method not allowed'}, status=405)
|
240
|
+
```
|
241
|
+
|
242
|
+
### Flask Integration
|
243
|
+
```python
|
244
|
+
from flask import Flask, request, jsonify
|
245
|
+
from pinarkive_client import PinarkiveClient
|
246
|
+
import os
|
247
|
+
|
248
|
+
app = Flask(__name__)
|
249
|
+
client = PinarkiveClient(api_key=os.environ.get('PINARKIVE_API_KEY'))
|
250
|
+
|
251
|
+
@app.route('/upload', methods=['POST'])
|
252
|
+
def upload_file():
|
253
|
+
if 'file' not in request.files:
|
254
|
+
return jsonify({'error': 'No file provided'}), 400
|
255
|
+
|
256
|
+
file = request.files['file']
|
257
|
+
if file.filename == '':
|
258
|
+
return jsonify({'error': 'No file selected'}), 400
|
259
|
+
|
260
|
+
# Save temporarily
|
261
|
+
temp_path = f'/tmp/{file.filename}'
|
262
|
+
file.save(temp_path)
|
263
|
+
|
264
|
+
try:
|
265
|
+
result = client.upload_file(temp_path)
|
266
|
+
os.remove(temp_path) # Clean up
|
267
|
+
return jsonify(result.json())
|
268
|
+
except Exception as e:
|
269
|
+
os.remove(temp_path) # Clean up on error
|
270
|
+
return jsonify({'error': str(e)}), 500
|
271
|
+
|
272
|
+
@app.route('/files', methods=['GET'])
|
273
|
+
def list_files():
|
274
|
+
try:
|
275
|
+
result = client.list_uploads()
|
276
|
+
return jsonify(result.json())
|
277
|
+
except Exception as e:
|
278
|
+
return jsonify({'error': str(e)}), 500
|
279
|
+
```
|
280
|
+
|
281
|
+
### FastAPI Integration
|
282
|
+
```python
|
283
|
+
from fastapi import FastAPI, File, UploadFile, HTTPException
|
284
|
+
from pinarkive_client import PinarkiveClient
|
285
|
+
import tempfile
|
286
|
+
import os
|
287
|
+
|
288
|
+
app = FastAPI()
|
289
|
+
client = PinarkiveClient(api_key=os.environ.get('PINARKIVE_API_KEY'))
|
290
|
+
|
291
|
+
@app.post("/upload")
|
292
|
+
async def upload_file(file: UploadFile = File(...)):
|
293
|
+
# Create temporary file
|
294
|
+
with tempfile.NamedTemporaryFile(delete=False) as temp_file:
|
295
|
+
content = await file.read()
|
296
|
+
temp_file.write(content)
|
297
|
+
temp_file.flush()
|
298
|
+
|
299
|
+
try:
|
300
|
+
result = client.upload_file(temp_file.name)
|
301
|
+
os.unlink(temp_file.name) # Clean up
|
302
|
+
return result.json()
|
303
|
+
except Exception as e:
|
304
|
+
os.unlink(temp_file.name) # Clean up on error
|
305
|
+
raise HTTPException(status_code=500, detail=str(e))
|
306
|
+
|
307
|
+
@app.get("/files")
|
308
|
+
async def list_files(page: int = 1, limit: int = 10):
|
309
|
+
try:
|
310
|
+
result = client.list_uploads(page=page, limit=limit)
|
311
|
+
return result.json()
|
312
|
+
except Exception as e:
|
313
|
+
raise HTTPException(status_code=500, detail=str(e))
|
314
|
+
```
|
315
|
+
|
316
|
+
## API Reference
|
317
|
+
|
318
|
+
### Constructor
|
319
|
+
```python
|
320
|
+
PinarkiveClient(token: Optional[str] = None, api_key: Optional[str] = None, base_url: str = 'https://api.pinarkive.com/api/v2')
|
321
|
+
```
|
322
|
+
- `token`: Optional JWT token for authentication
|
323
|
+
- `api_key`: Optional API key for authentication
|
324
|
+
- `base_url`: Base URL for the API (defaults to production)
|
325
|
+
|
326
|
+
### File Operations
|
327
|
+
- `upload_file(file_path: str)` - Upload single file
|
328
|
+
- `upload_directory(dir_path: str)` - Upload directory from path
|
329
|
+
- `upload_directory_dag(files_dict: Dict[str, Any], dir_name: Optional[str] = None)` - Upload directory as DAG
|
330
|
+
- `upload_directory_cluster(files: List[Dict[str, Any]])` - Upload directory using cluster
|
331
|
+
- `upload_file_to_directory(file_path: str, dir_path: str)` - Add file to existing directory
|
332
|
+
- `rename_file(upload_id: str, new_name: str)` - Rename uploaded file
|
333
|
+
- `remove_file(cid: str)` - Remove file from storage
|
334
|
+
|
335
|
+
### Pinning Operations
|
336
|
+
- `pin_cid(cid: str)` - Pin CID to account
|
337
|
+
- `pin_cid_with_name(cid: str, custom_name: Optional[str] = None)` - Pin CID with custom name
|
338
|
+
|
339
|
+
### User Operations
|
340
|
+
- `get_profile()` - Get user profile
|
341
|
+
- `update_profile(data: Dict[str, Any])` - Update user profile
|
342
|
+
- `list_uploads(page: int = 1, limit: int = 10)` - List uploaded files
|
343
|
+
- `get_referrals()` - Get referral information
|
344
|
+
|
345
|
+
### Token Management
|
346
|
+
- `generate_token(name: str, options: Optional[Dict[str, Any]] = None)` - Generate API key
|
347
|
+
- `list_tokens()` - List all API keys
|
348
|
+
- `revoke_token(name: str)` - Revoke API key
|
349
|
+
|
350
|
+
### Authentication
|
351
|
+
- `login(email: str, password: str)` - Login with credentials
|
352
|
+
- `signup(data: Dict[str, Any], locale: Optional[str] = None, refCode: Optional[str] = None)` - Create new account
|
353
|
+
- `logout()` - Logout current session
|
354
|
+
|
355
|
+
### Status & Monitoring
|
356
|
+
- `get_status(cid: str)` - Get file status
|
357
|
+
- `get_allocations(cid: str)` - Get storage allocations
|
358
|
+
|
359
|
+
## Examples
|
360
|
+
|
361
|
+
### Complete File Management Workflow
|
362
|
+
```python
|
363
|
+
from pinarkive_client import PinarkiveClient
|
364
|
+
|
365
|
+
def manage_files():
|
366
|
+
client = PinarkiveClient(api_key="your-api-key")
|
367
|
+
|
368
|
+
try:
|
369
|
+
# 1. Upload a file
|
370
|
+
result = client.upload_file("document.pdf")
|
371
|
+
upload_data = result.json()
|
372
|
+
print(f"Uploaded: {upload_data['cid']}")
|
373
|
+
|
374
|
+
# 2. Pin the CID with a custom name
|
375
|
+
pin_result = client.pin_cid_with_name(upload_data['cid'], "important-document")
|
376
|
+
print(f"Pinned: {pin_result.json()['pinned']}")
|
377
|
+
|
378
|
+
# 3. Rename the file
|
379
|
+
if 'uploadId' in upload_data:
|
380
|
+
rename_result = client.rename_file(upload_data['uploadId'], "my-document.pdf")
|
381
|
+
print(f"Renamed: {rename_result.json()['updated']}")
|
382
|
+
|
383
|
+
# 4. List all uploads
|
384
|
+
uploads = client.list_uploads()
|
385
|
+
print(f"All uploads: {uploads.json()['uploads']}")
|
386
|
+
|
387
|
+
except Exception as e:
|
388
|
+
print(f"Error: {e}")
|
389
|
+
|
390
|
+
manage_files()
|
391
|
+
```
|
392
|
+
|
393
|
+
### Directory Upload Workflow
|
394
|
+
```python
|
395
|
+
def upload_project():
|
396
|
+
client = PinarkiveClient(api_key="your-api-key")
|
397
|
+
|
398
|
+
# Create project structure
|
399
|
+
project_files = {
|
400
|
+
"src/main.py": "print('Hello World')",
|
401
|
+
"src/utils.py": "def helper(): pass",
|
402
|
+
"requirements.txt": "requests>=2.31.0",
|
403
|
+
"README.md": "# My Project\n\nThis is my project."
|
404
|
+
}
|
405
|
+
|
406
|
+
try:
|
407
|
+
result = client.upload_directory_dag(project_files, dir_name="my-project")
|
408
|
+
response_data = result.json()
|
409
|
+
print(f"Project uploaded: {response_data['dagCid']}")
|
410
|
+
print(f"Files: {response_data['files']}")
|
411
|
+
except Exception as e:
|
412
|
+
print(f"Upload failed: {e}")
|
413
|
+
|
414
|
+
upload_project()
|
415
|
+
```
|
416
|
+
|
417
|
+
### Batch File Processing
|
418
|
+
```python
|
419
|
+
import os
|
420
|
+
from pathlib import Path
|
421
|
+
|
422
|
+
def upload_directory_contents(directory_path: str):
|
423
|
+
client = PinarkiveClient(api_key="your-api-key")
|
424
|
+
|
425
|
+
files_dict = {}
|
426
|
+
directory = Path(directory_path)
|
427
|
+
|
428
|
+
# Recursively collect all files
|
429
|
+
for file_path in directory.rglob('*'):
|
430
|
+
if file_path.is_file():
|
431
|
+
# Get relative path from directory
|
432
|
+
relative_path = str(file_path.relative_to(directory))
|
433
|
+
|
434
|
+
# Read file content
|
435
|
+
with open(file_path, 'r', encoding='utf-8') as f:
|
436
|
+
content = f.read()
|
437
|
+
|
438
|
+
files_dict[relative_path] = content
|
439
|
+
|
440
|
+
try:
|
441
|
+
result = client.upload_directory_dag(files_dict, dir_name=directory.name)
|
442
|
+
print(f"Directory uploaded: {result.json()['dagCid']}")
|
443
|
+
except Exception as e:
|
444
|
+
print(f"Upload failed: {e}")
|
445
|
+
|
446
|
+
# Usage
|
447
|
+
upload_directory_contents("./my-project")
|
448
|
+
```
|
449
|
+
|
450
|
+
## Support
|
451
|
+
|
452
|
+
For issues or questions:
|
453
|
+
- GitHub Issues: [https://github.com/pinarkive/pinarkive-sdk/issues](https://github.com/pinarkive/pinarkive-sdk/issues)
|
454
|
+
- API Documentation: [https://api.pinarkive.com/docs](https://api.pinarkive.com/docs)
|
455
|
+
- Contact: [https://pinarkive.com/docs.php](https://pinarkive.com/docs.php)
|
@@ -0,0 +1,5 @@
|
|
1
|
+
pinarkive_client.py,sha256=okSNK0lkdjHCSC0cq6gDuxhq3sdAljNqCrX1ld7k1IY,9512
|
2
|
+
pinarkive_sdk-2.1.46.dist-info/METADATA,sha256=XnQn4i-BfVlMi-h1ThDERk4dpxg7hdsZznBT63Nl3jA,13885
|
3
|
+
pinarkive_sdk-2.1.46.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
4
|
+
pinarkive_sdk-2.1.46.dist-info/top_level.txt,sha256=kTyDY8vHnwgnB2cDHiBBLTnXN0-u2nD71SsSdVIC8bI,17
|
5
|
+
pinarkive_sdk-2.1.46.dist-info/RECORD,,
|
@@ -1,44 +0,0 @@
|
|
1
|
-
Metadata-Version: 2.4
|
2
|
-
Name: pinarkive-sdk
|
3
|
-
Version: 2.0.0
|
4
|
-
Summary: Python SDK for the Pinarkive API (v2.0)
|
5
|
-
Author: ITCS VIP, Joel_da
|
6
|
-
License: MIT
|
7
|
-
Project-URL: Homepage, https://github.com/pinarkive/pinarkive-sdk
|
8
|
-
Project-URL: Repository, https://github.com/pinarkive/pinarkive-sdk.git
|
9
|
-
Requires-Python: >=3.7
|
10
|
-
Description-Content-Type: text/markdown
|
11
|
-
Requires-Dist: requests>=2.31.0
|
12
|
-
|
13
|
-
# Pinarkive Python SDK
|
14
|
-
|
15
|
-
Python client for the Pinarkive API.
|
16
|
-
|
17
|
-
## Installation
|
18
|
-
|
19
|
-
```
|
20
|
-
pip install requests
|
21
|
-
```
|
22
|
-
|
23
|
-
Copy `pinarkive_client.py` to your project or install from your repository if you publish it.
|
24
|
-
|
25
|
-
## Usage
|
26
|
-
|
27
|
-
```python
|
28
|
-
from pinarkive_client import PinarkiveClient
|
29
|
-
|
30
|
-
client = PinarkiveClient(api_key='YOUR_API_KEY')
|
31
|
-
|
32
|
-
# Upload a file
|
33
|
-
client.upload_file('document.pdf')
|
34
|
-
|
35
|
-
# List files
|
36
|
-
client.list_uploads()
|
37
|
-
```
|
38
|
-
|
39
|
-
## Authentication
|
40
|
-
- JWT: `token='...'`
|
41
|
-
- API Key: `api_key='...'`
|
42
|
-
|
43
|
-
## Documentation
|
44
|
-
See [https://api.pinarkive.com/docs](https://api.pinarkive.com/docs)
|
@@ -1,5 +0,0 @@
|
|
1
|
-
pinarkive_client.py,sha256=dhIoH6PnMprjTDfihe7SA40RKyX5-S-sXX2wETwDArg,4511
|
2
|
-
pinarkive_sdk-2.0.0.dist-info/METADATA,sha256=gyp_bpQheyX59nj4pTuFutstGT5yeGsHwdSxd4rvlsY,989
|
3
|
-
pinarkive_sdk-2.0.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
4
|
-
pinarkive_sdk-2.0.0.dist-info/top_level.txt,sha256=kTyDY8vHnwgnB2cDHiBBLTnXN0-u2nD71SsSdVIC8bI,17
|
5
|
-
pinarkive_sdk-2.0.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|