hotglue-singer-sdk 1.0.2__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.
Files changed (53) hide show
  1. hotglue_singer_sdk/__init__.py +34 -0
  2. hotglue_singer_sdk/authenticators.py +554 -0
  3. hotglue_singer_sdk/cli/__init__.py +1 -0
  4. hotglue_singer_sdk/cli/common_options.py +37 -0
  5. hotglue_singer_sdk/configuration/__init__.py +1 -0
  6. hotglue_singer_sdk/configuration/_dict_config.py +101 -0
  7. hotglue_singer_sdk/exceptions.py +52 -0
  8. hotglue_singer_sdk/helpers/__init__.py +1 -0
  9. hotglue_singer_sdk/helpers/_catalog.py +122 -0
  10. hotglue_singer_sdk/helpers/_classproperty.py +18 -0
  11. hotglue_singer_sdk/helpers/_compat.py +15 -0
  12. hotglue_singer_sdk/helpers/_flattening.py +374 -0
  13. hotglue_singer_sdk/helpers/_schema.py +100 -0
  14. hotglue_singer_sdk/helpers/_secrets.py +41 -0
  15. hotglue_singer_sdk/helpers/_simpleeval.py +678 -0
  16. hotglue_singer_sdk/helpers/_singer.py +280 -0
  17. hotglue_singer_sdk/helpers/_state.py +282 -0
  18. hotglue_singer_sdk/helpers/_typing.py +231 -0
  19. hotglue_singer_sdk/helpers/_util.py +27 -0
  20. hotglue_singer_sdk/helpers/capabilities.py +240 -0
  21. hotglue_singer_sdk/helpers/jsonpath.py +39 -0
  22. hotglue_singer_sdk/io_base.py +134 -0
  23. hotglue_singer_sdk/mapper.py +691 -0
  24. hotglue_singer_sdk/mapper_base.py +156 -0
  25. hotglue_singer_sdk/plugin_base.py +415 -0
  26. hotglue_singer_sdk/py.typed +0 -0
  27. hotglue_singer_sdk/sinks/__init__.py +14 -0
  28. hotglue_singer_sdk/sinks/batch.py +90 -0
  29. hotglue_singer_sdk/sinks/core.py +412 -0
  30. hotglue_singer_sdk/sinks/record.py +66 -0
  31. hotglue_singer_sdk/sinks/sql.py +299 -0
  32. hotglue_singer_sdk/streams/__init__.py +14 -0
  33. hotglue_singer_sdk/streams/core.py +1294 -0
  34. hotglue_singer_sdk/streams/graphql.py +74 -0
  35. hotglue_singer_sdk/streams/rest.py +611 -0
  36. hotglue_singer_sdk/streams/sql.py +1023 -0
  37. hotglue_singer_sdk/tap_base.py +580 -0
  38. hotglue_singer_sdk/target_base.py +554 -0
  39. hotglue_singer_sdk/target_sdk/__init__.py +0 -0
  40. hotglue_singer_sdk/target_sdk/auth.py +124 -0
  41. hotglue_singer_sdk/target_sdk/client.py +286 -0
  42. hotglue_singer_sdk/target_sdk/common.py +13 -0
  43. hotglue_singer_sdk/target_sdk/lambda.py +121 -0
  44. hotglue_singer_sdk/target_sdk/rest.py +108 -0
  45. hotglue_singer_sdk/target_sdk/sinks.py +16 -0
  46. hotglue_singer_sdk/target_sdk/target.py +570 -0
  47. hotglue_singer_sdk/target_sdk/target_base.py +627 -0
  48. hotglue_singer_sdk/testing.py +198 -0
  49. hotglue_singer_sdk/typing.py +603 -0
  50. hotglue_singer_sdk-1.0.2.dist-info/METADATA +53 -0
  51. hotglue_singer_sdk-1.0.2.dist-info/RECORD +53 -0
  52. hotglue_singer_sdk-1.0.2.dist-info/WHEEL +4 -0
  53. hotglue_singer_sdk-1.0.2.dist-info/licenses/LICENSE +201 -0
