From f4ed65d9ea417602b15249ca1beb363644820da3 Mon Sep 17 00:00:00 2001 From: Alexey Potapov Date: Fri, 23 Aug 2024 20:10:52 +0300 Subject: [PATCH 1/3] snet sdk refactor --- .../naint/abstractive-summarisation.metta | 6 +- .../snet/snet/naint/code-generation.metta | 8 +- .../snet/snet/naint/generative-lms.metta | 8 +- .../snet/snet/naint/image-generation.metta | 8 +- .../snet/snet/naint/text-generation.metta | 8 +- python/sandbox/snet/snet_io.py | 120 +++++++++++++----- python/sandbox/snet/test_snet.metta | 28 ---- python/sandbox/snet/test_snet_call.metta | 27 ++++ python/sandbox/snet/test_snet_meta.metta | 25 ++++ 9 files changed, 152 insertions(+), 86 deletions(-) delete mode 100644 python/sandbox/snet/test_snet.metta create mode 100644 python/sandbox/snet/test_snet_call.metta create mode 100644 python/sandbox/snet/test_snet_meta.metta diff --git a/python/sandbox/snet/snet/naint/abstractive-summarisation.metta b/python/sandbox/snet/snet/naint/abstractive-summarisation.metta index 68ae79c48..13aa79d3c 100644 --- a/python/sandbox/snet/snet/naint/abstractive-summarisation.metta +++ b/python/sandbox/snet/snet/naint/abstractive-summarisation.metta @@ -2,12 +2,10 @@ !(add-reduct &self (= (abstractive-summarisation) - (snet-service "naint" "abstractive-summarisation" + (snet-sdk create_service_client "naint" "abstractive-summarisation" ; Put your data here or use environment variables ;(Kwargs - ; (private_key SNET_PRIVATE_KEY) - ; (eth_rpc_endpoint ETH_RPC_ENDPOINT) - ; (email SNET_EMAIL) ; (free_call_auth_token_bin FREE_CALL_AUTH_TOKEN_BIN) + ; (free_call_token_expiry_block FREE_CALL_TOKEN_EXPIRE_BLOCK) ;) ))) diff --git a/python/sandbox/snet/snet/naint/code-generation.metta b/python/sandbox/snet/snet/naint/code-generation.metta index 6ca301606..8ac755150 100644 --- a/python/sandbox/snet/snet/naint/code-generation.metta +++ b/python/sandbox/snet/snet/naint/code-generation.metta @@ -1,14 +1,10 @@ -!(import! &self snet_io) - !(add-reduct &self (= (code-generation) - (snet-service "naint" "code-generation" + (snet-sdk create_service_client "naint" "code-generation" ; Put your data here or use environment variables ;(Kwargs - ; (private_key SNET_PRIVATE_KEY) - ; (eth_rpc_endpoint ETH_RPC_ENDPOINT) - ; (email SNET_EMAIL) ; (free_call_auth_token_bin FREE_CALL_AUTH_TOKEN_BIN) + ; (free_call_token_expiry_block FREE_CALL_TOKEN_EXPIRE_BLOCK) ;) ))) diff --git a/python/sandbox/snet/snet/naint/generative-lms.metta b/python/sandbox/snet/snet/naint/generative-lms.metta index 87cc5bc98..9b8625925 100644 --- a/python/sandbox/snet/snet/naint/generative-lms.metta +++ b/python/sandbox/snet/snet/naint/generative-lms.metta @@ -1,13 +1,9 @@ -!(import! &self snet_io) - !(add-reduct &self (= (generative-lms) - (snet-service "naint" "generative-lms" + (snet-sdk create_service_client "naint" "generative-lms" ; Put your data here or use environment variables ;(Kwargs - ; (private_key SNET_PRIVATE_KEY) - ; (eth_rpc_endpoint ETH_RPC_ENDPOINT) - ; (email SNET_EMAIL) ; (free_call_auth_token_bin FREE_CALL_AUTH_TOKEN_BIN) + ; (free_call_token_expiry_block FREE_CALL_TOKEN_EXPIRE_BLOCK) ;) ))) diff --git a/python/sandbox/snet/snet/naint/image-generation.metta b/python/sandbox/snet/snet/naint/image-generation.metta index ae5963d5d..682387803 100644 --- a/python/sandbox/snet/snet/naint/image-generation.metta +++ b/python/sandbox/snet/snet/naint/image-generation.metta @@ -1,13 +1,9 @@ -!(import! &self snet_io) - !(add-reduct &self (= (image-generation) - (snet-service "naint" "image-generation" + (snet-sdk create_service_client "naint" "image-generation" ; Put your data here or use environment variables ;(Kwargs - ; (private_key SNET_PRIVATE_KEY) - ; (eth_rpc_endpoint ETH_RPC_ENDPOINT) - ; (email SNET_EMAIL) ; (free_call_auth_token_bin FREE_CALL_AUTH_TOKEN_BIN) + ; (free_call_token_expiry_block FREE_CALL_TOKEN_EXPIRE_BLOCK) ;) ))) diff --git a/python/sandbox/snet/snet/naint/text-generation.metta b/python/sandbox/snet/snet/naint/text-generation.metta index 9faa1d340..a05025297 100644 --- a/python/sandbox/snet/snet/naint/text-generation.metta +++ b/python/sandbox/snet/snet/naint/text-generation.metta @@ -1,14 +1,10 @@ -!(import! &self snet_io) - !(add-reduct &self (= (text-generation) - (snet-service "naint" "text-generation" + (snet-sdk create_service_client "naint" "text-generation" ; Put your data here or use environment variables ;(Kwargs - ; (private_key SNET_PRIVATE_KEY) - ; (eth_rpc_endpoint ETH_RPC_ENDPOINT) - ; (email SNET_EMAIL) ; (free_call_auth_token_bin FREE_CALL_AUTH_TOKEN_BIN) + ; (free_call_token_expiry_block FREE_CALL_TOKEN_EXPIRE_BLOCK) ;) ))) diff --git a/python/sandbox/snet/snet_io.py b/python/sandbox/snet/snet_io.py index 6fa63bed4..b389fc59e 100644 --- a/python/sandbox/snet/snet_io.py +++ b/python/sandbox/snet/snet_io.py @@ -1,43 +1,103 @@ -from hyperon.atoms import * +from hyperon import * from hyperon.ext import register_atoms import os from snet import sdk +class SNetSDKWrapper: + + def __init__(self): + self.snet_sdk = None + + def init_sdk(self, + private_key=os.getenv("SNET_PRIVATE_KEY", '0'*32), + eth_rpc_endpoint=os.getenv("ETH_RPC_ENDPOINT"), + email=os.getenv("SNET_EMAIL"), + identity_name="hyperon", + network="mainnet", + identity_type="key", + concurrency=False, + force_update=False): + config = { + "private_key": private_key, + "eth_rpc_endpoint": eth_rpc_endpoint, + "email": email, + "concurrency": concurrency, + "identity_name": identity_name, + "network": network, + "identity_type": identity_type, + "force_update": force_update + } + self.snet_sdk = sdk.SnetSDK(config) + + def organization_list(self): + return self.snet_sdk.get_organization_list() + + def service_list(self, org_id): + return self.snet_sdk.get_services_list(org_id) + + def create_service_client(self, org_id, service_id, + free_call_auth_token_bin=os.getenv("FREE_CALL_AUTH_TOKEN_BIN", None), + free_call_token_expiry_block=os.getenv("FREE_CALL_TOKEN_EXPIRE_BLOCK", None)): + if free_call_token_expiry_block is not None: + free_call_token_expiry_block = int(free_call_token_expiry_block) + service_client = self.snet_sdk.create_service_client( + org_id=org_id, service_id=service_id, + #group_name="default_group", + free_call_auth_token_bin=free_call_auth_token_bin, + free_call_token_expiry_block=free_call_token_expiry_block) + return ServiceCall(service_client) + + def _unwrap_atom(self, atom): + if isinstance(atom, GroundedAtom): + return atom.get_object().content + return repr(atom) + + def __call__(self, command_a, *args_a): + command = self._unwrap_atom(command_a) + args = [] + kwargs = {} + try: + for arg_a in args_a: + if isinstance(arg_a, ExpressionAtom): + ch = arg_a.get_children() + k = ch[0].get_name() + v = self._unwrap_atom(ch[1]) + kwargs[k] = v + else: + args += [self._unwrap_atom(arg_a)] + except: + return [E(S('Error'), E(S('snet-sdk'), command_a, *args_a), + ValueAtom(f'argument error'))] + if command == 'init': + self.init_sdk(*args, **kwargs) + return [E()] + if self.snet_sdk is None: + self.init_sdk() + if command == 'organization_list': + return list(map(lambda x: ValueAtom(x), self.organization_list())) + if command == 'service_list': + return list(map(lambda x: ValueAtom(x), self.service_list(*args, **kwargs))) + if command == 'create_service_client': + service_client = self.create_service_client(*args, **kwargs) + return [OperationAtom(service_client.get_service_details()[1], service_client)] + return [E(S('Error'), E(S('snet-sdk'), command_a, *args_a), + ValueAtom(f'unknown command {repr(command_a)}'))] + class ServiceCall: def __init__(self, service_client): self.service_client = service_client def __call__(self, method, input_type, **kwargs): return self.service_client.call_rpc(method, input_type, **kwargs) + def get_service_details(self): + return self.service_client.get_service_details() + def get_service_messages(self): + return self.service_client.get_services_and_messages_info() -def import_service(org_id, service_id, - private_key=os.getenv("SNET_PRIVATE_KEY"), - eth_rpc_endpoint=os.getenv("ETH_RPC_ENDPOINT"), - email=os.getenv("SNET_EMAIL", None), - free_call_auth_token_bin=os.getenv("FREE_CALL_AUTH_TOKEN_BIN", None), - free_call_token_expiry_block=os.getenv("FREE_CALL_TOKEN_EXPIRE_BLOCK", None) - ): - if free_call_token_expiry_block is not None: - free_call_token_expiry_block = int(free_call_token_expiry_block) - config = { - "private_key": private_key, - "eth_rpc_endpoint": eth_rpc_endpoint, - "email": email, - "concurrency": False, - "identity_name": "hyperon", - "network": "mainnet", - "identity_type": "key", - "force_update": False - } - snet_sdk = sdk.SnetSDK(config) - - service_client = snet_sdk.create_service_client( - org_id=org_id, service_id=service_id, - #group_name="default_group", - free_call_auth_token_bin=free_call_auth_token_bin, - free_call_token_expiry_block=free_call_token_expiry_block) - return ServiceCall(service_client) @register_atoms() def snet_atoms(): - serviceAtom = OperationAtom("snet-service", import_service) - return { 'snet-service': serviceAtom } + defaultSDKAtom = OperationAtom("snet-sdk", SNetSDKWrapper(), unwrap=False) + # TODO: new-sdk-atom + return { + 'snet-sdk': defaultSDKAtom, + } diff --git a/python/sandbox/snet/test_snet.metta b/python/sandbox/snet/test_snet.metta deleted file mode 100644 index 4476245ee..000000000 --- a/python/sandbox/snet/test_snet.metta +++ /dev/null @@ -1,28 +0,0 @@ -; !(import! &self snet_io) -; !(snet-service "naint" "image-generation") - -;!(import! &self snet:naint:image-generation) -;!((image-generation) -; "Gen" "Text" (Kwargs (sentence "Hello World") (type False))) - -!(import! &self snet:naint:code-generation) -;((code-generation) -; "generate" "Query" (Kwargs (request "Write Hello World in C#"))) -!(generate "Write Hello World in C#") - -;!(import! &self snet:naint:generative-lms) -;!((generative-lms) -; "generate" "Query" (Kwargs (request "Write Hello World in C#"))) - -;!(import! &self snet:naint:abstractive-summarisation) -;!((abstractive-summarisation) -; "neural_summarisation" "Query" (Kwargs (text "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce ullamcorper vehicula augue. Curabitur maximus aliquet ex sed fringilla. Mauris id erat dolor."))) - -(import! &self snet:naint:text-generation) -((text-generation) - "gen_gpt_2" "Query" - (Kwargs (start_text "What was the largest dinosaur?") - (run_name "universal") - (temperature 0.5) - (top_k 2) - (length 100))) diff --git a/python/sandbox/snet/test_snet_call.metta b/python/sandbox/snet/test_snet_call.metta new file mode 100644 index 000000000..6063bba40 --- /dev/null +++ b/python/sandbox/snet/test_snet_call.metta @@ -0,0 +1,27 @@ +!(import! &self snet_io) + +(include snet:naint:code-generation) +((py-dot (code-generation) get_service_messages)) +; code-generation requires passing data in json format, +; so it will return a parse error +;!(generate "Write Hello World in C#") +; FIXME: the following is converted to a Symbol, not String +;!(generate "{\"query\": \"Write Hello World in C#\"}")) +; A hacky way, which works for some reason atm +(generate (repr {"query":"Write_Hello_World_in_C#"})) + +; Doesn't work atm +(include snet:naint:image-generation) +((image-generation) + "Gen" "Text" (Kwargs (sentence "Hello World") (type False))) + +(include snet:naint:generative-lms) +((generative-lms) + "generate" "Query" (Kwargs (request "Write Hello World in C#"))) + +(include snet:naint:abstractive-summarisation) +((abstractive-summarisation) + "neural_summarisation" "Query" (Kwargs (text "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce ullamcorper vehicula augue. Curabitur maximus aliquet ex sed fringilla. Mauris id erat dolor."))) + +(include snet:naint:text-generation) +(gen_gpt_2 "What was the largest dinosaur?" "universal" 0.5 2 100) diff --git a/python/sandbox/snet/test_snet_meta.metta b/python/sandbox/snet/test_snet_meta.metta new file mode 100644 index 000000000..52c588dd2 --- /dev/null +++ b/python/sandbox/snet/test_snet_meta.metta @@ -0,0 +1,25 @@ +!(import! &self snet_io) + +; Only etherium endpoint is needed for retrieving metadata +; It should be either provided via init parameters or +; in the environment variable (ETH_RPC_ENDPOINT). +; In the latter case, it is not necessary to call `init` +; explicitly. +; !(snet-sdk init (eth_rpc_endpoint "YOUR ETH ENDPOINT")) + +!(snet-sdk organization_list) + +; Both positional and named arguments can be passed to snet-sdk +!(snet-sdk service_list (org_id "snet")) +!(snet-sdk service_list "naint") + +; We can create a service client and get its details without +; using a secret key, opening a channel, or using free calls +!(let $service + (snet-sdk create_service_client "naint" "question-answering-long-seq") + ((py-dot $service get_service_messages))) + +; we use `include` here, so `snet-sdk` is accessible in the included file +!(include snet:naint:image-generation) +!((py-dot (image-generation) get_service_messages)) + From 3605b85bdd70d9ea39d8ca691f423c9ad78395d6 Mon Sep 17 00:00:00 2001 From: Alexey Potapov Date: Fri, 23 Aug 2024 20:11:52 +0300 Subject: [PATCH 2/3] assert --- python/hyperon/atoms.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/python/hyperon/atoms.py b/python/hyperon/atoms.py index 90a8a3bc5..1dcbf24fd 100644 --- a/python/hyperon/atoms.py +++ b/python/hyperon/atoms.py @@ -306,6 +306,11 @@ class NoReduceError(Exception): """Custom exception; raised when a reduction operation cannot be performed.""" pass +class MettaError(Exception): + """Custom exception; raised when a error should be returned from OperationAtom, + , but we don't want to output Python error stack.""" + pass + class OperationObject(GroundedObject): """ An OperationObject represents an operation as a grounded object, allowing for more @@ -406,7 +411,10 @@ def execute(self, *atoms, res_typ=AtomType.UNDEFINED): # so a MeTTa program can catch and analyze it. # raise RuntimeError("Grounded operation " + self.name + " with unwrap=True expects only grounded arguments") raise NoReduceError() - result = self.op(*args, **kwargs) + try: + result = self.op(*args, **kwargs) + except MettaError as e: + return [E(S('Error'), *e.args)] if result is None: return [Atoms.UNIT] if callable(result): From cdbf80427da3ec7a975f5501ee7f809352e0659d Mon Sep 17 00:00:00 2001 From: Alexey Potapov Date: Fri, 23 Aug 2024 20:14:10 +0300 Subject: [PATCH 3/3] remove whitespaces --- python/sandbox/snet/snet/naint/code-generation.metta | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/sandbox/snet/snet/naint/code-generation.metta b/python/sandbox/snet/snet/naint/code-generation.metta index 8ac755150..4f76c26f0 100644 --- a/python/sandbox/snet/snet/naint/code-generation.metta +++ b/python/sandbox/snet/snet/naint/code-generation.metta @@ -1,6 +1,6 @@ !(add-reduct &self (= (code-generation) - (snet-sdk create_service_client "naint" "code-generation" + (snet-sdk create_service_client "naint" "code-generation" ; Put your data here or use environment variables ;(Kwargs ; (free_call_auth_token_bin FREE_CALL_AUTH_TOKEN_BIN)