Esempio n. 1
0
def floodlight_rows(
    config, task: dict, report_id: int
) -> Generator[list[str, str, str, str, str, str, int], None, None]:
    """ Monitor a report for completion and return rows

  Args:
    report_id - the report created earlier for a specific floodlight id.

  Returns:
    A stream of rows, see FLOODLIGHT_* constants for definitions.
  """

    # fetch report file if it exists
    filename, report = report_file(
        config,
        task['auth'],
        task['account'],
        report_id,
        None,  # no name
        10  # wait up to 10 minutes for report to complete
    )

    # clean up rows
    rows = report_to_rows(report)
    rows = report_clean(rows)
    rows = rows_header_trim(rows)
    rows = rows_to_type(rows, column=6)

    return rows
Esempio n. 2
0
def report_main(config,
                task,
                name,
                dateRange,
                schedule,
                advertiser,
                campaign,
                shadow=True):
    if config.verbose:
        print('DYNAMIC COSTS MAIN:', name)

    # base report schema
    schema = {
        'kind': 'dfareporting#report',
        'type': 'STANDARD',
        'name': 'Dynamic Costs %s - Main Advertiser ( StarThinker )' % name,
        'schedule': schedule,
        'criteria': {
            'dateRange':
            dateRange,
            'dimensionFilters': [{
                'kind': 'dfareporting#dimensionValue',
                'dimensionName': 'dfa:advertiser',
                'id': advertiser,
                'matchType': 'EXACT'
            }, {
                'kind': 'dfareporting#dimensionValue',
                'dimensionName': 'dfa:campaign',
                'id': campaign,
                'matchType': 'EXACT'
            }],
            'dimensions': [{
                'kind': 'dfareporting#sortedDimension',
                'name': 'dfa:placement'
            }, {
                'kind': 'dfareporting#sortedDimension',
                'name': 'dfa:placementId'
            }],
            'metricNames': ['dfa:impressions', 'dfa:clicks']
        }
    }

    # if not using shadow advertiser, pull DBM cost here
    if not shadow:
        schema['criteria']['metricNames'].append('dfa:dbmCost')

    # create the report if it does not exist
    report = report_build(config, task['auth'], task['account'], schema)

    # fetch report file if it exists ( timeout = 0 means grab most reent ready )
    filename, filedata = report_file(config, task['auth'], task['account'],
                                     report['id'], None, 60, DCM_CHUNK_SIZE)

    # write report to a table ( avoid collisions as best as possible )
    table_name = 'Dynamic_Costs_%s_Main_Advertiser' % name
    write_report(config, task, filedata, task['out']['dataset'], table_name)

    return table_name
Esempio n. 3
0
def report_shadow(config, task, name, dateRange, schedule, advertiser,
                  campaign):
    if config.verbose:
        print('DYNAMIC COSTS SHADOW:', name)

    # create the report if it does not exist
    report = report_build(
        config, task['auth'], task['account'], {
            'kind': 'dfareporting#report',
            'type': 'STANDARD',
            'name':
            'Dynamic Costs %s - Shadow Advertiser ( StarThinker )' % name,
            'schedule': schedule,
            'criteria': {
                'dateRange':
                dateRange,
                'dimensionFilters': [{
                    'dimensionName': 'dfa:advertiser',
                    'id': advertiser,
                    'kind': 'dfareporting#dimensionValue',
                    'matchType': 'EXACT'
                }, {
                    'dimensionName': 'dfa:campaign',
                    'id': campaign,
                    'kind': 'dfareporting#dimensionValue',
                    'matchType': 'EXACT'
                }],
                'dimensions': [{
                    'kind': 'dfareporting#sortedDimension',
                    'name': 'dfa:placement'
                }, {
                    'kind': 'dfareporting#sortedDimension',
                    'name': 'dfa:placementId'
                }],
                'metricNames': ['dfa:dbmCost']
            }
        })

    # fetch report file if it exists ( timeout = 0 means grab most reent ready )
    filename, filedata = report_file(config, task['auth'], task['account'],
                                     report['id'])

    # write report to a table ( avoid collisions as best as possible )
    table_name = 'Dynamic_Costs_%s_Shadow_Advertiser' % name
    write_report(config, task, filedata, task['out']['dataset'], table_name)

    return table_name
