Python Client para REST API do Jasper Report Server
Após Criar a biblioteca em Ruby que é meu forte, pra testar logo o Jasper Report e sua interface REST, tive que implementar uma biblioteca um pouco mais elaborada para que pudesse implantar em meus projetos Django. Eis o resultado
Look code in my Github https://github.com/LuizCarvalho/JasperRest/tree/master/python
[geshi lang="python" nums="1" target="_blank" ]
# -*- coding: utf-8 -*- ''' Python Rest Client for Jasper Report Server Biblioteca para facilitar o processo de comunicação com servidor de relatório Jasper Report Server ''' __author__ = "Luiz Carvalho" __copyright__ = "Copyright 2013, Defensoria Pública do Estado do Tocantins" __version__ = '1.0.1' import urllib2 import base64 from urlparse import urlparse import xml.etree.ElementTree as ET from datetime import datetime,date import time SERVER_ADDR= "127.0.0.1" SERVER_PORT = 8080 USERNAME = "jasperadmin" PASSWORD = "jasperadmin" REPORT_URI = "http://%s:%s/jasperserver/rest/report/"%(SERVER_ADDR,SERVER_PORT) class RestReport(): ''' RestReport é um cliente para acesso A API RESTful dos repositórios do Jasper Report Server Possibilitando de maneira simples a geração de relatórios presentes no servidor ''' report_name= None report_path = None format = 'pdf' auth_token = None auth_cookie = None uuid = None params = {} def __init__(self,report_path,report_name,format='pdf'): ''' PARAMS: report_path:`string` ex: 'athenas','athenas/rh','athenas/edoc' report_name:`string` ex: 'protocolo','contracheque' format:`string` (optional) ex: 'pdf','csv','xml','xls' OBS: para passar os parâmetros para consulta utilize o metodo +set_params(parametros)+ ''' self.report_name = report_name self.report_path = report_path self.format = format def set_params(self,params): ''' Inclui os parametros necessários para pesquisa no relatório PARAMS: params:`dict` ex: "criacao_inicio":`datetime`(2011,1,1),"criacao_final":`datetime`(2014,1,1),'protocolo':201302011234} ''' if(type(params) == dict): for k,v in params.items(): if isinstance(v,date): self.params[k]= self.to_ms(v) else: self.params[k]=v else: raise TypeError("Params is not Dict Type") def build_xml_request(self): ''' Cria a estrutura XML para acesso e consulta no relatório RETURN: xml_request:`string` ''' url_string = "/reports/"+self.report_path+"/"+self.report_name request_body = "" #print "CRIANDO XML PARA: "+url_string for k,v in self.params.items(): request_body += "\n%s\n"% (k, v) print "CHAVE=>",k,"VALOR=>",v request_body+="" return request_body def authenticator(self): ''' Realiza a autenticação e preparação no servidor Jasper Report para que seja possível a geração do relatório. ''' handle = None body = "" uri = REPORT_URI+"reports/"+self.report_path+"/"+self.report_name+"/?RUN_OUTPUT_FORMAT="+self.format req = urllib2.Request(uri) base64string = base64.encodestring('%s:%s' % (USERNAME, PASSWORD))[:-1] authheader = "Basic %s" % base64string req.add_header("Authorization", authheader) req.get_method = lambda: 'PUT' req.data = self.build_xml_request() try: handle = urllib2.urlopen(req) self.auth_cookie = handle.headers["Set-Cookie"] body = handle.read() except Exception, e: raise RestError(e,"O Servidor não está respondendo ao endereço solicitado: "+uri) xml = ET.fromstring(body) try: uuid = xml.find('uuid').text except Exception, e: raise ValueError(e,"Identificador do Relatório Não Encontrado (UUID)") self.uuid = uuid def generate_report(self): ''' Gera o relatório no servidor retornando o conteúdo do relatório em dados RETURN: report_data:`string` ''' body = None auth = self.authenticator() req = urllib2.Request(REPORT_URI+self.uuid+"?file=report") base64string = base64.encodestring('%s:%s' % (USERNAME, PASSWORD))[:-1] authheader = "Basic %s" % base64string req.add_header("Authorization", authheader) req.add_header("Cookie", self.auth_cookie) req.get_method = lambda: 'GET' try: handle = urllib2.urlopen(req) report_data = handle.read() except Exception, e: raise RestError(e,"Não foi possível obter o relatório do servidor: "+req.get_full_url()) return report_data def to_ms(self,final): ''' Converte Datas para tempo em milissegundos PARAMS: a_time:`datetime` RETURN: time_in_ms:`int` ''' start = datetime.utcfromtimestamp(0) #1970,1,1 final_ms = time.mktime(final.timetuple()) start_ms = time.mktime(start.timetuple()) return int(final_ms-start_ms)*1000 class RestError(Exception): """Rest Report exception""" def __init__(self, reason, message=None): self.reason = str(reason) self.full_message = str(message+"\n"+self.reason) #print "REST REPORT ERROR: "+self.reason def __str__(self): return self.full_message
[/geshi]