pycarlo 0.10.185__py3-none-any.whl → 0.12.4__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.

Potentially problematic release.


This version of pycarlo might be problematic. Click here for more details.

pycarlo/lib/types.py ADDED
@@ -0,0 +1,68 @@
1
+ """
2
+ Custom GraphQL types for the Monte Carlo Python Schema Library.
3
+
4
+ This module provides custom implementations of/replacements for sgqlc types that are used
5
+ in the auto-generated schema.
6
+ """
7
+
8
+ import logging
9
+ from typing import Any, Optional, Union
10
+
11
+ import sgqlc.types
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ class Enum(sgqlc.types.Enum):
17
+ """
18
+ A backward-compatible GraphQL enum type that gracefully handles unknown values.
19
+
20
+ Problem:
21
+ When new enum values are added to the Monte Carlo GraphQL API, older SDK versions
22
+ that don't have these values in their generated schema will crash with a ValueError
23
+ when trying to deserialize API responses containing the new values.
24
+
25
+ Solution:
26
+ This custom Enum class returns unknown enum values as plain strings instead of
27
+ raising an error. Since sgqlc enums are already represented as strings internally,
28
+ this maintains full compatibility with existing code while preventing crashes.
29
+
30
+ Behavior:
31
+ - Known enum values: Returned as strings (same as sgqlc.types.Enum)
32
+ - Unknown enum values: Returned as strings with a warning logged
33
+ - All comparisons, collections, and operations work identically
34
+
35
+ Example:
36
+ # Previous Values for EntitlementTypes = ['SSO', 'MULTI_WORKSPACE']
37
+ # API is updated to return new value: ['SSO', 'NEW_FEATURE', 'MULTI_WORKSPACE']
38
+
39
+ # With standard sgqlc.types.Enum:
40
+ # ValueError: EntitlementTypes does not accept value NEW_FEATURE
41
+
42
+ # With this Enum:
43
+ # Will return the new value as str and log a warning, no exception raised
44
+
45
+ # Code still works:
46
+ if 'SSO' in entitlements: # Works
47
+ enable_sso()
48
+ if 'NEW_FEATURE' in entitlements: # Also works
49
+ enable_new_feature()
50
+ """
51
+
52
+ def __new__(
53
+ cls, json_data: Any, _: Optional[Any] = None
54
+ ) -> Union[str, sgqlc.types.Variable, None]:
55
+ try:
56
+ return sgqlc.types.get_variable_or_none(json_data)
57
+ except ValueError:
58
+ pass
59
+
60
+ if json_data not in cls:
61
+ # Log warning but don't crash - return the unknown value as a string
62
+ logger.warning(
63
+ f"Unknown enum value '{json_data}' for {cls.__name__}. "
64
+ f"This may indicate the SDK is out of date. Returning raw string value."
65
+ )
66
+ return str(json_data)
67
+
68
+ return str(json_data)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pycarlo
3
- Version: 0.10.185
3
+ Version: 0.12.4
4
4
  Summary: Monte Carlo's Python SDK
5
5
  Home-page: https://www.montecarlodata.com/
6
6
  Author: Monte Carlo Data, Inc
@@ -19,15 +19,13 @@ Classifier: Programming Language :: Python :: 3.12
19
19
  Requires-Python: >=3.8
20
20
  Description-Content-Type: text/markdown
21
21
  License-File: LICENSE
22
- Requires-Dist: dataclasses-json <6.0.0,>=0.5.7
23
- Requires-Dist: python-box >=5.0.0
24
- Requires-Dist: requests <3.0.0,>=2.0.0
25
- Requires-Dist: responses >=0.20.0
26
- Requires-Dist: sgqlc <17.0,>=14.1
22
+ Requires-Dist: dataclasses-json<6.0.0,>=0.5.7
23
+ Requires-Dist: python-box>=5.0.0
24
+ Requires-Dist: requests<3.0.0,>=2.0.0
25
+ Requires-Dist: responses>=0.20.0
26
+ Requires-Dist: sgqlc<17.0,>=14.1
27
27
 
28
- # Pycarlo
29
-
30
- Monte Carlo's Alpha Python SDK!
28
+ # Pycarlo - Monte Carlo's Python SDK
31
29
 