Esempio n. 4
0
def dcm_replicate_download(config, task, account, name):

    filename, report = report_file(config, task['auth'], account, None, name)

    if report:
        if config.verbose:
            print('DCM FILE', filename)

        # clean up the report
        rows = report_to_rows(report)
        rows = report_clean(rows)

        # if bigquery, remove header and determine schema
        schema = None
        if 'bigquery' in task['out']:
            task['out']['bigquery']['table'] = table_name_sanitize(name)
            task['out']['bigquery']['schema'] = report_schema(next(rows))
            task['out']['bigquery']['skip_rows'] = 0

        # write rows using standard out block in json ( allows customization across all scripts )
        if rows:
            put_rows(config, task['auth'], task['out'], rows)
Esempio n. 5
0
def main():

    parser = argparse.ArgumentParser(
        formatter_class=argparse.RawDescriptionHelpFormatter,
        description=textwrap.dedent("""\
      Command line to help debug CM reports and build reporting tools.

      Examples:
        To get list of reports: python cm.py --account [id] --list -u [user credentials path]
        To get report: python cm.py --account [id] --report [id] -u [user credentials path]
        To get report files: python cm.py --account [id] --files [id] -u [user credentials path]
        To get report sample: python cm.py --account [id] --sample [id] -u [user credentials path]
        To get report schema: python cm.py --account [id] --schema [id] -u [user credentials path]

  """))

    parser.add_argument('--account',
                        help='Account ID to use to pull the report.',
                        default=None)
    parser.add_argument('--report',
                        help='Report ID to pull JSON definition.',
                        default=None)
    parser.add_argument('--schema',
                        help='Report ID to pull achema definition.',
                        default=None)
    parser.add_argument('--sample',
                        help='Report ID to pull sample data.',
                        default=None)
    parser.add_argument('--files',
                        help='Report ID to pull file list.',
                        default=None)
    parser.add_argument('--list', help='List reports.', action='store_true')

    # initialize project
    parser = commandline_parser(parser, arguments=('-u', '-c', '-s', '-v'))
    args = parser.parse_args()
    config = Configuration(user=args.user,
                           client=args.client,
                           service=args.service,
                           verbose=args.verbose)

    auth = 'service' if args.service else 'user'

    is_superuser, profile = get_profile_for_api(config, auth, args.account)
    kwargs = {
        'profileId': profile,
        'accountId': args.account
    } if is_superuser else {
        'profileId': profile
    }

    # get report list
    if args.report:
        kwargs['reportId'] = args.report
        report = API_DCM(
            config, auth,
            internal=is_superuser).reports().get(**kwargs).execute()
        print(json.dumps(report, indent=2, sort_keys=True))

    # get report files
    elif args.files:
        kwargs['reportId'] = args.files
        for rf in API_DCM(
                config, auth, internal=is_superuser,
                iterate=True).reports().files().list(**kwargs).execute():
            print(json.dumps(rf, indent=2, sort_keys=True))

    # get schema
    elif args.schema:
        filename, report = report_file(config, auth, args.account, args.schema,
                                       None, 10)
        rows = report_to_rows(report)
        rows = report_clean(rows)
        print(json.dumps(report_schema(next(rows)), indent=2, sort_keys=True))

    # get sample
    elif args.sample:
        filename, report = report_file(config, auth, args.account, args.sample,
                                       None, 10)
        rows = report_to_rows(report)
        rows = report_clean(rows)
        rows = rows_to_type(rows)
        for r in rows_print(rows, row_min=0, row_max=20):
            pass

    # get list
    else:
        for report in API_DCM(config,
                              auth,
                              internal=is_superuser,
                              iterate=True).reports().list(**kwargs).execute():
            print(json.dumps(report, indent=2, sort_keys=True))