@@ -0,0 +1,198 @@
1
+ """Pre-built test functions which can be applied to multiple taps."""
2
+
3
+ import io
4
+ from contextlib import redirect_stderr, redirect_stdout
5
+ from typing import Callable, List, Optional, Tuple, Type, cast
6
+
7
+ from hotglue_singer_sdk.helpers import _singer
8
+ from hotglue_singer_sdk.mapper_base import InlineMapper
9
+ from hotglue_singer_sdk.tap_base import Tap
10
+ from hotglue_singer_sdk.target_base import Target
11
+
12
+
13
+ def get_standard_tap_tests(tap_class: Type[Tap], config: dict = None) -> List[Callable]:
14
+ """Return callable pytest which executes simple discovery and connection tests.
15
+
16
+ Args:
17
+ tap_class: TODO
18
+ config: TODO
19
+
20
+ Returns:
21
+ TODO
22
+ """
23
+
24
+ def _test_cli_prints() -> None:
25
+ # Initialize with basic config
26
+ tap1: Tap = tap_class(config=config, parse_env_config=True)
27
+ # Test CLI prints
28
+ tap1.print_version()
29
+ tap1.print_about()
30
+ tap1.print_about(format="json")
31
+
32
+ def _test_discovery() -> None:
33
+ catalog1 = _get_tap_catalog(tap_class, config or {})
34
+ # Reset and re-initialize with an input catalog
35
+ tap2: Tap = tap_class(config=config, parse_env_config=True, catalog=catalog1)
36
+ assert tap2
37
+
38
+ def _test_stream_connections() -> None:
39
+ # Initialize with basic config
40
+ tap1: Tap = tap_class(config=config, parse_env_config=True)
41
+ tap1.run_connection_test()
42
+
43
+ return [_test_cli_prints, _test_discovery, _test_stream_connections]
44
+
45
+
46
+ def get_standard_target_tests(
47
+ target_class: Type[Target],
48
+ config: dict = None,
49
+ ) -> List[Callable]:
50
+ """Return callable pytest which executes simple discovery and connection tests.
51
+
52
+ Args:
53
+ target_class: The target class to test.
54
+ config: A config dictionary for the tests.
55
+
56
+ Returns:
57
+ A list of callable tests.
58
+ """
59
+ return []
60
+
61
+
62
+ def tap_sync_test(tap: Tap) -> Tuple[io.StringIO, io.StringIO]:
63
+ """Invokes a Tap object and return STDOUT and STDERR results in StringIO buffers.
64
+
65
+ Args:
66
+ tap: Any Tap object.
67
+
68
+ Returns:
69
+ A 2-item tuple with StringIO buffers from the Tap's output: (stdout, stderr)
70
+ """
71
+ stdout_buf = io.StringIO()
72
+ stderr_buf = io.StringIO()
73
+ with redirect_stdout(stdout_buf), redirect_stderr(stderr_buf):
74
+ tap.sync_all()
75
+ stdout_buf.seek(0)
76
+ stderr_buf.seek(0)
77
+ return stdout_buf, stderr_buf
78
+
79
+
80
+ def _get_tap_catalog(
81
+ tap_class: Type[Tap], config: dict, select_all: bool = False
82
+ ) -> dict:
83
+ """Return a catalog dict by running discovery.
84
+
85
+ Args:
86
+ tap_class: the tap class to create.
87
+ config: the config dict.
88
+ select_all: True to automatically select all streams in the catalog.
89
+
90
+ Returns:
91
+ Catalog dict created by discovery.
92
+ """
93
+ # Initialize with basic config
94
+ tap: Tap = tap_class(config=config, parse_env_config=True)
95
+ # Test discovery
96
+ tap.run_discovery()
97
+ catalog_dict = tap.catalog_dict
98
+ if select_all:
99
+ return _select_all(catalog_dict)
100
+
101
+ return catalog_dict
102
+
103
+
104
+ def _select_all(catalog_dict: dict) -> dict:
105
+ """Return the catalog dict with all streams selected.
106
+
107
+ Args:
108
+ catalog_dict (dict): [description]
109
+
110
+ Returns:
111
+ dict: [description]
112
+ """
113
+ catalog = _singer.Catalog.from_dict(catalog_dict)
114
+ for catalog_entry in catalog.streams:
115
+ catalog_entry.metadata.root.selected = True
116
+
117
+ return cast(dict, catalog.to_dict())
118
+
119
+
120
+ def target_sync_test(
121
+ target: Target, input: Optional[io.StringIO], finalize: bool = True
122
+ ) -> Tuple[io.StringIO, io.StringIO]:
123
+ """Invoke the target with the provided input.
124
+
125
+ Args:
126
+ target: Any Target object.
127
+ input: The input to process as if from STDIN.
128
+ finalize: True to process as the end of stream as a completion signal; False to
129
+ keep the sink operation open for further records.
130
+
131
+ Returns:
132
+ A 2-item tuple with StringIO buffers from the Target's output: (stdout, stderr)
133
+ """
134
+ stdout_buf = io.StringIO()
135
+ stderr_buf = io.StringIO()
136
+
137
+ with redirect_stdout(stdout_buf), redirect_stderr(stderr_buf):
138
+ if input is not None:
139
+ target._process_lines(input)
140
+ if finalize:
141
+ target._process_endofpipe()
142
+
143
+ stdout_buf.seek(0)
144
+ stderr_buf.seek(0)
145
+ return stdout_buf, stderr_buf
146
+
147
+
148
+ def tap_to_target_sync_test(
149
+ tap: Tap, target: Target
150
+ ) -> Tuple[io.StringIO, io.StringIO, io.StringIO, io.StringIO]:
151
+ """Test and end-to-end sink from the tap to the target.
152
+
153
+ Note: This method buffers all output from the tap in memory and should not be
154
+ used with larger datasets. Also note that the target will physically write out the
155
+ data. Cleanup afterwards should be handled by the caller, if necessary.
156
+
157
+ Args:
158
+ tap: Any Tap object.
159
+ target: Any Target object.
160
+
161
+ Returns:
162
+ A 4-item tuple with the StringIO buffers:
163
+ (tap_stdout, tap_stderr, target_stdout, target_stderr)
164
+ """
165
+ tap_stdout, tap_stderr = tap_sync_test(tap)
166
+ target_stdout, target_stderr = target_sync_test(target, tap_stdout, finalize=True)
167
+
168
+ # Reset the tap's stdout buffer before returning
169
+ tap_stdout.seek(0)
170
+
171
+ return tap_stdout, tap_stderr, target_stdout, target_stderr
172
+
173
+
174
+ def sync_end_to_end(tap: Tap, target: Target, *mappers: InlineMapper) -> None:
175
+ """Test and end-to-end sink from the tap to the target.
176
+
177
+ Args:
178
+ tap: Singer tap.
179
+ target: Singer target.
180
+ mappers: Zero or more inline mapper to apply in between the tap and target, in
181
+ order.
182
+ """
183
+ buf = io.StringIO()
184
+ with redirect_stdout(buf):
185
+ tap.sync_all()
186
+
187
+ buf.seek(0)
188
+ mapper_output = buf
189
+
190
+ for mapper in mappers:
191
+ buf = io.StringIO()
192
+ with redirect_stdout(buf):
193
+ mapper.listen(mapper_output)
194
+
195
+ buf.seek(0)
196
+ mapper_output = buf
197
+
198
+ target.listen(mapper_output)