Пример #1
0
class DCMReportRunner(ReportRunner):
  report_type = Type.CM

  def __init__(self, cm_id: str=None, profile: str=None,
               email: str=None, project: str=None):
    self.email = email
    self.cm_id = cm_id
    self.cm_profile = profile
    self.project = project
    self.firestore = Firestore(email=email, project=project)


  def run(self, unattended: bool=True) -> None:
    dcm = DCM(email=self.email, project=self.project, profile=self.cm_profile)
    
    if unattended:
      self._unattended_run(dcm)
    else:
      self._attended_run(dcm)


  def _attended_run(self, dcm: DCM) -> None:
    successful = []
    response = dcm.run_report(report_id=self.cm_id, synchronous=True)
    if response:
      buffer = StringIO()
      pprint.pprint(response, stream=buffer)
      logging.info(buffer.getvalue())

    while response['status'] == 'PROCESSING':
      time.sleep(60 * 0.5)
      response = dcm.report_state(report_id=self.cm_id, file_id=response['id'])
      buffer = StringIO()
      pprint.pprint(response, stream=buffer)
      logging.info(buffer.getvalue())

    report2bq = Report2BQ(
      cm=True, cm_id=self.cm_id, email=self.email, project=self.project,
      profile=self.cm_profile
    )
    report2bq.handle_report_fetcher(fetcher=dcm, report_id=self.cm_id)


  def _unattended_run(self, dcm: DCM) -> None:
    response = dcm.run_report(report_id=self.cm_id, synchronous=False)
    if response:
      buffer = StringIO()
      pprint.pprint(response, stream=buffer)
      logging.info(buffer.getvalue())

      runner = {
        'type': Type.CM.value,
        'project': self.project,
        'report_id': self.cm_id,
        'email': self.email,
        'profile': self.cm_profile,
        'file_id': response['id']
      }
      self.firestore.store_report_runner(runner)
Пример #2
0
class DBMReportRunner(ReportRunner):
    report_type = Type.DV360

    def __init__(self,
                 dbm_id: str = None,
                 email: str = None,
                 project: str = None):
        self.email = email
        self.dbm_id = dbm_id
        self.project = project
        self.firestore = Firestore(email=email, project=project)

    def run(self, unattended: bool = True):
        dbm = DBM(email=self.email, project=self.project)

        if unattended:
            self._unattended_run(dbm)
        else:
            self._attended_run(dbm)

    def _attended_run(self, dbm: DBM) -> None:
        response = dbm.run_report(self.dbm_id)
        if response:
            buffer = StringIO()
            pprint.pprint(response, stream=buffer)
            logging.info(buffer.getvalue())

        while True:
            status = dbm.report_state(self.dbm_id)
            logging.info(f'Report {self.dbm_id} status: {status}')
            if status == 'RUNNING':
                time.sleep(10)

            elif status == 'DONE':
                report2bq = Report2BQ(dv360=True,
                                      dv360_id=self.dbm_id,
                                      email=self.email,
                                      project=self.project)
                report2bq.handle_report_fetcher(fetcher=dbm,
                                                report_id=self.dbm_id)
                break

            else:
                logging.error(
                    f'DV360 Report {self.dbm_id} failed to run: {status}')
                break

    def _unattended_run(self, dbm: DBM) -> None:
        response = dbm.run_report(self.dbm_id)
        if response:
            runner = {
                'type': Type.DV360.value,
                'project': self.project,
                'report_id': self.dbm_id,
                'email': self.email,
            }
            self.firestore.store_report_runner(runner)
Пример #3
0
class SA360ReportRunner(ReportRunner):
  report_type = Type.SA360_RPT

  def __init__(self, report_id: str, email: str, project: str=None, timezone: str=None):
    self.email = email
    self.report_id = report_id
    self.project = project
    self.timezone = timezone

    self.firestore = Firestore()


  def run(self, unattended: bool = True) -> Dict[str, Any]:
    # TODO: Make SA360 object here
    sa360 = SA360(self.email, self.project)

    if unattended:
      return self._unattended_run(sa360=sa360)
    else:
      return self._attended_run(sa360=sa360)


  def _unattended_run(self, sa360: SA360) -> Dict[str, Any]:
    runner = None
    report_config = None
    try:
    
      report_config = self.firestore.get_document(type=Type.SA360_RPT, id=self.report_id)
      if not report_config:
        raise NotImplementedError(f'No such runner: {self.report_id}')

      _tz = pytz.timezone(report_config.get('timezone') or self.timezone or 'America/Toronto')
      _today = datetime.now(_tz)

      report_config['StartDate'] = (_today - timedelta(days=(report_config.get('offset') or 0))).strftime('%Y-%m-%d')
      report_config['EndDate'] = (_today - timedelta(days=(report_config.get('lookback') or 0))).strftime('%Y-%m-%d')

      template = self.firestore.get_document(Type.SA360_RPT, '_reports').get(report_config['report'])
      request_body = SA360ReportTemplate().prepare(template=template, values=report_config)
      sa360_service = DiscoverService.get_service(Service.SA360, sa360.creds)
      request = sa360_service.reports().request(body=request_body)
      response = request.execute()
      logging.info(response)

      runner = {
        'type': Type.SA360_RPT.value,
        'project': self.project,
        'report_id': self.report_id,
        'email': self.email,
        'file_id': response['id']
      }
      self.firestore.store_report_runner(runner)

    except Exception as e:
      self._email_error(email=self.email, error=e, report_config=report_config,
        message=f'Error in SA360 Report Runner for report {self.report_id}')

    finally:
      return runner

  def _email_error(self, message: str, email: str=None,
    error: Exception=None, report_config: Dict[str, Any]=None) -> None:
    _to = [email] if email else []
    _administrator = os.environ.get('ADMINISTRATOR_EMAIL') or self.FIRESTORE.get_document(Type._ADMIN, 'admin').get('email')
    _cc = [_administrator] if _administrator else []

    if _to or _cc:
      message = GMailMessage(
        to=_to, 
        cc=_cc,
        subject=message,
        body=f'''
{message}

Config: {report_config if report_config else 'Config unknown.'}

Error: {error if error else 'No exception.'}
''', 
        project=os.environ.get('GCP_PROJECT'))

      GMail().send_message(
        message=message,
        credentials=Credentials(email=email, project=os.environ.get('GCP_PROJECT'))
      )

  def _attended_run(self, sa360: SA360) -> None: 
    raise NotImplementedError()