def create_tra(service=SERVICE, ttl=2400): "Crear un Ticket de Requerimiento de Acceso (TRA)" tra = SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?>' '<loginTicketRequest version="1.0">' "</loginTicketRequest>") tra.add_child("header") # El source es opcional. Si falta, toma la firma (recomendado). # tra.header.addChild('source','subject=...') # tra.header.addChild('destination','cn=wsaahomo,o=afip,c=ar,serialNumber=CUIT 33693450239') tra.header.add_child("uniqueId", str(date("U"))) tra.header.add_child("generationTime", str(date("c", date("U") - ttl))) tra.header.add_child("expirationTime", str(date("c", date("U") + ttl))) tra.add_child("service", service) return tra.as_xml()
def create_tra(service=SERVICE,ttl=2400): "Crear un Ticket de Requerimiento de Acceso (TRA)" tra = SimpleXMLElement( '<?xml version="1.0" encoding="UTF-8"?>' '<loginTicketRequest version="1.0">' '</loginTicketRequest>') tra.add_child('header') # El source es opcional. Si falta, toma la firma (recomendado). #tra.header.addChild('source','subject=...') #tra.header.addChild('destination','cn=wsaahomo,o=afip,c=ar,serialNumber=CUIT 33693450239') tra.header.add_child('uniqueId',str(date('U'))) tra.header.add_child('generationTime',str(date('c',date('U')-ttl))) tra.header.add_child('expirationTime',str(date('c',date('U')+ttl))) tra.add_child('service',service) return tra.as_xml()
def test_issue46(self): """Example for sending an arbitrary header using SimpleXMLElement""" # fake connection (just to test xml_request): client = SoapClient( location="https://localhost:666/", namespace='http://localhost/api' ) # Using WSDL, the equivalent is: # client['MyTestHeader'] = {'username': '******', 'password': '******'} headers = SimpleXMLElement("<Headers/>") my_test_header = headers.add_child("MyTestHeader") my_test_header['xmlns'] = "service" my_test_header.marshall('username', 'test') my_test_header.marshall('password', 'password') try: client.methodname(headers=headers) except: open("issue46.xml", "wb").write(client.xml_request) self.assert_('<soap:Header><MyTestHeader xmlns="service">' '<username>test</username>' '<password>password</password>' '</MyTestHeader></soap:Header>' in client.xml_request.decode(), "header not in request!")
def test_issue78(self): """Example for sending an arbitrary header using SimpleXMLElement and WSDL""" # fake connection (just to test xml_request): client = SoapClient( wsdl='http://dczorgwelzijn-test.qmark.nl/qmwise4/qmwise.asmx?wsdl') # Using WSDL, the easier form is but this doesn't allow for namespaces to be used. # If the server requires these (buggy server?) the dictionary method won't work # and marshall will not marshall 'ns:username' style keys # client['MyTestHeader'] = {'username': '******', 'password': '******'} namespace = 'http://questionmark.com/QMWISe/' ns = 'qmw' header = SimpleXMLElement('<Headers/>', namespace=namespace, prefix=ns) security = header.add_child("Security") security['xmlns:qmw'] = namespace security.marshall('ClientID', 'NAME', ns=ns) security.marshall('Checksum', 'PASSWORD', ns=ns) client['Security'] = security try: client.GetParticipantList() except: #open("issue78.xml", "wb").write(client.xml_request) #print(client.xml_request) header = '<soap:Header>' \ '<qmw:Security xmlns:qmw="http://questionmark.com/QMWISe/">' \ '<qmw:ClientID>NAME</qmw:ClientID>' \ '<qmw:Checksum>PASSWORD</qmw:Checksum>' \ '</qmw:Security>' \ '</soap:Header>' xml = SimpleXMLElement(client.xml_request) self.assertEquals(str(xml.ClientID), "NAME") self.assertEquals(str(xml.Checksum), "PASSWORD")
def test_issue46(self): """Example for sending an arbitrary header using SimpleXMLElement""" # fake connection (just to test xml_request): client = SoapClient(location="https://localhost:666/", namespace='http://localhost/api') # Using WSDL, the equivalent is: # client['MyTestHeader'] = {'username': '******', 'password': '******'} headers = SimpleXMLElement("<Headers/>") my_test_header = headers.add_child("MyTestHeader") my_test_header['xmlns'] = "service" my_test_header.marshall('username', 'test') my_test_header.marshall('password', 'password') try: client.methodname(headers=headers) except: open("issue46.xml", "wb").write(client.xml_request) self.assert_( '<soap:Header><MyTestHeader xmlns="service">' '<username>test</username>' '<password>password</password>' '</MyTestHeader></soap:Header>' in client.xml_request.decode(), "header not in request!")
def test_issue78(self): "Example for sending an arbitrary header using SimpleXMLElement and WSDL" # fake connection (just to test xml_request): client = SoapClient(wsdl='http://dczorgwelzijn-test.qmark.nl/qmwise4/qmwise.asmx?wsdl') # Using WSDL, the easier form is but this doesn't allow for namespaces to be used. # If the server requires these (buggy server?) the dictionary method won't work # and marshall will not marshall 'ns:username' style keys # client['MyTestHeader'] = {'username': '******', 'password': '******'} namespace = 'http://questionmark.com/QMWISe/' ns = 'qmw' header = SimpleXMLElement('<Headers/>', namespace=namespace, prefix=ns) security = header.add_child("Security") security['xmlns:qmw']=namespace security.marshall('ClientID','NAME',ns=ns) security.marshall('Checksum','PASSWORD',ns=ns) client['Security']=security try: client.GetParticipantList() except: #open("issue78.xml", "wb").write(client.xml_request) print client.xml_request header="""<soap:Header><qmw:Security xmlns:qmw="http://questionmark.com/QMWISe/"><qmw:ClientID>NAME</qmw:ClientID><qmw:Checksum>PASSWORD</qmw:Checksum></qmw:Security></soap:Header>""" self.assert_(header in client.xml_request, "header not in request!")
def create_tra(service=None, ttl=2400, cert=None): "Create a Access Request Ticket (TRA)" # Base TRA squeleton (Ticket de Requerimiento de Acceso) tra = SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?>' '<loginTicketRequest version="1.0">' '</loginTicketRequest>') tra.add_child('header') # get the source from the certificate subject, ie "CN=empresa, O=dna, C=py" if cert: crt = xmlsec.x509_parse_cert(cert) tra.header.add_child('source', crt.get_subject().as_text()) tra.header.add_child('destination', 'C=py, O=dna, OU=sofia, CN=wsaatest') d = int(time.mktime(datetime.datetime.now().timetuple())) tra.header.add_child('uniqueId', str(d)) date = lambda ts: datetime.datetime.fromtimestamp(ts).isoformat() tra.header.add_child('generationTime', str(date(d - ttl))) tra.header.add_child('expirationTime', str(date(d + ttl))) tra.add_child('service', service) return tra.as_xml()
def create_tra(service=None, ttl=2400, cert=None): "Create a Access Request Ticket (TRA)" # Base TRA squeleton (Ticket de Requerimiento de Acceso) tra = SimpleXMLElement( '<?xml version="1.0" encoding="UTF-8"?>' '<loginTicketRequest version="1.0">' '</loginTicketRequest>') tra.add_child('header') # get the source from the certificate subject, ie "CN=empresa, O=dna, C=py" if cert: crt = xmlsec.x509_parse_cert(cert) tra.header.add_child('source', crt.get_subject().as_text()) tra.header.add_child('destination', 'C=py, O=dna, OU=sofia, CN=wsaatest') d = int(time.mktime(datetime.datetime.now().timetuple())) tra.header.add_child('uniqueId', str(d)) date = lambda ts: datetime.datetime.fromtimestamp(ts).isoformat() tra.header.add_child('generationTime', str(date(d-ttl))) tra.header.add_child('expirationTime', str(date(d+ttl))) tra.add_child('service', service) return tra.as_xml()
def test_issue47_raw(self): "Same example (clarizen), with raw headers (no wsdl)!" client = SoapClient(location="https://api.clarizen.com/v1.0/Clarizen.svc", namespace='http://clarizen.com/api', trace=False) headers = SimpleXMLElement("<Headers/>", namespace="http://clarizen.com/api", prefix="ns1") session = headers.add_child("Session") session['xmlns'] = "http://clarizen.com/api" session.marshall('ID', '1234') client.location = "https://api.clarizen.com/v1.0/Clarizen.svc" client.action = "http://clarizen.com/api/IClarizen/Logout" try: client.call("Logout", headers=headers) except: open("issue47_raw.xml", "wb").write(client.xml_request) self.assert_("""<soap:Header><ns1:Session xmlns="http://clarizen.com/api"><ID>1234</ID></ns1:Session></soap:Header>""" in client.xml_request, "Session header not in request!")
def test_issue47_raw(self): "Same example (clarizen), with raw headers (no wsdl)!" client = SoapClient( location="https://api.clarizen.com/v1.0/Clarizen.svc", namespace='http://clarizen.com/api', trace=False) headers = SimpleXMLElement("<Headers/>", namespace="http://clarizen.com/api", prefix="ns1") session = headers.add_child("Session") session['xmlns'] = "http://clarizen.com/api" session.marshall('ID', '1234') client.location = "https://api.clarizen.com/v1.0/Clarizen.svc" client.action = "http://clarizen.com/api/IClarizen/Logout" try: client.call("Logout", headers=headers) except: open("issue47_raw.xml", "wb").write(client.xml_request) self.assertTrue( """<soap:Header><ns1:Session xmlns="http://clarizen.com/api"><ID>1234</ID></ns1:Session></soap:Header>""" in client.xml_request, "Session header not in request!")
# Por el momento se utilizan llamadas crudas (RAW) y no se parsea el WSDL ##client = SoapClient(wsdl=wsdl, cache="cache") # Instancio el cliente para consumir el webservice client = SoapClient(LOCATION, ACTION, namespace="DGI_Modernizacion_Consolidado", ns="dgi", soap_ns="soapenv", trace=True) # si se usa el WSDL, se puede consultar client.help("EFACRECEPCIONSOBRE") # construir los parámetros de la llamada al webservice (requerimiento): param = SimpleXMLElement( """<dgi:WS_PersonaGetActEmpresarial.Execute xmlns:dgi="DGI_Modernizacion_Consolidado" />""", namespace="DGI_Modernizacion_Consolidado", prefix="dgi") rut = param.add_child("Rut", "210475730011", ns=True) # agregar seguridad WSSE (mensaje firmado digitalmente para autenticacion) # usar el certificado unico asociado al RUT emisor emitidos por la # Administración Nacional de Correos (CA: autoridad certificadora actual) plugin = BinaryTokenSignature(certificate="certificado.crt", private_key="private.key", password=None, cacert="CorreoUruguayoCA.crt", ) client.plugins += [plugin] # llamar al método remoto ret = client.call("AWS_PERSONAGETACTEMPRESARIAL.Execute", param)
firma_xml = (xmlsec.SIGNATURE_TMPL % vars) cfe("ns0:CFE").import_node(SimpleXMLElement(firma_xml)) # guardo el xml firmado para depuración open("test.xml", "w").write(cfe.as_xml()) print cfe.as_xml() # serializar CDATA según el ejemplo cdata = xml.dom.minidom.CDATASection() cdata.data = cfe.as_xml() # construir los parámetros de la llamada al webservice (requerimiento): param = SimpleXMLElement( """<dgi:WS_eFactura.EFACRECEPCIONSOBRE xmlns:dgi="http://dgi.gub.uy"/>""", namespace="http://dgi.gub.uy", prefix="dgi") data_in = param.add_child("Datain", ns=True) data_in.add_child("xmlData", cdata, ns=True) # agregar seguridad WSSE (mensaje firmado digitalmente para autenticacion) # usar el certificado unico asociado al RUT emisor emitidos por la # Administración Nacional de Correos (CA: autoridad certificadora actual) plugin = BinaryTokenSignature(certificate="certificado.crt", private_key="private.key", password=None, cacert="CorreoUruguayoCA.crt", ) client.plugins += [plugin] # llamar al método remoto ret = client.call("AWS_EFACTURA.EFACRECEPCIONSOBRE", param)
cfe("ns0:CFE").import_node(SimpleXMLElement(firma_xml)) # guardo el xml firmado para depuración open("test.xml", "w").write(cfe.as_xml()) print cfe.as_xml() # serializar CDATA según el ejemplo cdata = xml.dom.minidom.CDATASection() cdata.data = cfe.as_xml() # construir los parámetros de la llamada al webservice (requerimiento): param = SimpleXMLElement( """<dgi:WS_eFactura.EFACRECEPCIONSOBRE xmlns:dgi="http://dgi.gub.uy"/>""", namespace="http://dgi.gub.uy", prefix="dgi") data_in = param.add_child("Datain", ns=True) data_in.add_child("xmlData", cdata, ns=True) # agregar seguridad WSSE (mensaje firmado digitalmente para autenticacion) # usar el certificado unico asociado al RUT emisor emitidos por la # Administración Nacional de Correos (CA: autoridad certificadora actual) plugin = BinaryTokenSignature( certificate="certificado.crt", private_key="private.key", password=None, cacert="CorreoUruguayoCA.crt", ) client.plugins += [plugin] # llamar al método remoto
class Client(): ''' Client class consume the wsEspol ''' __service = None header = None namespaces = { 'http://schemas.xmlsoap.org/soap/envelope/': None, 'http://tempuri.org/': None, 'http://www.w3.org/2001/XMLSchema': None } def __init__(self): self.__service = SoapClient(location='https://ws.espol.edu.ec/saac/wsandroid.asmx', namespace='http://tempuri.org/', action='http://tempuri.org/') self.header = SimpleXMLElement('<Header/>') security = self.header.add_child("GTSIAuthSoapHeader") security['xmlns'] = "http://tempuri.org/" security.marshall('usuario', os.environ['SPIDER_USER']) security.marshall('key', os.environ['SPIDER_KEY']) def __replace_special_chars(self, string): ''' Replaces vowels with a string accent :param string: sting to remove acents :return: string without vocal acents ''' return string.replace('\xf3', 'o').replace('\xe2', 'a').replace('\xed', 'i').replace( '\xe9', 'e').replace('\xfa', 'u').replace('\xc1', 'A').replace('\xc9', 'E').replace( '\xcd', 'I').replace('\xd3', 'O').replace('\xda', 'U').replace( '\xf1', 'n').replace('\xd1', 'N') def __to_dict(self, order_dict): ''' Convert OrderDict with nested OrderDict in regular dict :param order_dict: object type OrderDict :return: object type dict ''' return loads(dumps(order_dict)) def __bytes_to_dict(self, byte_object): ''' Convert bytes response object to regular dict ''' tmp = str(byte_object.decode('UTF-8', 'replace')) return self.__to_dict(xmltodict.parse(self.__replace_special_chars(tmp), process_namespaces=True, namespaces=self.namespaces)) def __remove_unused_items(self, json): ''' Return clean object or list of objects :param json: object list or dict :return: object without noise items ''' if isinstance(json, list): result = [] for item in json: try: del item['@urn:schemas-microsoft-com:xml-diffgram-v1:id'] del item['@urn:schemas-microsoft-com:xml-msdata:rowOrder'] del item['@xmlns'] except KeyError: pass result.append(item) return result elif isinstance(json, dict): del json['@xmlns'] del json['@urn:schemas-microsoft-com:xml-diffgram-v1:id'] del json['@urn:schemas-microsoft-com:xml-msdata:rowOrder'] return json else: return json def ws_consultar_persona_nombres(self, name, lastname): ''' Consume wsConsultarPersonaPorNombres :param name: name of the student :param lastname: lastname of the student :return: object dict with the information or array with coincident people ''' if name.isalpha() and lastname.isalpha(): response = self.__service.wsConsultarPersonaPorNombres(nombre=name, apellido=lastname, headers=self.header) json_response = self.__bytes_to_dict(response.as_xml()) json_response = json_response.get('Envelope').get('Body').get( 'wsConsultarPersonaPorNombresResponse').get( 'wsConsultarPersonaPorNombresResult').get( 'urn:schemas-microsoft-com:xml-diffgram-v1:diffgram').get( 'NewDataSet').get('DATOSPERSONA') return self.__remove_unused_items(json_response) else: raise AttributeError('name and lastname invalid') def ws_consulta_calificaciones(self, year, term, student_code): ''' Consume wsConsultaCalificaciones :param year: year to see grades :param term: academic term to see grades :param student_code: student id :return: array of dicts with the grades ''' if student_code.isdigit() and year.isdigit() and term.isdigit(): response = self.__service.wsConsultaCalificaciones(anio=str(year), termino=str( term), estudiante=student_code, headers=self.header) json_response = self.__bytes_to_dict(response.as_xml()) json_response = json_response.get('Envelope').get('Body').get( 'wsConsultaCalificacionesResponse').get( 'wsConsultaCalificacionesResult').get( 'urn:schemas-microsoft-com:xml-diffgram-v1:diffgram').get( 'NewDataSet').get('CALIFICACIONES') return self.__remove_unused_items(json_response) else: raise AttributeError('student code must be a string of numbers') def ws_consulta_codigo_estudiante(self, username): ''' Consume wsConsultaCodigoEstudiante :param user: username of the student :return: json with the student code ''' if username.isalpha(): response = self.__service.wsConsultaCodigoEstudiante( user=username, headers=self.header) json_response = self.__bytes_to_dict(response.as_xml()) json_response = json_response.get('Envelope').get( 'Body').get('wsConsultaCodigoEstudianteResponse').get( 'wsConsultaCodigoEstudianteResult').get( 'urn:schemas-microsoft-com:xml-diffgram-v1:diffgram').get( 'NewDataSet').get('MATRICULA') return self.__remove_unused_items(json_response) else: raise AttributeError( 'username is a string without numbers or special chars') def ws_consulta_periodo_actual(self): ''' Consume wsConsultaPeriodoActual :return: json with actual academic term ''' response = self.__service.wsConsultaPeriodoActual(headers=self.header) json_response = self.__bytes_to_dict(response.as_xml()) json_response = json_response.get('Envelope').get('Body').get( 'wsConsultaPeriodoActualResponse').get('wsConsultaPeriodoActualResult').get( 'urn:schemas-microsoft-com:xml-diffgram-v1:diffgram').get( 'NewDataSet').get('PERIODO') return self.__remove_unused_items(json_response) def ws_estudiantes_registrados(self, course_code, parallel): ''' Consume wsEstudiantesRegistrados :param course_code: code course e.g. 'ICM0001' :param parallel: the number of the course to find e.g. 1 :return: array with the students {code, name} the name is _x0031_ <- wtf? ''' if course_code.isalnum() and parallel.isdigit(): response = self.__service.wsEstudiantesRegistrados(codigoMateria=course_code, paralelo=int(parallel), headers=self.header) json_response = self.__bytes_to_dict(response.as_xml()) json_response = json_response.get('Envelope').get('Body').get( 'wsEstudiantesRegistradosResponse').get('wsEstudiantesRegistradosResult').get( 'urn:schemas-microsoft-com:xml-diffgram-v1:diffgram').get( 'NewDataSet').get('ESTUDIANTESREGISTRADOS') return self.__remove_unused_items(json_response) else: raise AttributeError('invalid inputs') def ws_horario_clases(self, course_code, parallel): ''' Consume wsHorarioClases :param course_code: code course e.g. 'ICM0001' :param parallel: the number of the course to find e.g. 1 :return: list with hours or dict with 1 hour ''' if course_code.isalnum() and parallel.isdigit(): response = self.__service.wsHorarioClases(codigoMateria=course_code, paralelo=int(parallel), headers=self.header) json_response = self.__bytes_to_dict(response.as_xml()) json_response = json_response.get('Envelope').get('Body').get( 'wsHorarioClasesResponse').get('wsHorarioClasesResult').get( 'urn:schemas-microsoft-com:xml-diffgram-v1:diffgram').get( 'NewDataSet').get('HORARIOCLASES') return self.__remove_unused_items(json_response) else: raise AttributeError('invalid inputs') def ws_horario_examenes(self, course_code, parallel): ''' Consume wsHorarioExamenes :param course_code: code course e.g. 'ICM0001' :param parallel: the number of the course to find e.g. 1 :return: list with tests date ''' if course_code.isalnum() and parallel.isdigit(): response = self.__service.wsHorarioExamenes(codigoMateria=course_code, paralelo=int(parallel), headers=self.header) json_response = self.__bytes_to_dict(response.as_xml()) json_response = json_response.get('Envelope').get('Body').get( 'wsHorarioExamenesResponse').get('wsHorarioExamenesResult').get( 'urn:schemas-microsoft-com:xml-diffgram-v1:diffgram').get( 'NewDataSet').get('_x0020__x0020_') # '_x0020__x0020_' <- wtf? return self.__remove_unused_items(json_response) else: raise AttributeError('invalid inputs') def ws_materias_registradas(self, student_code): ''' Consume wsMateriasRegistradas :param student_code: student id ''' if student_code.isdigit(): response = self.__service.wsMateriasRegistradas(codigoestudiante=student_code, headers=self.header) json_response = self.__bytes_to_dict(response.as_xml()) json_response = json_response.get('Envelope').get('Body').get( 'wsMateriasRegistradasResponse').get('wsMateriasRegistradasResult').get( 'urn:schemas-microsoft-com:xml-diffgram-v1:diffgram').get( 'NewDataSet').get('MATERIASREGISTRADAS') return self.__remove_unused_items(json_response) else: raise AttributeError('student code must be a string of numbers') def ws_info_estudiante_general(self, student_code): ''' Consume wsInfoEstudianteGeneral :param student_code: student id ''' if student_code.isdigit(): response = self.__service.wsInfoEstudianteGeneral(codestudiante=student_code, headers=self.header) json_response = self.__bytes_to_dict(response.as_xml()) json_response = json_response.get('Envelope').get('Body').get( 'wsInfoEstudianteGeneralResponse').get('wsInfoEstudianteGeneralResult').get( 'urn:schemas-microsoft-com:xml-diffgram-v1:diffgram').get( 'NewDataSet').get('ESTUDIANTE') return self.__remove_unused_items(json_response) else: raise AttributeError('student code must be a string of numbers') def ws_info_estudiante(self, student_code): ''' consume wsInfoEstudiante :param student_code: student id ''' if student_code.isdigit(): response = self.__service.wsInfoEstudiante(codigoEstudiante=student_code, headers=self.header) json_response = self.__bytes_to_dict(response.as_xml()) json_response = json_response.get('Envelope').get('Body').get( 'wsInfoEstudianteResponse').get('wsInfoEstudianteResult').get( 'urn:schemas-microsoft-com:xml-diffgram-v1:diffgram').get( 'NewDataSet').get('INFOESTUDIANTE') return self.__remove_unused_items(json_response) else: raise AttributeError('student code must be a string of numbers') def ws_info_estudiante_carrera(self, student_code): ''' Consume wsInfoEstudianteCarrera :param student_code: student id ''' if student_code.isdigit(): response = self.__service.wsInfoEstudianteCarrera(codigoEstudiante=student_code, headers=self.header) json_response = self.__bytes_to_dict(response.as_xml()) json_response = json_response.get('Envelope').get('Body').get( 'wsInfoEstudianteCarreraResponse').get('wsInfoEstudianteCarreraResult').get( 'urn:schemas-microsoft-com:xml-diffgram-v1:diffgram').get( 'NewDataSet').get('ESTUDIANTECARRERA') return self.__remove_unused_items(json_response) else: raise AttributeError('student code must be a string of numbers') def ws_info_personal_estudiante(self, student_code, dni): ''' Consume wsInfoPersonalEstudiante :param student_code: student id :param dni: dni code ''' if student_code.isdigit() and dni.isdigit(): response = self.__service.wsInfoPersonalEstudiante(matricula=student_code, identificacion=dni, headers=self.header) json_response = self.__bytes_to_dict(response.as_xml()) json_response = json_response.get('Envelope').get('Body').get( 'wsInfoPersonalEstudianteResponse').get('wsInfoPersonalEstudianteResult').get( 'urn:schemas-microsoft-com:xml-diffgram-v1:diffgram').get( 'NewDataSet').get('INFOPERSONALESTUDIANTE') return self.__remove_unused_items(json_response) else: raise AttributeError('student code or dni invalid') def ws_info_usuario(self, user): ''' Consume wsInfoUsuario :param user: username in the academic system ''' if user.isalpha(): response = self.__service.wsInfoUsuario(usuario=user, headers=self.header) json_response = self.__bytes_to_dict(response.as_xml()) json_response = json_response.get('Envelope').get('Body').get( 'wsInfoUsuarioResponse').get('wsInfoUsuarioResult').get( 'urn:schemas-microsoft-com:xml-diffgram-v1:diffgram').get( 'NewDataSet').get('INFORMACIONUSUARIO') return self.__remove_unused_items(json_response) else: raise AttributeError('username incorrect') def ws_info_paralelo(self, course_code, parallel): ''' Consume wsInfoparalelo :param course_code: code course e.g. 'ICM0001' :param parallel: the number of the course to find e.g. 1 ''' if course_code.isalnum() and parallel.isdigit(): response = self.__service.wsInfoparalelo(codigoMateria=course_code, paralelo=int(parallel), headers=self.header) json_response = self.__bytes_to_dict(response.as_xml()) json_response = json_response.get('Envelope').get('Body').get( 'wsInfoparaleloResponse').get('wsInfoparaleloResult').get( 'urn:schemas-microsoft-com:xml-diffgram-v1:diffgram').get( 'NewDataSet').get('INFORMACIONMATERIA') return self.__remove_unused_items(json_response) else: raise AttributeError('invalid inputs') def ws_materias_disponibles(self, student_code): ''' Consume wsMateriasDisponibles :param student_code: student id ''' if student_code.isdigit(): response = self.__service.wsMateriasDisponibles(codigoestudiante=student_code, headers=self.header) json_response = self.__bytes_to_dict(response.as_xml()) json_response = json_response.get('Envelope').get('Body').get( 'wsMateriasDisponiblesResponse').get('wsMateriasDisponiblesResult').get( 'urn:schemas-microsoft-com:xml-diffgram-v1:diffgram').get( 'NewDataSet').get('MATERIASDISPONIBLES') return self.__remove_unused_items(json_response) else: raise AttributeError('student code must be a string of numbers')
# Instancio el cliente para consumir el webservice client = SoapClient(LOCATION, ACTION, namespace="DGI_Modernizacion_Consolidado", ns="dgi", soap_ns="soapenv", trace=True) # si se usa el WSDL, se puede consultar client.help("EFACRECEPCIONSOBRE") # construir los parámetros de la llamada al webservice (requerimiento): param = SimpleXMLElement( """<dgi:WS_PersonaGetActEmpresarial.Execute xmlns:dgi="DGI_Modernizacion_Consolidado" />""", namespace="DGI_Modernizacion_Consolidado", prefix="dgi") rut = param.add_child("Rut", "210475730011", ns=True) # agregar seguridad WSSE (mensaje firmado digitalmente para autenticacion) # usar el certificado unico asociado al RUT emisor emitidos por la # Administración Nacional de Correos (CA: autoridad certificadora actual) plugin = BinaryTokenSignature( certificate="certificado.crt", private_key="private.key", password=None, cacert="CorreoUruguayoCA.crt", ) client.plugins += [plugin] # llamar al método remoto ret = client.call("AWS_PERSONAGETACTEMPRESARIAL.Execute", param)