viruPVS/langchain-docs huggingface dataset:
Source code for langchain_community.tools.ainetwork.base
from __future__ import annotations
import asyncio
import threading
from enum import Enum
from typing import TYPE_CHECKING, Any, Optional
from langchain_core.callbacks import CallbackManagerForToolRun
from langchain_core.pydantic_v1 import Field
from langchain_core.tools import BaseTool
from langchain_community.tools.ainetwork.utils import authenticate
if TYPE_CHECKING:
    from ain.ain import Ain
[docs]class OperationType(str, Enum):
    """Type of operation as enumerator."""
    SET = "SET"
    GET = "GET"
[docs]class AINBaseTool(BaseTool):
    """Base class for the AINetwork tools."""
    interface: Ain = Field(default_factory=authenticate)
    """The interface object for the AINetwork Blockchain."""
    def _run(
        self,
        *args: Any,
        run_manager: Optional[CallbackManagerForToolRun] = None,
        **kwargs: Any,
    ) -> str:
        try:
            loop = asyncio.get_event_loop()
        except RuntimeError:
            loop = asyncio.new_event_loop()
            asyncio.set_event_loop(loop)
        if loop.is_closed():
            loop = asyncio.new_event_loop()
            asyncio.set_event_loop(loop)
        if loop.is_running():
            result_container = []
            def thread_target() -> None:
                nonlocal result_container
                new_loop = asyncio.new_event_loop()
                asyncio.set_event_loop(new_loop)
                try:
                    result_container.append(
                        new_loop.run_until_complete(self._arun(*args, **kwargs))
                    )
                except Exception as e:
                    result_container.append(e)
                finally:
                    new_loop.close()
            thread = threading.Thread(target=thread_target)
Source code for langchain_community.tools.ainetwork.rule
import builtins
import json
from typing import Optional, Type
from langchain_core.callbacks import AsyncCallbackManagerForToolRun
from langchain_core.pydantic_v1 import BaseModel, Field
from langchain_community.tools.ainetwork.base import AINBaseTool, OperationType
[docs]class RuleSchema(BaseModel):
    """Schema for owner operations."""
    type: OperationType = Field(...)
    path: str = Field(..., description="Path on the blockchain where the rule applies")
    eval: Optional[str] = Field(None, description="eval string to determine permission")
[docs]class AINRuleOps(AINBaseTool):
    """Tool for owner operations."""
    name: str = "AINruleOps"
    description: str = """
Covers the write `rule` for the AINetwork Blockchain database. The SET type specifies write permissions using the `eval` variable as a JavaScript eval string.
In order to AINvalueOps with SET at the path, the execution result of the `eval` string must be true.
## Path Rules
1. Allowed characters for directory: `[a-zA-Z_0-9]`
2. Use `$<key>` for template variables as directory.
## Eval String Special Variables
- auth.addr: Address of the writer for the path
- newData: New data for the path
- data: Current data for the path
- currentTime: Time in seconds
- lastBlockNumber: Latest processed block number
## Eval String Functions
- getValue(<path>)
- getRule(<path>)
- getOwner(<path>)
- getFunction(<path>)
- evalRule(<path>, <value to set>, auth, currentTime)
- evalOwner(<path>, 'write_owner', auth)
## SET Example
- type: SET
## SET Example
- type: SET
- path: /apps/langchain_project_1/$from/$to/$img
- eval: auth.addr===$from&&!getValue('/apps/image_db/'+$img)
## GET Example
- type: GET
- path: /apps/langchain_project_1
"""  # noqa: E501
    args_schema: Type[BaseModel] = RuleSchema
    async def _arun(
        self,
        type: OperationType,
        path: str,
        eval: Optional[str] = None,
        run_manager: Optional[AsyncCallbackManagerForToolRun] = None,
    ) -> str:
        from ain.types import ValueOnlyTransactionInput
        try:
            if type is OperationType.SET:
                if eval is None:
                    raise ValueError("'eval' is required for SET operation.")
                res = await self.interface.db.ref(path).setRule(
                    transactionInput=ValueOnlyTransactionInput(
                        value={".rule": {"write": eval}}
                    )
                )
            elif type is OperationType.GET:
                res = await self.interface.db.ref(path).getRule()
            else:
                raise ValueError(f"Unsupported 'type': {type}.")
            return json.dumps(res, ensure_ascii=False)
        except Exception as e:
            return f"{builtins.type(e).__name__}: {str(e)}"
