Python Client para REST API do Jasper Report Server

python-report-jasper-server+logo

 

 

 

 

 

 

 

 

 

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]