Python: How to use the Infura NFT API

Hello friends! :wave:

In this article we’ll take a look at how to acquire certain NFT related data, using API requests. This script is working with Infura’s NFT-SDK. Although this is a JavaScript tool, we can make use of the REST API’s implemented within it, to get our NFT related data with python.

After going through with the tutorial, you will be able to fetch:

  • all the NFTs owned by an Ethereum address:
{'pageNumber': 1, 'network': 'ETHEREUM', 'total': 47, 'account': '0x0a267cf51ef038fc00e71801f5a524aec06e4f07', 'type': 'NFT', 'assets': [{'contract': '0xb94c3fd0016888bab09dbc229f9397294e828a54', 'tokenId': '0', 'supply': '1', 'type': 'ERC1155', 'metadata': {'name': 'Forgotten Runes Comic: Issue #0', 'image': 'https://nftz.forgottenrunes.com/comics/0/0.mp4', 'attributes': [{'trait_type': 'Description', 'value': 'Magic Machine presents the inaugural issue of the Forgotten Runes Comic.'}, {'trait_type': 'Issue Number', 'value': '0'}, {'trait_type': 'Cover Artist', 'value': 'Reilly Brown'}, {'trait_type': 'Genesis', 'value': 'true'}], 'background_color': '000000'}}, {'contract': '0x9690b63eb85467be5267a3603f770589ab12dc95', 'tokenId': '13086', 'supply': '1', 'type': 'ERC721', 'metadata': {'name': 'Seth Contaminator of Goblins', 'image': 'https://portal.forgottenrunes.com/api/warriors/img/13086', 'attributes': [{'trait_type': 'background', 'value': 'Red'}, {'trait_type': 'companion', 'value': 'Azure Raptor'}, {'trait_type': 'body', 'value': 'Armor of Fire'}, {'trait_type': 'head', 'value': 'Cyber Viking'}, {'trait_type': 'shield', 'value': 'Shield of Up Only'}, {'trait_type': 'weapon', 'value': 'Durendal'}, {'trait_type': 'rune', 'value': 'Rune of Venus'}, {'trait_type': 'Affinity', 'value': 'Gold'}, {'trait_type': '# Traits', 'value': '6'}, {'trait_type': '# Traits in Affinity', 'value': '4'}, {'trait_type': '% Traits in Affinity', 'value': '66 percent'}], 'background_color': '1E0200'}}, ... other 44 NFTs
  • the metadata of a specific NFT:
{'contract': '0x31d45de84fde2fb36575085e05754a4932dd5170', 'tokenId': '5', 'name': 'Rare Apepe #5', 'description': 'This Rare Apepe is an homage to Bored Ape #5', 'image': 'https://data.rareapepes.com/5.png', 'attributes': [{'trait_type': 'Hat', 'value': 'Bayc Flipped Brim'}, {'trait_type': 'Eyes', 'value': 'X Eyes'}, {'trait_type': 'Skin', 'value': 'Green'}, {'trait_type': 'Background', 'value': 'Army Green'}, {'trait_type': 'Clothes', 'value': 'Bayc T Red'}, {'trait_type': 'Mouth', 'value': 'Dumbfounded'}]}
  • the NFTs of a specific collection:
{'pageNumber': 1, 'network': 'ETHEREUM', 'total': 100, 'account': '0x31d45de84fdE2fB36575085e05754a4932DD5170', 'type': 'NFT', 'assets': [{'contract': '0x31d45de84fde2fb36575085e05754a4932dd5170', 'tokenId': '7673', 'supply': '1', 'type': 'ERC721', 'metadata': {'image': 'https://data.rareapepes.com/7673.png', 'attributes': [{'trait_type': 'Background', 'value': 'Army Green'}, {'trait_type': 'Hat', 'value': 'Short Mohawk'}, {'trait_type': 'Mouth', 'value': 'Bored'}, {'trait_type': 'Skin', 'value': 'Green'}, {'trait_type': 'Eyes', 'value': 'Closed'}], 'name': 'Rare Apepe #7673', 'description': 'This Rare Apepe is an homage to Bored Ape #3004'}}, {'contract': '0x31d45de84fde2fb36575085e05754a4932dd5170', 'tokenId': '5435', 'supply': '1', 'type': 'ERC721', 'metadata': {'image': 'https://data.rareapepes.com/5435.png', 'attributes': [{'trait_type': 'Hat', 'value': 'Bunny Ears'}, {'trait_type': 'Background', 'value': 'Blue'}, {'trait_type': 'Eyes', 'value': 'X Eyes'}, {'trait_type': 'Mouth', 'value': 'Jovial'}, {'trait_type': 'Clothes', 'value': 'Black Holes T'}, {'trait_type': 'Earring', 'value': 'Diamond Stud'}, {'trait_type': 'Skin', 'value': 'Pink'}], 'name': 'Rare Apepe #5435', 'description': 'This Rare Apepe is an homage to Bored Ape #4515'}}, {'contract': '0x31d45de84fde2fb36575085e05754a4932dd5170', ... other 98 NFTs
  • the metadata of an NFT collection:
{'contract': '0x31d45de84fde2fb36575085e05754a4932dd5170', 'name': 'RareApepeYachtClub', 'symbol': 'RAYC', 'tokenType': 'ERC721'}

Setting Up Our Project

If you haven’t already, make sure that you request access to the NFT API by completing the form here. This is required for us to be able to use the APIs in this tutorial.

Since we are not querying the blockchain directly (through methods like eth_getBlockByNumber), but through requests to Infura’s NFT API, we will not be needing the web3 library for this script. This being said, our only prerequisite is installing the requests library, which we will be using for performing the API requests.

To do so, simply bring up a terminal in your project’s directory and run the following command:

pip install requests

We will also be using the json module which is already built-in python, for reading the responses received as a result of the API requests.

Now, let’s import the needed modules into our project so we can get started coding!

import requests
import json

Connecting to Infura

In order for us to be able to use the API, we’ll need to perform authenticated requests and create the URL that we’ll pass to the API. The requests’ URLs follow the format shown below, which can also be found here.

For this tutorial we will be working with the Ethereum Mainnet, so we’ll replace {chainId} with 1. Now let’s create the constants for the URL and our Infura project’s keys:

infura_url = 'https://nft.api.infura.io/networks/1/'
proj_id = 'YOUR_PROJECT_ID'
proj_secret = 'YOUR_PROJECT_SECRET'

Notice how we only added the recurring part of the URLs shown in the image above to our URL - we’ll build onto this URL for our full URL requests, depending on which of the above requests we want to perform.

Get NFTs owned by an Ethereum address

For getting the NFTs owned by a specific address we will use the second URL from the image above. This means that to our infura_url variable created earlier, we’ll add the ‘accounts/’ keyword, along with the Ethereum address we are querying and then ‘/assets/nfts/’.

request_url = infura_url + 'accounts/' + address + '/assets/nfts/'

The final request_url will look like this:

https://nft.api.infura.io/networks/1/0x0a267cf51ef038fc00e71801f5a524aec06e4f07/assets/nfts

After building the URL, let’s perform a GET api request, by using the requests library along with our Infura keys to authenticate the request.

	response = requests.get(request_url, auth=(proj_id, proj_secret))

Finally, if the request returns the status code 200, it means that everything went well so we can parse our received response to json and then print it.

if response.status_code == 200:
		res = response.json()
		if res['total'] == 0:
			print('No NFTs owned by ' + address)
		else:
			print(res)

Here is the full method for fetching the NFTs owned by an address.

def getNFTsOwned(address):
	request_url = infura_url + 'accounts/' + address + '/assets/nfts/'
	response = requests.get(request_url, auth=(proj_id, proj_secret))
	if response.status_code == 200:
		res = response.json()
		if res['total'] == 0:
			print('No NFTs owned by ' + address)
		else:
			print(res)

Note that if the ‘total’ field of the response is 0, it means that there are no NFTs owned by the address we’ve queried.

For the other 3 methods, the only difference is the url of the request, here they are below:

Get NFT’s metadata

def getNFTMetadata(token_address, token_id):
	request_url = infura_url + 'nfts/' + token_address + '/tokens/' + token_id
	response = requests.get(request_url, auth=(proj_id, proj_secret))
	if response.status_code == 200:
		res = response.json()
		print(res)

Note that the token_address and token_id are passed in as strings in this example, to make it easier for them to be included in the URL directly.

Get all NFTs of a collection

def getNFTsByCollection(token_address):
	request_url = infura_url + 'nfts/' + token_address + '/tokens/'
	response = requests.get(request_url, auth=(proj_id, proj_secret))
	if response.status_code == 200:
		res = response.json()
		print(res)

Get metadata of the collection

def getCollectionMetadata(token_address):
	request_url = infura_url + 'nfts/' + token_address
	response = requests.get(request_url, auth=(proj_id, proj_secret))
	if response.status_code == 200:
		res = response.json()
		print(res)

Complete code overview

This script was kept as simple as possible for clarity, if you’d like more details on how to use requests with python check out this resource.

For anyone who wants to have all the methods described above available in a single file, here it is:

import requests
import json

infura_url = 'https://nft.api.infura.io/networks/1/'
proj_id = 'YOUR_PROJECT_ID'
proj_secret = 'YOUR_PROJECT_SECRET'

# token_address is a String by default
def getCollectionMetadata(token_address):
	request_url = infura_url + 'nfts/' + token_address
	response = requests.get(request_url, auth=(proj_id, proj_secret))
	if response.status_code == 200:
		res = response.json()
		print(res)

# token_address, token_id are strings
def getNFTMetadata(token_address, token_id):
	request_url = infura_url + 'nfts/' + token_address + '/tokens/' + token_id
	response = requests.get(request_url, auth=(proj_id, proj_secret))
	if response.status_code == 200:
		res = response.json()
		print(res)

#token_address is a string
def getNFTsByCollection(token_address):
	request_url = infura_url + 'nfts/' + token_address + '/tokens/'
	response = requests.get(request_url, auth=(proj_id, proj_secret))
	if response.status_code == 200:
		res = response.json()
		print(res)

# address is a string
def getNFTsOwned(address):
	request_url = infura_url + 'accounts/' + address + '/assets/nfts/'
	response = requests.get(request_url, auth=(proj_id, proj_secret))
	if response.status_code == 200:
		res = response.json()
		if res['total'] == 0:
			print('No NFTs owned by ' + address)
		else:
			print(res)

# Uncomment any line for testing different methods
if __name__ == "__main__":
	getNFTsOwned('0x0a267cf51ef038fc00e71801f5a524aec06e4f07')
	# getCollectionMetadata('0x31d45de84fdE2fB36575085e05754a4932DD5170')
	# getNFTMetadata('0x31d45de84fdE2fB36575085e05754a4932DD5170', '5')
	# getNFTsByCollection('0x31d45de84fdE2fB36575085e05754a4932DD5170')

Congratulations for completing this tutorial! :tada: Feel free to let us know if you have any questions below!

4 Likes