Decentralized File Storage with Python, IPFS & Gateway3

Decentralized File Storage with Python, IPFS & Gateway3

Streamlining Data Storage and Retrieval with IPFS and Gateway3

ยท

5 min read

IPFS, the InterPlanetary File System, revolutionizes data storage and distribution through its decentralized approach. IPFS offers enhanced resilience, performance, data integrity, and censorship resistance by leveraging peer-to-peer networking and content addressing. Gateway3, an innovative IPFS portal, simplifies access to the IPFS network for developers and users. With its comprehensive APIs and SDKs, Gateway3 streamlines product development by eliminating the need for dedicated gateways or nodes. The scalable architecture intelligently balances requests across a distributed network, ensuring optimal performance. Gateway3 maintains a decentralized protocol, enabling any IPFS node adhering to the protocol to contribute, preserving data ownership and accessibility from any IPFS peer. IPFS and Gateway3 empower a new era of secure and efficient data storage and sharing.

As of 8 July 2023, Gateway3 does not provide native client support for Python, thus this article discusses how to wrap CurL Commands to access IPFS via Gw3 API. This article focuses on Update & Fetch API. Know more about Gw3 here

Let's Get Going

Libraries

  • Configure venv using python -m venv venv

  • Activate venv using source <path>/venv/bin/activate

  • Install Necessary Libraries pip install requests

Setting up Gateway3

  • Click Create & Copy the access key and Secret

Code

Libraries & Client

import time
import requests
import json
import os


# Replace with your own API Key and Secret Key
api = "<ACCESS KEY>"
key = "<SECRET KEY>"

# Replace with your own URL
URL = "https://gw3.io/ipfs/"

Functions to Upload Files & Objects

def call_api(GW3_SECRET_KEY = key, GW3_ACCESS_KEY = api, file_path = 'random_new.txt', URL = URL):
    UNIX_TIMESTAMP = int(time.time())
    headers = {
        "X-Access-Key": GW3_ACCESS_KEY,
        "X-Access-Secret": GW3_SECRET_KEY
    }

    try:
        #filesize in bytes
        file_stats = os.stat(file_path)
        filesize = file_stats.st_size
        # print(filesize)
        params = {
            "size": filesize*10,
            "ts": UNIX_TIMESTAMP
        }
        # print(filesize)
        response = requests.post(URL, headers=headers, params=params)
        print(response.json())
        # Get Upload URL based on Size of file & Timestamp
        url = response.json()['data']['url']


        #File upload
        # print(os.stat(file_path).st_size)
        ipfs_response = requests.post(url, files={'file': open(file_path, 'rb')})
        print(ipfs_response)
        return ipfs_response

    except Exception as e:
        print(e)
        print("Error uploading file to IPFS")

if __name__ == "__main__":
    # CALL API TO GET UPLOAD URL & UPLOAD FILE
    response_data = call_api(file_path='random_new.txt')
    print(f'Response is {response_data.text}')
    ipfs_hash = response_data.headers.get('ipfs-hash')
    print(f'IPFS HASH is {ipfs_hash}')

Output:


{'code': 200, 'msg': '', 'data': {'url': 'https://631f2aa27f0f6c14.gtw3.io/ipfs/?sargs=H4sIAAAJbogA_6pWKlCyyivNydFRyoAxEpWsoquVspWslBKL0nUTdTNTlHSUypSslMwslGp1EDJJOGXy8lNSoXqcHV2DPf1dEw098rOLHS2jzDwcA7IzspNSnPIKSgrKKs28i7Ky3L1KS91DfX1STCxRbCjOrIKZY2xqgCJVmpdZAZUyNLOwsDA3MDc0U6qNrQUMAN029dvSAAAA&ssig=3olxXqpjr6pl54V5NyCUZzeO5Wgt4rtFoltNFObchZKwSNLYEzij%2BQcIRcY0Zi2VbDfGtwbNLXKuXn7HRUB1Dg%3D%3D'}}
<Response [200]>
Response is 
IPFS HASH is QmPrmXWV9HgZ9fS12tHMFWnNDaWBXVh3YRz5a9pfMejUbf
  1. Generating Timestamp and Setting Headers:

    • Retrieves the current UNIX timestamp using time.time().

    • Sets the headers for the API request, including the X-Access-Key and X-Access-Secret based on the provided access keys.

  2. Retrieving File Size and Setting Parameters:

    • Uses os.stat to retrieve the file stats, including the file size in bytes.

    • Multiplies the file size by 10 and assigns it to the size parameter.

    • Assigns the generated UNIX timestamp to the ts parameter.

  3. Making the API Request to Get Upload URL:

    • Sends a POST request to the specified URL with the headers and parameters.

    • Retrieves the JSON response using response.json().

    • Extracts the upload URL from the response data.

    • The Upload URL is unique for each file and thus should only be used to upload that particular file.

  4. Uploading the File:

    • Sends a POST request to the obtained upload URL.

    • Attaches the file to be uploaded using the files parameter with the open function.

    • Retrieves the response of the IPFS upload.

The IPFS hash will further be used to Fetch Back the Document

Functions to Fetch Files

def fetch_api(GW3_SECRET_KEY = key, GW3_ACCESS_KEY = api, hash = hash):
    UNIX_TIMESTAMP = int(time.time())
    headers = {
        "X-Access-Key": GW3_ACCESS_KEY,
        "X-Access-Secret": GW3_SECRET_KEY
    }
    url = f'https://gw3.io/ipfs/{hash}?ts={UNIX_TIMESTAMP}'
    try:
        response = requests.get(url, headers=headers)
        # print(response.text)
        return response.text
    except Exception as e:
        print(e)

if __name__ == "__main__":
    # CALL API TO GET FILE FROM IPFS USING IPFS HASH FROM LAST CODE BLOCK
    response_data = fetch_api(hash=ipfs_hash)
    print(response_data)

Output:


--e028d1463d3dba7663d3c387df0835df----e028d1463d3dba7663d3c387df0835df
Content-Disposition: form-data; name="file"; filename="random_new.txt"

Hi
Hello world This is Version 2.0

--e028d1463d3dba7663d3c387df0835df--
  1. Generating Timestamp and Setting Headers:

    • Retrieves the current UNIX timestamp using time.time().

    • Sets the headers for the API request, including the X-Access-Key and X-Access-Secret based on the provided access keys.

  2. Constructing the Request URL:

    • Constructs the URL by appending the provided hash value and the generated timestamp as query parameters.

    • This URL is unique for each Hash and thus points to Hash and is used for retrieval of files. The same link can be used to access files via browser or for sharing too.

  3. Making the API Request to Retrieve File from IPFS:

    • Sends a GET request to the constructed URL with the headers.

    • Retrieves the response using response.text.

REMARKS

The benefit of using Gw3 instead of IPFS-python Client is, it does not require any installation or daemon runs or browser applications. Gw3 provides simple to use API, that can be called with any programming language providing the right Headers.

Conclusion

IPFS (InterPlanetary File System) revolutionizes data storage and distribution by offering a decentralized approach that enhances resilience, performance, data integrity, and censorship resistance. Gateway3, an innovative IPFS portal, simplifies access to the IPFS network for developers and users through comprehensive APIs and SDKs. By eliminating the need for dedicated gateways or nodes and intelligently balancing requests across a distributed network, Gateway3 enables optimal performance and scalability. With its decentralized protocol, any IPFS node adhering to the Gateway3 protocol can contribute, ensuring data ownership and accessibility from any IPFS peer. IPFS and Gateway3 empower a new era of secure and efficient data storage and sharing, offering a cloud-like experience while preserving the benefits of decentralization.

Did you find this article valuable?

Support Everything Python ๐Ÿ๐Ÿš€ by becoming a sponsor. Any amount is appreciated!

ย