dbt-common 1.0.4__py3-none-any.whl → 1.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
dbt_common/__about__.py CHANGED
@@ -1 +1 @@
1
- version = "1.0.4"
1
+ version = "1.2.0"
@@ -0,0 +1,26 @@
1
+ from dataclasses import dataclass
2
+ from typing import Dict, Optional, Union
3
+
4
+ from dbt_common.dataclass_schema import dbtClassMixin
5
+
6
+
7
+ @dataclass
8
+ class StatsItem(dbtClassMixin):
9
+ id: str
10
+ label: str
11
+ value: Union[bool, str, float, None]
12
+ include: bool
13
+ description: Optional[str] = None
14
+
15
+
16
+ StatsDict = Dict[str, StatsItem]
17
+
18
+
19
+ @dataclass
20
+ class TableMetadata(dbtClassMixin):
21
+ type: str
22
+ schema: str
23
+ name: str
24
+ database: Optional[str] = None
25
+ comment: Optional[str] = None
26
+ owner: Optional[str] = None
@@ -6,14 +6,11 @@ import sys
6
6
  from google.protobuf.json_format import ParseDict, MessageToDict, MessageToJson
7
7
  from google.protobuf.message import Message
8
8
  from dbt_common.events.helpers import get_json_string_utcnow
9
- from typing import Optional
9
+ from typing import Callable, Optional
10
10
 
11
11
  from dbt_common.invocation import get_invocation_id
12
12
 
13
- if sys.version_info >= (3, 8):
14
- from typing import Protocol
15
- else:
16
- from typing_extensions import Protocol
13
+ from typing import Protocol
17
14
 
18
15
 
19
16
  # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
@@ -128,6 +125,9 @@ class EventMsg(Protocol):
128
125
  data: Message
129
126
 
130
127
 
128
+ TCallback = Callable[[EventMsg], None]
129
+
130
+
131
131
  def msg_from_base_event(event: BaseEvent, level: Optional[EventLevel] = None):
132
132
  msg_class_name = f"{type(event).__name__}Msg"
133
133
  msg_cls = getattr(event.PROTO_TYPES_MODULE, msg_class_name)
@@ -1,15 +1,15 @@
1
1
  import os
2
2
  import traceback
3
- from typing import Callable, List, Optional, Protocol, Tuple
3
+ from typing import List, Optional, Protocol, Tuple
4
4
 
5
- from dbt_common.events.base_types import BaseEvent, EventLevel, msg_from_base_event, EventMsg
5
+ from dbt_common.events.base_types import BaseEvent, EventLevel, msg_from_base_event, TCallback
6
6
  from dbt_common.events.logger import LoggerConfig, _Logger, _TextLogger, _JsonLogger, LineFormat
7
7
 
8
8
 
9
9
  class EventManager:
10
10
  def __init__(self) -> None:
11
11
  self.loggers: List[_Logger] = []
12
- self.callbacks: List[Callable[[EventMsg], None]] = []
12
+ self.callbacks: List[TCallback] = []
13
13
 
14
14
  def fire_event(self, e: BaseEvent, level: Optional[EventLevel] = None) -> None:
15
15
  msg = msg_from_base_event(e, level=level)
@@ -37,13 +37,16 @@ class EventManager:
37
37
  )
38
38
  self.loggers.append(logger)
39
39
 
40
+ def add_callback(self, callback: TCallback) -> None:
41
+ self.callbacks.append(callback)
42
+
40
43
  def flush(self) -> None:
41
44
  for logger in self.loggers:
42
45
  logger.flush()
43
46
 
44
47
 
45
48
  class IEventManager(Protocol):
46
- callbacks: List[Callable[[EventMsg], None]]
49
+ callbacks: List[TCallback]
47
50
  loggers: List[_Logger]
48
51
 
49
52
  def fire_event(self, e: BaseEvent, level: Optional[EventLevel] = None) -> None:
@@ -52,6 +55,9 @@ class IEventManager(Protocol):
52
55
  def add_logger(self, config: LoggerConfig) -> None:
53
56
  ...
54
57
 
58
+ def add_callback(self, callback: TCallback) -> None:
59
+ ...
60
+
55
61
 
56
62
  class TestEventManager(IEventManager):
57
63
  __test__ = False
@@ -1,6 +1,7 @@
1
1
  # Since dbt-rpc does not do its own log setup, and since some events can
2
2
  # currently fire before logs can be configured by setup_event_logger(), we
3
3
  # create a default configuration with default settings and no file output.
4
+ from dbt_common.events.base_types import TCallback
4
5
  from dbt_common.events.event_manager import IEventManager, EventManager
5
6
 
6
7
  _EVENT_MANAGER: IEventManager = EventManager()
