99import google .protobuf .internal .api_implementation
1010from google .protobuf import symbol_database as _symbol_database
1111
12- from snet .sdk .registry .models import StorageType
12+ from snet .sdk .exceptions import NoGroupsFoundError , GroupNotFoundError , ServiceMetadataMismatchError
13+ from snet .sdk .registry .models import StorageType , FileURI
1314from snet .sdk .registry .organization_metadata import OrganizationMetadata
1415from snet .sdk .registry .registry_contract import RegistryContract
15- from snet .sdk .registry .service_metadata import MPEServiceMetadata , ServiceMetadata
16+ from snet .sdk .registry .service_metadata import ServiceMetadata , Group
1617
1718with warnings .catch_warnings ():
1819 # Suppress the eth-typing package`s warnings related to some new networks
@@ -74,15 +75,18 @@ def create_service_client(
7475 options = None ,
7576 concurrent_calls : int = 1 ,
7677 ):
77-
78- # Create and instance of the Config object,
79- # so we can create an instance of ClientLibGenerator
78+ service_metadata = self ._enhance_service_metadata (org_id , service_id )
8079 lib_generator = ClientLibGenerator (self .storage_provider , org_id , service_id )
8180
82- # Download the proto file and generate stubs if needed
81+ if service_metadata .service_api_source is not None :
82+ service_api_source = service_metadata .service_api_source
83+ else :
84+ service_api_source = service_metadata .model_ipfs_hash
85+ service_api_source = FileURI .from_raw_uri (service_api_source )
86+
8387 force_update = config .FORCE_UPDATE
8488 if force_update :
85- lib_generator .generate_client_library ()
89+ lib_generator .generate_client_library (service_api_source )
8690 else :
8791 path_to_pb_files = lib_generator .proto_dir
8892 pb_2_file_name = find_file_by_keyword (
@@ -93,7 +97,7 @@ def create_service_client(
9397 )
9498 if not pb_2_file_name or not pb_2_grpc_file_name :
9599 print ("Generating client library..." )
96- lib_generator .generate_client_library ()
100+ lib_generator .generate_client_library (service_api_source )
97101
98102 if options is None :
99103 options = dict ()
@@ -103,16 +107,14 @@ def create_service_client(
103107 if payment_strategy is None :
104108 payment_strategy = payment_strategy_type .value ()
105109
106- service_metadata = self ._enhance_service_metadata (org_id , service_id )
107- group = self ._get_service_group_details (service_metadata , group_name )
110+ group = self ._get_service_group (org_id , service_id , service_metadata , group_name )
108111
109112 service_stubs = self .get_service_stub (lib_generator )
110113
111114 pb2_module = self .get_module_by_keyword ("pb2.py" , lib_generator )
112115 _service_client = ServiceClient (
113116 org_id ,
114117 service_id ,
115- service_metadata ,
116118 group ,
117119 service_stubs ,
118120 payment_strategy ,
@@ -162,36 +164,28 @@ def get_module_by_keyword(self, keyword: str, lib_generator: ClientLibGenerator)
162164 module_name = os .path .splitext (file_name )[0 ]
163165 return ModuleName (module_name )
164166
165- def get_service_metadata (self , org_id , service_id ):
167+ def get_service_metadata (self , org_id , service_id ) -> ServiceMetadata :
166168 service = self .registry_contract .get_service (org_id , service_id )
167169 return self .storage_provider .fetch_service_metadata (service .metadata_uri )
168170
169171 def get_organization_metadata (self , org_id : str ) -> OrganizationMetadata :
170172 org = self .registry_contract .get_org (org_id )
171173 return self .storage_provider .fetch_org_metadata (org .metadata_uri )
172174
173- def _get_first_group (self , service_metadata : MPEServiceMetadata ) -> dict :
174- return service_metadata ["groups" ][0 ]
175-
176- def _get_group_by_group_name (
177- self , service_metadata : MPEServiceMetadata , group_name : str
178- ) -> dict :
179- for group in service_metadata ["groups" ]:
180- if group ["group_name" ] == group_name :
181- return group
182- # TODO: configure exceptions
183- raise Exception ()
184-
185- def _get_service_group_details (
186- self , service_metadata : MPEServiceMetadata , group_name : str
187- ) -> dict :
188- if len (service_metadata ["groups" ]) == 0 :
189- raise Exception ("No Groups found for given service, Please add group to the service" )
175+ def _get_service_group (
176+ self , org_id : str , service_id : str , service_metadata : ServiceMetadata , group_name : str
177+ ) -> Group :
178+ if len (service_metadata .groups ) == 0 :
179+ raise NoGroupsFoundError (org_id , service_id )
190180
191181 if group_name is None :
192- return self . _get_first_group ( service_metadata )
182+ return service_metadata . groups [ 0 ]
193183
194- return self ._get_group_by_group_name (service_metadata , group_name )
184+ for group in service_metadata .groups :
185+ if group .group_name == group_name :
186+ return group
187+
188+ raise GroupNotFoundError (org_id , service_id , group_name )
195189
196190 def get_organization_list (self ) -> list :
197191 return self .registry_contract .list_orgs ()
@@ -215,13 +209,68 @@ def publish_service_comprehensively(
215209 5. publish service into Registry contract
216210 """
217211 proto_uri = self .storage_provider .publish_proto (proto_dir , storage_type )
218-
219212 metadata .service_api_source = str (proto_uri )
220213 metadata .mpe_address = self .mpe_contract .contract .address
221214
215+ self ._check_and_update_service_groups (org_id , metadata .groups )
222216 metadata_uri = self .storage_provider .publish_service_metadata (metadata , storage_type )
217+
223218 receipt = self .registry_contract .create_service (
224219 self .account , org_id , service_id , metadata_uri
225220 )
226221
227222 return receipt ["status" ] != 0
223+
224+ def update_service (
225+ self ,
226+ org_id : str ,
227+ service_id : str ,
228+ metadata : ServiceMetadata ,
229+ proto_dir : Union [str , Path , None ] = None ,
230+ storage_type : StorageType = StorageType .IPFS ,
231+ ) -> bool :
232+ if proto_dir is not None :
233+ proto_uri = self .storage_provider .publish_proto (proto_dir , storage_type )
234+ metadata .service_api_source = str (proto_uri )
235+
236+ if not metadata .mpe_address :
237+ metadata .mpe_address = self .mpe_contract .contract .address
238+
239+ self ._check_and_update_service_groups (org_id , metadata .groups )
240+ metadata_uri = self .storage_provider .publish_service_metadata (metadata , storage_type )
241+
242+ receipt = self .registry_contract .update_service_metadata (
243+ self .account , org_id , service_id , metadata_uri
244+ )
245+
246+ return receipt ["status" ] != 0
247+
248+ def update_organization (
249+ self ,
250+ org_id : str ,
251+ organization_metadata : OrganizationMetadata ,
252+ storage_type : StorageType = StorageType .IPFS ,
253+ ) -> bool :
254+ metadata_uri = self .storage_provider .publish_organization_metadata (
255+ organization_metadata , storage_type
256+ )
257+ receipt = self .registry_contract .update_org_metadata (self .account , org_id , metadata_uri )
258+
259+ return receipt ["status" ] != 0
260+
261+ def _check_and_update_service_groups (
262+ self , org_id : str , service_groups : list [Group ]
263+ ) -> list [Group ]:
264+ org = self .registry_contract .get_org (org_id )
265+ org_metadata = self .storage_provider .fetch_org_metadata (org .metadata_uri )
266+ org_groups_map = {g .group_name : g for g in org_metadata .groups }
267+
268+ for group in service_groups :
269+ try :
270+ group .group_id = org_groups_map [group .group_name ].group_id
271+ except KeyError :
272+ raise ServiceMetadataMismatchError (
273+ "All groups added to the service must also exist in the organization!"
274+ )
275+
276+ return service_groups
0 commit comments