Esempio n. 6
0
def dcm(config, task):
    if config.verbose:
        print('DCM')

    # stores existing report json
    report = None

    # check if report is to be deleted
    if task.get('delete', False):
        if config.verbose:
            print(
                'DCM DELETE', task['report'].get('name', None)
                or task['report'].get('body', {}).get('name', None)
                or task['report'].get('report_id', None))
        report_delete(
            config,
            task['auth'],
            task['report']['account'],
            task['report'].get('report_id', None),
            task['report'].get('name', None)
            or task['report'].get('body', {}).get('name', None),
        )

    # check if report is to be run
    if task.get('report_run_only', False):
        if config.verbose:
            print(
                'DCM REPORT RUN', task['report'].get('name', None)
                or task['report'].get('report_id', None))
        report_run(
            config,
            task['auth'],
            task['report']['account'],
            task['report'].get('report_id', None),
            task['report'].get('name', None),
        )

    # check if report is to be created
    if 'body' in task['report']:
        if config.verbose:
            print('DCM BUILD', task['report']['body']['name'])

        if 'filters' in task['report']:
            task['report']['body'] = report_filter(config, task['auth'],
                                                   task['report']['body'],
                                                   task['report']['filters'])

        report = report_build(
            config, task['auth'], task['report']['body'].get('accountId')
            or task['report']['account'], task['report']['body'])

    # moving a report
    if 'out' in task:
        filename, report = report_file(
            config,
            task['auth'],
            task['report']['account'],
            task['report'].get('report_id', None),
            task['report'].get('name', None)
            or task['report'].get('body', {}).get('name', None),
            task['report'].get('timeout', 10),
        )

        if report:
            if config.verbose:
                print('DCM FILE', filename)

            # clean up the report
            rows = report_to_rows(report)
            rows = report_clean(rows)

            # if bigquery, remove header and determine schema
            schema = None
            if 'bigquery' in task['out']:
                schema = report_schema(next(rows))
                task['out']['bigquery']['schema'] = schema
                task['out']['bigquery']['skip_rows'] = 0

            # write rows using standard out block in json ( allows customization across all scripts )
            if rows:
                put_rows(config, task['auth'], task['out'], rows)
Esempio n. 7
0
def run_floodlight_reports(config, task):
  if config.verbose:
    print('Creating Floodlight reports')

  body = {
    "kind": "dfareporting#report",
    "name": '', # this is updated below based on Floodlight Config ID
    "format": "CSV",
    "type": "FLOODLIGHT",
    "floodlightCriteria": {
      "dateRange": {
        "kind": "dfareporting#dateRange",
        "relativeDateRange": "LAST_60_DAYS"
      },
      "floodlightConfigId": {
        "kind": "dfareporting#dimensionValue",
        "dimensionName": "dfa:floodlightConfigId",
        "value": 0, # updated below and replaced with Floodlight Config ID
        "matchType": "EXACT"
      },
      "reportProperties": {
        "includeUnattributedIPConversions": False,
        "includeUnattributedCookieConversions": True
      },
      "dimensions": [
      {
        "kind": "dfareporting#sortedDimension",
        "name": "dfa:site"
      },
      {
        "kind": "dfareporting#sortedDimension",
        "name": "dfa:floodlightAttributionType"
      },
      {
        "kind": "dfareporting#sortedDimension",
        "name": "dfa:interactionType"
      },
      {
        "kind": "dfareporting#sortedDimension",
        "name": "dfa:pathType"
      },
      {
        "kind": "dfareporting#sortedDimension",
        "name": "dfa:browserPlatform"
      },
      {
        "kind": "dfareporting#sortedDimension",
        "name": "dfa:platformType"
      },
      {
        "kind": "dfareporting#sortedDimension",
        "name": "dfa:week"
      },
      {
        "kind": "dfareporting#sortedDimension",
        "name": "dfa:placementId"
      },
      {
        "kind": "dfareporting#sortedDimension",
        "name": "dfa:floodlightConfigId"
      }],
      "metricNames": [
        "dfa:activityClickThroughConversions",
        "dfa:activityViewThroughConversions",
        "dfa:totalConversions",
        "dfa:totalConversionsRevenue"
      ]
    },
    "schedule": {
      "active": True,
      "repeats": "WEEKLY",
      "every": 1,
      "repeatsOnWeekDays":["Sunday"]
    },
    "delivery": {
      "emailOwner": False
    }
  }

  reports = []
  floodlightConfigs = task.get('floodlightConfigIds', None)

  for configId in floodlightConfigs:
    body['name'] = task.get('reportPrefix', '') + "_" + str(configId)
    body['floodlightCriteria']['floodlightConfigId']['value'] = configId
    report = report_build(
      config, task['auth_cm'],
      task['account'],
      body
    )
    reports.append(report['id'])

  if config.verbose:
    print('Finished creating Floodlight reports - moving to BQ')

  queries = []

  for createdReportId in reports:
    filename, report = report_file(
      config, task['auth_cm'],
      task['account'],
      createdReportId,
      None,
      task.get('timeout', 10),
    )

    if report:
      if config.verbose:
        print('Floodlight config report ', filename)

      # clean up the report
      rows = report_to_rows(report)
      rows = report_clean(rows)

      # determine schema
      schema = report_schema(next(rows))

      out_block = {}
      out_block['bigquery'] = {}


      out_block['bigquery']['dataset'] = task['dataset']
      out_block['bigquery']['schema'] = schema
      out_block['bigquery']['skip_rows'] = 0
      out_block['bigquery']['table'] = 'z_Floodlight_CM_Report_' + str(createdReportId)

      # write rows using standard out block in json ( allows customization across all scripts )
      if rows: put_rows(config, task['auth_bq'], out_block, rows)
      queries.append('SELECT * FROM `{0}.{1}.{2}`'.format(config.project, out_block['bigquery']['dataset'], out_block['bigquery']['table']))

  if config.verbose:
    print('Moved reports to BQ tables - starting join')
  finalQuery = ' UNION ALL '.join(queries)

  query_to_table(
    config, task['auth_bq'],
    config.project,
    task['dataset'],
    CM_FLOODLIGHT_OUTPUT_TABLE,
    finalQuery,
    legacy=False
  )

  if config.verbose:
    print('Finished with Floodlight Config reports')