@@ -16,6 +17,11 @@ def add_logger_to_manager(logger) -> None:
16
17
  _EVENT_MANAGER.add_logger(logger)
17
18
 
18
19
 
20
+ def add_callback_to_manager(callback: TCallback) -> None:
21
+ global _EVENT_MANAGER
22
+ _EVENT_MANAGER.add_callback(callback)
23
+
24
+
19
25
  def ctx_set_event_manager(event_manager: IEventManager) -> None:
20
26
  global _EVENT_MANAGER
21
27
  _EVENT_MANAGER = event_manager
@@ -13,6 +13,13 @@ from dbt_common.events.base_types import EventLevel, EventMsg
13
13
  from dbt_common.events.format import timestamp_to_datetime_string
14
14
  from dbt_common.utils.encoding import ForgivingJSONEncoder
15
15
 
16
+ PRINT_EVENT_NAME = "PrintEvent"
17
+
18
+
19
+ def _is_print_event(msg: EventMsg) -> bool:
20
+ return msg.info.name == PRINT_EVENT_NAME
21
+
22
+
16
23
  # A Filter is a function which takes a BaseEvent and returns True if the event
17
24
  # should be logged, False otherwise.
18
25
  Filter = Callable[[EventMsg], bool]
@@ -120,7 +127,14 @@ class _Logger:
120
127
  def write_line(self, msg: EventMsg):
121
128
  line = self.create_line(msg)
122
129
  if self._python_logger is not None:
123
- send_to_logger(self._python_logger, msg.info.level, line)
130
+ # We send PrintEvent to logger as error so it goes to stdout
131
+ # when --quiet flag is set.
132
+ # --quiet flag will filter out all events lower than ERROR.
133
+ if _is_print_event(msg):
134
+ level = "error"
135
+ else:
136
+ level = msg.info.level
137
+ send_to_logger(self._python_logger, level, line)
124
138
 
125
139
  def flush(self):
126
140
  if self._python_logger is not None:
@@ -138,8 +152,11 @@ class _TextLogger(_Logger):
138
152
  return self.create_debug_line(msg) if self.use_debug_format else self.create_info_line(msg)
139
153
 
140
154
  def create_info_line(self, msg: EventMsg) -> str:
141
- ts: str = datetime.utcnow().strftime("%H:%M:%S")
142
155
  scrubbed_msg: str = self.scrubber(msg.info.msg) # type: ignore
156
+ if _is_print_event(msg):
157
+ # PrintEvent is a special case, we don't want to add a timestamp
158
+ return scrubbed_msg
159
+ ts: str = datetime.utcnow().strftime("%H:%M:%S")
143
160
  return f"{self._get_color_tag()}{ts} {scrubbed_msg}"
144
161
 
145
162
  def create_debug_line(self, msg: EventMsg) -> str:
@@ -119,3 +119,13 @@ message NoteMsg {
119
119
  EventInfo info = 1;
120
120
  Note data = 2;
121
121
  }
122
+
123
+ // Z052
124
+ message PrintEvent {
125
+ string msg = 1;
126
+ }
127
+
128
+ message PrintEventMsg {
129
+ EventInfo info = 1;
130
+ PrintEvent data = 2;
131
+ }
@@ -125,3 +125,14 @@ class Note(InfoLevel):
125
125
 
126
126
  def message(self) -> str:
127
127
  return self.msg
128
+
129
+
130
+ class PrintEvent(InfoLevel):
131
+ # Use this event to skip any formatting and just print a message
132
+ # This event will get to stdout even if the logger is set to ERROR
133
+ # This is to support commands that want --quiet option but also log something to stdout
134
+ def code(self) -> str:
135
+ return "Z052"
136
+
137
+ def message(self) -> str:
138
+ return self.msg
@@ -1,11 +1,12 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # Generated by the protocol buffer compiler. DO NOT EDIT!
3
3
  # source: types.proto
4
+ # Protobuf Python Version: 5.26.1
4
5
  """Generated protocol buffer code."""
5
- from google.protobuf.internal import builder as _builder
6
6
  from google.protobuf import descriptor as _descriptor
7
7
  from google.protobuf import descriptor_pool as _descriptor_pool
8
8
  from google.protobuf import symbol_database as _symbol_database
9
+ from google.protobuf.internal import builder as _builder
9
10
  # @@protoc_insertion_point(imports)
10
11
 
11
12
  _sym_db = _symbol_database.Default()
@@ -14,55 +15,59 @@ _sym_db = _symbol_database.Default()
14
15
  from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2
15
16
 
16
17
 
