How-to: Add a Job (Task) Type๏
In order to add a new Job Type, the following steps shall be used:
Each job is uniquely identified by two keys: platform and type name. Platform is a value from the
ppc_robot_lib.platform.PlatformType
enum. Type name is a short identifier which should describe the job type and should be consistent with other platforms, e.g.custom_report
,url_check_report
,ad_multivariate_test_report
and so on.Create a new subpackage in
ppc_robot_task_types/<platform>/<task_type>
(e.g.ppc_robot_task_types/adwords/custom_report
). The__init__.py
file can be blank.Create your first version of the report: create a module named
<type_name>_v1.py
. The file should contain a class namedTypeNameV1
that implements theppc_robot_lib.tasks.abstract_task_type.AbstractReportType
:from typing import Any, Dict from ppc_robot_lib.platform import PlatformType from ppc_robot_lib.tasks.abstract_task_type import AbstractReportType class TypeNameV1(AbstractReportType): @classmethod def get_name(cls) -> str: return 'type_name' # Short type name. @classmethod def get_platform(cls) -> PlatformType: return PlatformType.ADWORDS # Return the correct platform constant. @classmethod def get_version(cls): return 1 # Return the version @classmethod def get_level(cls) -> TaskLevel: return TaskLevel.CLIENT_ACCOUNT @classmethod def get_description(cls) -> TaskDescription: # Gets the task description displayed in the interface. See the TaskDescription object for available fields. return TaskDescription( title='My First Task Type', short_description='Short task type description', description='<p>Longer description, HTML can be used.</p>', ) @classmethod def upgrade_from_previous(cls, parameters: Dict[str, Any]) -> Dict[str, Any]: # Should upgrade parameters if they changed in the new version. # Since this is the first version, we can safely return the input parameters. return parameters @classmethod def get_default_parameters(cls) -> Dict[str, Any]: return {} # Return default parameters.ยจ def execute(self, parameters: Dict[str, Any]): pass
Note
Pay extra attention to the get_level()
method. This method determines level of objects on which the task
operates. By returning TaskLevel.SERVICE_ACCOUNT
, you will instruct PPC Robot that the report is not created
for individual Client Account, but for a whole Service Account.
This means that the user will not be able to select individual account in the last step of record creation and Service Account Selection will have be done in the second step. This is used for Managed Accounts (MCC) overview reports, so make sure you check this method when copying code from other reports!
Implement the
execute()
method. This method is called when the report is run. You can use any of the Reporting Functions.Example:
from ppc_robot_lib.adwords import Query from ppc_robot_lib.output.types import Table from ppc_robot_lib.reporting.input import download_adwords_report from ppc_robot_lib.reporting.output import write_tables from ppc_robot_lib.utils.types import Column class TypeNameV1(AbstractReportType): # ... other methods ... def execute(self, parameters: Dict[str, Any]): # Download a report. query = Query( select=['AccountDescriptiveName', 'Clicks'], from_report='ACCOUNT_PERFORMANCE_REPORT' ) report = download_adwords_report(query) # Output the table. write_tables([ Table( report, sheet_name='Report', header=[ Column('Account Name', 'AccountDescriptiveName'), Column('Total Clicks', 'Clicks'), ] ) ])
Testing the job type: you can test the job type without the user interface or any additional dependencies (however, it is recommended to start the rate limiter before you start testing your job).
In the
dev_scripts/reports
folder, create a new JSON file, for exampletask_type.json
(the name is not significant). The contents of the file should look like this:{ "platform": "adwords", "taskType": "type_name", "taskTypeVersion": 1, "parameters": { } }
The parameters dictionary will be passed directly to your report type, so fill-in the values accordingly to your task type.
Run the following script (you can also create a new PyCharm configuration):
$ python dev_scripts/test_report.py -c ID dev_scripts/reports/task_type.json
Where ID is an ID of
ClientAccount
in the database that sould be used for the test. Look for rows in therobot_client_accounts
table.
You should have a working job type by now. The type will already be available in the interface for selection, but there is no interface for entering parameters for this type. You have to create a so-called parameter editor, which is a Vue.js component used to manage the parameters.
Create a new file in
ppc_robot_web/assets/js/TaskTypes/<Platform>/
named<TypeName>.vue
(please note the CamelCase naming convention used in JavaScript):<template> <div class="task-type-editor main-content"> <h2>{{ pgettext('title', 'Report Settings') }}</h2> <!-- Your UI template. --> </div> </template> <script> import Vue from "vue"; import Component from "vue-class-component"; import {ReportEditorStore} from "../../Stores/ReportEditorStore"; @Component({ props: { parameters: Object, store: ReportEditorStore, defaultParameters: Object, validation: Object, }, }) export default class UrlCheckerReport extends Vue { getValidations() { return { // Define your parameter validation here. // See https://monterail.github.io/vuelidate/ }; } } </script>
The component will receive 4 parameters:
parameters
: parameters object, this is the dictionary that is passed to create_steps.store
: instance ofReportEditorStore
which contains the parameters. If you set itsallowContinue
property tofalse
, user will not be able to save the parameters.defaultParameters
: default parameters for the given report type (as returned by theget_default_parameters()
method). Useful if your report consists of multiple tables that can be configured by user โ you can simply create a new table by coping the default one.validation
: validation result. See documentation for the Vuelidate library.
Additionally, the editor has one method:
getValidations()
. This method should return the validation schema that is used to validate the parameters โ see documentation for the Vuelidate library for more details. Additionally,AdWords/AdExtensionReport.vue
is a nice example of validation in action.- One last change to make! In
ppc_robot_web/assets/js/TaskTypes/editors.js
, add your component to the
EDITOR_MAP
(it is a nested object, so keep the structure):export const EDITOR_MAP = { // ... 'adwords': { 'type_name': d(require('./AdWords/TypeName.vue')), } };
- One last change to make! In