diff --git a/buildproto.sh b/buildproto.sh old mode 100644 new mode 100755 index a9ba6cf..8b741e4 --- a/buildproto.sh +++ b/buildproto.sh @@ -1,2 +1,5 @@ #! /bin/bash -python3 -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. service/service_spec/example_service.proto +echo `pwd` +python3 -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. singnet/snet-daemon/pricing/pricing.proto --proto_path=/home/adminaccount/singnet/src +python3 -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. singnet/snet-daemon/training/training.proto --proto_path=/home/adminaccount/singnet/src +python3 -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. service/service_spec/example_service.proto --proto_path=/home/adminaccount/singnet/src diff --git a/service/example_service.py b/service/example_service.py index 97dd523..420ba5f 100644 --- a/service/example_service.py +++ b/service/example_service.py @@ -1,5 +1,6 @@ import sys import logging +import uuid import grpc import concurrent.futures as futures @@ -8,12 +9,14 @@ # Importing the generated codes from buildproto.sh import service.service_spec.example_service_pb2_grpc as grpc_bt_grpc -from service.service_spec.example_service_pb2 import Result +from service.model_server import ModelServicer +from service.service_spec.example_service_pb2 import Result, ModelId, TrainingResponse +from singnet.snet_daemon.pricing.pricing_pb2 import PriceInCogs +import singnet.snet_daemon.training.training_pb2_grpc as grpc_bt_grpc_training logging.basicConfig(level=10, format="%(asctime)s - [%(levelname)8s] - %(name)s - %(message)s") log = logging.getLogger("example_service") - """ Simple arithmetic service to test the Snet Daemon (gRPC), dApp and/or Snet-CLI. The user must provide the method (arithmetic operation) and @@ -67,6 +70,41 @@ def add(self, request, context): log.debug("add({},{})={}".format(self.a, self.b, self.result.value)) return self.result + def train_add(self, request, context): + log.debug("GOING TO START TRAINING DATA NOW..................................") + + # To respond we need to create a Result() object (from .proto file) + self.result = TrainingResponse() + self.result.model_id = request.model_id + self.result.status = "In Progress" + + log.debug("TrainingResponse({},{})".format(self.result.model_id, self.result.status)) + return self.result + + + + def dynamic_pricing_train_add(self, request, context): + log.debug("DYNAMIC PRICE method dynamic_pricing_train_add , invoked for train_add") + + # To respond we need to create a Result() object (from .proto file) + self.result = PriceInCogs() + + self.result.price = 13 + log.debug("price returned is {}".format(self.result.price)) + return self.result + + def dynamic_pricing_add(self, request, context): + # In our case, request is a Numbers() object (from .proto file) + self.a = request.a + self.b = request.b + + # To respond we need to create a Result() object (from .proto file) + self.result = PriceInCogs() + + self.result.price = 13 + log.debug("add({},{})={}".format(self.a, self.b, self.result.price)) + return self.result + def sub(self, request, context): self.a = request.a self.b = request.b @@ -106,6 +144,7 @@ def div(self, request, context): def serve(max_workers=10, port=7777): server = grpc.server(futures.ThreadPoolExecutor(max_workers=max_workers)) grpc_bt_grpc.add_CalculatorServicer_to_server(CalculatorServicer(), server) + grpc_bt_grpc_training.add_ModelServicer_to_server(ModelServicer(), server) server.add_insecure_port("[::]:{}".format(port)) return server diff --git a/service/model_server.py b/service/model_server.py new file mode 100644 index 0000000..a07fc1c --- /dev/null +++ b/service/model_server.py @@ -0,0 +1,65 @@ +import sys +import logging +import time +import uuid + +import grpc +import concurrent.futures as futures + +import service.common + +# Importing the generated codes from buildproto.sh +import singnet.snet_daemon.training.training_pb2_grpc as grpc_bt_grpc +from singnet.snet_daemon.training.training_pb2 import ModelDetailsResponse +from singnet.snet_daemon.training.training_pb2 import IN_PROGRESS +from singnet.snet_daemon.training.training_pb2 import CREATED +from singnet.snet_daemon.training.training_pb2 import COMPLETED + +logging.basicConfig(level=10, format="%(asctime)s - [%(levelname)8s] - %(name)s - %(message)s") +log = logging.getLogger("model_training") + + +# Create a class to be added to the gRPC server +# derived from the protobuf codes. +class ModelServicer(grpc_bt_grpc.ModelServicer): + def __init__(self): + # Just for debugging purpose. + log.debug("ModelServicer created") + + # The method that will be exposed to the snet-cli call command. + # request: incoming data + # context: object that provides RPC-specific information (timeout, etc). + def create_model(self, request, context): + log.debug("Create Model ") + # AI developer needs to implement this and send back a unique custom ID + self.result = ModelDetailsResponse() + self.result.model_id = "#CLientgeneratedModelId" + self.result.status = CREATED + return self.result + + def update_model_access(self, request, context): + log.debug(" daemon will take care of this , AI developer is to just provide a dummy code as below") + # To respond we need to create a Result() object (from .proto file) + self.result = ModelDetailsResponse() + self.result.status = IN_PROGRESS + return self.result + + def delete_model(self, request, context): + log.debug("Request to delete the model , ai developer needs to handel this ....") + # To respond we need to create a Result() object (from .proto file) + self.result = ModelDetailsResponse() + self.result.status = COMPLETED + return self.result + + def get_all_models(self, request, context): + log.debug(" daemon will take care of this , AI developer is to just provide a dummy code as below") + self.result = ModelDetailsResponse() + return self.result + + def get_training_status(self, request, context): + # AI developer to keep track of the training models status and return + log.debug("get training status ") + + self.result = ModelDetailsResponse() + self.result.status = IN_PROGRESS + return self.result diff --git a/service/service_spec/example_service.proto b/service/service_spec/example_service.proto index f904f6a..5752af4 100644 --- a/service/service_spec/example_service.proto +++ b/service/service_spec/example_service.proto @@ -1,19 +1,52 @@ syntax = "proto3"; - +import "singnet/snet-daemon/training/training.proto"; +import "singnet/snet-daemon/pricing/pricing.proto"; package example_service; +message AddressList { + repeated string address = 1; + string model_details = 2; +} + message Numbers { float a = 1; float b = 2; + //highlight this as part of documentation + string model_id = 3; } message Result { float value = 1; } +message ModelId { + string model_id = 1; +} +message TrainingRequest { + string link = 1; + string address = 2; + string model_id =3 ; + string request_id =4; +} +message TrainingResponse { + string link = 1; + string model_id =2 ; + string status = 3;//put this in enum + string request_id = 4; +} service Calculator { - rpc add(Numbers) returns (Result) {} + //AI developer can define their own training methods , if you wish to have a different pricing , please use + // define the pricing method as shown below, dynamic_pricing_train_add, please make sure the i/p is exactly the same + rpc train_add(TrainingRequest) returns (TrainingResponse) { + option (pricing.my_method_option).estimatePriceMethod = "dynamic_pricing_train_add"; + option (training.my_method_option).trainingMethodIndicator = "true"; + } + + //make sure the params to the method are exactly the same as that of the method in which needs dynamic price computation + rpc dynamic_pricing_train_add(TrainingRequest) returns (pricing.PriceInCogs) {} + rpc dynamic_pricing_add(Numbers) returns (pricing.PriceInCogs) {} + rpc add(Numbers) returns (Result) {option (pricing.my_method_option).estimatePriceMethod = "dynamic_pricing_add";} rpc sub(Numbers) returns (Result) {} rpc mul(Numbers) returns (Result) {} rpc div(Numbers) returns (Result) {} -} \ No newline at end of file +}