1515from zeep .plugins import HistoryPlugin
1616
1717from lxml import etree
18- from lxml .builder import ElementMaker
1918
20- import random
2119import os
2220import uuid
2321
24- import json
2522import xmltodict
2623
27- from datetime import datetime , timezone
28- import aniso8601
29-
3024import urllib3
3125
32- import logging
26+ from OPDM import __version__ as package_version
3327
28+ import logging
3429logger = logging .getLogger (__name__ )
3530
3631
@@ -71,10 +66,9 @@ def __init__(self, server, username="", password="", debug=False, verify=False):
7166
7267 self .debug = debug
7368 self .history = HistoryPlugin ()
74- self .API_VERSION = "0.0.11" # TODO - Get the version from versioneer
69+ self .API_VERSION = package_version
7570
7671 service_wsdl = '{}/cxf/OPDMSoapInterface?wsdl' .format (server )
77- auth_wsdl = '{}/cxf/OPDMSoapInterface/SoapAuthentication?wsdl' .format (server )
7872 ruleset_wsdl = '{}/cxf/OPDMSoapInterface/RuleSetManagementService?wsdl' .format (server )
7973
8074 session = Session ()
@@ -85,27 +79,13 @@ def __init__(self, server, username="", password="", debug=False, verify=False):
8579 session .verify = False
8680
8781 # Set up client
82+ self .client = Client (service_wsdl , transport = Transport (session = session ), wsse = UsernameToken (username , password = password ))
83+ self .ruleset_client = Client (ruleset_wsdl , transport = Transport (session = session ), wsse = UsernameToken (username , password = password ))
84+
8885 if debug :
89- self .client = Client ( service_wsdl , transport = Transport ( session = session ), plugins = [self .history ])
90- self .ruleset_client = Client ( ruleset_wsdl , transport = Transport ( session = session ), plugins = [self .history ])
86+ self .client . plugins = [self .history ]
87+ self .ruleset_client . plugins = [self .history ]
9188 logging .basicConfig (format = '%(asctime)s | %(name)s | %(levelname)s | %(message)s' , level = logging .DEBUG )
92- else :
93- self .client = Client (service_wsdl , transport = Transport (session = session ))
94- self .ruleset_client = Client (ruleset_wsdl , transport = Transport (session = session ))
95-
96- # Set up auth
97- if username == "" :
98- self .auth = False
99- elif debug :
100- self .auth = True
101- self .auth_client = Client (auth_wsdl , transport = Transport (session = session ), wsse = UsernameToken (username , password = password ), plugins = [self .history ])
102- self .auth_valid_until = datetime .now (timezone .utc )
103- self .token = None
104- else :
105- self .auth = True
106- self .auth_client = Client (auth_wsdl , transport = Transport (session = session ), wsse = UsernameToken (username , password = password ))
107- self .auth_valid_until = datetime .now (timezone .utc )
108- self .token = None
10989
11090 def _print_last_message_exchange (self ):
11191 """Prints out last sent and received SOAP messages"""
@@ -225,40 +205,9 @@ class Operations:
225205 </sm:GetProfilePublicationReport>
226206 """
227207
228- def request_security_token (self , pretty_print = False ):
229- """Return the token as string and it's validity time"""
230- token_string = self .auth_client .service .RequestSecurityToken ()
231- token = etree .fromstring (token_string )
232- valid_unitl = aniso8601 .parse_datetime (token .find (".//{*}Conditions" ).attrib ['NotOnOrAfter' ])
233-
234- if pretty_print :
235- print (json .dumps (xmltodict .parse (token_string ), indent = 4 ))
236-
237- return token , valid_unitl
238-
239- def check_token (self ):
240- """Check if token is due to expire and renew if needed"""
241- utc_now = datetime .now (timezone .utc )
242-
243- if utc_now > self .auth_valid_until - aniso8601 .parse_duration ("PT5S" ):
244- self .token , self .auth_valid_until = self .request_security_token ()
245- logger .debug ("Requesting new Auth Token" )
246-
247- elif self .debug :
248- logger .debug (f"Auth Token still valid for { self .auth_valid_until - utc_now } " )
249-
250- def create_saml_header (self ):
251- """Create SOAP SAML authentication header element for zeep"""
252- if self .auth :
253- self .check_token ()
254- WSSE = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
255- return [ElementMaker (namespace = WSSE ).Security (self .token )]
256- else :
257- return []
258-
259208 def execute_operation (self , operation_xml ):
260209 """ExecuteOperation(payload: xsd:base64Binary) -> return: ns0:resultDto"""
261- response = self .client .service .ExecuteOperation (operation_xml , _soapheaders = self . create_saml_header () )
210+ response = self .client .service .ExecuteOperation (operation_xml )
262211 return response
263212
264213 def publication_request (self , file_path_or_file_object , content_type = "CGMES" ):
@@ -278,11 +227,11 @@ def publication_request(self, file_path_or_file_object, content_type="CGMES"):
278227
279228 payload = {"id" : file_name , "type" : content_type , "content" : file_string }
280229
281- response = self .client .service .PublicationRequest (payload , _soapheaders = self . create_saml_header () )
230+ response = self .client .service .PublicationRequest (payload )
282231
283232 return response
284233
285- def query_object (self , object_type = "IGM" , metadata_dict = "" , components = [] , dependencies = [] ):
234+ def query_object (self , object_type = "IGM" , metadata_dict = None , components = None , dependencies = None ):
286235 """
287236 object_type ->IGM, CGM, BDS
288237 metadata_dict_example = {'pmd:cgmesProfile': 'SV', 'pmd:scenarioDate': '2018-12-07T00:30:00+01:00', 'pmd:timeHorizon': '1D'}
@@ -293,14 +242,16 @@ def query_object(self, object_type="IGM", metadata_dict="", components=[], depen
293242
294243 _QueryObject = self .Operations .QueryObject .format (query_id = query_id , object_type = object_type ).encode ()
295244
296- if metadata_dict != "" :
245+ if metadata_dict :
297246 _QueryObject = add_xml_elements (_QueryObject , ".//opdm:OPDMObject" , metadata_dict )
298247
299- for component in components :
300- _QueryObject = add_xml_elements (_QueryObject , ".//opde:Components" , component )
248+ if components :
249+ for component in components :
250+ _QueryObject = add_xml_elements (_QueryObject , ".//opde:Components" , component )
301251
302- for dependency in dependencies :
303- _QueryObject = add_xml_elements (_QueryObject , ".//opde:Dependencies" , dependency )
252+ if dependencies :
253+ for dependency in dependencies :
254+ _QueryObject = add_xml_elements (_QueryObject , ".//opde:Dependencies" , dependency )
304255
305256 logger .debug (_QueryObject .decode ())
306257
@@ -346,6 +297,7 @@ def get_content(self, content_id, return_payload=False, object_type="file"):
346297
347298 result = xmltodict .parse (etree .tostring (self .execute_operation (get_content_result .encode ())), xml_attribs = False )
348299
300+ # TODO - add better error handling, in case error message was returned
349301 if type (result ['sm:GetContentResult' ]['sm:part' ]) == list :
350302 logger .info ("File downloaded" )
351303 #logger.debug(result['sm:GetContentResult']['sm:part'][1]['opdm:Profile']['opde:Content'])
@@ -373,8 +325,7 @@ def publication_subscribe(self, object_type="BDS", subscription_id="", publicati
373325 # Get available publications
374326 available_publications = self .publication_list ()
375327
376-
377- object_types = {item ['opde:messageType' ]["@v" ].split ("-" )[- 1 ]:item ['opde:publicationID' ]["@v" ] for item in available_publications ['sm:PublicationsSubscriptionListResult' ]['sm:part' ]['opdm:PublicationsList' ]['opdm:Publication' ]}
328+ object_types = {item ['opde:messageType' ]["@v" ].split ("-" )[- 1 ]: item ['opde:publicationID' ]["@v" ] for item in available_publications ['sm:PublicationsSubscriptionListResult' ]['sm:part' ]['opdm:PublicationsList' ]['opdm:Publication' ]}
378329
379330 if object_type not in object_types .keys ():
380331 logger .warning (f"ObjectType '{ object_type } ' not supported, supported types are: { object_types } " )
@@ -437,19 +388,19 @@ def publication_cancel_subscription(self, subscription_id):
437388
438389 def get_installed_ruleset_version (self ):
439390 """Retrurns a string with the latest ruleset version"""
440- return self .ruleset_client .service .GetInstalledRuleSetVersion (_soapheaders = self . create_saml_header () )
391+ return self .ruleset_client .service .GetInstalledRuleSetVersion ()
441392
442393 def list_available_rulesets (self ):
443394 """Returns a list of available rulesets"""
444- return self .ruleset_client .service .ListAvailableRuleSets (_soapheaders = self . create_saml_header () )
395+ return self .ruleset_client .service .ListAvailableRuleSets ()
445396
446397 def install_ruleset (self , version = None ):
447398 """Install ruleset library by providing the library version as a string. To get available ruleset libraries use list_available_rulesets()"""
448- return self .ruleset_client .service .Install (Version = version , _soapheaders = self . create_saml_header () )
399+ return self .ruleset_client .service .Install (Version = version )
449400
450401 def reset_ruleset (self ):
451402 """Reset ruleset library"""
452- return self .ruleset_client .service .Reset (_soapheaders = self . create_saml_header () )
403+ return self .ruleset_client .service .Reset ()
453404
454405
455406if __name__ == '__main__' :
0 commit comments