17
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0btypes.proto\x12\x0bproto_types\x1a\x1fgoogle/protobuf/timestamp.proto\"\x91\x02\n\tEventInfo\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04\x63ode\x18\x02 \x01(\t\x12\x0b\n\x03msg\x18\x03 \x01(\t\x12\r\n\x05level\x18\x04 \x01(\t\x12\x15\n\rinvocation_id\x18\x05 \x01(\t\x12\x0b\n\x03pid\x18\x06 \x01(\x05\x12\x0e\n\x06thread\x18\x07 \x01(\t\x12&\n\x02ts\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x30\n\x05\x65xtra\x18\t \x03(\x0b\x32!.proto_types.EventInfo.ExtraEntry\x12\x10\n\x08\x63\x61tegory\x18\n \x01(\t\x1a,\n\nExtraEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"6\n\x0eGenericMessage\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\"1\n\x11RetryExternalCall\x12\x0f\n\x07\x61ttempt\x18\x01 \x01(\x05\x12\x0b\n\x03max\x18\x02 \x01(\x05\"j\n\x14RetryExternalCallMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12,\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32\x1e.proto_types.RetryExternalCall\"#\n\x14RecordRetryException\x12\x0b\n\x03\x65xc\x18\x01 \x01(\t\"p\n\x17RecordRetryExceptionMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12/\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32!.proto_types.RecordRetryException\"@\n\x13SystemCouldNotWrite\x12\x0c\n\x04path\x18\x01 \x01(\t\x12\x0e\n\x06reason\x18\x02 \x01(\t\x12\x0b\n\x03\x65xc\x18\x03 \x01(\t\"n\n\x16SystemCouldNotWriteMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12.\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32 .proto_types.SystemCouldNotWrite\"!\n\x12SystemExecutingCmd\x12\x0b\n\x03\x63md\x18\x01 \x03(\t\"l\n\x15SystemExecutingCmdMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12-\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32\x1f.proto_types.SystemExecutingCmd\"\x1c\n\x0cSystemStdOut\x12\x0c\n\x04\x62msg\x18\x01 \x01(\t\"`\n\x0fSystemStdOutMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12\'\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32\x19.proto_types.SystemStdOut\"\x1c\n\x0cSystemStdErr\x12\x0c\n\x04\x62msg\x18\x01 \x01(\t\"`\n\x0fSystemStdErrMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12\'\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32\x19.proto_types.SystemStdErr\",\n\x16SystemReportReturnCode\x12\x12\n\nreturncode\x18\x01 \x01(\x05\"t\n\x19SystemReportReturnCodeMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12\x31\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32#.proto_types.SystemReportReturnCode\"\x19\n\nFormatting\x12\x0b\n\x03msg\x18\x01 \x01(\t\"\\\n\rFormattingMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12%\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32\x17.proto_types.Formatting\"\x13\n\x04Note\x12\x0b\n\x03msg\x18\x01 \x01(\t\"P\n\x07NoteMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12\x1f\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32\x11.proto_types.Noteb\x06proto3')
18
-
19
- _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
20
- _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'types_pb2', globals())
21
- if _descriptor._USE_C_DESCRIPTORS == False:
18
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0btypes.proto\x12\x0bproto_types\x1a\x1fgoogle/protobuf/timestamp.proto\"\x91\x02\n\tEventInfo\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04\x63ode\x18\x02 \x01(\t\x12\x0b\n\x03msg\x18\x03 \x01(\t\x12\r\n\x05level\x18\x04 \x01(\t\x12\x15\n\rinvocation_id\x18\x05 \x01(\t\x12\x0b\n\x03pid\x18\x06 \x01(\x05\x12\x0e\n\x06thread\x18\x07 \x01(\t\x12&\n\x02ts\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x30\n\x05\x65xtra\x18\t \x03(\x0b\x32!.proto_types.EventInfo.ExtraEntry\x12\x10\n\x08\x63\x61tegory\x18\n \x01(\t\x1a,\n\nExtraEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"6\n\x0eGenericMessage\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\"1\n\x11RetryExternalCall\x12\x0f\n\x07\x61ttempt\x18\x01 \x01(\x05\x12\x0b\n\x03max\x18\x02 \x01(\x05\"j\n\x14RetryExternalCallMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12,\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32\x1e.proto_types.RetryExternalCall\"#\n\x14RecordRetryException\x12\x0b\n\x03\x65xc\x18\x01 \x01(\t\"p\n\x17RecordRetryExceptionMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12/\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32!.proto_types.RecordRetryException\"@\n\x13SystemCouldNotWrite\x12\x0c\n\x04path\x18\x01 \x01(\t\x12\x0e\n\x06reason\x18\x02 \x01(\t\x12\x0b\n\x03\x65xc\x18\x03 \x01(\t\"n\n\x16SystemCouldNotWriteMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12.\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32 .proto_types.SystemCouldNotWrite\"!\n\x12SystemExecutingCmd\x12\x0b\n\x03\x63md\x18\x01 \x03(\t\"l\n\x15SystemExecutingCmdMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12-\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32\x1f.proto_types.SystemExecutingCmd\"\x1c\n\x0cSystemStdOut\x12\x0c\n\x04\x62msg\x18\x01 \x01(\t\"`\n\x0fSystemStdOutMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12\'\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32\x19.proto_types.SystemStdOut\"\x1c\n\x0cSystemStdErr\x12\x0c\n\x04\x62msg\x18\x01 \x01(\t\"`\n\x0fSystemStdErrMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12\'\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32\x19.proto_types.SystemStdErr\",\n\x16SystemReportReturnCode\x12\x12\n\nreturncode\x18\x01 \x01(\x05\"t\n\x19SystemReportReturnCodeMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12\x31\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32#.proto_types.SystemReportReturnCode\"\x19\n\nFormatting\x12\x0b\n\x03msg\x18\x01 \x01(\t\"\\\n\rFormattingMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12%\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32\x17.proto_types.Formatting\"\x13\n\x04Note\x12\x0b\n\x03msg\x18\x01 \x01(\t\"P\n\x07NoteMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12\x1f\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32\x11.proto_types.Note\"\x19\n\nPrintEvent\x12\x0b\n\x03msg\x18\x01 \x01(\t\"\\\n\rPrintEventMsg\x12$\n\x04info\x18\x01 \x01(\x0b\x32\x16.proto_types.EventInfo\x12%\n\x04\x64\x61ta\x18\x02 \x01(\x0b\x32\x17.proto_types.PrintEventb\x06proto3')
22
19
 
