Python IPFS Integration — Core Concepts
Why IPFS matters for Python developers
IPFS solves the permanence problem. Traditional URLs break when servers change or shut down — studies show over 50% of URLs from 10 years ago are dead. IPFS addresses content by its cryptographic hash, meaning the same content always has the same address regardless of where it’s stored. Python developers use IPFS for NFT storage, decentralized app data, scientific dataset distribution, and censorship-resistant publishing.
Content addressing: how CIDs work
Every file on IPFS gets a Content Identifier (CID) — a hash derived from the file’s contents:
QmPK1s3pNYLi9ERiq3BDxKa4XosgWwFRQUydHUtz4YgpqB
CIDs have two versions:
- CIDv0: Starts with
Qm, uses SHA-256, base58 encoded. Legacy but still common. - CIDv1: Starts with
bafy..., supports multiple hash functions, base32 encoded. Modern standard.
The critical property: if you change even one byte of the file, the CID changes completely. This makes IPFS tamper-proof — you can verify that the content you received matches what was originally published.
Adding and retrieving files
Using the IPFS HTTP API
If you’re running a local IPFS node (or connecting to a remote one), the ipfshttpclient library provides a Python interface:
import ipfshttpclient
client = ipfshttpclient.connect("/ip4/127.0.0.1/tcp/5001")
# Add a file
result = client.add("my_document.pdf")
print(f"CID: {result['Hash']}")
# CID: QmPK1s3pNYLi9ERiq3BDxKa4XosgWwFRQUydHUtz4YgpqB
# Add a string directly
result = client.add_str("Hello, IPFS!")
# Retrieve a file
data = client.cat(result)
print(data.decode()) # "Hello, IPFS!"
Using pinning service APIs
Most production apps use pinning services (Pinata, Web3.Storage, NFT.Storage) instead of running their own nodes:
import requests
def pin_to_pinata(file_path, api_key, secret):
url = "https://api.pinata.cloud/pinning/pinFileToIPFS"
headers = {
"pinata_api_key": api_key,
"pinata_secret_api_key": secret,
}
with open(file_path, "rb") as f:
response = requests.post(url, files={"file": f}, headers=headers)
return response.json()["IpfsHash"]
Pinning: keeping files alive
Adding a file to IPFS announces it to the network, but garbage collection will eventually remove unpinned files from individual nodes. Pinning tells a node “keep this file forever, don’t garbage collect it.”
Three pinning approaches:
| Approach | Pros | Cons |
|---|---|---|
| Self-hosted node | Full control, no fees | Requires maintenance, single point of failure |
| Pinning service | Reliable, redundant, easy API | Monthly costs, vendor dependency |
| Filecoin deals | Blockchain-verified storage | Complex setup, retrieval can be slow |
For important data, use multiple pinning providers simultaneously. If one goes down, others still serve the content.
IPFS gateways
Gateways let anyone access IPFS content through regular HTTP, without running a node:
https://ipfs.io/ipfs/QmPK1s3pNYLi9ERiq3BDxKa4XosgWwFRQUydHUtz4YgpqB
https://gateway.pinata.cloud/ipfs/QmPK1s3pNYLi9ERiq3BDxKa4XosgWwFRQUydHUtz4YgpqB
https://cloudflare-ipfs.com/ipfs/QmPK1s3pNYLi9ERiq3BDxKa4XosgWwFRQUydHUtz4YgpqB
Python applications often use gateways for reading (fetching data that’s already on IPFS) and direct API calls for writing (uploading new content).
def fetch_from_ipfs(cid, gateway="https://ipfs.io"):
response = requests.get(f"{gateway}/ipfs/{cid}", timeout=30)
response.raise_for_status()
return response.content
Directory uploads
IPFS supports directories, which is essential for NFT collections and websites:
# Adding a directory creates a wrapping CID
result = client.add("my_directory/", recursive=True)
# Returns a list: individual file CIDs + directory CID
# Access files within the directory:
# ipfs://<directory-CID>/filename.json
The directory CID acts as a base path. For NFT collections, this means one CID serves all 10,000 metadata files: ipfs://QmDir.../0.json, ipfs://QmDir.../1.json, etc.
Common misconception
Many developers treat IPFS like a database — uploading data and expecting to update it later. IPFS is immutable by design. If you change a file, it gets a new CID. For mutable references, use IPNS (InterPlanetary Name System), which maps a persistent name to a changing CID, similar to how domain names map to changing IP addresses.
One thing to remember
IPFS gives Python applications content-addressed storage where files are identified by their cryptographic fingerprint — making data verifiable and location-independent, but permanence depends on pinning rather than being automatic.
See Also
- Python Blockchain Data Analysis How Python detectives read the blockchain's public ledger to find patterns, explained with a library guest book analogy.
- Python Crypto Trading Bots How Python programs trade cryptocurrency automatically while you sleep, explained with a lemonade stand price watcher.
- Python Defi Protocol Integration How Python connects to decentralized finance protocols, explained through a self-service banking analogy.
- Python Nft Metadata Generation How Python creates the descriptions and images behind NFT collections, told through a trading card factory story.
- Python Smart Contract Testing Why testing blockchain programs with Python matters, explained through a vending machine story anyone can follow.