Python SDK for the Pinarkive API v2.3.1 - Easy IPFS file management with directory DAG uploads, file renaming, and enhanced API key management. Includes type hints for better IDE support.
Reason this release was yanked:
Deprecated. Please upgrade to 3.0.x – this version uses the deprecated API v2.
Project description
Pinarkive Python SDK
Python client for the Pinarkive API v2.3.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.
Installation
pip install pinarkive-sdk-py
Quick Start
from pinarkive_client import PinarkiveClient
# Initialize with API key
client = PinarkiveClient(api_key="your-api-key-here")
# Upload a file
result = client.upload_file("document.pdf")
print(f"File uploaded: {result.json()['cid']}")
# Generate API key
token = client.generate_token("my-app", {
"expires_in_days": 30
})
print(f"New API key: {token.json()['token']}")
Authentication
The SDK supports two authentication methods:
API Key Authentication (Recommended)
client = PinarkiveClient(api_key="your-api-key-here")
Note: The SDK automatically sends the API key using the Authorization: Bearer header format, not X-API-Key.
JWT Token Authentication
client = PinarkiveClient(token="your-jwt-token-here")
Basic Usage
File Upload
# Upload single file
result = client.upload_file("document.pdf")
response_data = result.json()
print(f"CID: {response_data['cid']}")
print(f"Status: {response_data['status']}")
Directory Upload
# Upload directory from local path
result = client.upload_directory("/path/to/directory")
print(f"Directory CID: {result.json()['cid']}")
List Uploads
# List all uploaded files with pagination
result = client.list_uploads(page=1, limit=20)
response_data = result.json()
print(f"Uploads: {response_data['uploads']}")
print(f"Total: {response_data['pagination']['total']}")
Advanced Features
Directory DAG Upload
Upload entire directory structures as DAG (Directed Acyclic Graph):
# Create project structure
project_files = {
"src/index.py": "print('Hello World')",
"src/utils.py": "def utils(): pass",
"requirements.txt": "requests>=2.31.0",
"README.md": "# My Project\n\nThis is my project."
}
# Upload as DAG
result = client.upload_directory_dag(project_files, dir_name="my-project")
response_data = result.json()
print(f"DAG CID: {response_data['dagCid']}")
print(f"Files: {response_data['files']}")
Directory Cluster Upload
# Upload using cluster-based approach
files = [
{"path": "file1.txt", "content": "Content 1"},
{"path": "file2.txt", "content": "Content 2"}
]
result = client.upload_directory_cluster(files)
print(f"Cluster CID: {result.json()['cid']}")
Upload File to Existing Directory
# Add file to existing directory
result = client.upload_file_to_directory("new-file.txt", "existing-directory-path")
print(f"File added to directory: {result.json()['cid']}")
File Renaming
# Rename an uploaded file
result = client.rename_file("upload-id-here", "new-file-name.pdf")
print(f"File renamed: {result.json()['updated']}")
File Removal
# Remove a file from storage
result = client.remove_file("QmYourCIDHere")
print(f"File removed: {result.json()['success']}")
Pinning Operations
Basic CID Pinning
# Pin with filename
result = client.pin_cid("QmYourCIDHere", "my-file.pdf")
print(f"CID pinned: {result.json()['pinned']}")
# Pin without filename (backend will use default)
result2 = client.pin_cid("QmYourCIDHere")
print(f"CID pinned: {result2.json()['pinned']}")
Pin with Custom Name
result = client.pin_cid_with_name("QmYourCIDHere", "my-important-file")
print(f"CID pinned with name: {result.json()['pinned']}")
API Key Management
Generate API Key
# Basic token generation
token = client.generate_token("my-app")
# Advanced token with options
token = client.generate_token("my-app", {
"expires_in_days": 30,
"ip_allowlist": ["192.168.1.1", "10.0.0.1"],
"permissions": ["upload", "pin"]
})
print(f"New API key: {token.json()['token']}")
List API Keys
tokens = client.list_tokens()
print(f"API Keys: {tokens.json()['tokens']}")
Revoke API Key
result = client.revoke_token("my-app")
print(f"Token revoked: {result.json()['revoked']}")
Type Hints Support
The SDK includes comprehensive type hints for better IDE support:
from typing import Dict, Any, Optional
from pinarkive_client import PinarkiveClient
# Type hints provide better autocomplete and error checking
client = PinarkiveClient(api_key="your-key")
# IDE will show parameter types and return types
def upload_project_files(files: Dict[str, str]) -> Any:
return client.upload_directory_dag(files, dir_name="project")
# Type hints for options
token_options: Dict[str, Any] = {
"expires_in_days": 30,
"ip_allowlist": ["192.168.1.1"]
}
token = client.generate_token("my-app", token_options)
Error Handling
import requests
try:
result = client.upload_file("document.pdf")
print("Success:", result.json())
except requests.exceptions.RequestException as e:
if hasattr(e, 'response') and e.response is not None:
print(f"API Error: {e.response.status_code}")
print(f"Response: {e.response.json()}")
else:
print(f"Network Error: {e}")
Integration Examples
Django Integration
# views.py
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from pinarkive_client import PinarkiveClient
import json
@csrf_exempt
def upload_file(request):
if request.method == 'POST':
client = PinarkiveClient(api_key=settings.PINARKIVE_API_KEY)
uploaded_file = request.FILES['file']
# Save temporarily
with open(f'/tmp/{uploaded_file.name}', 'wb+') as destination:
for chunk in uploaded_file.chunks():
destination.write(chunk)
try:
result = client.upload_file(f'/tmp/{uploaded_file.name}')
return JsonResponse(result.json())
except Exception as e:
return JsonResponse({'error': str(e)}, status=500)
return JsonResponse({'error': 'Method not allowed'}, status=405)
Flask Integration
from flask import Flask, request, jsonify
from pinarkive_client import PinarkiveClient
import os
app = Flask(__name__)
client = PinarkiveClient(api_key=os.environ.get('PINARKIVE_API_KEY'))
@app.route('/upload', methods=['POST'])
def upload_file():
if 'file' not in request.files:
return jsonify({'error': 'No file provided'}), 400
file = request.files['file']
if file.filename == '':
return jsonify({'error': 'No file selected'}), 400
# Save temporarily
temp_path = f'/tmp/{file.filename}'
file.save(temp_path)
try:
result = client.upload_file(temp_path)
os.remove(temp_path) # Clean up
return jsonify(result.json())
except Exception as e:
os.remove(temp_path) # Clean up on error
return jsonify({'error': str(e)}), 500
@app.route('/files', methods=['GET'])
def list_files():
try:
result = client.list_uploads()
return jsonify(result.json())
except Exception as e:
return jsonify({'error': str(e)}), 500
FastAPI Integration
from fastapi import FastAPI, File, UploadFile, HTTPException
from pinarkive_client import PinarkiveClient
import tempfile
import os
app = FastAPI()
client = PinarkiveClient(api_key=os.environ.get('PINARKIVE_API_KEY'))
@app.post("/upload")
async def upload_file(file: UploadFile = File(...)):
# Create temporary file
with tempfile.NamedTemporaryFile(delete=False) as temp_file:
content = await file.read()
temp_file.write(content)
temp_file.flush()
try:
result = client.upload_file(temp_file.name)
os.unlink(temp_file.name) # Clean up
return result.json()
except Exception as e:
os.unlink(temp_file.name) # Clean up on error
raise HTTPException(status_code=500, detail=str(e))
@app.get("/files")
async def list_files(page: int = 1, limit: int = 10):
try:
result = client.list_uploads(page=page, limit=limit)
return result.json()
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
API Reference
Constructor
PinarkiveClient(token: Optional[str] = None, api_key: Optional[str] = None, base_url: str = 'https://api.pinarkive.com/api/v2')
token: Optional JWT token for authenticationapi_key: Optional API key for authenticationbase_url: Base URL for the API (defaults to production)
File Operations
uploadFile(file_path: str)- Upload single fileuploadDirectory(dir_path: str)- Upload directory recursively (calls uploadFile for each file)uploadDirectoryDAG(files_dict: Dict[str, Any], dir_name: Optional[str] = None)- Upload directory as DAG structurerenameFile(upload_id: str, new_name: str)- Rename uploaded fileremoveFile(cid: str)- Remove file from storage
Pinning Operations
pinCid(cid: str, filename: Optional[str] = None)- Pin CID to account with optional filename
User Operations
listUploads(page: int = 1, limit: int = 10)- List uploaded files
Token Management
generateToken(name: str, options: Optional[Dict[str, Any]] = None)- Generate API keylistTokens()- List all API keysrevokeToken(name: str)- Revoke API key
Status & Monitoring
getStatus(cid: str)- Get file statusgetAllocations(cid: str)- Get storage allocations
Examples
Complete File Management Workflow
from pinarkive_client import PinarkiveClient
def manage_files():
client = PinarkiveClient(api_key="your-api-key")
try:
# 1. Upload a file
result = client.upload_file("document.pdf")
upload_data = result.json()
print(f"Uploaded: {upload_data['cid']}")
# 2. Pin the CID with a custom name
pin_result = client.pin_cid_with_name(upload_data['cid'], "important-document")
print(f"Pinned: {pin_result.json()['pinned']}")
# 3. Rename the file
if 'uploadId' in upload_data:
rename_result = client.rename_file(upload_data['uploadId'], "my-document.pdf")
print(f"Renamed: {rename_result.json()['updated']}")
# 4. List all uploads
uploads = client.list_uploads()
print(f"All uploads: {uploads.json()['uploads']}")
except Exception as e:
print(f"Error: {e}")
manage_files()
Directory Upload Workflow
def upload_project():
client = PinarkiveClient(api_key="your-api-key")
# Create project structure
project_files = {
"src/main.py": "print('Hello World')",
"src/utils.py": "def helper(): pass",
"requirements.txt": "requests>=2.31.0",
"README.md": "# My Project\n\nThis is my project."
}
try:
result = client.upload_directory_dag(project_files, dir_name="my-project")
response_data = result.json()
print(f"Project uploaded: {response_data['dagCid']}")
print(f"Files: {response_data['files']}")
except Exception as e:
print(f"Upload failed: {e}")
upload_project()
Batch File Processing
import os
from pathlib import Path
def upload_directory_contents(directory_path: str):
client = PinarkiveClient(api_key="your-api-key")
files_dict = {}
directory = Path(directory_path)
# Recursively collect all files
for file_path in directory.rglob('*'):
if file_path.is_file():
# Get relative path from directory
relative_path = str(file_path.relative_to(directory))
# Read file content
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
files_dict[relative_path] = content
try:
result = client.upload_directory_dag(files_dict, dir_name=directory.name)
print(f"Directory uploaded: {result.json()['dagCid']}")
except Exception as e:
print(f"Upload failed: {e}")
# Usage
upload_directory_contents("./my-project")
Publishing Instructions
Publishing to PyPI
This package is published to PyPI using the following process:
# Update version in pyproject.toml
python -m build
twine upload dist/*
Development Build
For testing before publishing:
# Build the package
python -m build
# Upload to TestPyPI for testing
twine upload --repository testpypi dist/*
# Install from TestPyPI to test
pip install --index-url https://test.pypi.org/simple/ pinarkive-sdk-py
Version Management
- Update version in
pyproject.toml - Build the package with
python -m build - Upload to PyPI with
twine upload dist/* - Tag the release in git:
git tag v2.3.1 && git push origin v2.3.1
PyPI Best Practices
- Use semantic versioning (2.3.1, 2.4.0, etc.)
- Test on TestPyPI before publishing to production
- Include comprehensive README and documentation
- Use proper classifiers in pyproject.toml
Support
For issues or questions:
- GitHub Issues: https://github.com/pinarkive/pinarkive-sdk-py/issues
- API Documentation: https://api.pinarkive.com/docs
- Contact: https://pinarkive.com/docs.php
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pinarkive_sdk_py-2.3.1.tar.gz.
File metadata
- Download URL: pinarkive_sdk_py-2.3.1.tar.gz
- Upload date:
- Size: 6.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e1f91ab035394dfd8642974e381854c7afe5705d3b4906550eed7930ecd455c7
|
|
| MD5 |
bd9583e6bc9186a29cd030d58db9756c
|
|
| BLAKE2b-256 |
ab72f42dcccc8a7802ce5f70733b2b33a6000c04a249539bb0f6d33336ea48de
|
File details
Details for the file pinarkive_sdk_py-2.3.1-py3-none-any.whl.
File metadata
- Download URL: pinarkive_sdk_py-2.3.1-py3-none-any.whl
- Upload date:
- Size: 6.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
13af5485d2e2133cc737b19bd5550c5229092ef6de7ed03239ccf50f35ae2055
|
|
| MD5 |
0e337546617191164b4d151ac4851f7e
|
|
| BLAKE2b-256 |
ecc9e320652f63a52ca993512fda7b609590434ad1c040005d48b6113292fa62
|