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:

ApproachProsCons
Self-hosted nodeFull control, no feesRequires maintenance, single point of failure
Pinning serviceReliable, redundant, easy APIMonthly costs, vendor dependency
Filecoin dealsBlockchain-verified storageComplex 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.

pythonblockchainstorage

See Also