Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
mintbase.py265 linesDownload Raw Back to document_loaders
1import json2import os3import re4import time5from typing import Iterator, List, Literal, Optional6 7import requests8from langchain_core.documents import Document9 10from langchain_community.document_loaders.base import BaseLoader11 12 13class MintbaseDocumentLoader(BaseLoader):14    """Load elements from a blockchain smart contract.15 16    The supported blockchains are: Near mainnet, Near testnet.17 18    If no BlockchainType is specified, the default is Near mainnet.19 20    The Loader uses the Mintbase API to interact with the blockchain.21    MB_API_KEY environment variable must be set to use this loader.22 23    The API returns 100 NFTs per request and can be paginated using the24    startToken parameter.25 26    If get_all_tokens is set to True, the loader will get all tokens27    on the contract.  Note that for contracts with a large number of tokens,28    this may take a long time (e.g. 10k tokens is 100 requests).29    Default value is false for this reason.30 31    The max_execution_time (sec) can be set to limit the execution time32    of the loader.33 34    Future versions of this loader can:35        - Support additional Mintbase APIs (e.g. getTokens, etc.)36 37    Example:38        .. code-block:: python39 40            contractAddress = "nft.yearofchef.near"  # Year of chef contract address41            blockchainLoader = MintbaseDocumentLoader(42                contract_address=contractAddress, blockchain_type="mainnet",api_key="omni-site"43            )44    """  # noqa: E50145 46    def __init__(47        self,48        contract_address: str,49        *,50        blockchain_type: Literal["mainnet", "testnet"],51        api_key: str = "",52        table: str = "",53        select: str = "",54        fields: Optional[List[str]] = None,55        get_all_tokens: bool = False,56        max_execution_time: Optional[int] = None,57    ):58        """59 60        Args:61            contract_address: The address of the smart contract.62            blockchainType: The blockchain type.63            api_key: The Mintbase API key.64            table: name of the table to query65            select: Conditions for querying66            fields: Information to display after query67            get_all_tokens: Whether to get all tokens on the contract.68            max_execution_time: The maximum execution time (sec).69        """70        self.contract_address = contract_address71        self.blockchainType = blockchain_type72        self.api_key = os.environ.get("MB_API_KEY") or api_key73        self.table = "mb_views_nft_tokens" or table74        self.select = 'where: {nft_contract_id: {_eq: "contract_address"}}' or select75        self.fields = fields or [76            "base_uri",77            "burned_receipt_id",78            "burned_timestamp",79            "copies",80            "description",81            "expires_at",82            "extra",83            "issued_at",84            "last_transfer_receipt_id",85            "last_transfer_timestamp",86            "media",87            "media_hash",88            "metadata_content_flag",89            "metadata_id",90            "mint_memo",91            "minted_receipt_id",92            "minted_timestamp",93            "minter",94            "nft_contract_content_flag",95            "nft_contract_created_at",96            "nft_contract_icon",97            "nft_contract_id",98            "nft_contract_is_mintbase",99            "nft_contract_name",100            "nft_contract_owner_id",101            "nft_contract_reference",102            "nft_contract_spec",103            "nft_contract_symbol",104            "owner",105            "reference",106            "reference_blob",107            "reference_hash",108            "royalties",109            "royalties_percent",110            "splits",111            "starts_at",112            "title",113            "token_id",114            "updated_at",115        ]116 117        self.get_all_tokens = get_all_tokens118        self.max_execution_time = max_execution_time119 120        if not self.api_key:121            raise ValueError("Mintbase API key not provided.")122 123        if not re.match(124            r"^(([a-z\d]+[\-_])*[a-z\d]+\.)*([a-z\d]+[\-_])*[a-z\d]+$",125            self.contract_address,126        ):127            raise ValueError(f"Invalid contract address {self.contract_address}")128 129    def load(self) -> List[Document]:130        result = []131 132        start_time = time.time()133 134        while True:135            # Define the GraphQL query as a multi-line string136            operations_doc = """137            query MyQuery {138            table(select) {139                fields140            }141            }142            """143 144            # Replace the placeholder with the actual contract address145            operations_doc = operations_doc.replace("select", self.select)146            operations_doc = operations_doc.replace(147                "contract_address", self.contract_address148            )149            operations_doc = operations_doc.replace("table", self.table)150            operations_doc = operations_doc.replace("fields", "\n".join(self.fields))151 152            # Define the headers153            headers = {"mb-api-key": self.api_key, "Content-Type": "application/json"}154            # Define the POST data155            data = {156                "query": operations_doc,157                "variables": {},158                "operationName": "MyQuery",159            }160 161            url = f"https://graph.mintbase.xyz/{self.blockchainType}"162 163            response = requests.post(url, headers=headers, data=json.dumps(data))164 165            if response.status_code != 200:166                raise ValueError(167                    f"Request failed with status code {response.status_code}"168                )169 170            items = response.json()["data"]["mb_views_nft_tokens"]171 172            if not items:173                break174 175            for item in items:176                content = str(item)177                token_id = item["token_id"]178                metadata = {179                    "source": self.contract_address,180                    "blockchain": self.blockchainType,181                    "tokenId": token_id,182                }183                result.append(Document(page_content=content, metadata=metadata))184 185            # exit after the first API call if get_all_tokens is False186            if not self.get_all_tokens:187                break188 189            if (190                self.max_execution_time is not None191                and (time.time() - start_time) > self.max_execution_time192            ):193                raise RuntimeError("Execution time exceeded the allowed time limit.")194 195        if not result:196            raise ValueError(197                f"No NFTs found for contract address {self.contract_address}"198            )199 200        return result201 202    def lazy_load(self) -> Iterator[Document]:203        start_time = time.time()204 205        while True:206            # Define the GraphQL query as a multi-line string207            operations_doc = """208            query MyQuery {209            table(select) {210                fields211            }212            }213            """214 215            # Replace the placeholder with the actual contract address216            operations_doc = operations_doc.replace("select", self.select)217            operations_doc = operations_doc.replace(218                "contract_address", self.contract_address219            )220            operations_doc = operations_doc.replace("table", self.table)221            operations_doc = operations_doc.replace("fields", "\n".join(self.fields))222 223            # Define the headers224            headers = {"mb-api-key": self.api_key, "Content-Type": "application/json"}225            # Define the POST data226            data = {227                "query": operations_doc,228                "variables": {},229                "operationName": "MyQuery",230            }231 232            url = f"https://graph.mintbase.xyz/{self.blockchainType}"233 234            response = requests.post(url, headers=headers, data=json.dumps(data))235 236            if response.status_code != 200:237                raise ValueError(238                    f"Request failed with status code {response.status_code}"239                )240 241            items = response.json()["data"]["mb_views_nft_tokens"]242 243            if not items:244                break245 246            for item in items:247                content = str(item)248                tokenId = item["token_id"]249                metadata = {250                    "source": self.contract_address,251                    "blockchain": self.blockchainType,252                    "tokenId": tokenId,253                }254                yield Document(page_content=content, metadata=metadata)255 256            # exit after the first API call if get_all_tokens is False257            if not self.get_all_tokens:258                break259 260            if (261                self.max_execution_time is not None262                and (time.time() - start_time) > self.max_execution_time263            ):264                raise RuntimeError("Execution time exceeded the allowed time limit.")265 
codekingpro/portable-devtools · Team Ai