23
- DESCRIPTOR._options = None
24
- _EVENTINFO_EXTRAENTRY._options = None
25
- _EVENTINFO_EXTRAENTRY._serialized_options = b'8\001'
26
- _EVENTINFO._serialized_start=62
27
- _EVENTINFO._serialized_end=335
28
- _EVENTINFO_EXTRAENTRY._serialized_start=291
29
- _EVENTINFO_EXTRAENTRY._serialized_end=335
30
- _GENERICMESSAGE._serialized_start=337
31
- _GENERICMESSAGE._serialized_end=391
32
- _RETRYEXTERNALCALL._serialized_start=393
33
- _RETRYEXTERNALCALL._serialized_end=442
34
- _RETRYEXTERNALCALLMSG._serialized_start=444
35
- _RETRYEXTERNALCALLMSG._serialized_end=550
36
- _RECORDRETRYEXCEPTION._serialized_start=552
37
- _RECORDRETRYEXCEPTION._serialized_end=587
38
- _RECORDRETRYEXCEPTIONMSG._serialized_start=589
39
- _RECORDRETRYEXCEPTIONMSG._serialized_end=701
40
- _SYSTEMCOULDNOTWRITE._serialized_start=703
41
- _SYSTEMCOULDNOTWRITE._serialized_end=767
42
- _SYSTEMCOULDNOTWRITEMSG._serialized_start=769
43
- _SYSTEMCOULDNOTWRITEMSG._serialized_end=879
44
- _SYSTEMEXECUTINGCMD._serialized_start=881
45
- _SYSTEMEXECUTINGCMD._serialized_end=914
46
- _SYSTEMEXECUTINGCMDMSG._serialized_start=916
47
- _SYSTEMEXECUTINGCMDMSG._serialized_end=1024
48
- _SYSTEMSTDOUT._serialized_start=1026
49
- _SYSTEMSTDOUT._serialized_end=1054
50
- _SYSTEMSTDOUTMSG._serialized_start=1056
51
- _SYSTEMSTDOUTMSG._serialized_end=1152
52
- _SYSTEMSTDERR._serialized_start=1154
53
- _SYSTEMSTDERR._serialized_end=1182
54
- _SYSTEMSTDERRMSG._serialized_start=1184
55
- _SYSTEMSTDERRMSG._serialized_end=1280
56
- _SYSTEMREPORTRETURNCODE._serialized_start=1282
57
- _SYSTEMREPORTRETURNCODE._serialized_end=1326
58
- _SYSTEMREPORTRETURNCODEMSG._serialized_start=1328
59
- _SYSTEMREPORTRETURNCODEMSG._serialized_end=1444
60
- _FORMATTING._serialized_start=1446
61
- _FORMATTING._serialized_end=1471
62
- _FORMATTINGMSG._serialized_start=1473
63
- _FORMATTINGMSG._serialized_end=1565
64
- _NOTE._serialized_start=1567
65
- _NOTE._serialized_end=1586
66
- _NOTEMSG._serialized_start=1588
67
- _NOTEMSG._serialized_end=1668
20
+ _globals = globals()
21
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
22
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'types_pb2', _globals)
23
+ if not _descriptor._USE_C_DESCRIPTORS:
24
+ DESCRIPTOR._loaded_options = None
25
+ _globals['_EVENTINFO_EXTRAENTRY']._loaded_options = None
26
+ _globals['_EVENTINFO_EXTRAENTRY']._serialized_options = b'8\001'
27
+ _globals['_EVENTINFO']._serialized_start=62
28
+ _globals['_EVENTINFO']._serialized_end=335
29
+ _globals['_EVENTINFO_EXTRAENTRY']._serialized_start=291
30
+ _globals['_EVENTINFO_EXTRAENTRY']._serialized_end=335
31
+ _globals['_GENERICMESSAGE']._serialized_start=337
32
+ _globals['_GENERICMESSAGE']._serialized_end=391
33
+ _globals['_RETRYEXTERNALCALL']._serialized_start=393
34
+ _globals['_RETRYEXTERNALCALL']._serialized_end=442
35
+ _globals['_RETRYEXTERNALCALLMSG']._serialized_start=444
36
+ _globals['_RETRYEXTERNALCALLMSG']._serialized_end=550
37
+ _globals['_RECORDRETRYEXCEPTION']._serialized_start=552
38
+ _globals['_RECORDRETRYEXCEPTION']._serialized_end=587
39
+ _globals['_RECORDRETRYEXCEPTIONMSG']._serialized_start=589
40
+ _globals['_RECORDRETRYEXCEPTIONMSG']._serialized_end=701
41
+ _globals['_SYSTEMCOULDNOTWRITE']._serialized_start=703
42
+ _globals['_SYSTEMCOULDNOTWRITE']._serialized_end=767
43
+ _globals['_SYSTEMCOULDNOTWRITEMSG']._serialized_start=769
44
+ _globals['_SYSTEMCOULDNOTWRITEMSG']._serialized_end=879
45
+ _globals['_SYSTEMEXECUTINGCMD']._serialized_start=881
46
+ _globals['_SYSTEMEXECUTINGCMD']._serialized_end=914
47
+ _globals['_SYSTEMEXECUTINGCMDMSG']._serialized_start=916
48
+ _globals['_SYSTEMEXECUTINGCMDMSG']._serialized_end=1024
49
+ _globals['_SYSTEMSTDOUT']._serialized_start=1026
50
+ _globals['_SYSTEMSTDOUT']._serialized_end=1054
51
+ _globals['_SYSTEMSTDOUTMSG']._serialized_start=1056
52
+ _globals['_SYSTEMSTDOUTMSG']._serialized_end=1152
53
+ _globals['_SYSTEMSTDERR']._serialized_start=1154
54
+ _globals['_SYSTEMSTDERR']._serialized_end=1182
55
+ _globals['_SYSTEMSTDERRMSG']._serialized_start=1184
56
+ _globals['_SYSTEMSTDERRMSG']._serialized_end=1280
57
+ _globals['_SYSTEMREPORTRETURNCODE']._serialized_start=1282
58
+ _globals['_SYSTEMREPORTRETURNCODE']._serialized_end=1326
59
+ _globals['_SYSTEMREPORTRETURNCODEMSG']._serialized_start=1328
60
+ _globals['_SYSTEMREPORTRETURNCODEMSG']._serialized_end=1444
61
+ _globals['_FORMATTING']._serialized_start=1446
62
+ _globals['_FORMATTING']._serialized_end=1471
63
+ _globals['_FORMATTINGMSG']._serialized_start=1473
64
+ _globals['_FORMATTINGMSG']._serialized_end=1565
65
+ _globals['_NOTE']._serialized_start=1567
66
+ _globals['_NOTE']._serialized_end=1586
67
+ _globals['_NOTEMSG']._serialized_start=1588
68
+ _globals['_NOTEMSG']._serialized_end=1668
69
+ _globals['_PRINTEVENT']._serialized_start=1670
70
+ _globals['_PRINTEVENT']._serialized_end=1695
71
+ _globals['_PRINTEVENTMSG']._serialized_start=1697
72
+ _globals['_PRINTEVENTMSG']._serialized_end=1789
68
73
  # @@protoc_insertion_point(module_scope)