Esempio n. 8
0
def report_combos(config, task, name, dateRange, schedule, advertiser,
                  campaign, dynamicProfile):
    if config.verbose:
        print('DYNAMIC COSTS COMBOS:', name)

    # basic report schema, with no dynamic elements
    schema = {
        'kind': 'dfareporting#report',
        'type': 'STANDARD',
        'name': 'Dynamic Costs %s - Dynamic Combos ( StarThinker )' % name,
        'schedule': schedule,
        'criteria': {
            'dateRange':
            dateRange,
            'dimensionFilters': [{
                'kind': 'dfareporting#dimensionValue',
                'dimensionName': 'dfa:dynamicProfile',
                'id': dynamicProfile,
                'matchType': 'EXACT'
            }, {
                'kind': 'dfareporting#dimensionValue',
                'dimensionName': 'dfa:advertiser',
                'id': advertiser,
                'matchType': 'EXACT'
            }, {
                'kind': 'dfareporting#dimensionValue',
                'dimensionName': 'dfa:campaign',
                'id': campaign,
                'matchType': 'EXACT'
            }],
            'dimensions': [{
                'kind': 'dfareporting#sortedDimension',
                'name': 'dfa:placement'
            }, {
                'kind': 'dfareporting#sortedDimension',
                'name': 'dfa:placementId'
            }, {
                'kind': 'dfareporting#sortedDimension',
                'name': 'dfa:activity'
            }, {
                'kind': 'dfareporting#sortedDimension',
                'name': 'dfa:activityId'
            }],
            'metricNames':
            ['dfa:impressions', 'dfa:clicks', 'dfa:totalConversions']
        }
    }

    # add in all reasonable dynamic elements
    for i in range(1, 5 + 1):  # 5 elements/feeds
        for j in range(1, 6 + 1):  # 6 fields per element
            schema['criteria']['dimensions'].append({
                'kind':
                'dfareporting#sortedDimension',
                'name':
                'dfa:dynamicElement%iField%iValue' % (i, j)
            })

    print(json.dumps(schema, indent=2))

    # create the report if it does not exist
    report = report_build(config, task['auth'], task['account'], schema)

    # fetch report file if it exists ( timeout = 0 means grab most reent ready )
    filename, filedata = report_file(config, task['auth'], task['account'],
                                     report['id'], None, 60, DCM_CHUNK_SIZE)

    # write report to a table ( avoid collisions as best as possible )
    table_name = 'Dynamic_Costs_%s_Dynamic_Combos' % name
    write_report(config, task, filedata, task['out']['dataset'], table_name)

    return table_name