Decentralized File Storage with Python, IPFS & Gateway3
Streamlining Data Storage and Retrieval with IPFS and Gateway3
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
usingpython -m venv venv
Activate
venv
usingsource <path>/venv/bin/activate
Install Necessary Libraries
pip install requests
Setting up Gateway3
Move on to https://www.gw3.io/apis
Generate a New API, with Admin access.
- Click Create & Copy the access key and Secret
- Move on to https://www.gw3.io/dashboard to access the dashboard
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
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
andX-Access-Secret
based on the provided access keys.
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.
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.
Uploading the File:
Sends a POST request to the obtained upload URL.
Attaches the file to be uploaded using the
files
parameter with theopen
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--
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
andX-Access-Secret
based on the provided access keys.
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.
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.