diff --git a/docs/index.md b/docs/index.md index 0c687ef5..74677c8f 100644 --- a/docs/index.md +++ b/docs/index.md @@ -263,7 +263,7 @@ Pyasic implements a few dataclasses as helpers to make data return types consist [`MinerData`][pyasic.data.MinerData] is a return from the [`get_data()`](#get-data) function, and is used to have a consistent dataset across all returns. -You can call [`MinerData.asdict()`][pyasic.data.MinerData.asdict] to get the dataclass as a dictionary, and there are many other helper functions contained in the class to convert to different data formats. +You can call [`MinerData.as_dict()`][pyasic.data.MinerData.as_dict] to get the dataclass as a dictionary, and there are many other helper functions contained in the class to convert to different data formats. [`MinerData`][pyasic.data.MinerData] instances can also be added to each other to combine their data and can be divided by a number to divide all their data, allowing you to get average data from many miners by doing - ```python @@ -288,3 +288,27 @@ It is the return from [`get_config()`](#get-config). Each miner has a unique way to convert the [`MinerConfig`][pyasic.config.MinerConfig] to their specific type, there are helper functions in the class. In most cases these helper functions should not be used, as [`send_config()`](#send-config) takes a [`MinerConfig`][pyasic.config.MinerConfig] and will do the conversion to the right type for you. + +## Settings +`pyasic` has settings designed to make using large groups of miners easier. You can set the default password for all types of miners using the [`pyasic.settings`][pyasic.settings] module, used as follows: + +```python +from pyasic import settings + +settings.update("default_antminer_password", "my_pwd") +``` + +Here are of all the settings, and their default values: +``` +"network_ping_retries": 1, +"network_ping_timeout": 3, +"network_scan_threads": 300, +"factory_get_retries": 1, +"get_data_retries": 1, +"default_whatsminer_password": "admin", +"default_innosilicon_password": "admin", +"default_antminer_password": "root", +"default_bosminer_password": "root", +"default_vnish_password": "admin", +"default_goldshell_password": "123456789", +``` diff --git a/docs/miners/miner_factory.md b/docs/miners/miner_factory.md index b47a4266..d3ae33e3 100644 --- a/docs/miners/miner_factory.md +++ b/docs/miners/miner_factory.md @@ -1,6 +1,14 @@ # pyasic ## Miner Factory +[`MinerFactory`][pyasic.miners.miner_factory.MinerFactory] is the way to create miner types in `pyasic`. The most important method is [`get_miner()`][pyasic.get_miner], which is mapped to [`pyasic.get_miner()`][pyasic.get_miner], and should be used from there. + +The instance used for [`pyasic.get_miner()`][pyasic.get_miner] is `pyasic.miner_factory`. + +[`MinerFactory`][pyasic.MinerFactory] also keeps a cache, which can be cleared if needed with `pyasic.miner_factory.clear_cached_miners()`. + +Finally, there is functionality to get multiple miners without using `asyncio.gather()` explicitly. Use `pyasic.miner_factory.get_multiple_miners()` with a list of IPs as strings to get a list of miner instances. You can also get multiple miners with an `AsyncGenerator` by using `pyasic.miner_factory.get_miner_generator()`. + ::: pyasic.miners.miner_factory.MinerFactory handler: python options: diff --git a/docs/settings/settings.md b/docs/settings/settings.md new file mode 100644 index 00000000..058b263a --- /dev/null +++ b/docs/settings/settings.md @@ -0,0 +1,23 @@ +# pyasic +## settings + +::: pyasic.settings + handler: python + options: + show_root_heading: false + heading_level: 4 + + +### get +::: pyasic.settings.get + handler: python + options: + show_root_heading: false + heading_level: 4 + +### update +::: pyasic.settings.update + handler: python + options: + show_root_heading: false + heading_level: 4 diff --git a/mkdocs.yml b/mkdocs.yml index f44f65a9..e0c8273f 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -53,7 +53,8 @@ nav: - Goldshell X5: "miners/goldshell/X5.md" - Goldshell XMax: "miners/goldshell/XMax.md" - Base Miner: "miners/base_miner.md" - +- Settings: + - Settings: "settings/settings.md" plugins: - mkdocstrings diff --git a/pyasic/__init__.py b/pyasic/__init__.py index 3803375e..14b24259 100644 --- a/pyasic/__init__.py +++ b/pyasic/__init__.py @@ -30,7 +30,7 @@ from pyasic.data import ( from pyasic.errors import APIError, APIWarning from pyasic.miners import get_miner from pyasic.miners.base import AnyMiner -from pyasic.miners.miner_factory import MinerFactory +from pyasic.miners.miner_factory import MinerFactory, miner_factory from pyasic.miners.miner_listener import MinerListener from pyasic.network import MinerNetwork @@ -51,6 +51,7 @@ __all__ = [ "get_miner", "AnyMiner", "MinerFactory", + "miner_factory", "MinerListener", "MinerNetwork", "settings", diff --git a/pyasic/miners/miner_factory.py b/pyasic/miners/miner_factory.py index 31f343b1..1f311aaf 100644 --- a/pyasic/miners/miner_factory.py +++ b/pyasic/miners/miner_factory.py @@ -20,7 +20,7 @@ import enum import ipaddress import json import re -from typing import Callable, List, Optional, Tuple, Union +from typing import AsyncGenerator, Callable, List, Optional, Tuple, Union import httpx @@ -379,7 +379,9 @@ class MinerFactory: def clear_cached_miners(self): self.cache = {} - async def get_multiple_miners(self, ips: List[str], limit: int = 200): + async def get_multiple_miners( + self, ips: List[str], limit: int = 200 + ) -> List[AnyMiner]: results = [] async for miner in self.get_miner_generator(ips, limit): @@ -387,7 +389,7 @@ class MinerFactory: return results - async def get_miner_generator(self, ips: list, limit: int = 200): + async def get_miner_generator(self, ips: list, limit: int = 200) -> AsyncGenerator: tasks = [] semaphore = asyncio.Semaphore(limit) @@ -395,13 +397,10 @@ class MinerFactory: tasks.append(asyncio.create_task(self.get_miner(ip))) for task in tasks: - await semaphore.acquire() - try: + async with semaphore: result = await task if result is not None: yield result - finally: - semaphore.release() async def get_miner(self, ip: str): ip = str(ip)