Source code for langchain_community.tools.ainetwork.utils
"""AINetwork Blockchain tool utils."""
from __future__ import annotations
import os
from typing import TYPE_CHECKING, Literal, Optional
if TYPE_CHECKING:
    from ain.ain import Ain
[docs]def authenticate(network: Optional[Literal["mainnet", "testnet"]] = "testnet") -> Ain:
    """Authenticate using the AIN Blockchain"""
    try:
        from ain.ain import Ain
    except ImportError as e:
        raise ImportError(
            "Cannot import ain-py related modules. Please install the package with "
            "`pip install ain-py`."
        ) from e
    if network == "mainnet":
        provider_url = "https://mainnet-api.ainetwork.ai/"
        chain_id = 1
        if "AIN_BLOCKCHAIN_ACCOUNT_PRIVATE_KEY" in os.environ:
            private_key = os.environ["AIN_BLOCKCHAIN_ACCOUNT_PRIVATE_KEY"]
        else:
            raise EnvironmentError(
                "Error: The AIN_BLOCKCHAIN_ACCOUNT_PRIVATE_KEY environmental variable "
                "has not been set."
            )
    elif network == "testnet":
        provider_url = "https://testnet-api.ainetwork.ai/"
        chain_id = 0
        if "AIN_BLOCKCHAIN_ACCOUNT_PRIVATE_KEY" in os.environ:
            private_key = os.environ["AIN_BLOCKCHAIN_ACCOUNT_PRIVATE_KEY"]
        else:
            raise EnvironmentError(
                "Error: The AIN_BLOCKCHAIN_ACCOUNT_PRIVATE_KEY environmental variable "
                "has not been set."
            )
    elif network is None:
        if (
            "AIN_BLOCKCHAIN_PROVIDER_URL" in os.environ
            and "AIN_BLOCKCHAIN_CHAIN_ID" in os.environ
            and "AIN_BLOCKCHAIN_ACCOUNT_PRIVATE_KEY" in os.environ
        ):
and "AIN_BLOCKCHAIN_ACCOUNT_PRIVATE_KEY" in os.environ
        ):
            provider_url = os.environ["AIN_BLOCKCHAIN_PROVIDER_URL"]
            chain_id = int(os.environ["AIN_BLOCKCHAIN_CHAIN_ID"])
            private_key = os.environ["AIN_BLOCKCHAIN_ACCOUNT_PRIVATE_KEY"]
        else:
            raise EnvironmentError(
                "Error: The AIN_BLOCKCHAIN_PROVIDER_URL and "
                "AIN_BLOCKCHAIN_ACCOUNT_PRIVATE_KEY and AIN_BLOCKCHAIN_CHAIN_ID "
                "environmental variable has not been set."
            )
    else:
        raise ValueError(f"Unsupported 'network': {network}")
    ain = Ain(provider_url, chain_id)
    ain.wallet.addAndSetDefaultAccount(private_key)
    return ain
Source code for langchain_community.tools.ainetwork.owner
import builtins
import json
from typing import List, Optional, Type, Union
from langchain_core.callbacks import AsyncCallbackManagerForToolRun
from langchain_core.pydantic_v1 import BaseModel, Field
from langchain_community.tools.ainetwork.base import AINBaseTool, OperationType
[docs]class RuleSchema(BaseModel):
    """Schema for owner operations."""
    type: OperationType = Field(...)
    path: str = Field(..., description="Blockchain reference path")
    address: Optional[Union[str, List[str]]] = Field(
        None, description="A single address or a list of addresses"
    )
    write_owner: Optional[bool] = Field(
        False, description="Authority to edit the `owner` property of the path"
    )
    write_rule: Optional[bool] = Field(
        False, description="Authority to edit `write rule` for the path"
    )
    write_function: Optional[bool] = Field(
        False, description="Authority to `set function` for the path"
    )
    branch_owner: Optional[bool] = Field(
        False, description="Authority to initialize `owner` of sub-paths"
    )