32
30
  ## Installation
33
31
 
@@ -40,23 +38,22 @@ virtualenv venv
40
38
  pip install -U pycarlo
41
39
  ```
42
40
 
43
- Developers of the SDK can use:
44
-
45
- ```shell
46
- make install-with-tests
47
- . venv/bin/activate
48
- pre-commit install
49
- ```
50
-
51
41
  ## Overview
52
42
 
53
43
  Pycarlo comprises two components: `core` and `features`.
54
44
 
55
- All Monte Carlo API queries and mutations that you could execute via the API are supported via the `core` library. Operations can be executed as first class objects, using [sgqlc](https://github.com/profusion/sgqlc), or as raw GQL with variables. In both cases, a consistent object where fields can be referenced by dot notation and the more pythonic snake_case is returned for ease of use.
45
+ All Monte Carlo API queries and mutations that you could execute via the API are supported via the
46
+ `core` library. Operations can be executed as first class objects, using
47
+ [sgqlc](https://github.com/profusion/sgqlc), or as raw GQL with variables. In both cases, a
48
+ consistent object where fields can be referenced by dot notation and the more pythonic snake_case is
49
+ returned for ease of use.
56
50
 
57
- The `features` library provides additional convenience for performing common operations like with dbt, circuit breaking, and pii filtering.
51
+ The `features` library provides additional convenience for performing common operations like with
52
+ dbt, circuit breaking, and pii filtering.
58
53
 
59
- Note that an API Key is required to use the SDK. See [here](https://docs.getmontecarlo.com/docs/developer-resources#creating-an-api-key) for details on how to generate one.
54
+ Note that an API Key is required to use the SDK. See
55
+ [our docs on generating API keys](https://docs.getmontecarlo.com/docs/developer-resources#creating-an-api-key)
56
+ for details.
60
57
 
61
58
  ## Basic usage
62
59
 
@@ -144,13 +141,20 @@ print(client(mutation))
144
141
  # ]
145
142
  ```
146
143
 
147
- Note that you can find Monte Carlo's API reference [here](https://apidocs.getmontecarlo.com/).
144
+ ### Examples
145
+
146
+ We have [a few examples here you can reference](./examples).
148
147
 
