15
15
16
16
LOGGER = singer .get_logger ()
17
17
18
- #def check_authorization(atx):
19
- # atx.client.get('/settings')
20
-
21
-
22
- # Some taps do discovery dynamically where the catalog is read in from a
23
- # call to the api but with the odd frontapp structure, we won't do that
24
- # here we never use atx in here since the schema is from file but we
25
- # would use it if we pulled schema from the API def discover(atx):
26
-
27
18
28
19
def discover ():
29
20
catalog = Catalog ([])
30
-
21
+
31
22
# Build initial catalog from schema files
32
23
for tap_stream_id in schemas .STATIC_SCHEMA_STREAM_IDS :
33
24
LOGGER .info ("tap stream id=%s" , tap_stream_id )
34
25
schema = Schema .from_dict (schemas .load_schema (tap_stream_id ))
35
26
metadata = []
36
-
37
- # Stream -level metadata select the stream
27
+
28
+ # Add discoverable stream -level metadata
38
29
metadata .append ({
39
30
"metadata" : {
40
- "selected" : True # Make sure to select every stream
31
+ "inclusion" : "available" ,
32
+ "selected-by-default" : True ,
33
+ "inclusion-reason" : "automatic"
41
34
},
42
35
"breadcrumb" : []
43
36
})
44
-
45
- # Field level metadata with inclusion type
37
+
38
+ # Add discoverable field- level metadata
46
39
for field_name in schema .properties .keys ():
47
- if field_name in schemas .PK_FIELDS [tap_stream_id ]:
48
- inclusion = 'automatic'
49
- else :
50
- inclusion = 'available'
40
+ inclusion = "automatic" if field_name in schemas .PK_FIELDS [tap_stream_id ] else "available"
51
41
metadata .append ({
52
42
"metadata" : {
53
- "inclusion" : inclusion
43
+ "inclusion" : inclusion ,
44
+ "selected-by-default" : True ,
45
+ "inclusion-reason" : "manual"
54
46
},
55
- "breadcrumb" : [' properties' , field_name ]
47
+ "breadcrumb" : [" properties" , field_name ]
56
48
})
57
-
49
+
58
50
catalog .streams .append (CatalogEntry (
59
51
stream = tap_stream_id ,
60
52
tap_stream_id = tap_stream_id ,
61
53
key_properties = schemas .PK_FIELDS [tap_stream_id ],
62
54
schema = schema ,
63
55
metadata = metadata
64
56
))
65
-
66
- # Creating a dict to change before converting
57
+
67
58
catalog_dict = catalog .to_dict ()
68
-
69
- required_streams = [
70
- "accounts_table" ,
71
- "channels_table" ,
72
- "inboxes_table" ,
73
- "tags_table" ,
74
- "teammates_table" ,
75
- "teams_table"
76
- ]
77
-
78
- # We verify this to ensure all mandatory streams are available even if schema files are missing
79
- present_streams = {stream ['tap_stream_id' ] for stream in catalog_dict ['streams' ]}
80
-
81
- # Ensure all required streams are included even if schema is missing
82
- for stream_name in required_streams :
83
- if stream_name not in present_streams :
59
+ present_streams = {stream ["tap_stream_id" ] for stream in catalog_dict ["streams" ]}
84
60
61
+ # Use METRIC_API_DESCRIPTION_KEY keys instead of hardcoded list
62
+ for stream_name in streams .METRIC_API_DESCRIPTION_KEY .keys ():
63
+ if stream_name not in present_streams :
85
64
LOGGER .info ("Adding missing required stream: %s" , stream_name )
86
-
87
- # Create a minimal stream entry that will be visible in the output
88
- catalog_dict ['streams' ].append ({
65
+ catalog_dict ["streams" ].append ({
89
66
"stream" : stream_name ,
90
67
"tap_stream_id" : stream_name ,
91
68
"schema" : {
92
- "type" : [' null' , ' object' ],
69
+ "type" : [" null" , " object" ],
93
70
"properties" : {},
94
71
"additionalProperties" : False
95
72
},
96
73
"key_properties" : [],
97
74
"metadata" : [
98
75
{
99
76
"metadata" : {
100
- "selected" : True
77
+ "inclusion" : "available" ,
78
+ "selected-by-default" : True ,
79
+ "inclusion-reason" : "automatic"
101
80
},
102
81
"breadcrumb" : []
103
82
}
104
83
]
105
84
})
106
-
107
- # This ensure singer tools recognize all streams in the catalog dictionary
108
- for stream in catalog_dict ['streams' ]:
109
- has_selection = False
110
- for metadata_item in stream .get ('metadata' , []):
111
- if metadata_item .get ('breadcrumb' ) == [] and metadata_item .get ('metadata' , {}).get ('selected' ) is True :
112
- has_selection = True
113
- break
114
-
115
- if not has_selection :
116
- LOGGER .info ("Adding selection metadata to stream: %s" , stream ['tap_stream_id' ])
117
- stream .setdefault ('metadata' , []).insert (0 , {
118
- "metadata" : {
119
- "selected" : True
120
- },
121
- "breadcrumb" : []
122
- })
123
-
124
- # Convert back to a Catalog object
125
- modified_catalog = Catalog .from_dict (catalog_dict )
126
85
127
-
128
- return modified_catalog
86
+ return Catalog .from_dict (catalog_dict )
129
87
130
88
131
89
def get_abs_path (path : str ):
132
- """Returns absolute path for URL ."""
90
+ """Returns absolute path for a given relative path ."""
133
91
return os .path .join (os .path .dirname (os .path .realpath (__file__ )), path )
134
92
135
93
136
- # this is already defined in schemas.py though w/o dependencies
137
94
def load_schema (tap_stream_id ):
138
- path = "schemas/{}.json" .format (tap_stream_id )
95
+ """Loads schema from JSON file, resolving dependencies."""
96
+ path = f"schemas/{ tap_stream_id } .json"
139
97
schema = utils .load_json (get_abs_path (path ))
140
98
dependencies = schema .pop ("tap_schema_dependencies" , [])
141
- refs = {}
142
- for sub_stream_id in dependencies :
143
- refs [sub_stream_id ] = load_schema (sub_stream_id )
99
+ refs = {sub_id : load_schema (sub_id ) for sub_id in dependencies }
144
100
if refs :
145
101
singer .resolve_schema_references (schema , refs )
146
102
return schema
@@ -149,7 +105,6 @@ def load_schema(tap_stream_id):
149
105
def sync (atx ):
150
106
for tap_stream_id in schemas .STATIC_SCHEMA_STREAM_IDS :
151
107
schemas .load_and_write_schema (tap_stream_id )
152
-
153
108
streams .sync_selected_streams (atx )
154
109
155
110
@@ -158,13 +113,12 @@ def main():
158
113
args = utils .parse_args (REQUIRED_CONFIG_KEYS )
159
114
atx = Context (args .config , args .state )
160
115
if args .discover :
161
- # the schema is static from file so we don't need to pass in atx for connection info.
162
116
catalog = discover ()
163
117
json .dump (catalog .to_dict (), sys .stdout )
164
118
else :
165
- atx .catalog = Catalog .from_dict (args .properties ) \
166
- if args .properties else discover ()
119
+ atx .catalog = Catalog .from_dict (args .properties ) if args .properties else discover ()
167
120
sync (atx )
168
121
122
+
169
123
if __name__ == "__main__" :
170
- main ()
124
+ main ()
0 commit comments