dbt_common/record.py CHANGED
@@ -2,8 +2,8 @@
2
2
  external systems during a command invocation, so that the command can be re-run
3
3
  later with the recording 'replayed' to dbt.
4
4
 
5
- If dbt behaves sufficiently deterministically, we will be able to use the
6
- record/replay mechanism in several interesting test and debugging scenarios.
5
+ The rationale for and architecture of this module is described in detail in the
6
+ docs/guides/record_replay.md document in this repository.
7
7
  """
8
8
  import functools
9
9
  import dataclasses
@@ -59,14 +59,18 @@ class Diff:
59
59
  class RecorderMode(Enum):
60
60
  RECORD = 1
61
61
  REPLAY = 2
62
+ RECORD_QUERIES = 3
62
63
 
63
64
 
64
65
  class Recorder:
65
66
  _record_cls_by_name: Dict[str, Type] = {}
66
67
  _record_name_by_params_name: Dict[str, str] = {}
67
68
 
68
- def __init__(self, mode: RecorderMode, recording_path: Optional[str] = None) -> None:
69
+ def __init__(
70
+ self, mode: RecorderMode, types: Optional[List], recording_path: Optional[str] = None
71
+ ) -> None:
69
72
  self.mode = mode
73
+ self.types = types
70
74
  self._records_by_type: Dict[str, List[Record]] = {}
71
75
  self._replay_diffs: List["Diff"] = []
72
76
 
@@ -118,13 +122,14 @@ class Recorder:
118
122
  records_by_type: Dict[str, List[Record]] = {}
119
123
 
120
124
  for record_type_name in loaded_dct:
125
+ # TODO: this breaks with QueryRecord on replay since it's
126
+ # not in common so isn't part of cls._record_cls_by_name yet
121
127
  record_cls = cls._record_cls_by_name[record_type_name]
122
128
  rec_list = []
123
129
  for record_dct in loaded_dct[record_type_name]:
124
130
  rec = record_cls.from_dict(record_dct)
125
131
  rec_list.append(rec) # type: ignore
126
132
  records_by_type[record_type_name] = rec_list
127
-
128
133
  return records_by_type
129
134
 
130
135
  def expect_record(self, params: Any) -> Any:
@@ -147,17 +152,44 @@ class Recorder:
147
152
 
148
153
 
149
154
  def get_record_mode_from_env() -> Optional[RecorderMode]:
150
- replay_val = os.environ.get("DBT_REPLAY")
151
- if replay_val is not None and replay_val != "0" and replay_val.lower() != "false":
152
- return RecorderMode.REPLAY
155
+ """
156
+ Get the record mode from the environment variables.
157
+
158
+ If the mode is not set to 'RECORD' or 'REPLAY', return None.
159
+ Expected format: 'DBT_RECORDER_MODE=RECORD'
160
+ """
161
+ record_mode = os.environ.get("DBT_RECORDER_MODE")
153
162
 
154
- record_val = os.environ.get("DBT_RECORD")
155
- if record_val is not None and record_val != "0" and record_val.lower() != "false":
163
+ if record_mode is None:
164
+ return None
165
+
166
+ if record_mode.lower() == "record":
156
167
  return RecorderMode.RECORD
168
+ # replaying requires a file path, otherwise treat as noop
169
+ elif record_mode.lower() == "replay" and os.environ.get("DBT_RECORDER_FILE_PATH") is not None:
170
+ return RecorderMode.REPLAY
157
171
 
172
+ # if you don't specify record/replay it's a noop
158
173
  return None
159
174
 
160
175
 
176
+ def get_record_types_from_env() -> Optional[List]:
177
+ """
178
+ Get the record subset from the environment variables.
179
+
180
+ If no types are provided, there will be no filtering.
181
+ Invalid types will be ignored.
182
+ Expected format: 'DBT_RECORDER_TYPES=QueryRecord,FileLoadRecord,OtherRecord'
183
+ """
184
+ record_types_str = os.environ.get("DBT_RECORDER_TYPES")
185
+
186
+ # if all is specified we don't want any type filtering
187
+ if record_types_str is None or record_types_str.lower == "all":
188
+ return None
189
+
190
+ return record_types_str.split(",")
191
+
192
+
161
193
  def record_function(record_type, method=False, tuple_result=False):
162
194
  def record_function_inner(func_to_record):
163
195
  # To avoid runtime overhead and other unpleasantness, we only apply the
@@ -176,6 +208,9 @@ def record_function(record_type, method=False, tuple_result=False):
176
208
  if recorder is None:
177
209
  return func_to_record(*args, **kwargs)
178
210
 
211
+ if recorder.types is not None and record_type.__name__ not in recorder.types:
212
+ return func_to_record(*args, **kwargs)
213
+
179
214
  # For methods, peel off the 'self' argument before calling the
180
215
  # params constructor.
181
216
  param_args = args[1:] if method else args
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: dbt-common
3
- Version: 1.0.4
3
+ Version: 1.2.0
4
4
  Summary: The shared common utilities that dbt-core and adapter implementations use
5
5
  Project-URL: Homepage, https://github.com/dbt-labs/dbt-common
6
6
  Project-URL: Repository, https://github.com/dbt-labs/dbt-common.git
@@ -55,6 +55,7 @@ Requires-Dist: types-requests; extra == 'lint'
55
55
  Provides-Extra: test
56
56
  Requires-Dist: hypothesis<7.0,>=6.87; extra == 'test'
57
57
  Requires-Dist: pytest-cov<5.0,>=4.1; extra == 'test'
58
+ Requires-Dist: pytest-mock; extra == 'test'
58
59
  Requires-Dist: pytest-xdist<4.0,>=3.2; extra == 'test'
59
60
  Requires-Dist: pytest<8.0,>=7.3; extra == 'test'
60
61
  Description-Content-Type: text/markdown
@@ -1,4 +1,4 @@
1
- dbt_common/__about__.py,sha256=R604FHUDDjGzi5hem3DYdlBvcBVjznL7PmfCQFtRkDI,18
1
+ dbt_common/__about__.py,sha256=-XvoSdwL-0go8ZX6VN74e-D6dwG0z-0p7vL5MO0Sz5s,18
2
2
  dbt_common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  dbt_common/constants.py,sha256=-Y5DIL1SDPQWtlCNizXRYxFgbx1D7LaLs1ysamvGMRk,278
4
4
  dbt_common/context.py,sha256=BhgT7IgyvpZHEtIdFVVuBBBX5LuU7obXT7NvIPeuD2g,1760
@@ -6,7 +6,7 @@ dbt_common/dataclass_schema.py,sha256=t3HGD0oXTSjitctuCVHv3iyq5BT3jxoSxv_VGkrJlE
6
6
  dbt_common/helper_types.py,sha256=NoxqGFAq9bOjh7rqtz_eepXAxk20n3mmW_gUVpnMyYU,3901
7
7
  dbt_common/invocation.py,sha256=Zw8jRPn75oi2VrUD6qGvaCDtSyIfqm5pJlPpRjs3s1E,202
8
8
  dbt_common/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
- dbt_common/record.py,sha256=bQ_1fC5qp_RlQxLXq_wHYl5G37BvkzE0d_F2F39PDUA,7015
9
+ dbt_common/record.py,sha256=fwp8Q2x0UiB9fHbMFkmOlAgKLst1dhDxQpSSsd04aDw,8204
10
10
  dbt_common/semver.py,sha256=2zoZYCQ7PfswqslT2NHuMGgPGMuMuX-yRThVoqfDWQU,13954
11
11
  dbt_common/tests.py,sha256=6lC_JuRtoYO6cbAF8-R5aTM4HtQiM_EH8X5m_97duGY,315
12
12
  dbt_common/ui.py,sha256=rc2TEM29raBFc_LXcg901pMDD07C2ohwp9qzkE-7pBY,2567
@@ -17,6 +17,7 @@ dbt_common/clients/jinja.py,sha256=i6VQ94FU4F6ZCQLHTxNSeGHmvyYSIe34nDhNkH6wO08,1
17
17
  dbt_common/clients/system.py,sha256=OOhRDWR5t0Ns3OhkqjPTNTtyl_RMRWPDHWCzDoFtgkA,23014
18
18
  dbt_common/contracts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
19
  dbt_common/contracts/constraints.py,sha256=hyqTW2oPB1dfXWW388LWnL-EFdqTpQciKISH3CeLkro,1267
20
+ dbt_common/contracts/metadata.py,sha256=d5zKvIR3s2j6_ZvafvlyNm5z6MVs8augT2jclbOSG-k,528
20
21
  dbt_common/contracts/util.py,sha256=RZpeEExSKdyFwTq7MM3rd1ZkAf11C7I-bgppUJ6SXOg,741
21
22
  dbt_common/contracts/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
23
  dbt_common/contracts/config/base.py,sha256=jWLf6SBUy7wngYs0Z5Zmx1O1v86XRueYaABlZ0W2Bxc,8356
@@ -25,19 +26,19 @@ dbt_common/contracts/config/metadata.py,sha256=X47-tEA8q2ZfSMcYv0godUwTSVjt8NI77
25
26
  dbt_common/contracts/config/properties.py,sha256=gWt6xsP4rVOqRKhmagiUhWnDynzD9mykfMYMTviwpEU,2281
26
27
  dbt_common/events/README.md,sha256=CSwVajoxCAqOug2UCnXldH1EUK7Kjf3rcq7z9ACjrss,3023
27
28
  dbt_common/events/__init__.py,sha256=av08vfpxo0ek7PqZNtMxY8FODJ3xwph4ehRxgInx4LA,383
28
- dbt_common/events/base_types.py,sha256=E--Fl-KMdJd_UZCN93AuLxnJcQoys2MJjiJxkV03HpM,5448
29
+ dbt_common/events/base_types.py,sha256=1l4Yx8zuma7jABB1fcPvL20ltpQ46w0mlYxn48kHykY,5415
29
30
  dbt_common/events/contextvars.py,sha256=Jx2J_Nkx0DH8EE1Sno_mbv7PMLBfCzm7byeFlUeflLA,3079
30
31
  dbt_common/events/event_handler.py,sha256=jfi0PyqIOGnXCG9HEa0VIVULqNvXs1RYmAg0b50ChQs,1385
31
- dbt_common/events/event_manager.py,sha256=ZXJ-N4NsfQTnkEpvuedTjHD8Gt8DgYHbz601eTVCm-o,2175
32
- dbt_common/events/event_manager_client.py,sha256=etDlUv-3iIwM5IXXuzc1cmQID2fHOXw8dE9snp39-jk,1014
32
+ dbt_common/events/event_manager.py,sha256=IIUwSyt_RcBbUI_iE5mnpmZt2uW7lG49RXOWz2VlUv0,2300
33
+ dbt_common/events/event_manager_client.py,sha256=VKlIYJPcexmDKnidkyrs8BIuNZ1_CwDFGz-gBM2SAvo,1193
33
34
  dbt_common/events/format.py,sha256=x1RWDZ8G7ZMHmxdld6Q4VXca4kvnhiQOIaQXkC6Uo0Q,1609
34
35
  dbt_common/events/functions.py,sha256=K-R-FBTeO03U51gtMBu1EUcNsIAsgw_e5spWxLJ44VE,4762
35
36
  dbt_common/events/helpers.py,sha256=CfsWwNDjsLJkPIgOtAfuLEnZ3rGUKeYsH8aDtCW12OA,410
36
37
  dbt_common/events/interfaces.py,sha256=hEDeDoB0FW2RYHVZBG7gebEt_mUVBzkn1yPubpaxs-s,147
37
- dbt_common/events/logger.py,sha256=6LLH8aLoRziFLBmwu-TCR5-EMpBtD28pSaL0FmKpeGA,6159
38
- dbt_common/events/types.proto,sha256=SujcfPOPAfyHzeRXkn9_uKEDeQ-andSW1pI6fpWpQdo,1885
39
- dbt_common/events/types.py,sha256=Bq-EvKQ8IPcRLwf_ukjfqjpYvakOcg4RzOL2zbPttbM,3538
40
- dbt_common/events/types_pb2.py,sha256=5DHt8X_ejqOuRiP-GrnVw8wDFUOTfBRlZQ2In1L1LOw,5569
38
+ dbt_common/events/logger.py,sha256=mAUNLZlIIOl3T2u7KOe8FF_deTNNe1CRJqmkPw4YH1U,6728
39
+ dbt_common/events/types.proto,sha256=nsOE3XFYBPovT9Th8WMkDWxBXa-adqiL23zCYfOdVk0,2013
40
+ dbt_common/events/types.py,sha256=quE22Kp78J51_8f1Si_K-xg0gA2Sg-fw9XDjNrcy81M,3905
41
+ dbt_common/events/types_pb2.py,sha256=Gn3exMla0FjoA-5OQTjOeKCT_DLxzvcA3YHPfbFjAck,6563
41
42
  dbt_common/exceptions/__init__.py,sha256=X_Uw7BxOzXev_9JMYfs5Cm-_i_Qf2PJim8_-dDJI7Y8,361
42
43
  dbt_common/exceptions/base.py,sha256=uuI_2y_BQrjCyjHKR2pWeCica1dyoo1cc4e1Tq0de7M,7583
43
44
  dbt_common/exceptions/cache.py,sha256=0z4fBcdNZMAR41YbPRo2GN0__xAMaYs8Uc-t3hjmVio,2532
@@ -55,7 +56,7 @@ dbt_common/utils/encoding.py,sha256=6_kSY2FvGNYMg7oX7PrbvVioieydih3Kl7Ii802LaHI,
55
56
  dbt_common/utils/executor.py,sha256=Zyzd1wML3aN-iYn9ZG2Gc_jj5vknmvQNyH-c0RaPIpo,2446
56
57
  dbt_common/utils/formatting.py,sha256=JUn5rzJ-uajs9wPCN0-f2iRFY1pOJF5YjTD9dERuLoc,165
57
58
  dbt_common/utils/jinja.py,sha256=XNfZHuZhLM_R_yPmzYojPm6bF7QOoxIjSWrkJRw6wks,965
58
- dbt_common-1.0.4.dist-info/METADATA,sha256=HgrDiDH28wvDXD8aJGX_XRNAlBQvnHySqjOBNxy_ALw,5220
59
- dbt_common-1.0.4.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
60
- dbt_common-1.0.4.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
61
- dbt_common-1.0.4.dist-info/RECORD,,
59
+ dbt_common-1.2.0.dist-info/METADATA,sha256=7rA7to-AQn0UQvVJVAy14wx7uhcyB8D_1wHmTTtEHDo,5264
60
+ dbt_common-1.2.0.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
61
+ dbt_common-1.2.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
62
+ dbt_common-1.2.0.dist-info/RECORD,,