149
- For details and additional examples on how to map (convert) GraphQL queries to `sgqlc` operations please refer to the docs [here](https://sgqlc.readthedocs.io/en/latest/sgqlc.operation.html).
148
+ See [Monte Carlo's API reference](https://apidocs.getmontecarlo.com/) for all supported queries and
149
+ mutations.
150
+
151
+ For details and additional examples on how to map (convert) GraphQL queries to `sgqlc` operations
152
+ please refer to [the sgqlc docs](https://sgqlc.readthedocs.io/en/latest/sgqlc.operation.html).
150
153
 
151
154
  ### Features
152
155
 
153
- You can use [pydoc](https://docs.python.org/3.8/library/pydoc.html) to retrieve documentation on any feature packages (`pydoc pycarlo.features`).
156
+ You can use [pydoc](https://docs.python.org/library/pydoc.html) to retrieve documentation on any
157
+ feature packages (`pydoc pycarlo.features`).
154
158
 
155
159
  For instance for [circuit breakers](https://docs.getmontecarlo.com/docs/circuit-breakers):
156
160
 
@@ -160,9 +164,13 @@ pydoc pycarlo.features.circuit_breakers.service
160
164
 
161
165
  ## Session configuration
162
166
 
163
- By default, when creating a client the `default` profile from `~/.mcd/profiles.ini` is used. This file created via [montecarlo configure](https://docs.getmontecarlo.com/docs/using-the-cli#setting-up-the-cli) on the CLI. Note that you can find Monte Carlo's CLI reference [here](https://clidocs.getmontecarlo.com/).
167
+ By default, when creating a client the `default` profile from `~/.mcd/profiles.ini` is used. This
168
+ file created via
169
+ [montecarlo configure](https://docs.getmontecarlo.com/docs/using-the-cli#setting-up-the-cli) on the
170
+ CLI. See [Monte Carlo's CLI reference](https://clidocs.getmontecarlo.com/) for more details.
164
171
 
165
- You can override this usage by creating a custom `Session`. For instance, if you want to pass the ID and Token:
172
+ You can override this usage by creating a custom `Session`. For instance, if you want to pass the ID
173
+ and Token:
166
174
 
167
175
  ```python
168
176
  from pycarlo.core import Client, Session
@@ -174,7 +182,8 @@ Sessions support the following params:
174
182
 
175
183
  - `mcd_id`: API Key ID.
176
184
  - `mcd_token`: API secret.
177
- - `mcd_profile`: Named profile containing credentials. This is created via the CLI (e.g. `montecarlo configure --profile-name zeus`).
185
+ - `mcd_profile`: Named profile containing credentials. This is created via the CLI (e.g.
186
+ `montecarlo configure --profile-name zeus`).
178
187
  - `mcd_config_path`: Path to file containing credentials. Defaults to `~/.mcd/`.
179
188
 
180
189
  You can also specify the API Key, secret or profile name using the following environment variables:
@@ -183,7 +192,8 @@ You can also specify the API Key, secret or profile name using the following env
183
192
  - `MCD_DEFAULT_API_TOKEN`
184
193
  - `MCD_DEFAULT_PROFILE`
185
194
 
186
- When creating a session any explicitly passed `mcd_id` and `mcd_token` params take precedence, followed by environmental variables and then any config-file options.
195
+ When creating a session any explicitly passed `mcd_id` and `mcd_token` params take precedence,
196
+ followed by environmental variables and then any config-file options.
187
197
 
188
198
  Environment variables can be mixed with passed credentials, but not the config-file profile.
189
199
 
@@ -191,9 +201,11 @@ Environment variables can be mixed with passed credentials, but not the config-f
191
201
 
192
202
  ## Integration Gateway API
193
203
 
194
- There are features that require the Integration Gateway API instead of the regular GraphQL Application API, for example Airflow Callbacks invoked by the `airflow-mcd` library.
204
+ There are features that require the Integration Gateway API instead of the regular GraphQL
205
+ Application API, for example Airflow Callbacks invoked by the `airflow-mcd` library.
195
206
 
196
- To use the Gateway you need to initialize the `Session` object passing a `scope` parameter and then use `make_request` to invoke Gateway endpoints:
207
+ To use the Gateway you need to initialize the `Session` object passing a `scope` parameter and then
208
+ use `make_request` to invoke Gateway endpoints:
197
209
 
198
210
  ```python
199
211
  from pycarlo.core import Client, Session
@@ -211,17 +223,22 @@ The following values also be set by the environment:
211
223
  - `MCD_VERBOSE_ERRORS`: Enable logging. This includes a trace ID for each session and request.
212
224
  - `MCD_API_ENDPOINT`: Customize the endpoint where queries and mutations are executed.
213
225
 
214
- ## Tests and releases
226
+ ## Enum Backward Compatibility
227
+
228
+ Unlike the baseline `sgqlc` behavior, this SDK is designed to maintain backward compatibility when
229
+ new enum values are added to the Monte Carlo API. If the API returns an enum value that doesn't
230
+ exist in your SDK version, it will be returned as a string with a warning logged, rather than
231
+ raising an error. This allows older SDK versions to continue working when new features are added.
215
232
 
216
- To update queries and mutations via introspection, use `make generate`.
233
+ To avoid warnings and ensure full feature support, keep your SDK updated to the latest version.
217
234
 
218
- `make test` can be used to run all tests locally. CircleCI manages all testing for deployment. When ready for a review, create a PR against `main`.
235
+ ## Contributing
219
236
 
220
- When ready to release, create a new [Github release](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository) with a tag using semantic versioning (e.g. `v0.42.0`) and CircleCI will test and publish to PyPI. Note that an existing version will not be deployed.
237
+ See [CONTRIBUTING.md](./CONTRIBUTING.md) for details.
221
238
 
222
239
  ## References
223
240
 
224
- - Dashboard: <https://getmontecarlo.com>
241
+ - Monte Carlo App: <https://getmontecarlo.com>
225
242
  - Product docs: <https://docs.getmontecarlo.com>
226
243
  - Status page: <https://status.getmontecarlo.com>
227
244
  - API (and SDK): <https://apidocs.getmontecarlo.com>
@@ -229,4 +246,4 @@ When ready to release, create a new [Github release](https://docs.github.com/en/
229
246
 
230
247
  ## License
231
248
 
232
- Apache 2.0 - See the [LICENSE](http://www.apache.org/licenses/LICENSE-2.0) for more information.
249
+ Apache 2.0 - See the [LICENSE](./LICENSE) for more information.
@@ -20,9 +20,12 @@ pycarlo/features/circuit_breakers/service.py,sha256=TljwMOhA5igBumkpJwM22iEJGyvt
20
20
  pycarlo/features/dbt/__init__.py,sha256=A2cFr8_aSY_kDw1m7jR6QkHfiBMC1cZ6O8WosF9XrRg,85
21
21
  pycarlo/features/dbt/dbt_importer.py,sha256=eJb9Jiu7tAEb_xsLO-ycDOjjVm-LLfTtbAzlzIRxT5I,7328
22
22
  pycarlo/features/dbt/queries.py,sha256=9o1HevRECYyGXQ0lG0LrN4iuuXCS-SWjz7NTgAAZIro,621
23
- pycarlo/features/metadata/__init__.py,sha256=lSfQ-3W6d4YCWpjWlbxBNm07KomrmPORweCGLvLbGuM,360
24
- pycarlo/features/metadata/allow_block_list.py,sha256=UWqGOzLELRRryHVRgNXqlfUfHFX9SeXuhKix_5B_7CY,5823
25
- pycarlo/features/metadata/metadata_filters_container.py,sha256=iHMd3S-JQLkTVgiKU5sgeJN9Wb6KWm-6YuulOCStGZ4,12670
23
+ pycarlo/features/metadata/__init__.py,sha256=0RDVHnwPvQcNXkeXEAxL4VJ8VWrl2P0fft_Kl2nlo7I,912
24
+ pycarlo/features/metadata/asset_allow_block_list.py,sha256=jXCS7HtUJhexEXZyRzyN4MT-BPSaMTKWCWiBT_l-Ijo,761
25
+ pycarlo/features/metadata/asset_filters_container.py,sha256=O15SC6u7HMGlViYnX7H8MRFttQrIXQd3a0oOrz7My5U,3411
26
+ pycarlo/features/metadata/base_allow_block_list.py,sha256=c8zd0BXkNSfQ3LkNC_A0KrO2AsYtIowc8FjbdyDyDu0,4738
27
+ pycarlo/features/metadata/metadata_allow_block_list.py,sha256=HzgXE0WhwDZoBHeV04e8dwe88rUSVVnOl8nFEPlb0jA,3496
28
+ pycarlo/features/metadata/metadata_filters_container.py,sha256=p7FNg71KYZZrvgJmlx9rID2TAL_e9LKzNQZ9KKN5uGs,12812
26
29
  pycarlo/features/pii/__init__.py,sha256=w5X-oD8HWaL6fP2jt40AhlXO-MNzlVAlhRaZ5kQqAZY,247
27
30
  pycarlo/features/pii/constants.py,sha256=XWeiikXk9AtljdWsGfl49b9zI6w8EzK8F__Euc0vQ3w,70
28
31
  pycarlo/features/pii/pii_filterer.py,sha256=k53b_V_mddY4A17-DJ5vQKszFDlUaiP3E650JFHAeJA,6209
@@ -33,12 +36,13 @@ pycarlo/features/user/exceptions.py,sha256=Za5mPMynNDW_UQkfMbCSGjP1ht-xSUkwoI6hV
33
36
  pycarlo/features/user/models.py,sha256=fhvS7tBhTtx7p9624yN5tzebXs5ERrl1XQ9B_DYor0E,126
34
37
  pycarlo/features/user/queries.py,sha256=m97RvM0oiBlrU5xmOwe_JJ5N0G0NG5hIOeyQqN2O8_4,170
35
38
  pycarlo/features/user/service.py,sha256=DHkhuonySaHro07NTd0YNe3cNkDk62CiRTY77dhVaMs,2890
36
- pycarlo/lib/README.md,sha256=QGNeUefPzLKGyZqn5aITpcFgkC9WQTNS292BGisRFHk,139
39
+ pycarlo/lib/README.md,sha256=CVVrPPgje7pkXNNsPvwLSeUOm5aktb22MlttmoxX08k,1677
37
40
  pycarlo/lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
- pycarlo/lib/schema.json,sha256=BSHvPzz4iNRcIUt6m0EaxCSwvM-0_GyGv3KK2ZXeQuo,6326661
39
- pycarlo/lib/schema.py,sha256=DiLA7cehL0JQBDtFHECKrDx2-RL6ECsHooT3TR4LCOg,2755115
40
- pycarlo-0.10.185.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
41
- pycarlo-0.10.185.dist-info/METADATA,sha256=ynNxJd6Mo_HCFLbigLfLswRwXNtDFA_0ZilfN-zeJjE,8742
42
- pycarlo-0.10.185.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
43
- pycarlo-0.10.185.dist-info/top_level.txt,sha256=TIE04H4pgzGaFxAB-gvkmVAUOAoHxxFfhnEcpuQ5bF4,8
44
- pycarlo-0.10.185.dist-info/RECORD,,
41
+ pycarlo/lib/schema.json,sha256=8hy9VhDelnqo-W6kv7l79DqNcOGSs1iTDeqeZF7vVgU,6592980
42
+ pycarlo/lib/schema.py,sha256=8lvj7QJU3T4VgWQGA7zYeevneQs0IWmCxY1repQLGZI,2866173
43
+ pycarlo/lib/types.py,sha256=lGOrm5Qm-SieDAkOkVOFSgyUJYGOjKnea961AD9Dv6s,2404
44
+ pycarlo-0.12.4.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
45
+ pycarlo-0.12.4.dist-info/METADATA,sha256=ehp5avs5JNX2r6D9lfdRuBw3F51p-cRTHXk8h_G1iLI,8717
46
+ pycarlo-0.12.4.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
47
+ pycarlo-0.12.4.dist-info/top_level.txt,sha256=TIE04H4pgzGaFxAB-gvkmVAUOAoHxxFfhnEcpuQ5bF4,8
48
+ pycarlo-0.12.4.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.43.0)
2
+ Generator: setuptools (75.3.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,159 +0,0 @@
1
- import enum
2
- import re
3
- from dataclasses import dataclass, field
4
- from typing import Any, Callable, List, Optional
5
-
6
- from dataclasses_json import config, dataclass_json
7
-
8
- from pycarlo.common import get_logger
9
-
10
- logger = get_logger(__name__)
11
-
12
- # For documentation and samples check the link below:
13
- # https://www.notion.so/montecarlodata/Catalog-Schema-Filtering-59edd6eff7f74c94ab6bfca75d2e3ff1
14
-
15
-
16
- def _exclude_none_values(value: Any) -> bool:
17
- return value is None
18
-
19
-
20
- class FilterEffectType(enum.Enum):
21
- BLOCK = "block"
22
- ALLOW = "allow"
23
-
24
-
25
- class FilterType(enum.Enum):
26
- EXACT_MATCH = "exact_match"
27
- PREFIX = "prefix"
28
- SUFFIX = "suffix"
29
- SUBSTRING = "substring"
30
- REGEXP = "regexp"
31
-
32
-
33
- @dataclass_json
34
- @dataclass
35
- class MetadataFilter:
36
- # we're using exclude=_exclude_none_values to prevent these properties to be serialized to json
37
- # when None, to keep the json doc simpler
38
- project: Optional[str] = field(metadata=config(exclude=_exclude_none_values), default=None)
39
- dataset: Optional[str] = field(metadata=config(exclude=_exclude_none_values), default=None)
40
- table_type: Optional[str] = field(metadata=config(exclude=_exclude_none_values), default=None)
41
- table_name: Optional[str] = field(metadata=config(exclude=_exclude_none_values), default=None)
42
- type: FilterType = FilterType.EXACT_MATCH
43
- effect: FilterEffectType = FilterEffectType.BLOCK
44
-
45
- def matches(self, force_regexp: bool = False, **kwargs: Any) -> bool:
46
- """
47
- Returns True if all properties specified in kwargs match the conditions specified in
48
- properties of the same name in this object.
49
- Supported keys in kwargs: 'project', 'dataset', 'table', 'table_type'
50
- For example kwargs={'project': 'prj_1'} will evaluate if 'prj_1' matches the condition in
51
- self.project. For kwargs={'project': 'prj_1', 'dataset': 'ds_1'} will evaluate if 'prj_1'
52
- matches the condition in self.project and if 'ds_1' matches the condition in self.dataset.
53
- If any of the conditions (for example self.project) is None, that condition will be matched.
54
- """
55
- if not kwargs:
56
- raise ValueError("At least one field needs to be specified for matching")
57
-
58
- # kwargs must match the field names in this class, if any of them do not,
59
- # invalidate the filter.
60
- try:
61
- is_match = all(
62
- self._safe_match(
63
- component=getattr(self, component),
64
- value=value,
65
- force_regexp=force_regexp,
66
- filter_type=self.type
67
- if self.filter_type_target_field() == component
68
- else FilterType.EXACT_MATCH,
69
- )
70
- for component, value in kwargs.items()
71
- )
72
- except AttributeError:
73
- is_match = False
74
-
75
- return is_match
76
-
77
- def filter_type_target_field(self) -> str:
78
- """
79
- The field that is evaluated using filter type. Other fields should be
80
- compared using exact match.
81
- """
82
- if self.table_name is not None:
83
- return "table_name"
84
- if self.dataset is not None:
85
- return "dataset"
86
- if self.project is not None:
87
- return "project"
88
-
89
- logger.exception("Invalid filter, missing target values")
90
- return ""
91
-
92
- @classmethod
93
- def _safe_match(
94
- cls,
95
- component: Optional[str],
96
- value: Optional[str],
97
- force_regexp: bool,
98
- filter_type: FilterType,
99
- ) -> bool:
100
- # Field not specified on this object, e.g. self.dataset=None, which matches everything
101
- if component is None:
102
- return True
103
- # The value in kwargs is empty, it does not match the condition.
104
- if value is None:
105
- return False
106
-
107
- # Convert it in lowercase. In the normalizer we are converting identifiers
108
- # (like project/dataset) to lowercase so the metadata filters may be defined with
109
- # lowercase on the UI, however on Snowflake the identifiers are usually in uppercase.
110
- # Therefore, we perform the evaluation case-insensitive.
111
- component = component.lower()
112
- value = value.lower()
113
-
114
- if force_regexp or filter_type == FilterType.REGEXP:
115
- regexp = f"^{component}$" # Anchor the regexp to be more strict about what to match.
116
- return re.match(regexp, value) is not None
117
- elif filter_type == FilterType.PREFIX:
118
- return value.startswith(component)
119
- elif filter_type == FilterType.SUFFIX:
120
- return value.endswith(component)
121
- elif filter_type == FilterType.SUBSTRING:
122
- return component in value
123
- else:
124
- return component == value
125
-
126
-
127
- @dataclass_json
128
- @dataclass
129
- class AllowBlockList:
130
- filters: List[MetadataFilter] = field(default_factory=list)
131
- default_effect: FilterEffectType = FilterEffectType.ALLOW
132
-
133
- @property
134
- def other_effect(self) -> FilterEffectType:
135
- return (
136
- FilterEffectType.ALLOW
137
- if self.default_effect == FilterEffectType.BLOCK
138
- else FilterEffectType.BLOCK
139
- )
140
-
141
- def get_default_effect_filters(
142
- self, condition: Optional[Callable[[MetadataFilter], bool]] = None
143
- ) -> List[MetadataFilter]:
144
- return list(
145
- filter(
146
- lambda f: f.effect == self.default_effect and (condition is None or condition(f)),
147
- self.filters,
148
- )
149
- )
150
-
151
- def get_other_effect_filters(
152
- self, condition: Optional[Callable[[MetadataFilter], bool]] = None
153
- ) -> List[MetadataFilter]:
154
- return list(
155
- filter(
156
- lambda f: f.effect != self.default_effect and (condition is None or condition(f)),
157
- self.filters,
158
- )
159
- )