· Nacho Coll · Tutorials · 9 Min. Lesezeit
Python IPFS Upload: Vollständiger Leitfaden mit Code-Beispielen
Lade Dateien von Python zu IPFS hoch mit der IPFS.NINJA REST API. Vollständiger Leitfaden mit Beispielen der requests-Bibliothek.

Python-Entwickler, die Dateien zu IPFS hochladen möchten, müssen keinen lokalen IPFS-Knoten betreiben oder mit komplexen Bibliotheksabhängigkeiten umgehen. Während IPFS.NINJA kein dediziertes Python SDK bereitstellt, ist seine REST-API perfekt für Python-Anwendungen geeignet, die die eingebaute requests-Bibliothek verwenden.
Dieser Leitfaden zeigt Ihnen, wie Sie Dateien, Bilder und JSON-Daten von Python zu IPFS hochladen, Ihre gepinnten Dateien verwalten und erweiterte Funktionen wie signierte Upload-Token für sichere clientseitige Uploads nutzen können.

Warum IPFS.NINJA für die Python-Entwicklung wählen?
Bevor wir in die Code-Beispiele eintauchen, lassen Sie uns verstehen, warum IPFS.NINJA eine ausgezeichnete Wahl für Python-Entwickler ist:
- Keine SDK-Abhängigkeiten: Verwenden Sie Pythons eingebaute
requests-Bibliothek - RESTful API: Saubere, vorhersehbare Endpunkte, die HTTP-Standards folgen
- JSON-nativ: Lade JSON-Daten direkt ohne Dateikonvertierung hoch
- Mehrere Authentifizierungsmethoden: API-Schlüssel, signierte Token oder JWT
- Eingebaute Analytics: Verfolge Upload-Performance und Nutzung
- Benutzerdefinierte Gateways: Branded IPFS-Zugriff für deine Anwendungen
Wenn Sie neu bei IPFS-Pinning-Konzepten sind, lesen Sie unseren umfassenden Leitfaden, was IPFS-Pinning ist und wie man Dateien auf IPFS hochlädt.
Einrichten Ihrer Python-Umgebung
Stellen Sie zunächst sicher, dass Sie Python 3.6+ haben und installieren Sie die erforderlichen Bibliotheken:
pip install requestsFür Bildverarbeitungsbeispiele später in diesem Leitfaden:
pip install Pillow # Für die BildverarbeitungAuthentifizierungs-Setup
Alle IPFS.NINJA-API-Aufrufe erfordern Authentifizierung. Die einfachste Methode für Python-Anwendungen ist die Verwendung von API-Schlüsseln mit dem X-Api-Key-Header.
import requests
import json
import base64
# Ihr IPFS.NINJA API-Schlüssel (Format: bws_ + 32 Hex-Zeichen)
API_KEY = "bws_1234567890abcdef1234567890abcdef"
BASE_URL = "https://api.ipfs.ninja"
# Standard-Header für alle Anfragen
headers = {
"X-Api-Key": API_KEY,
"Content-Type": "application/json"
}Erhalten Sie Ihren API-Schlüssel über das IPFS.NINJA-Dashboard, nachdem Sie Ihr Konto erstellt haben.
Hochladen von JSON-Daten zu IPFS
Eine der einzigartigen Funktionen von IPFS.NINJA ist die native JSON-Unterstützung. Sie müssen JSON nicht in Dateien konvertieren — laden Sie Objekte direkt hoch:
def upload_json_to_ipfs(data, description=None, metadata=None):
"""
JSON-Daten direkt zu IPFS hochladen
Args:
data (dict): Die hochzuladenden JSON-Daten
description (str, optional): Beschreibung für die Datei
metadata (dict, optional): Zusätzliche Metadaten
Returns:
dict: Antwort mit CID und Zugriffs-URLs
"""
payload = {
"content": data,
"description": description,
"metadata": metadata
}
response = requests.post(
f"{BASE_URL}/upload/new",
headers=headers,
json=payload
)
if response.status_code == 200:
return response.json()
else:
raise Exception(f"Upload failed: {response.status_code} - {response.text}")
# Beispiel: Benutzerprofil hochladen
user_profile = {
"name": "Alice Smith",
"bio": "Python developer and IPFS enthusiast",
"website": "https://alice.dev",
"social": {
"github": "alicesmith",
"twitter": "@alice_dev"
}
}
try:
result = upload_json_to_ipfs(
data=user_profile,
description="User profile for Alice Smith",
metadata={"type": "profile", "version": "1.0"}
)
print(f"✅ Upload successful!")
print(f"CID: {result['cid']}")
print(f"Size: {result['sizeMB']} MB")
print(f"IPFS URL: {result['uris']['ipfs']}")
print(f"Gateway URL: {result['uris']['url']}")
except Exception as e:
print(f"❌ Upload failed: {e}")Hochladen von Dateien mit Base64-Kodierung
Für Binärdateien wie Bilder, Dokumente oder jeden Dateityp verwenden Sie Base64-Kodierung:
def upload_file_to_ipfs(file_path, description=None, metadata=None):
"""
Eine Datei mit Base64-Kodierung zu IPFS hochladen
Args:
file_path (str): Pfad zur hochzuladenden Datei
description (str, optional): Beschreibung für die Datei
metadata (dict, optional): Zusätzliche Metadaten
Returns:
dict: Antwort mit CID und Zugriffs-URLs
"""
try:
with open(file_path, "rb") as file:
file_content = base64.b64encode(file.read()).decode('utf-8')
payload = {
"content": file_content,
"description": description or f"File upload: {file_path}",
"metadata": metadata
}
response = requests.post(
f"{BASE_URL}/upload/new",
headers=headers,
json=payload
)
if response.status_code == 200:
return response.json()
else:
raise Exception(f"Upload failed: {response.status_code} - {response.text}")
except FileNotFoundError:
raise Exception(f"File not found: {file_path}")
# Beispiel: Ein Bild hochladen
try:
result = upload_file_to_ipfs(
file_path="./logo.png",
description="Company logo",
metadata={
"type": "image",
"format": "png",
"purpose": "branding"
}
)
print(f"✅ Image uploaded successfully!")
print(f"CID: {result['cid']}")
print(f"View at: {result['uris']['url']}")
except Exception as e:
print(f"❌ Upload failed: {e}")Batch-Upload-Funktion
Für effizientes Hochladen mehrerer Dateien:
import os
from pathlib import Path
def batch_upload_files(directory_path, file_extensions=None):
"""
Mehrere Dateien aus einem Verzeichnis hochladen
Args:
directory_path (str): Verzeichnis mit hochzuladenden Dateien
file_extensions (list, optional): Nach Dateierweiterungen filtern (z.B., ['.png', '.jpg'])
Returns:
list: Ergebnisse von jedem Upload
"""
results = []
directory = Path(directory_path)
if not directory.exists():
raise Exception(f"Directory not found: {directory_path}")
# Alle Dateien holen oder nach Erweiterungen filtern
if file_extensions:
files = []
for ext in file_extensions:
files.extend(directory.glob(f"*{ext}"))
else:
files = [f for f in directory.iterdir() if f.is_file()]
print(f"Found {len(files)} files to upload...")
for file_path in files:
try:
print(f"Uploading {file_path.name}...")
result = upload_file_to_ipfs(
file_path=str(file_path),
description=f"Batch upload: {file_path.name}",
metadata={
"batch_upload": True,
"original_name": file_path.name,
"file_size": file_path.stat().st_size
}
)
results.append({
"filename": file_path.name,
"success": True,
"cid": result['cid'],
"url": result['uris']['url']
})
except Exception as e:
results.append({
"filename": file_path.name,
"success": False,
"error": str(e)
})
print(f"Failed to upload {file_path.name}: {e}")
return results
# Beispiel-Verwendung
try:
results = batch_upload_files("./images", file_extensions=['.png', '.jpg', '.jpeg'])
successful = [r for r in results if r['success']]
failed = [r for r in results if not r['success']]
print(f"\n✅ Successfully uploaded: {len(successful)} files")
print(f"❌ Failed uploads: {len(failed)} files")
for result in successful:
print(f" - {result['filename']}: {result['url']}")
except Exception as e:
print(f"Batch upload error: {e}")Verwalten Ihrer gepinnten Dateien
Abrufen und Verwalten Ihrer hochgeladenen Dateien:
def list_pinned_files(limit=50, offset=0):
"""
Ihre gepinnten Dateien auflisten
Args:
limit (int): Anzahl der abzurufenden Dateien (max. 100)
offset (int): Anzahl der zu überspringenden Dateien
Returns:
dict: Antwort mit Dateiliste und Paginierung
"""
params = {
"limit": limit,
"offset": offset
}
response = requests.get(
f"{BASE_URL}/files",
headers=headers,
params=params
)
if response.status_code == 200:
return response.json()
else:
raise Exception(f"Failed to list files: {response.status_code} - {response.text}")
def get_file_details(cid):
"""
Details für eine bestimmte Datei abrufen
Args:
cid (str): Der Content Identifier der Datei
Returns:
dict: Dateidetails
"""
response = requests.get(
f"{BASE_URL}/files/{cid}",
headers=headers
)
if response.status_code == 200:
return response.json()
else:
raise Exception(f"Failed to get file details: {response.status_code} - {response.text}")
# Beispiel: Aktuelle Uploads auflisten
try:
files = list_pinned_files(limit=10)
print(f"Total files: {files.get('total', 0)}")
print("\nRecent uploads:")
for file_info in files.get('files', []):
print(f" - {file_info['cid'][:12]}... | {file_info['sizeMB']} MB | {file_info['description']}")
except Exception as e:
print(f"Failed to list files: {e}")Vorhandene IPFS-Inhalte pinnen
Pinne Inhalte, die bereits auf IPFS existieren:
def pin_existing_cid(cid, description=None):
"""
Vorhandene IPFS-Inhalte per CID pinnen
Args:
cid (str): Der zu pinnende Content Identifier
description (str, optional): Beschreibung für den gepinnten Inhalt
Returns:
dict: Antwort mit Pin-Status
"""
payload = {
"cid": cid,
"description": description or f"Pinned existing content: {cid}"
}
response = requests.post(
f"{BASE_URL}/pin",
headers=headers,
json=payload
)
if response.status_code == 200:
return response.json()
else:
raise Exception(f"Pin failed: {response.status_code} - {response.text}")
# Beispiel: Beliebte NFT-Metadaten pinnen
try:
result = pin_existing_cid(
cid="QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG",
description="Popular NFT metadata backup"
)
print(f"✅ Successfully pinned existing content!")
print(f"CID: {result['cid']}")
except Exception as e:
print(f"❌ Pin failed: {e}")Verwenden von signierten Upload-Token
Für sichere clientseitige Uploads oder temporären Zugriff verwenden Sie signierte Token:
def create_upload_token(expires_in_hours=24, max_uses=None):
"""
Einen signierten Upload-Token für temporäre Uploads erstellen
Args:
expires_in_hours (int): Ablaufzeit des Tokens in Stunden
max_uses (int, optional): Maximale Anzahl von Verwendungen (unbegrenzt wenn None)
Returns:
dict: Token-Details einschließlich der signierten Token-Zeichenfolge
"""
from datetime import datetime, timedelta
expiry_time = datetime.utcnow() + timedelta(hours=expires_in_hours)
payload = {
"expiry": expiry_time.isoformat() + "Z",
"maxUses": max_uses
}
response = requests.post(
f"{BASE_URL}/upload-tokens",
headers=headers,
json=payload
)
if response.status_code == 200:
return response.json()
else:
raise Exception(f"Token creation failed: {response.status_code} - {response.text}")
def upload_with_token(data, token, description=None):
"""
Hochladen mit signiertem Token anstelle eines API-Schlüssels
Args:
data: Hochzuladender Inhalt (dict für JSON, base64-String für Dateien)
token (str): Signierter Upload-Token
description (str, optional): Beschreibung für den Upload
Returns:
dict: Upload-Antwort
"""
token_headers = {
"Authorization": f"Signed {token}",
"Content-Type": "application/json"
}
payload = {
"content": data,
"description": description
}
response = requests.post(
f"{BASE_URL}/upload/new",
headers=token_headers,
json=payload
)
if response.status_code == 200:
return response.json()
else:
raise Exception(f"Token upload failed: {response.status_code} - {response.text}")
# Beispiel: Token für clientseitige Uploads erstellen
try:
token_info = create_upload_token(expires_in_hours=1, max_uses=10)
upload_token = token_info['token']
print(f"Created upload token: {upload_token[:20]}...")
print(f"Expires: {token_info['expiry']}")
print(f"Max uses: {token_info.get('maxUses', 'unlimited')}")
# Den Token für einen Upload verwenden
test_data = {"message": "Hello from signed token!"}
result = upload_with_token(test_data, upload_token, "Token test upload")
print(f"✅ Token upload successful: {result['cid']}")
except Exception as e:
print(f"❌ Token operation failed: {e}")Vollständiges Beispiel: NFT-Metadaten-Uploader
Hier ist ein praktisches Beispiel, das mehrere Konzepte für die NFT-Metadaten-Verwaltung kombiniert:
class NFTMetadataUploader:
def __init__(self, api_key):
self.api_key = api_key
self.base_url = "https://api.ipfs.ninja"
self.headers = {
"X-Api-Key": api_key,
"Content-Type": "application/json"
}
def upload_nft_image(self, image_path, name, description=""):
"""NFT-Bild hochladen und IPFS-URL zurückgeben"""
try:
with open(image_path, "rb") as file:
image_content = base64.b64encode(file.read()).decode('utf-8')
payload = {
"content": image_content,
"description": f"NFT Image: {name}",
"metadata": {
"type": "nft_image",
"name": name,
"description": description
}
}
response = requests.post(
f"{self.base_url}/upload/new",
headers=self.headers,
json=payload
)
if response.status_code == 200:
result = response.json()
return result['uris']['ipfs'] # IPFS-URI zurückgeben
else:
raise Exception(f"Image upload failed: {response.text}")
except Exception as e:
raise Exception(f"Failed to upload image {image_path}: {e}")
def upload_nft_metadata(self, name, description, image_ipfs_url, attributes=None, external_url=None):
"""Vollständige NFT-Metadaten hochladen"""
metadata = {
"name": name,
"description": description,
"image": image_ipfs_url,
}
if attributes:
metadata["attributes"] = attributes
if external_url:
metadata["external_url"] = external_url
payload = {
"content": metadata,
"description": f"NFT Metadata: {name}",
"metadata": {
"type": "nft_metadata",
"standard": "ERC-721"
}
}
response = requests.post(
f"{self.base_url}/upload/new",
headers=self.headers,
json=payload
)
if response.status_code == 200:
return response.json()
else:
raise Exception(f"Metadata upload failed: {response.text}")
def create_complete_nft(self, image_path, name, description, attributes=None, external_url=None):
"""Bild und Metadaten für einen vollständigen NFT hochladen"""
print(f"Creating NFT: {name}")
# Schritt 1: Bild hochladen
print(" 1. Uploading image...")
image_ipfs_url = self.upload_nft_image(image_path, name, description)
print(f" Image IPFS URL: {image_ipfs_url}")
# Schritt 2: Metadaten hochladen
print(" 2. Uploading metadata...")
metadata_result = self.upload_nft_metadata(
name=name,
description=description,
image_ipfs_url=image_ipfs_url,
attributes=attributes,
external_url=external_url
)
print(f" Metadata CID: {metadata_result['cid']}")
print(f" Metadata URL: {metadata_result['uris']['url']}")
return {
"image_ipfs": image_ipfs_url,
"metadata_cid": metadata_result['cid'],
"metadata_url": metadata_result['uris']['url'],
"metadata_ipfs": metadata_result['uris']['ipfs']
}
# Beispiel-Verwendung
if __name__ == "__main__":
uploader = NFTMetadataUploader("bws_1234567890abcdef1234567890abcdef")
try:
nft_result = uploader.create_complete_nft(
image_path="./nft_artwork.png",
name="Cosmic Cat #001",
description="A rare cosmic cat exploring the digital universe",
attributes=[
{"trait_type": "Background", "value": "Space"},
{"trait_type": "Species", "value": "Cosmic Cat"},
{"trait_type": "Rarity", "value": "Legendary"},
{"trait_type": "Power Level", "value": 95}
],
external_url="https://myproject.com/nft/1"
)
print("\n🎉 NFT created successfully!")
print(f"Use this metadata URI in your smart contract: {nft_result['metadata_ipfs']}")
except Exception as e:
print(f"❌ NFT creation failed: {e}")Fehlerbehandlung und Best Practices
Implementiere robuste Fehlerbehandlung für Produktionsanwendungen:
import time
from functools import wraps
def retry_on_failure(max_retries=3, delay=1):
"""Decorator zum Wiederholen fehlgeschlagener Uploads"""
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
for attempt in range(max_retries):
try:
return func(*args, **kwargs)
except Exception as e:
if attempt == max_retries - 1:
raise e
print(f"Attempt {attempt + 1} failed: {e}")
print(f"Retrying in {delay} seconds...")
time.sleep(delay)
return None
return wrapper
return decorator
@retry_on_failure(max_retries=3, delay=2)
def robust_upload(file_path, description=None):
"""Hochladen mit automatischem Wiederholungsversuch bei Fehler"""
return upload_file_to_ipfs(file_path, description)
def validate_api_response(response, operation="operation"):
"""API-Antwort validieren und detaillierte Fehlerinfo bereitstellen"""
if response.status_code == 200:
return response.json()
elif response.status_code == 401:
raise Exception(f"Authentication failed for {operation}. Check your API key.")
elif response.status_code == 413:
raise Exception(f"File too large for {operation}. Check your plan limits.")
elif response.status_code == 429:
raise Exception(f"Rate limit exceeded for {operation}. Please wait and retry.")
else:
raise Exception(f"{operation} failed: {response.status_code} - {response.text}")Nächste Schritte
Sie haben jetzt ein komplettes Toolkit zum Hochladen von Dateien zu IPFS von Python aus! Dies deckt ab:
- JSON- und Datei-Uploads mit der IPFS.NINJA-API
- Batch-Verarbeitung für mehrere Dateien
- Dateiverwaltung und Pinnen vorhandener Inhalte
- Sichere Uploads mit signierten Token
- Produktionsreife Fehlerbehandlung
Für weitere fortgeschrittene Funktionen erkunden Sie unsere anderen Leitfäden:
- Vollständiges IPFS-Upload-API-Tutorial für API-Details
- IPFS.NINJA vs Pinata Vergleich, um die Vorteile zu verstehen
- Beste IPFS-Pinning-Services für Service-Vergleiche
Die IPFS.NINJA-API bietet alles, was Sie für Python-basierte IPFS-Anwendungen benötigen, ohne die Komplexität, eine eigene Infrastruktur zu betreiben.
Bereit zum Pinnen? Erstellen Sie ein kostenloses Konto — 50 Dateien, 1 GB Speicher, 2 GB Bandbreite/Monat. Keine Kreditkarte erforderlich.