[docs]class AINOwnerOps(AINBaseTool):
    """Tool for owner operations."""
    name: str = "AINownerOps"
    description: str = """
Rules for `owner` in AINetwork Blockchain database.
An address set as `owner` can modify permissions according to its granted authorities
## Path Rule
- (/[a-zA-Z_0-9]+)+
- Permission checks ascend from the most specific (child) path to broader (parent) paths until an `owner` is located.
## Address Rules
## Address Rules
- 0x[0-9a-fA-F]{40}: 40-digit hexadecimal address
- *: All addresses permitted
- Defaults to the current session's address
## SET
- `SET` alters permissions for specific addresses, while other addresses remain unaffected.
- When removing an address of `owner`, set all authorities for that address to false.
- message `write_owner permission evaluated false` if fail
### Example
- type: SET
- path: /apps/langchain
- address: [<address 1>, <address 2>]
- write_owner: True
- write_rule: True
- write_function: True
- branch_owner: True
## GET
- Provides all addresses with `owner` permissions and their authorities in the path.
### Example
- type: GET
- path: /apps/langchain
"""  # noqa: E501
    args_schema: Type[BaseModel] = RuleSchema
    async def _arun(
        self,
        type: OperationType,
        path: str,
        address: Optional[Union[str, List[str]]] = None,
        write_owner: Optional[bool] = None,
        write_rule: Optional[bool] = None,
        write_function: Optional[bool] = None,
        branch_owner: Optional[bool] = None,
        run_manager: Optional[AsyncCallbackManagerForToolRun] = None,
    ) -> str:
        from ain.types import ValueOnlyTransactionInput
        try:
            if type is OperationType.SET:
                if address is None:
                    address = self.interface.wallet.defaultAccount.address
                if isinstance(address, str):
                    address = [address]
                res = await self.interface.db.ref(path).setOwner(
                    transactionInput=ValueOnlyTransactionInput(
                        value={
transactionInput=ValueOnlyTransactionInput(
                        value={
                            ".owner": {
                                "owners": {
                                    address: {
                                        "write_owner": write_owner or False,
                                        "write_rule": write_rule or False,
                                        "write_function": write_function or False,
                                        "branch_owner": branch_owner or False,
                                    }
                                    for address in address
                                }
                            }
                        }
                    )
                )
            elif type is OperationType.GET:
                res = await self.interface.db.ref(path).getOwner()
            else:
                raise ValueError(f"Unsupported 'type': {type}.")
            return json.dumps(res, ensure_ascii=False)
        except Exception as e:
            return f"{builtins.type(e).__name__}: {str(e)}"
Source code for langchain_community.tools.ainetwork.value
import builtins
import json
from typing import Optional, Type, Union
from langchain_core.callbacks import AsyncCallbackManagerForToolRun
from langchain_core.pydantic_v1 import BaseModel, Field
from langchain_community.tools.ainetwork.base import AINBaseTool, OperationType
[docs]class ValueSchema(BaseModel):
    """Schema for value operations."""
    type: OperationType = Field(...)
    path: str = Field(..., description="Blockchain reference path")
    value: Optional[Union[int, str, float, dict]] = Field(
        None, description="Value to be set at the path"
    )
[docs]class AINValueOps(AINBaseTool):
    """Tool for value operations."""
    name: str = "AINvalueOps"
    description: str = """
Covers the read and write value for the AINetwork Blockchain database.
## SET
- Set a value at a given path
### Example
- type: SET
- path: /apps/langchain_test_1/object
- value: {1: 2, "34": 56}
## GET
- Retrieve a value at a given path
### Example
- type: GET
- path: /apps/langchain_test_1/DB
## Special paths
- `/accounts/<address>/balance`: Account balance
- `/accounts/<address>/nonce`: Account nonce
- `/apps`: Applications
- `/consensus`: Consensus
- `/checkin`: Check-in
- `/deposit/<service id>/<address>/<deposit id>`: Deposit
- `/deposit_accounts/<service id>/<address>/<account id>`: Deposit accounts
- `/escrow`: Escrow
- `/payments`: Payment
- `/sharding`: Sharding
- `/token/name`: Token name
- `/sharding`: Sharding
- `/token/name`: Token name
- `/token/symbol`: Token symbol
- `/token/total_supply`: Token total supply
- `/transfer/<address from>/<address to>/<key>/value`: Transfer
- `/withdraw/<service id>/<address>/<withdraw id>`: Withdraw
"""
    args_schema: Type[BaseModel] = ValueSchema
    async def _arun(
        self,
        type: OperationType,
        path: str,
        value: Optional[Union[int, str, float, dict]] = None,
        run_manager: Optional[AsyncCallbackManagerForToolRun] = None,
    ) -> str:
        from ain.types import ValueOnlyTransactionInput
        try:
            if type is OperationType.SET:
                if value is None:
                    raise ValueError("'value' is required for SET operation.")
                res = await self.interface.db.ref(path).setValue(
                    transactionInput=ValueOnlyTransactionInput(value=value)
                )
            elif type is OperationType.GET:
                res = await self.interface.db.ref(path).getValue()
            else:
                raise ValueError(f"Unsupported 'type': {type}.")
            return json.dumps(res, ensure_ascii=False)
        except Exception as e:
            return f"{builtins.type(e).__name__}: {str(e)}"
Source code for langchain_community.tools.ainetwork.transfer
import json
from typing import Optional, Type
from langchain_core.callbacks import AsyncCallbackManagerForToolRun
from langchain_core.pydantic_v1 import BaseModel, Field
from langchain_community.tools.ainetwork.base import AINBaseTool
[docs]class TransferSchema(BaseModel):
    """Schema for transfer operations."""
    address: str = Field(..., description="Address to transfer AIN to")
    amount: int = Field(..., description="Amount of AIN to transfer")
[docs]class AINTransfer(AINBaseTool):
    """Tool for transfer operations."""
    name: str = "AINtransfer"
    description: str = "Transfers AIN to a specified address"
    args_schema: Type[TransferSchema] = TransferSchema
    async def _arun(
        self,
        address: str,
        amount: int,
        run_manager: Optional[AsyncCallbackManagerForToolRun] = None,
    ) -> str:
        try:
            res = await self.interface.wallet.transfer(address, amount, nonce=-1)
            return json.dumps(res, ensure_ascii=False)
        except Exception as e:
            return f"{type(e).__name__}: {str(e)}"
Source code for langchain_community.tools.ainetwork.app
import builtins
import json
from enum import Enum
from typing import List, Optional, Type, Union
from langchain_core.callbacks import AsyncCallbackManagerForToolRun
from langchain_core.pydantic_v1 import BaseModel, Field
from langchain_community.tools.ainetwork.base import AINBaseTool
[docs]class AppOperationType(str, Enum):
    """Type of app operation as enumerator."""
    SET_ADMIN = "SET_ADMIN"
    GET_CONFIG = "GET_CONFIG"
[docs]class AppSchema(BaseModel):
    """Schema for app operations."""
    type: AppOperationType = Field(...)
    appName: str = Field(..., description="Name of the application on the blockchain")
    address: Optional[Union[str, List[str]]] = Field(
        None,
        description=(
            "A single address or a list of addresses. Default: current session's "
            "address"
        ),
    )
[docs]class AINAppOps(AINBaseTool):
    """Tool for app operations."""
    name: str = "AINappOps"
    description: str = """
Create an app in the AINetwork Blockchain database by creating the /apps/<appName> path.
An address set as `admin` can grant `owner` rights to other addresses (refer to `AINownerOps` for more details).
Also, `admin` is initialized to have all `owner` permissions and `rule` allowed for that path.
## appName Rule
- [a-z_0-9]+
## address Rules
- 0x[0-9a-fA-F]{40}
- Defaults to the current session's address
- Multiple addresses can be specified if needed
## SET_ADMIN Example 1
- type: SET_ADMIN
- appName: ain_project
## SET_ADMIN Example 1
- type: SET_ADMIN
- appName: ain_project
### Result:
1. Path /apps/ain_project created.
2. Current session's address registered as admin.
## SET_ADMIN Example 2
- type: SET_ADMIN
- appName: test_project
- address: [<address1>, <address2>]
### Result:
1. Path /apps/test_project created.
2. <address1> and <address2> registered as admin.
"""  # noqa: E501
    args_schema: Type[BaseModel] = AppSchema
    async def _arun(
        self,
        type: AppOperationType,
        appName: str,
        address: Optional[Union[str, List[str]]] = None,
        run_manager: Optional[AsyncCallbackManagerForToolRun] = None,
    ) -> str:
        from ain.types import ValueOnlyTransactionInput
        from ain.utils import getTimestamp
        try:
            if type is AppOperationType.SET_ADMIN:
                if address is None:
                    address = self.interface.wallet.defaultAccount.address
                if isinstance(address, str):
                    address = [address]
                res = await self.interface.db.ref(
                    f"/manage_app/{appName}/create/{getTimestamp()}"
                ).setValue(
                    transactionInput=ValueOnlyTransactionInput(
                        value={"admin": {address: True for address in address}}
                    )
                )
            elif type is AppOperationType.GET_CONFIG:
                res = await self.interface.db.ref(
                    f"/manage_app/{appName}/config"
                ).getValue()
            else:
                raise ValueError(f"Unsupported 'type': {type}.")
            return json.dumps(res, ensure_ascii=False)
        except Exception as e:
Source code for langchain_community.tools.edenai.edenai_base_tool
from __future__ import annotations
import logging
from abc import abstractmethod
from typing import Any, Dict, List, Optional
import requests
from langchain_core.callbacks import CallbackManagerForToolRun
from langchain_core.pydantic_v1 import root_validator
from langchain_core.tools import BaseTool
from langchain_core.utils import get_from_dict_or_env
logger = logging.getLogger(__name__)
[docs]class EdenaiTool(BaseTool):
    """
    the base tool for all the EdenAI Tools .
    you should have
    the environment variable ``EDENAI_API_KEY`` set with your API token.
    You can find your token here: https://app.edenai.run/admin/account/settings
    """
    feature: str
    subfeature: str
    edenai_api_key: Optional[str] = None
    is_async: bool = False
    providers: List[str]
    """provider to use for the API call."""
    @root_validator(allow_reuse=True)
    def validate_environment(cls, values: Dict) -> Dict:
        """Validate that api key exists in environment."""
        values["edenai_api_key"] = get_from_dict_or_env(
            values, "edenai_api_key", "EDENAI_API_KEY"
        )
        return values
[docs]    @staticmethod
    def get_user_agent() -> str:
        from langchain_community import __version__
        return f"langchain/{__version__}"
    def _call_eden_ai(self, query_params: Dict[str, Any]) -> str:
        """
        Make an API call to the EdenAI service with the specified query parameters.
        Args:
            query_params (dict): The parameters to include in the API call.
        Returns:
query_params (dict): The parameters to include in the API call.
        Returns:
            requests.Response: The response from the EdenAI API call.
        """
        # faire l'API call
        headers = {
            "Authorization": f"Bearer {self.edenai_api_key}",
            "User-Agent": self.get_user_agent(),
        }
        url = f"https://api.edenai.run/v2/{self.feature}/{self.subfeature}"
        payload = {
            "providers": str(self.providers),
            "response_as_dict": False,
            "attributes_as_list": True,
            "show_original_response": False,
        }
        payload.update(query_params)
        response = requests.post(url, json=payload, headers=headers)
        self._raise_on_error(response)
        try:
            return self._parse_response(response.json())
        except Exception as e:
            raise RuntimeError(f"An error occurred while running tool: {e}")
    def _raise_on_error(self, response: requests.Response) -> None:
        if response.status_code >= 500:
            raise Exception(f"EdenAI Server: Error {response.status_code}")
        elif response.status_code >= 400:
            raise ValueError(f"EdenAI received an invalid payload: {response.text}")
        elif response.status_code != 200:
            raise Exception(
                f"EdenAI returned an unexpected response with status "
                f"{response.status_code}: {response.text}"
            )
        # case where edenai call succeeded but provider returned an error
        # (eg: rate limit, server error, etc.)
        if self.is_async is False:
            # async call are different and only return a job_id,
            # not the provider response directly
            provider_response = response.json()[0]
# not the provider response directly
            provider_response = response.json()[0]
            if provider_response.get("status") == "fail":
                err_msg = provider_response["error"]["message"]
                raise ValueError(err_msg)
    @abstractmethod
    def _run(
        self, query: str, run_manager: Optional[CallbackManagerForToolRun] = None
    ) -> str:
        pass
    @abstractmethod
    def _parse_response(self, response: Any) -> str:
        """Take a dict response and condense it's data in a human readable string"""
        pass
    def _get_edenai(self, url: str) -> requests.Response:
        headers = {
            "accept": "application/json",
            "authorization": f"Bearer {self.edenai_api_key}",
            "User-Agent": self.get_user_agent(),
        }
        response = requests.get(url, headers=headers)
        self._raise_on_error(response)
        return response
    def _parse_json_multilevel(
        self, extracted_data: dict, formatted_list: list, level: int = 0
    ) -> None:
        for section, subsections in extracted_data.items():
            indentation = "  " * level
            if isinstance(subsections, str):
                subsections = subsections.replace("\n", ",")
                formatted_list.append(f"{indentation}{section} : {subsections}")
            elif isinstance(subsections, list):
                formatted_list.append(f"{indentation}{section} : ")
                self._list_handling(subsections, formatted_list, level + 1)
            elif isinstance(subsections, dict):
                formatted_list.append(f"{indentation}{section} : ")
                self._parse_json_multilevel(subsections, formatted_list, level + 1)
self._parse_json_multilevel(subsections, formatted_list, level + 1)
    def _list_handling(
        self, subsection_list: list, formatted_list: list, level: int
    ) -> None:
        for list_item in subsection_list:
            if isinstance(list_item, dict):
                self._parse_json_multilevel(list_item, formatted_list, level)
            elif isinstance(list_item, list):
                self._list_handling(list_item, formatted_list, level + 1)
            else:
                formatted_list.append(f"{'  ' * level}{list_item}")