Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
latentvector committed Dec 17, 2024
1 parent 90a1dce commit b0e944f
Show file tree
Hide file tree
Showing 45 changed files with 395 additions and 2,537 deletions.
7 changes: 1 addition & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,16 @@ FROM ubuntu:22.04
ARG DEBIAN_FRONTEND=noninteractive
RUN usermod -s /bin/bash root
RUN apt-get update

#RUST
RUN apt-get install curl nano build-essential cargo libstd-rust-dev -y

#NPM/JS
RUN apt-get install -y nodejs npm
RUN npm install -g pm2

#PYTHON
RUN apt-get install python3 python3-pip python3-venv -y
COPY ./ /commune
# RUN git clone -b main https://github.com/commune-ai/commune.git /commune
RUN pip install -e /commune

WORKDIR /app
# TODO DOCKER

# TODO DOCKERIZE THE ENTRYPOINT
ENTRYPOINT [ "tail", "-f", "/dev/null"]
8 changes: 3 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
SCRIPTS_PATH=./scripts
build:
${SCRIPTS_PATH}/build.sh
run:
${SCRIPTS_PATH}/run.sh
start:
${SCRIPTS_PATH}/start.sh
stop:
${SCRIPTS_PATH}/stop.sh
enter:
Expand All @@ -12,9 +12,7 @@ test:
chmod:
chmod +x ${SCRIPTS_PATH}/*
up:
make run
make start
down:
make stop
start:
make run

135 changes: 70 additions & 65 deletions commune/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,89 +50,94 @@ def determine_type(x):
pass
return x

def forward(argv = None, sep = '--', fn_splitters = [':', '/', '//', '::'], base = 'module', helper_fns = ['code', 'schema', 'fn_schema', 'help', 'fn_info', 'fn_hash'], default_fn = 'vs'):

t0 = time.time()
argv = argv or sys.argv[1:]
if len(argv) == 0:
argv = [default_fn]
output = None

def get_args_kwargs(argv):
args = []
kwargs = {}
parsing_kwargs = False
for arg in c.copy(argv):
if '=' in arg:
parsing_kwargs = True
key, value = arg.split('=')
kwargs[key] = determine_type(value)
else:
assert parsing_kwargs is False, 'Cannot mix positional and keyword arguments'
args.append(determine_type(arg))
return args, kwargs


def get_init_kwargs(argv, helper_fns = ['code', 'schema', 'fn_schema', 'help', 'fn_info', 'fn_hash']):
init_kwargs = {}
if any([arg.startswith(sep) for arg in argv]):
for arg in c.copy(argv):
if arg.startswith(sep):
key = arg[len(sep):].split('=')[0]
if key in helper_fns:
# is it a helper function
return forward([key , argv[0]])
else:
value = arg.split('=')[-1] if '=' in arg else True
argv.remove(arg)
init_kwargs[key] = determine_type(value)
# any of the --flags are init kwargs
for arg in c.copy(argv):
if arg.startswith('--'): # init kwargs
key = arg[len('--'):].split('=')[0]
if key in helper_fns:
# is it a helper function
return forward([key , argv[0]])
else:
value = arg.split('=')[-1] if '=' in arg else True
argv.remove(arg)
init_kwargs[key] = determine_type(value)
continue
return init_kwargs

def get_fn(argv, fn_splitters = [':', '/', '//', '::'], init_kwargs={}, default_fn='forward'):

if len(argv) == 0:
argv = [default_fn]
fn = argv.pop(0).replace('-', '_')
module = c.module(base)
fs = [fs for fs in fn_splitters if fs in fn]
if len(fs) == 1:
module, fn = fn.split(fs[0])


init_kwargs = get_init_kwargs(argv)

# get the function object
fn_splitters = [fs for fs in fn_splitters if fs in fn]
if len(fn_splitters) == 1:
fn_splitter = fn_splitters[0]
module, fn = fn.split(fn_splitter)
module = c.shortcuts.get(module, module)
modules = c.get_modules()
module_options = []
for m in modules:
if module == m:
module_options = [m]
break
if module in m:
module_options.append(m)
if len(module_options)>0:
module = module_options[0]
print('Module:', module)
module = c.module(module)
else:
raise AttributeError(f'Function {fn} not found in {module}')
module = c.module(module)
elif len(fn_splitters) == 0:
module = c.module()
if hasattr(module, 'fn2module') and not hasattr(module, fn):
c.print(f'ROUTE_ACTIVATED({fn} from {module})')
fn2module = module.fn2module()
fn2module = module.fn2module() if callable(module.fn2module) else module.fn2module
if not fn in fn2module:
return c.print(f'FN({fn}) not found {module}', color='red')
raise Exception(f'Function({fn}) NOT IN Module({module})', color='red')
module = c.module(fn2module[fn])
if not hasattr(module, fn):
module = module()

fn_obj = getattr(module, fn)
if c.is_property(fn_obj) or c.classify_fn(fn_obj) == 'self':
fn_obj = getattr(module(**init_kwargs), fn)
if callable(fn_obj):
args = []
kwargs = {}
parsing_kwargs = False
for arg in argv:
if '=' in arg:
parsing_kwargs = True
key, value = arg.split('=')
kwargs[key] = determine_type(value)
else:
assert parsing_kwargs is False, 'Cannot mix positional and keyword arguments'
args.append(determine_type(arg))
output = fn_obj(*args, **kwargs)
else:
output = fn_obj
buffer = '⚡️'*4
c.print(buffer+fn+buffer, color='yellow')
initialize_module_class = bool(not hasattr(module, fn) or isinstance(fn, property) or 'self' in c.get_args(fn_obj))
module = module(**init_kwargs) if initialize_module_class else module
print('⚡️'*4+fn+'⚡️'*4, color='yellow')
fn_obj = getattr(module, fn)
return fn_obj

def run_fn(fn_obj, args, kwargs):
# call the function
t0 = time.time()
output = fn_obj(*args, **kwargs) if callable(fn_obj) else fn_obj
latency = time.time() - t0
is_error = c.is_error(output)
msg = f'❌Error({latency:.3f}sec)❌' if is_error else f'✅Result({latency:.3f}s)✅'
c.print(msg)
print(f'❌Error({latency:.3f}sec)❌' if is_error else f'✅Result({latency:.3f}s)✅')
is_generator = c.is_generator(output)
if is_generator:
for item in output:
if isinstance(item, dict):
c.print(item)
print(item)
else:
c.print(item, end='')
print(item, end='')
else:
c.print(output)
print(output)
return output

def forward():
argv = sys.argv[1:]
fn = get_fn(argv)
args, kwargs = get_args_kwargs(argv)
return run_fn(fn, args, kwargs)


def main():
forward()

102 changes: 50 additions & 52 deletions commune/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,12 @@
import commune as c

class Client(c.Module):
network2namespace = {}
stream_prefix = 'data: '

def __init__( self, module : str = 'module',
network: Optional[bool] = 'local',
mode: Optional[str] = 'http',
key : Optional[str]= None ,
serializer: Optional[c.Module] = 'serializer',

def __init__( self, module : str = 'module',
key : Optional[str]= None ,
network: Optional[bool] = 'local',
mode: Optional[str] = 'http',
serializer: Optional[c.Module] = 'serializer',
**kwargs
):
self.serializer = c.module(serializer)()
Expand Down Expand Up @@ -55,7 +53,9 @@ def call(cls,
module = fn
fn = 'info'
client = cls(module=module, network=network)
return client.forward(fn=fn, args=args, kwargs=kwargs, timeout=timeout, **extra_kwargs)
kwargs = kwargs or {}
kwargs = {**kwargs, **extra_kwargs}
return client.forward(fn=fn, args=args, kwargs=kwargs, timeout=timeout, key=key)

@classmethod
def connect(cls,
Expand Down Expand Up @@ -89,12 +89,42 @@ def get_url(self, fn, mode='http'):
module_address = module_address.replace(ip, '0.0.0.0')
url = f"{module_address}/{fn}/"
return url

def request(self, url: str,
data: dict,
headers: dict,
timeout: int = 10,
stream: bool = True):


def get_data(self, args=[], kwargs={}, params = None):
# derefernece
args = c.copy(args or [])
kwargs = c.copy(kwargs or {})
if isinstance(args, dict):
kwargs = {**kwargs, **args}
args = []
if params:
if isinstance(params, dict):
kwargs = {**kwargs, **params}
elif isinstance(params, list):
args = params
else:
raise Exception(f'Invalid params {params}')
data = { "args": args, "kwargs": kwargs}
data = self.serializer.serialize(data)
return data

def forward(self,
fn = 'info',
params: Optional[Union[list, dict]] = None,
args : Optional[list] = [],
kwargs : Optional[dict] = {},
timeout:int=2,
key : str = None,
mode: str = 'http',
data=None,
headers = None,
stream:bool = False):

key = self.resolve_key(key)
url = self.get_url(fn=fn, mode=mode)
data = data or self.get_data(params=params, args=args, kwargs=kwargs, )
headers = headers or self.get_header(data=data, key=key)
try:
response = self.session.post(url, json=data, headers=headers, timeout=timeout, stream=stream)
if 'text/event-stream' in response.headers.get('Content-Type', ''):
Expand All @@ -111,27 +141,6 @@ def request(self, url: str,
except Exception as e:
result = c.detailed_error(e)
return result

def get_data(self, args=[], kwargs={}, **extra_kwargs):
# derefernece
args = c.copy(args or [])
kwargs = c.copy(kwargs or {})
if isinstance(args, dict):
kwargs = {**kwargs, **args}
args = []
if extra_kwargs:
kwargs = {**kwargs, **extra_kwargs}
data = { "args": args, "kwargs": kwargs}
data = self.serializer.serialize(data)
return data

def forward(self, fn = 'info', args : str = [], kwargs : str = {},
timeout:int=2, key : str = None, mode: str = 'http', data=None, headers = None, **extra_kwargs):
key = self.resolve_key(key)
url = self.get_url(fn=fn, mode=mode)
data = data or self.get_data(args=args, kwargs=kwargs,**extra_kwargs)
headers = headers or self.get_header(data=data, key=key)
return self.request(url=url, data=data,headers=headers, timeout=timeout)

def __del__(self):
try:
Expand All @@ -156,10 +165,10 @@ def stream(self, response):
print(f'Error in stream: {e}')
yield None

def process_stream_line(self, line):
def process_stream_line(self, line, stream_prefix = 'data: '):
event_data = line.decode('utf-8')
if event_data.startswith(self.stream_prefix):
event_data = event_data[len(self.stream_prefix):]
if event_data.startswith(stream_prefix):
event_data = event_data[len(stream_prefix):]
if event_data == "": # skip empty lines if the event data is empty
return ''
if isinstance(event_data, str):
Expand All @@ -173,28 +182,17 @@ def check_response(x) -> bool:
return False
else:
return True

class Virtual:
protected_attributes = [ 'client', 'remote_call']

class Virtual:
def __init__(self, client: str ='ReactAgentModule'):
if isinstance(client, str):
client = c.connect(client)
self.client = client

def remote_call(self, *args, remote_fn, timeout:int=10, key=None, **kwargs):
result = self.client.forward(fn=remote_fn, args=args, kwargs=kwargs, timeout=timeout, key=key)
return result

def __str__(self):
return str(self.client)

def __repr__(self):
return self.__str__()

def __getattr__(self, key):

if key in self.protected_attributes :
if key in [ 'client', 'remote_call'] :
return getattr(self, key)
else:
return lambda *args, **kwargs : self.remote_call(*args, remote_fn=key, **kwargs)
Expand Down
Loading

0 comments on commit b0e944f

Please sign in to comment.