diff --git a/commune/module.py b/commune/module.py index e86d09c2..353fdc50 100755 --- a/commune/module.py +++ b/commune/module.py @@ -56,7 +56,8 @@ class c: 'executor', 'client', 'server', 'namespace' ] libname = lib_name = lib = 'commune' # the name of the library - cost = 1 + module_cache = {} + _obj = None description = """This is a module""" base_module = 'module' # the base module giturl = 'https://github.com/commune-ai/commune.git' # tge gutg @@ -111,14 +112,12 @@ def dirpath(cls) -> str: @classmethod def module_name(cls, obj=None): - if hasattr(cls, 'name') and isinstance(cls.name, str): - return cls.name obj = cls.resolve_object(obj) + # if hasattr(cls, 'name') and isinstance(cls.name, str): + # return cls.name module_file = inspect.getfile(obj) return c.path2simple(module_file) - - path = name = module_name - + @classmethod def module_class(cls) -> str: return cls.__name__ @@ -127,6 +126,7 @@ def module_class(cls) -> str: def class_name(cls, obj= None) -> str: obj = obj if obj != None else cls return obj.__name__ + classname = class_name @@ -134,37 +134,6 @@ def class_name(cls, obj= None) -> str: def config_path(cls) -> str: return cls.filepath().replace('.py', '.yaml') - @classmethod - def sandbox(cls): - c.cmd(f'python3 {c.root_path}/sandbox.py', verbose=True) - return - - sand = sandbox - - module_cache = {} - _obj = None - - @classmethod - def obj2module(cls,obj): - import commune as c - class WrapperModule(c.Module): - _obj = obj - def __name__(self): - return obj.__name__ - def __class__(self): - return obj.__class__ - @classmethod - def filepath(cls) -> str: - return super().filepath(cls._obj) - - for fn in dir(WrapperModule): - try: - setattr(obj, fn, getattr(WrapperModule, fn)) - except: - pass - - return obj - @classmethod def storage_dir(cls): return f'{c.cache_path}/{cls.module_name()}' @@ -173,28 +142,6 @@ def storage_dir(cls): def __str__(cls): return cls.__name__ - @classmethod - def root_address(cls, name:str='module', - network : str = 'local', - timeout:int = 100, - sleep_interval:int = 1, - **kwargs): - """ - Root module - """ - try: - if not c.server_exists(name, network=network): - c.serve(name, network=network, wait_for_server=True, **kwargs) - address = c.call('module/address', network=network, timeout=timeout) - ip = c.ip() - address = ip+':'+address.split(':')[-1] - except Exception as e: - c.print(f'Error: {e}', color='red') - address = None - return address - - addy = root_address - @classmethod def is_module(cls, obj=None) -> bool: @@ -205,7 +152,7 @@ def is_module(cls, obj=None) -> bool: return False @classmethod - def is_root(cls, obj=None) -> bool: + def is_root_module(cls, obj=None) -> bool: required_features = ['info', 'schema', 'root_module_class', 'module_name'] if obj is None: obj = cls @@ -215,7 +162,6 @@ def is_root(cls, obj=None) -> bool: return True return False - is_module_root = is_root_module = is_root @classmethod def serialize(cls, *args, **kwargs): @@ -239,9 +185,9 @@ def resolve_object(cls, obj:str = None, **kwargs): if isinstance(obj, str): obj = c.module(obj, **kwargs) if cls._obj != None: - return cls._obj - else: - return obj or cls + obj = cls._obj + obj = obj or cls + return obj @classmethod def restart(cls, name:str, mode:str='pm2', verbose:bool = False, prefix_match:bool = True): @@ -279,16 +225,13 @@ def run(cls, name:str = None) -> Any: if not is_main: return {'success':False, 'message':f'Not main module {name}'} args = cls.argparse() - if args.function == '__init__': - return cls(*args.args, **args.kwargs) + fn = getattr(cls, args.function) + fn_type = cls.classify_fn(fn) + if fn_type == 'self': + module = cls(*args.args, **args.kwargs) else: - fn = getattr(cls, args.function) - fn_type = cls.classify_fn(fn) - if fn_type == 'self': - module = cls(*args.args, **args.kwargs) - else: - module = cls - return getattr(module, args.function)(*args.args, **args.kwargs) + module = cls + return getattr(module, args.function)(*args.args, **args.kwargs) @classmethod def commit_hash(cls, libpath:str = None): @@ -660,6 +603,7 @@ def routes(cls, cache=True): routes_path = os.path.dirname(__file__)+ '/routes.yaml' routes = cls.get_yaml(routes_path) cls.route_cache = routes + return routes #### THE FINAL TOUCH , ROUTE ALL OF THE MODULES TO THE CURRENT MODULE BASED ON THE routes CONFIG @@ -708,10 +652,7 @@ def fn_generator( *args, module_ph, fn_ph, **kwargs): return {'success': False, 'msg': 'routes not found'} routes = cls.routes() if callable(cls.routes) else cls.routes for m, fns in routes.items(): - if fns in ['all', '*']: - fns = c.functions(m) for fn in fns: - if type(fn) in [list, set, tuple] and len(fn) == 2: # option 1: ['fn_name', 'name_in_current_module'] from_fn = fn[0] @@ -1225,7 +1166,6 @@ def base_config(cls, cache=True): return cls._base_config - default_port_range = [50050, 50150] # the port range between 50050 and 50150 @classmethod def put_json(cls, @@ -1934,17 +1874,9 @@ def is_generator(cls, obj): result = inspect.isgeneratorfunction(obj) return result @classmethod - def get_parents(cls, obj = None,recursive=True, avoid_classes=['object']) -> List[str]: + def get_parents(cls, obj = None,recursive=False, avoid_classes=['object']) -> List[str]: obj = cls.resolve_object(obj) parents = list(obj.__bases__) - if recursive: - for parent in parents: - parent_parents = cls.get_parents(parent, recursive=recursive) - if len(parent_parents) > 0: - for pp in parent_parents: - if pp.__name__ not in avoid_classes: - - parents += [pp] return parents @classmethod @@ -2137,15 +2069,11 @@ def lines_of_code(cls, code:str=None): return len(code.split('\n')) @classmethod - def code(cls, module = None, search=None, *args, **kwargs): - if '/' in str(module) or module in cls.fns(): - return cls.fn_code(module) - module = cls.resolve_object(module) - text = cls.get_text( module.filepath(), *args, **kwargs) - if search != None: - find_lines = cls.find_lines(text=text, search=search) - return find_lines - return text + def code(cls, obj = None, search=None, *args, **kwargs): + import inspect + obj = cls.resolve_object(obj) + return inspect.getsource(obj) + pycode = code @classmethod def chash(cls, *args, **kwargs): @@ -2221,44 +2149,6 @@ def fn_info(cls, fn:str='test_fn') -> dict: 'mode': mode } - @classmethod - def set_line(cls, idx:int, text:str): - code = cls.code() - lines = code.split('\n') - if '\n' in text: - front_lines = lines[:idx] - back_lines = lines[idx:] - new_lines = text.split('\n') - lines = front_lines + new_lines + back_lines - else: - lines[idx-1] = text - new_code = '\n'.join(lines) - cls.put_text(cls.filepath(), new_code) - return {'success': True, 'msg': f'Set line {idx} to {text}'} - - @classmethod - def add_line(cls, idx=0, text:str = '', module=None ): - """ - add line to an index of the module code - """ - - code = cls.code() if module == None else c.module(module).code() - lines = code.split('\n') - new_lines = text.split('\n') if '\n' in text else [text] - lines = lines[:idx] + new_lines + lines[idx:] - new_code = '\n'.join(lines) - cls.put_text(cls.filepath(), new_code) - return {'success': True, 'msg': f'Added line {idx} to {text}'} - - @classmethod - def get_line(cls, idx): - code = cls.code() - lines = code.split('\n') - assert idx < len(lines), f'idx {idx} is out of range for {len(lines)}' - line = lines[max(idx, 0)] - print(len(line)) - return line - @classmethod def fn_defaults(cls, fn): """ @@ -2382,7 +2272,7 @@ def parent2functions(cls, obj=None): @classmethod def get_functions(cls, obj: Any = None, search = None, - include_parents:bool=True, + include_parents:bool=False, include_hidden:bool = False) -> List[str]: ''' Get a list of functions in a class @@ -2392,8 +2282,9 @@ def get_functions(cls, obj: Any = None, include_parents: whether to include the parent functions include_hidden: whether to include hidden functions (starts and begins with "__") ''' - is_root_module = cls.is_root_module() obj = cls.resolve_object(obj) + is_module = cls.is_module(obj) + is_root_module = is_module and cls.is_root_module() if include_parents: parent_functions = cls.parent_functions(obj) else: @@ -2672,23 +2563,6 @@ def is_dir_module(cls, path:str) -> bool: return True return False - @classmethod - def add_line(cls, path:str, text:str, line=None) -> None: - # Get the absolute path of the file - path = cls.resolve_path(path) - text = str(text) - # Write the text to the file - if line != None: - line=int(line) - lines = cls.get_text(path).split('\n') - lines = lines[:line] + [text] + lines[line:] - - text = '\n'.join(lines) - with open(path, 'w') as file: - file.write(text) - - return {'success': True, 'msg': f'Added line to {path}'} - @staticmethod def is_imported(package:str) : return bool(package in sys.modules) @@ -2698,24 +2572,6 @@ def is_parent(cls, obj=None): obj = obj or cls return bool(obj in cls.get_parents()) - @classmethod - def find_code_lines(cls, search:str = None , module=None) -> List[str]: - module_code = cls.get_module(module).code() - return cls.find_lines(search=search, text=module_code) - - @classmethod - def find_lines(self, text:str, search:str) -> List[str]: - """ - Finds the lines in text with search - """ - found_lines = [] - lines = text.split('\n') - for line in lines: - if search in line: - found_lines += [line] - - return found_lines - @classmethod def params(cls, fn='__init__'): params = cls.fn_defaults(fn) @@ -2885,7 +2741,6 @@ def path2simple(cls, @classmethod def find_classes(cls, path='./', working=False, avoid_folders = avoid_folders): - path = os.path.abspath(path) if os.path.isdir(path): classes = [] @@ -2970,11 +2825,15 @@ def find_class2functions(cls, path, working=False): def path2objectpath(cls, path:str, **kwargs) -> str: libpath = cls.libpath if path.startswith(libpath): - path = path.replace(libpath , '')[1:].replace('/', '.').replace('.py', '') + path = path.replace(libpath , '')[1:].replace('/', '.') else: pwd = cls.pwd() if path.startswith(pwd): - path = path.replace(pwd, '')[1:].replace('/', '.').replace('.py', '') + path = path.replace(pwd, '')[1:].replace('/', '.') + + if path.endswith('.py'): + path = path[:-3] + return path.replace('__init__.', '.') @@ -2987,8 +2846,6 @@ def objecpath2path(cls, objectpath:str, **kwargs) -> str: return path raise ValueError(f'Path not found for objectpath {objectpath}') - - @classmethod def find_functions(cls, path = './', working=False): fns = [] @@ -3071,16 +2928,7 @@ def import_module(cls, try_prefixes = ['commune','commune.modules', 'modules', 'commune.subspace', 'subspace'] ) -> 'Object': from importlib import import_module - if included_pwd_in_path and not cls.included_pwd_in_path: - import sys - pwd = cls.pwd() - sys.path.append(pwd) - sys.path = list(set(sys.path)) - cls.included_pwd_in_path = True - # if commune is in the path more than once, we want to remove the duplicates - if cls.libname in import_path: - import_path = cls.libname + import_path.split(cls.libname)[-1] - pwd = cls.pwd() + import sys try: return import_module(import_path) except Exception as _e: @@ -3150,7 +2998,6 @@ def module_exists(cls, module:str, **kwargs) -> bool: ''' try: module_path = c.simple2path(module) - print(module_path) module_exists = c.exists(module_path) except: module_exists = False @@ -3215,7 +3062,6 @@ def local_tree(cls ): @classmethod def get_tree(cls, path): - print(path) class_paths = cls.find_classes(path) simple_paths = cls.simplify_object_paths(class_paths) return dict(zip(simple_paths, class_paths)) @@ -3256,11 +3102,10 @@ def get_module(cls, # ensure module if verbose: c.print(f'Loaded {path} in {c.time() - t0} seconds', color='green') + if not c.is_module(module): + setattr(module, 'module_name', lambda : module.__name__) if init_kwargs != None: module = module(**init_kwargs) - is_module = c.is_module(module) - if not is_module: - module = cls.obj2module(module) if cache: c.module_cache[cache_key] = module return module @@ -3651,16 +3496,6 @@ def ps(cls, *args, **kwargs): @classmethod def addresses(cls, *args, **kwargs) -> List[str]: return list(cls.namespace(*args,**kwargs).values()) - - @classmethod - def task(cls, fn, timeout=1, mode='asyncio'): - - if mode == 'asyncio': - assert callable(fn) - future = asyncio.wait_for(fn, timeout=timeout) - return future - else: - raise NotImplemented @classmethod def shuffle(cls, x:list)->list: @@ -3683,13 +3518,6 @@ def wrapper(*args, **kwargs): print(f'Retrying {fn.__name__} {i+1}/{trials}') return wrapper - - @staticmethod - def reverse_map(x:dict)->dict: - ''' - reverse a dictionary - ''' - return {v:k for k,v in x.items()} @classmethod def df(cls, x, **kwargs): @@ -3800,18 +3628,6 @@ def get_util(cls, util:str, prefix='commune.utils'): def random_float(cls, min=0, max=1): return random.uniform(min, max) - @classmethod - def random_ratio_selection(cls, x:list, ratio:float = 0.5)->list: - if type(x) in [float, int]: - x = list(range(int(x))) - assert len(x)>0 - if ratio == 1: - return x - assert ratio > 0 and ratio <= 1 - random.shuffle(x) - k = max(int(len(x) * ratio),1) - return x[:k] - @classmethod def filter(cls, text_list: List[str], filter_text: str) -> List[str]: return [text for text in text_list if filter_text in text] @@ -4153,8 +3969,18 @@ def vscode(self, path = None): path = c.module(path).dirpath() else: if path == None: - path = c.libpath if self.is_root() else self.dirpath() + path = c.libpath if self.is_root_module() else self.dirpath() return path + + def util2fn(self)-> str: + utils = self.utils() + util2fn = {} + for u in utils: + name = u.split('.')[-1] + fn = c.import_object(u) + util2fn[name] = fn + return util2fn + def path(self): return self.filepath() diff --git a/commune/modules/git/git.py b/commune/modules/git/git.py index 949e7d5f..032916db 100644 --- a/commune/modules/git/git.py +++ b/commune/modules/git/git.py @@ -9,19 +9,17 @@ def is_repo(self, libpath:str ): # has the .git folder return c.cmd(f'ls -a {libpath}').count('.git') > 0 - @staticmethod - def clone(repo_url:str, target_directory:str = None, branch=None): + def clone(repo_url:str, path:str = None, branch=None): prefix = 'https://github.com/' if not repo_url.startswith(prefix): repo_url = f'{prefix}{repo_url}' - - if target_directory == None: - target_directory = repo_url.split('/')[-1].split('.')[0] + if path == None: + path = path.split('/')[-1].split('.')[0] else: - target_directory = c.resolve_path(target_directory) + path = c.resolve_path(path) # Clone the repository - return subprocess.run(['git', 'clone', repo_url, target_directory]) + return subprocess.run(['git', 'clone', repo_url, path]) @@ -130,7 +128,10 @@ def merge_remote_repo(cls, remote_name:str, remote_url:str, remote_branch:str, l cmd = ' && '.join(cmds) return c.cmd(cmd, cwd) - - - + @classmethod + def clone(cls, url): + prefix = 'https://github.com/' + if not url.startswith(prefix): + url = prefix + url + return c.cmd(f'git clone {url}', verbose=True, cwd=c.libpath) diff --git a/commune/modules/template/template.py b/commune/modules/template/template.py deleted file mode 100644 index f21b5a71..00000000 --- a/commune/modules/template/template.py +++ /dev/null @@ -1,61 +0,0 @@ -import commune as c - - -class Template(c.Module): - def __init__(self, obj=None, ): - is_fn = callable(obj) - if is_fn: - self.set_fn(obj) - else: - self.set_module(obj) - def set_module(self, module): - if module == None: - return None - self.module = module - for fn in dir(module): - setattr(self, fn, getattr(self, fn)) - - def set_fn(self, fn): - if fn == None: - return None - self.fn = fn - - - def forward(self, *args, **kwargs): - return self.fn(*args, **kwargs) - - def from_fn(cls, fn): - return cls(fn=fn) - - def from_module(cls, module): - return cls(module=module) - - - - def test(self): - print('test') - template = c.module('template')() - - def fn1(): - return 0 - - def fn2(): - return 1 - - template.set_fn(fn1) - assert template.forward() == 0 - template.set_fn(fn2) - assert template.forward() == 1 - - class Custom(c.Module): - - def test(self, a=1, b=2): - return a+b - - custom = Custom() - template = c.module('template')(obj=custom) - assert template.forward(a=3, b=4) == 7 - print('template test passed') - - - diff --git a/commune/namespace.py b/commune/namespace.py index 5019a62d..c778b9a5 100644 --- a/commune/namespace.py +++ b/commune/namespace.py @@ -5,7 +5,6 @@ # THIS IS WHAT THE INTERNET IS, A BUNCH OF NAMESPACES, AND A BUNCH OF SERVERS, AND A BUNCH OF MODULES. # THIS IS THE INTERNET OF INTERNETS. class Namespace(c.Module): - # the default network : str = 'local' @classmethod diff --git a/commune/serializer.py b/commune/serializer/__init__.py similarity index 98% rename from commune/serializer.py rename to commune/serializer/__init__.py index 17f9280d..bb67f884 100644 --- a/commune/serializer.py +++ b/commune/serializer/__init__.py @@ -92,9 +92,9 @@ def deserialize(self, x) -> object: return x def serializer_map(self): - type_path = self.dirpath() + '/serializers' + type_path = self.dirpath() module_paths = c.find_objects(type_path) - return {p.split('.')[-2]: c.obj(p)() for p in module_paths} + return {p.split('.')[-2]: c.obj(p)() for p in module_paths if '__init__' not in p} def types(self): diff --git a/commune/serializers/bytes.py b/commune/serializer/bytes.py similarity index 100% rename from commune/serializers/bytes.py rename to commune/serializer/bytes.py diff --git a/commune/serializers/munch.py b/commune/serializer/munch.py similarity index 100% rename from commune/serializers/munch.py rename to commune/serializer/munch.py diff --git a/commune/serializers/numpy.py b/commune/serializer/numpy.py similarity index 100% rename from commune/serializers/numpy.py rename to commune/serializer/numpy.py diff --git a/commune/serializers/pandas.py b/commune/serializer/pandas.py similarity index 100% rename from commune/serializers/pandas.py rename to commune/serializer/pandas.py diff --git a/commune/serializers/torch.py b/commune/serializer/torch.py similarity index 100% rename from commune/serializers/torch.py rename to commune/serializer/torch.py diff --git a/commune/subspace.py b/commune/subspace.py index fa11c163..d00eccd8 100644 --- a/commune/subspace.py +++ b/commune/subspace.py @@ -2,14 +2,12 @@ from retry import retry from typing import * import json -import os import commune as c import requests from substrateinterface import SubstrateInterface __ss58_format__ = 42 - class Subspace(c.Module): """ Handles interactions with the subspace chain. @@ -25,8 +23,78 @@ class Subspace(c.Module): 'get_stake_to', 'get_stake_from'] + subnet_param_features = [ + "ImmunityPeriod", + "MinAllowedWeights", + "MaxAllowedWeights", + "Tempo", + "MaxAllowedUids", + "Founder", + "FounderShare", + "IncentiveRatio", + "TrustRatio", + "SubnetNames", + "MaxWeightAge", + "BondsMovingAverage", + "MaximumSetWeightCallsPerEpoch", + "MinValidatorStake", + "MaxAllowedValidators", + "ModuleBurnConfig", + "SubnetMetadata", + 'SubnetGovernanceConfig' + ] + + global_param_features = [ + 'MaxNameLength', + 'MaxAllowedModules', + 'MaxAllowedSubnets', + 'MaxRegistrationsPerBlock', + 'MinWeightStake', + ] + supported_modes = ['http', 'ws'] + urls = { + "main": [ + "commune-api-node-0.communeai.net", + "commune-api-node-1.communeai.net", + "commune-api-node-2.communeai.net", + "commune-api-node-3.communeai.net", + "commune-api-node-4.communeai.net", + "commune-api-node-5.communeai.net", + "commune-api-node-6.communeai.net", + "commune-api-node-7.communeai.net", + "commune-api-node-8.communeai.net", + "commune-api-node-9.communeai.net", + "commune-api-node-10.communeai.net", + "commune-api-node-11.communeai.net", + "commune-api-node-12.communeai.net", + "commune-api-node-13.communeai.net", + "commune-api-node-14.communeai.net", + "commune-api-node-15.communeai.net", + "commune-api-node-16.communeai.net", + "commune-api-node-17.communeai.net", + "commune-api-node-18.communeai.net", + "commune-api-node-19.communeai.net", + "commune-api-node-20.communeai.net", + "commune-api-node-21.communeai.net", + "commune-api-node-22.communeai.net", + "commune-api-node-23.communeai.net", + "commune-api-node-24.communeai.net", + "commune-api-node-25.communeai.net", + "commune-api-node-26.communeai.net", + "commune-api-node-27.communeai.net", + "commune-api-node-28.communeai.net", + "commune-api-node-29.communeai.net", + "commune-api-node-30.communeai.net", + "commune-api-node-31.communeai.net" + ], + "test": [ + "testnet-commune-api-node-0.communeai.net" + ] + + } + def __init__(self, network: str = 'main', network_mode: str = 'ws', @@ -40,8 +108,6 @@ def __init__(self, **kwargs, ): self.config = self.set_config(locals()) - - # merge the config with the subspace config self.config = c.dict2munch({**Subspace.config(), **self.config}) self.set_network(network ) self.set_netuid(netuid) @@ -50,32 +116,11 @@ def __init__(self, init_subspace = __init__ - ########################### - #### Global Parameters #### - ########################### def set_netuid(self, netuid:int): self.netuid = netuid return self.netuid - def feature2storage(self, feature:str): - storage = '' - capitalize = True - for i, x in enumerate(feature): - if capitalize: - x = x.upper() - capitalize = False - - if '_' in x: - capitalize = True - - storage += x - return storage - - def name2feature(self, name='min_stake_fam'): - chunks = name.split('_') - return ''.join([c.capitalize() for c in chunks]) - def get_account(self, key = None): key = self.resolve_key_ss58(key) account = self.substrate.query( @@ -134,30 +179,6 @@ def clean_keys(self, keys_left += [key] return {'success': True, 'msg': 'cleaned keys', 'keys_left': len(keys_left), 'rm_keys': len(rm_keys)} - - def load_launcher_keys(self, amount=600, **kwargs): - launcher_keys = self.launcher_keys() - key2address = c.key2address() - destinations = [] - amounts = [] - launcher2balance = c.get_balances(launcher_keys) - for k in launcher_keys: - k_address = key2address[k] - amount_needed = amount - launcher2balance.get(k_address, 0) - if amount_needed > 0: - destinations.append(k_address) - amounts.append(amount_needed) - else: - c.print(f'{k} has enough balance --> {launcher2balance.get(k, 0)}') - - return c.transfer_many(amounts=amounts, destinations=destinations, **kwargs) - - def launcher_keys(self, netuid=0, min_stake=500, **kwargs): - keys = c.keys() - key2balance = c.key2balance(netuid=netuid,**kwargs) - key2balance = {k: v for k,v in key2balance.items() if v > min_stake} - return [k for k in keys] - def resolve_key(self, key = None): if key == None: @@ -176,18 +197,7 @@ def resolve_key(self, key = None): assert hasattr(key, 'key'), f"Invalid Key {key} as it should have ss58_address attribute." return key - - def filter_url(self, url): - """ - Filter urls based on the url_search parameter - """ - if self.config.url_search == None: - return True - url_search_terms = [url.strip() for x in self.config.url_search.split(',')] - return any([x in url for x in url_search_terms]) - - - def resolve_url(self, + def get_url(self, url = None, mode='ws', network=None, @@ -199,15 +209,15 @@ def resolve_url(self, return url network = self.resolve_network(network) if url == None: - urls_map = self.urls() - urls = urls_map.get(mode, []) + urls = self.urls[network] assert len(urls) > 0, f'No urls found for network {network} and mode {mode}' - if len(urls) > 1: - urls_map = list(filter(self.filter_url, urls)) url = c.choice(urls) + if 'ws' in mode and not url.startswith('ws'): + url = f'wss://{url}' + elif 'http' in mode and not url.startswith('http'): + url = f'https://{url}' return url - @property def network(self): return self.config.network @@ -216,7 +226,6 @@ def network(self): def network(self, value): self.config.network = value - _substrate = None @property def substrate(self): @@ -224,9 +233,6 @@ def substrate(self): self.set_network() return self._substrate - def urls(self): - return c.get_yaml(self.dirpath() + '/urls.yaml').get(self.network) - @substrate.setter def substrate(self, value): self._substrate = value @@ -277,7 +283,7 @@ def get_substrate(self, for i in range(trials): try: - url = self.resolve_url(url, mode=mode, network=network) + url = self.get_url(url, mode=mode, network=network) if not update: if url in self.url2substrate: @@ -514,8 +520,6 @@ def to_nanos(self,x): return x * (10**self.token_decimals) from_token = to_nanos - - """ Returns the stake under a coldkey - hotkey pairing """ def format_amount(self, x, fmt='nano', decimals = None, format=None, features=None, **kwargs): @@ -564,8 +568,6 @@ def query_multi(self, params_batch , raise e return results - - def resolve_network(self, network: Optional[int] = None, **kwargs) -> int: @@ -706,7 +708,6 @@ def compose_call(self, if t == trials - 1: raise e - tx_state['end_time'] = c.datetime() tx_state['status'] = 'completed' tx_state['response'] = response @@ -781,15 +782,7 @@ def resolve_key_ss58(self, key:str,netuid:int=0, resolve_name=True, **kwargs): key_address = key.ss58_address return key_address - - global_param_features = [ - 'MaxNameLength', - 'MaxAllowedModules', - 'MaxAllowedSubnets', - 'MaxRegistrationsPerBlock', - 'MinWeightStake', - ] - + def global_params(self, update = False, max_age = 1000, @@ -821,7 +814,6 @@ def global_params(self, subnet_params[k] = self.format_amount(subnet_params[k], fmt=fmt) return subnet_params - def global_state(self, max_age=None, update=False): max_age = max_age or self.config.max_age global_state = self.get('global_state', None, max_age=max_age, update=update) @@ -964,7 +956,6 @@ def add_profit_shares( return response - def stake_many( self, modules:List[str] = None, amounts:Union[List[str], float, int] = None, @@ -1143,7 +1134,6 @@ def update_module( # IF SUCCESSFUL, MOVE THE KEYS, AS THIS IS A NON-REVERSIBLE OPERATION - return reponse update = update_server = update_module @@ -1319,9 +1309,6 @@ def my_stake_to(self, fmt='j', **kwargs): return my_stake_to - - - def my_stake_from(self, netuid = 0, block=None, update=False, fmt='j', max_age=1000 , **kwargs): stake_from_tuples = self.stake_from(netuid=netuid, block=block, @@ -1414,8 +1401,7 @@ def stats(self, color = c.random_color() c.print(f'\n {subnet_name.upper()} :: (netuid:{netuid})\n', color=color) c.print(stats[netuid], color=color) - - + modules = modules or self.my_modules(netuid=netuid, update=update, fmt=fmt, search=search) stats = [] @@ -1490,10 +1476,6 @@ def update_modules(self, search=None, c.print(future.result()) return results - - - - def stake( self, module: Optional[str] = None, # defaults to key if not provided @@ -1557,9 +1539,6 @@ def key_info(self, key:str = None, netuid='all', detail=0, timeout=10, update=Fa return key_info - - - def subnet2modules(self, **kwargs): subnet2modules = {} @@ -1569,23 +1548,6 @@ def subnet2modules(self, **kwargs): return subnet2modules - def staking_rewards( self, - key: str = None, - module_key=None, - block: Optional[int] = None, - timeout=20, - period = 100, - names = False, - fmt='j' , update=False, - max_age = 1000, - **kwargs) -> Optional['Balance']: - - block = int(block or self.block) - block_yesterday = int(block - period) - day_before_stake = self.my_total_stake_to(key=key, module_key=module_key, block=block_yesterday, timeout=timeout, names=names, fmt=fmt, update=update, max_age=max_age, **kwargs) - day_after_stake = self.my_total_stake_to(key=key, module_key=module_key, block=block, timeout=timeout, names=names, fmt=fmt, update=update, max_age=max_age, **kwargs) - return (day_after_stake - day_before_stake) - def registered_servers(self, netuid = 0, **kwargs): netuid = self.resolve_netuid(netuid) servers = c.servers() @@ -1632,16 +1594,6 @@ def key2balance(self, search=None, key2balance = {address2key[k]: v for k,v in key2balance.items()} return key2balance - def empty_keys(self, block=None, update=False, max_age=1000, fmt='j'): - key2address = c.key2address() - key2value = self.key2value( block=block, update=update, max_age=max_age, fmt=fmt) - empty_keys = [] - for key,key_address in key2address.items(): - key_value = key2value.get(key_address, 0) - if key_value == 0: - empty_keys.append(key) - return empty_keys - def profit_shares(self, key=None, **kwargs) -> List[Dict[str, Union[str, int]]]: key = self.resolve_module_key(key) return self.query_map('ProfitShares', **kwargs) @@ -1835,34 +1787,6 @@ def registrations_per_block(self,**kwargs) -> int: def max_registrations_per_block(self, **kwargs) -> int: return self.query('MaxRegistrationsPerBlock', params=[], **kwargs) - ################# - #### Serving #### - ################# - def update_global( - self, - key: str = None, - network : str = 'main', - sudo: bool = True, - **params, - ) -> bool: - - key = self.resolve_key(key) - network = self.resolve_network(network) - global_params = self.global_params(fmt='nanos') - global_params.update(params) - params = global_params - for k,v in params.items(): - if isinstance(v, str): - params[k] = v.encode('utf-8') - # this is a sudo call - return self.compose_call(fn='update_global', - params=params, - key=key, - sudo=sudo) - - - ################# - #### Serving #### ################# def vote_proposal( self, @@ -1992,9 +1916,7 @@ def set_weights( weights = (weights / weights.sum()) * vector_length # normalize the weights between 0 and 1 weights = torch.clamp(weights, 0, vector_length) # min_value and max_value are between 0 and 1 - params = {'uids': list(map(int, uids)), - 'weights': list(map(int, weights.tolist())), - 'netuid': netuid} + params = {'uids': list(map(int, uids)), 'weights': list(map(int, weights.tolist())), 'netuid': netuid} return self.compose_call('set_weights',params = params , key=key, nonce=nonce, **kwargs) @@ -2052,29 +1974,6 @@ def registered_keys(self, netuid='all'): return registered_keys - subnet_param_features = [ - "ImmunityPeriod", - "MinAllowedWeights", - "MaxAllowedWeights", - "Tempo", - "MaxAllowedUids", - "Founder", - "FounderShare", - "IncentiveRatio", - "TrustRatio", - "SubnetNames", - "MaxWeightAge", - "BondsMovingAverage", - "MaximumSetWeightCallsPerEpoch", - "MinValidatorStake", - "MaxAllowedValidators", - "ModuleBurnConfig", - "SubnetMetadata", - 'SubnetGovernanceConfig' - ] - - - def stake_to(self, block=None, max_age=1000, update=False, fmt='nano', **kwargs): stake_to = self.query_map('StakeTo', block=block, max_age=max_age, update=update, **kwargs) format_value = lambda v: {v_k: self.format_amount(v_v, fmt=fmt) for v_k, v_v in v.items()} @@ -2353,27 +2252,6 @@ def subnet_names(self , search=None, update=False, block=None, max_age=60, **kwa def subnets(self, **kwargs) -> Dict[int, str]: return self.subnet_names(**kwargs) - - def num_subnets(self, **kwargs) -> int: - return len(self.subnets(**kwargs)) - - def subnet2stake(self, fmt='j'): - netuid2subnet = self.netuid2subnet() - netuid2stake = self.netuid2stake(fmt=fmt) - subnet2stake = {} - for netuid, subnet in netuid2subnet.items(): - subnet2stake[subnet] = netuid2stake[netuid] - return subnet2stake - - def netuid2stake(self, fmt='j', **kwargs): - netuid2stake = self.query_map('TotalStake', **kwargs) - for netuid, stake in netuid2stake.items(): - netuid2stake[netuid] = self.format_amount(stake, fmt=fmt) - return netuid2stake - - def netuid2n(self, fmt='j', **kwargs): - netuid2n = self.query_map('N', **kwargs) - return netuid2n def trust(self, netuid = 0, @@ -2388,6 +2266,7 @@ def incentives(self, update:bool = False, **kwargs): return self.query_vector('Incentive', netuid=netuid, block=block, update=update, **kwargs) + incentive = incentives def last_update(self, netuid = 0, update=False, **kwargs): @@ -2425,20 +2304,7 @@ def uids(self, keys = list(keys.keys()) return keys - def subnet2n(self, fmt='j', **kwargs): - netuid2n = self.netuid2n(fmt=fmt, **kwargs) - netuid2subnet = self.netuid2subnet() - subnet2n = {} - for netuid, subnet in netuid2subnet.items(): - subnet2n[subnet] = netuid2n[netuid] - return subnet2n - def subnet2stakes(self, block=None, update=False, fmt='j', **kwargs): - subnet2stakes = {} - for netuid in self.netuids( update=update): - subnet2stakes[netuid] = self.stakes(netuid=netuid, block=block, update=update, fmt=fmt, **kwargs) - return subnet2stakes - def subnet_state(self, netuid='all', block=None, update=False, fmt='j', **kwargs): subnet_state = { @@ -2473,7 +2339,6 @@ def uid2key(self, uid=None, return uid2key[uid] return uid2key - def key2uid(self, key = None, netuid: int = 0, update=False, netuids=None , **kwargs): uid2key = self.uid2key( netuid=netuid, update=update, **kwargs) reverse_map = lambda x: {v: k for k,v in x.items()} @@ -2576,7 +2441,7 @@ def get_module(self, c.print(f'No module specified, using {module}') module = c.key2address().get(module, module) - url = self.resolve_url( mode=mode) + url = self.get_url( mode=mode) module_key = module is_valid_key = c.valid_ss58_address(module) if not is_valid_key: @@ -2613,7 +2478,6 @@ def get_module(self, assert module['key'] == module_key, f"Key mismatch {module['key']} != {module_key}" return module - def root_valis(self, search=None, netuid = 0, update=False, **kwargs): root_valis = [] for module in self.get_modules(netuid=netuid, update=update, **kwargs): @@ -2624,26 +2488,16 @@ def root_valis(self, search=None, netuid = 0, update=False, **kwargs): root_valis += [module ] return c.df(root_valis)[['name', 'key', 'stake']] - def root_keys(self, netuid = 0, update=False, **kwargs): return self.keys(netuid=netuid, update=update, **kwargs) - - - def registration_block(self, netuid: int = 0, update=False, **kwargs): registration_blocks = self.query_map('RegistrationBlock', netuid=netuid, update=update, **kwargs) return registration_blocks regblocks = registration_blocks = registration_block - - - - - - def key2name(self, key=None, netuid: int = None, update=False) -> Dict[str, str]: key2name = {v:k for k,v in self.name2key(netuid=netuid, update=update).items()} @@ -2651,9 +2505,6 @@ def key2name(self, key=None, netuid: int = None, update=False) -> Dict[str, str] return key2name[key] return key2name - - - def name2key(self, name:str=None, max_age=1000, timeout=30, @@ -2679,12 +2530,9 @@ def name2key(self, name:str=None, return self.name2key(name=name, timeout=timeout, netuid=netuid, update=True, trials=trials, **kwargs) - + return name2key - - - - + def name2uid(self, name = None, netuid: int = 0, search=None) -> int: netuid = self.resolve_netuid(netuid) uid2name = self.uid2name(netuid=netuid) @@ -2726,11 +2574,9 @@ def subnet2netuid(self, subnet=None, update=False, **kwargs ) -> Dict[str, str return subnet2netuid name2netuid = subnet2netuid - def get_uid( self, key: str, netuid: int = 0, block: Optional[int] = None, update=False, **kwargs) -> int: return self.query( 'Uids', block=block, params=[ netuid, key ] , update=update, **kwargs) - def weights(self, netuid = 0, update=False, **kwargs) -> list: weights = self.query_map('Weights',netuid=netuid, update=update, **kwargs) @@ -2758,8 +2604,6 @@ def resolve_uid(self, uid=None, netuid=None, **kwargs) -> int: return uid - - def get_weights(self, key=None, netuid = 0, update=False, **kwargs) -> list: uid = self.resolve_uid(key, netuid=netuid) weights = self.query('Weights', params=[netuid, uid], update=update, **kwargs) @@ -2781,32 +2625,6 @@ def total_emissions(self, netuid = 9, block=None, update=False, fmt = 'j', **kwa return sum(emissions) - - - # def state(self, block=None, netuid='all', update=False, max_age=10000, fmt='j', **kwargs): - # subnet_params = self.subnet_params(block=block, netuid=netuid, max_age=max_age, **kwargs) - # subnet2emissions = self.emissions(netuid=netuid, max_age=max_age, block=block, **kwargs) - # subnet2staketo = self.stake_to(netuid=netuid, block=block, update=update, fmt=fmt, **kwargs) - # subnet2incentives = self.incentives(netuid=netuid, block=block, update=update, fmt=fmt, **kwargs) - # subnet2trust = self.trust(netuid=netuid, block=block, update=update, fmt=fmt, **kwargs) - # subnet2keys = self.keys(netuid=netuid, block=block, update=update, **kwargs) - - # subnet2state = {} - # for netuid, params in subnet_params.items(): - # subnet_state = { - # 'params': params, - # 'incentives': subnet2incentives[netuid], - # 'emissions': subnet2emissions[netuid], - # '' - # 'stake_to': subnet2staketo[netuid], - # 'keys': subnet2keys[netuid], - - # } - # subnet_state[netuid] = subnet_state - - # return subnet2state - - def netuid2emission(self, fmt='j', period='day', names=None, **kwargs): netuid2emission = {} netuid2tempo = None @@ -2832,9 +2650,6 @@ def subnet2emission(self, fmt='j', period='day', **kwargs): def global_emissions(self, **kwargs): return sum(list(self.subnet2emissions( **kwargs).values())) - - - def subnet2params( self, block: Optional[int] = None ) -> Optional[float]: netuids = self.netuids() subnet2params = {} @@ -2844,9 +2659,6 @@ def subnet2params( self, block: Optional[int] = None ) -> Optional[float]: subnet2params[subnet] = self.subnet_params(netuid=netuid, block=block) return subnet2params - - - ################# #### UPDATE SUBNET #### ################# @@ -2883,7 +2695,6 @@ def update_subnet( params['netuid'] = netuid return self.compose_call(fn='update_subnet', params=params, key=key, nonce=nonce) - ################# #### Serving #### ################# @@ -2912,8 +2723,6 @@ def propose_subnet_update( return response - - def get_stake( self, key_ss58: str, block: Optional[int] = None, netuid:int = None , fmt='j', update=True ) -> Optional['Balance']: key_ss58 = self.resolve_key_ss58( key_ss58) @@ -2921,16 +2730,11 @@ def get_stake( self, key_ss58: str, block: Optional[int] = None, netuid:int = No stake = self.query( 'Stake',params=[netuid, key_ss58], block=block , update=update) return self.format_amount(stake, fmt=fmt) - - def min_register_stake(self, netuid: int = 0, fmt='j', **kwargs) -> float: netuid = self.resolve_netuid(netuid) min_burn = self.min_burn( fmt=fmt) min_stake = self.min_stake(netuid=netuid, fmt=fmt) return min_stake + min_burn - - - def resolve_netuid(self, netuid: int = None) -> int: ''' @@ -2966,10 +2770,6 @@ def blocks_until_vote(self, netuid=None, **kwargs): def emission_per_epoch(self, netuid=None): return self.subnet(netuid=netuid)['emission']*self.epoch_time(netuid=netuid) - - - - def get_stake_to( self, key: str = None, module_key=None, @@ -2990,12 +2790,10 @@ def get_stake_from( self, key: str, block: Optional[int] = None, fmt='j', updat stake_from = {k: self.format_amount(v, fmt=fmt) for k, v in stake_from.items()} return stake_from - def epoch_time(self, netuid=None, update=False, **kwargs): netuid = self.resolve_netuid(netuid) return self.subnet_params(netuid=netuid, update=update, **kwargs)['tempo']*self.block_time - def seconds_per_day(self ): return 24*60*60 @@ -3006,8 +2804,7 @@ def epochs_per_day(self, netuid=None): def seconds_per_epoch(self, netuid=0): netuid =self.resolve_netuid(netuid) return self.block_time * self.subnet_params(netuid=netuid)['tempo'] - - + def format_module(self, module: 'ModuleInfo', fmt:str='j') -> 'ModuleInfo': U16_MAX = 2**16 - 1 for k in ['emission']: @@ -3018,49 +2815,6 @@ def format_module(self, module: 'ModuleInfo', fmt:str='j') -> 'ModuleInfo': module['stake_from'] = {k: self.format_amount(v, fmt=fmt) for k, v in module['stake_from']} return module - - - def netuid2module(self, update=False, fmt:str='j', **kwargs) -> 'ModuleInfo': - netuids = self.netuids(update=update) - future2netuid = {} - for netuid in netuids: - f = c.submit(self.get_module, dict(netuid=netuid, update=update, fmt=fmt, **kwargs)) - future2netuid[f] = netuid - netuid2module = {} - progress = c.tqdm(len(netuids)) - - for future in c.as_completed(future2netuid): - netuid = future2netuid.pop(future) - module = future.result() - if not c.is_error(module): - netuid2module[netuid] = module - progress.update(1) - - return netuid2module - - def netuid2uid(self, key=None, update=False, **kwargs) -> Dict[str, str]: - key = self.resolve_key_ss58(key) - netuids = self.netuids(update=update) - netuid2uid = {} - progress = c.tqdm(len(netuids)) - - future2netuid = {} - for netuid in netuids: - f = c.submit(self.get_uid, kwargs=dict(key=key, netuid=netuid, **kwargs)) - future2netuid[f] = netuid - - for future in c.as_completed(future2netuid): - netuid = future2netuid.pop(future) - uid = future.result() - if uid != None: - netuid2uid[netuid] = uid - progress.update(1) - # sort by netuid key - netuid2uid = dict(sorted(netuid2uid.items(), key=lambda x: x[0])) - - return netuid2uid - - def subnet_state(self, netuid=0, update=False, **kwargs): modules = self.get_modules(netuid=netuid, update=update, **kwargs) @@ -3097,6 +2851,5 @@ def register_subnet(self, key: 'Keypair', name: str, metadata: str | None = None return response - Subspace.run(__name__) diff --git a/commune/template.py b/commune/template.py new file mode 100644 index 00000000..d276fe61 --- /dev/null +++ b/commune/template.py @@ -0,0 +1,22 @@ +import commune as c + +class Custom: + def __init__(self,fam=1): + pass + def testfjdjfhh(self, a=1, b=2): + return a+b + +class Template(c.Module): + @classmethod + def from_object(cls, obj=Custom): + if isinstance(obj, str): + obj = c.import_object(obj) + module_name = obj.__name__.lower() + cls.module_name = lambda *args, **kwargs : module_name + cls._obj = obj + assert not c.module_exists(obj), f'{obj} already exists' + cls.__name__ = obj.__name__ + cls.__doc__ = obj.__doc__ + cls.__str__ = lambda *args, **kwargs : obj.__str__() + return str(cls) + diff --git a/commune/urls.yaml b/commune/urls.yaml index 6de297f1..e69de29b 100644 --- a/commune/urls.yaml +++ b/commune/urls.yaml @@ -1,74 +0,0 @@ -main: - http: - - https://commune.api.onfinality.io/public-http - - https://commune-api-node-0.communeai.net - - https://commune-api-node-1.communeai.net - - https://commune-api-node-2.communeai.net - - https://commune-api-node-3.communeai.net - - https://commune-api-node-4.communeai.net - - https://commune-api-node-5.communeai.net - - https://commune-api-node-6.communeai.net - - https://commune-api-node-7.communeai.net - - https://commune-api-node-8.communeai.net - - https://commune-api-node-9.communeai.net - - https://commune-api-node-10.communeai.net - - https://commune-api-node-11.communeai.net - - https://commune-api-node-12.communeai.net - - https://commune-api-node-13.communeai.net - - https://commune-api-node-14.communeai.net - - https://commune-api-node-15.communeai.net - - https://commune-api-node-16.communeai.net - - https://commune-api-node-17.communeai.net - - https://commune-api-node-18.communeai.net - - https://commune-api-node-19.communeai.net - - https://commune-api-node-20.communeai.net - - https://commune-api-node-21.communeai.net - - https://commune-api-node-22.communeai.net - - https://commune-api-node-23.communeai.net - - https://commune-api-node-24.communeai.net - - https://commune-api-node-25.communeai.net - - https://commune-api-node-26.communeai.net - - https://commune-api-node-27.communeai.net - - https://commune-api-node-28.communeai.net - - https://commune-api-node-29.communeai.net - - https://commune-api-node-30.communeai.net - - https://commune-api-node-31.communeai.net - ws: - - wss://commune.api.onfinality.io/public-ws - - wss://commune-api-node-0.communeai.net - - wss://commune-api-node-1.communeai.net - - wss://commune-api-node-2.communeai.net - - wss://commune-api-node-3.communeai.net - - wss://commune-api-node-4.communeai.net - - wss://commune-api-node-5.communeai.net - - wss://commune-api-node-6.communeai.net - - wss://commune-api-node-7.communeai.net - - wss://commune-api-node-8.communeai.net - - wss://commune-api-node-9.communeai.net - - wss://commune-api-node-10.communeai.net - - wss://commune-api-node-11.communeai.net - - wss://commune-api-node-12.communeai.net - - wss://commune-api-node-13.communeai.net - - wss://commune-api-node-14.communeai.net - - wss://commune-api-node-15.communeai.net - - wss://commune-api-node-16.communeai.net - - wss://commune-api-node-17.communeai.net - - wss://commune-api-node-18.communeai.net - - wss://commune-api-node-19.communeai.net - - wss://commune-api-node-20.communeai.net - - wss://commune-api-node-21.communeai.net - - wss://commune-api-node-22.communeai.net - - wss://commune-api-node-23.communeai.net - - wss://commune-api-node-24.communeai.net - - wss://commune-api-node-25.communeai.net - - wss://commune-api-node-26.communeai.net - - wss://commune-api-node-27.communeai.net - - wss://commune-api-node-28.communeai.net - - wss://commune-api-node-29.communeai.net - - wss://commune-api-node-30.communeai.net - - wss://commune-api-node-31.communeai.net -test: - http: - - https://testnet-commune-api-node-0.communeai.net - ws: - - wss://testnet-commune-api-node-0.communeai.net \ No newline at end of file diff --git a/commune/utils/__init__.py b/commune/utils/__init__.py deleted file mode 100755 index e69de29b..00000000 diff --git a/commune/utils/class.py b/commune/utils/class.py deleted file mode 100644 index 396b4a7c..00000000 --- a/commune/utils/class.py +++ /dev/null @@ -1,67 +0,0 @@ - -from typing import Any - - - -def merge_dicts(a: Any, b: Any, - include_hidden:bool=False, - allow_conflicts:bool=True): - ''' - Merge the dictionaries of a python object into the current object - ''' - for b_k,b_v in b.__dict__.items(): - - if include_hidden == False and (b_k.startswith('__') and b_k.endswith('__')): - #i`f the function name starts with __ then it is hidden - continue - - if not allow_conflicts: - assert not hasattr(a, b_k), f'attribute {b_k} already exists in {a}' - a.__dict__[b_k] = b_v - - return a - -def merge_functions(a: Any, b: Any, - include_hidden:bool=False, - allow_conflicts:bool=True): - ''' - Merge the functions of a python object into the current object - ''' - for b_fn_name in dir(b): - if include_hidden == False: - #i`f the function name starts with __ then it is hidden - if b_fn_name.startswith('__'): - continue - - # if the function already exists in the object, raise an error - if not allow_conflicts: - assert not hasattr(a, b_fn_name), f'function {b_fn_name} already exists in {a}' - - - # get the function from the python object - try: - b_fn = getattr(b, b_fn_name) - except NotImplementedError as e: - print(e) - if callable(b_fn): - setattr(a, b_fn_name, b_fn) - - return a - -def merge(a:Any, b: Any, - include_hidden:bool=False, - allow_conflicts:bool=True) -> 'self': - ''' - merge b into a and return a - ''' - - # merge the attributes - a = merge_dicts(a=a,b=b, include_hidden=include_hidden, allow_conflicts=allow_conflicts) - - # merge the functions - a = merge_functions(a=a,b=b, include_hidden=include_hidden, allow_conflicts=allow_conflicts) - - return a - - - \ No newline at end of file diff --git a/commune/utils/dict.py b/commune/utils/dict.py index 25b3878d..72b73205 100644 --- a/commune/utils/dict.py +++ b/commune/utils/dict.py @@ -543,3 +543,77 @@ def check_kwargs(kwargs:dict, defaults:Union[list, dict], return_bool=False): else: raise e + + + +from typing import Any + + + +def merge_dicts(a: Any, b: Any, + include_hidden:bool=False, + allow_conflicts:bool=True): + ''' + Merge the dictionaries of a python object into the current object + ''' + for b_k,b_v in b.__dict__.items(): + + if include_hidden == False and (b_k.startswith('__') and b_k.endswith('__')): + #i`f the function name starts with __ then it is hidden + continue + + if not allow_conflicts: + assert not hasattr(a, b_k), f'attribute {b_k} already exists in {a}' + a.__dict__[b_k] = b_v + + return a + +def merge_functions(a: Any, b: Any, + include_hidden:bool=False, + allow_conflicts:bool=True): + ''' + Merge the functions of a python object into the current object + ''' + for b_fn_name in dir(b): + if include_hidden == False: + #i`f the function name starts with __ then it is hidden + if b_fn_name.startswith('__'): + continue + + # if the function already exists in the object, raise an error + if not allow_conflicts: + assert not hasattr(a, b_fn_name), f'function {b_fn_name} already exists in {a}' + + + # get the function from the python object + try: + b_fn = getattr(b, b_fn_name) + except NotImplementedError as e: + print(e) + if callable(b_fn): + setattr(a, b_fn_name, b_fn) + + return a + +def merge(a:Any, b: Any, + include_hidden:bool=False, + allow_conflicts:bool=True) -> 'self': + ''' + merge b into a and return a + ''' + + # merge the attributes + a = merge_dicts(a=a,b=b, include_hidden=include_hidden, allow_conflicts=allow_conflicts) + + # merge the functions + a = merge_functions(a=a,b=b, include_hidden=include_hidden, allow_conflicts=allow_conflicts) + + return a + + + +def reverse_map(x:dict)->dict: + ''' + reverse a dictionary + ''' + return {v:k for k,v in x.items()} diff --git a/commune/utils/function.py b/commune/utils/function.py index 283145e5..373046d3 100755 --- a/commune/utils/function.py +++ b/commune/utils/function.py @@ -285,3 +285,18 @@ def try_fn_n_times(fn, kwargs:Dict, try_count_limit: int = 10): + + +def find_class2functions( path, working=False): + import commune as c + import os + path = os.path.abspath(path) + if os.path.isdir(path): + class2functions = {} + for p in c.glob(path+'/**/**.py'): + if p.endswith('.py'): + object_path = c.path2objectpath(p) + response = find_class2functions(p ) + for k,v in response.items(): + class2functions[object_path+ '.' +k] = v + return class2functions diff --git a/commune/utils/hardware.py b/commune/utils/hardware.py deleted file mode 100644 index e69de29b..00000000 diff --git a/commune/utils/math.py b/commune/utils/math.py index 7baf15fb..54d9748f 100644 --- a/commune/utils/math.py +++ b/commune/utils/math.py @@ -106,4 +106,15 @@ def test(cls): print(self.value) assert self.value == (variable_value - window_size/2) print(self.window_values) - \ No newline at end of file + +def random_ratio_selection(x:list, ratio:float = 0.5)->list: + import random + if type(x) in [float, int]: + x = list(range(int(x))) + assert len(x)>0 + if ratio == 1: + return x + assert ratio > 0 and ratio <= 1 + random.shuffle(x) + k = max(int(len(x) * ratio),1) + return x[:k] \ No newline at end of file diff --git a/commune/utils/misc.py b/commune/utils/misc.py new file mode 100644 index 00000000..65d5445a --- /dev/null +++ b/commune/utils/misc.py @@ -0,0 +1,17 @@ +from typing import * + +def find_lines(text:str, search:str) -> List[str]: + """ + Finds the lines in text with search + """ + found_lines = [] + lines = text.split('\n') + for line in lines: + if search in line: + found_lines += [line] + return found_lines + +def find_code_lines( search:str = None , module=None) -> List[str]: + import commune as c + code = c.module(module).code() + return find_lines(search=search, text=code) diff --git a/commune/utils/network.py b/commune/utils/network.py index 18c00cbe..c82563a4 100644 --- a/commune/utils/network.py +++ b/commune/utils/network.py @@ -107,7 +107,7 @@ def external_ip() -> str: ip = c.cmd('curl -s ifconfig.me') except Exception as e: c.print(e) - + # --- Try ipify try: ip = requests.get('https://api.ipify.org').text diff --git a/commune/utils/os.py b/commune/utils/os.py index 77e3a892..eb7daa52 100644 --- a/commune/utils/os.py +++ b/commune/utils/os.py @@ -6,10 +6,11 @@ import sys from typing import * -def resolve_path(path): +def abspath(path): path = os.path.expanduser(path) path = os.path.abspath(path) return path +resolve_path = abspath def check_pid(pid): """ Check For the existence of a unix pid. """ diff --git a/commune/utils/schema.py b/commune/utils/schema.py index 65d5445a..e69de29b 100644 --- a/commune/utils/schema.py +++ b/commune/utils/schema.py @@ -1,17 +0,0 @@ -from typing import * - -def find_lines(text:str, search:str) -> List[str]: - """ - Finds the lines in text with search - """ - found_lines = [] - lines = text.split('\n') - for line in lines: - if search in line: - found_lines += [line] - return found_lines - -def find_code_lines( search:str = None , module=None) -> List[str]: - import commune as c - code = c.module(module).code() - return find_lines(search=search, text=code) diff --git a/commune/utils/time.py b/commune/utils/time.py index 82ef3f30..21ee7a46 100755 --- a/commune/utils/time.py +++ b/commune/utils/time.py @@ -1,11 +1,11 @@ +from time import strftime +from time import gmtime def time() -> float: import time return time.time() def get_current_time(): - from time import strftime - from time import gmtime return strftime("%m%d%H%M%S", gmtime()) def roundTime(dt=None, roundTo=60): """Round a datetime object to any time lapse in seconds diff --git a/tests/test_validator.py b/tests/test_validator.py index 8c78ec46..ca138538 100644 --- a/tests/test_validator.py +++ b/tests/test_validator.py @@ -2,4 +2,4 @@ import commune as c import pandas as pd -test_net = c.module('vali').test_net() \ No newline at end of file +test_net = c.module('vali').test_net \ No newline at end of file