summaryrefslogtreecommitdiffstats
path: root/third_party/python/glean_parser/glean_parser/pings.py
blob: 3099fa1d16b87d437bc1a35ae88ecf0bc680062e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# -*- coding: utf-8 -*-

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

"""
Classes for managing the description of pings.
"""

from typing import Dict, List, Optional


from . import util


RESERVED_PING_NAMES = ["baseline", "metrics", "events", "deletion-request", "default"]


class Ping:
    def __init__(
        self,
        name: str,
        description: str,
        bugs: List[str],
        notification_emails: List[str],
        metadata: Optional[Dict] = None,
        data_reviews: Optional[List[str]] = None,
        include_client_id: bool = False,
        send_if_empty: bool = False,
        reasons: Optional[Dict[str, str]] = None,
        defined_in: Optional[Dict] = None,
        no_lint: Optional[List[str]] = None,
        _validated: bool = False,
    ):
        # Avoid cyclical import
        from . import parser

        self.name = name
        self.description = description

        self.bugs = bugs
        self.notification_emails = notification_emails
        if metadata is None:
            metadata = {}
        self.metadata = metadata
        self.precise_timestamps = self.metadata.get("precise_timestamps", True)
        if data_reviews is None:
            data_reviews = []
        self.data_reviews = data_reviews
        self.include_client_id = include_client_id
        self.send_if_empty = send_if_empty
        if reasons is None:
            reasons = {}
        self.reasons = reasons
        self.defined_in = defined_in
        if no_lint is None:
            no_lint = []
        self.no_lint = no_lint

        # _validated indicates whether this ping has already been jsonschema
        # validated (but not any of the Python-level validation).
        if not _validated:
            data: Dict[str, util.JSONType] = {
                "$schema": parser.PINGS_ID,
                self.name: self._serialize_input(),
            }
            for error in parser.validate(data):
                raise ValueError(error)

    _generate_enums = [("reason_codes", "ReasonCodes")]

    @property
    def type(self) -> str:
        return "ping"

    @property
    def reason_codes(self) -> List[str]:
        return sorted(list(self.reasons.keys()))

    def serialize(self) -> Dict[str, util.JSONType]:
        """
        Serialize the metric back to JSON object model.
        """
        d = self.__dict__.copy()
        del d["name"]
        return d

    def _serialize_input(self) -> Dict[str, util.JSONType]:
        d = self.serialize()
        modified_dict = util.remove_output_params(d, "defined_in")
        modified_dict = util.remove_output_params(modified_dict, "precise_timestamps")
        return modified_dict

    def identifier(self) -> str:
        """
        Used for the "generated from ..." comment in the output.
        """
        return self.name