tradingview_screener.column

  1from __future__ import annotations
  2
  3from typing import TYPE_CHECKING
  4
  5
  6if TYPE_CHECKING:
  7    from typing import Optional, Iterable
  8    from tradingview_screener.models import FilterOperationDict
  9
 10
 11class Column:
 12    """
 13    A Column object represents a field in the tradingview stock screener,
 14    and it's used in SELECT queries and WHERE queries with the `Query` object.
 15
 16    A `Column` supports all the comparison operations:
 17    `<`, `<=`, `>`, `>=`, `==`, `!=`, and also other methods like `between()`, `isin()`, etc.
 18
 19    Examples:
 20
 21    Some of the operations you can do:
 22    >>> Column('close') > 2.5
 23    >>> Column('High.All') <= 'high'
 24    >>> Column('high') > 'VWAP'
 25    >>> Column('high') > Column('VWAP')  # same thing as above
 26    >>> Column('is_primary') == True
 27    >>> Column('exchange') != 'OTC'
 28
 29    >>> Column('close').above_pct('VWAP', 1.03)
 30    >>> Column('close').above_pct('price_52_week_low', 2.5)
 31    >>> Column('close').below_pct('VWAP', 1.03)
 32    >>> Column('close').between_pct('EMA200', 1.2, 1.5)
 33    >>> Column('close').not_between_pct('EMA200', 1.2, 1.5)
 34
 35    >>> Column('close').between(2.5, 15)
 36    >>> Column('close').between('EMA5', 'EMA20')
 37
 38    >>> Column('type').isin(['stock', 'fund'])
 39    >>> Column('exchange').isin(['AMEX', 'NASDAQ', 'NYSE'])
 40    >>> Column('sector').not_in(['Health Technology', 'Health Services'])
 41    >>> Column('typespecs').has(['common']),
 42    >>> Column('typespecs').has_none_of(['reit', 'etn', 'etf']),
 43
 44    >>> Column('description').like('apple')  # the same as `description LIKE '%apple%'`
 45    >>> Column('premarket_change').not_empty()  # same as `Column('premarket_change') != None`
 46    >>> Column('earnings_release_next_trading_date_fq').in_day_range(0, 0)  # same day
 47    """
 48
 49    def __init__(self, name: str) -> None:
 50        self.name = name
 51
 52    @staticmethod
 53    def _extract_name(obj) -> ...:
 54        if isinstance(obj, Column):
 55            return obj.name
 56        return obj
 57
 58    def __gt__(self, other) -> FilterOperationDict:
 59        return {'left': self.name, 'operation': 'greater', 'right': self._extract_name(other)}
 60
 61    def __ge__(self, other) -> FilterOperationDict:
 62        return {'left': self.name, 'operation': 'egreater', 'right': self._extract_name(other)}
 63
 64    def __lt__(self, other) -> FilterOperationDict:
 65        return {'left': self.name, 'operation': 'less', 'right': self._extract_name(other)}
 66
 67    def __le__(self, other) -> FilterOperationDict:
 68        return {'left': self.name, 'operation': 'eless', 'right': self._extract_name(other)}
 69
 70    def __eq__(self, other) -> FilterOperationDict:  # pyright: ignore [reportIncompatibleMethodOverride]
 71        return {'left': self.name, 'operation': 'equal', 'right': self._extract_name(other)}
 72
 73    def __ne__(self, other) -> FilterOperationDict:  # pyright: ignore [reportIncompatibleMethodOverride]
 74        return {'left': self.name, 'operation': 'nequal', 'right': self._extract_name(other)}
 75
 76    def crosses(self, other) -> FilterOperationDict:
 77        return {'left': self.name, 'operation': 'crosses', 'right': self._extract_name(other)}
 78
 79    def crosses_above(self, other) -> FilterOperationDict:
 80        return {'left': self.name, 'operation': 'crosses_above', 'right': self._extract_name(other)}
 81
 82    def crosses_below(self, other) -> FilterOperationDict:
 83        return {'left': self.name, 'operation': 'crosses_below', 'right': self._extract_name(other)}
 84
 85    def between(self, left, right) -> FilterOperationDict:
 86        return {
 87            'left': self.name,
 88            'operation': 'in_range',
 89            'right': [self._extract_name(left), self._extract_name(right)],
 90        }
 91
 92    def not_between(self, left, right) -> FilterOperationDict:
 93        return {
 94            'left': self.name,
 95            'operation': 'not_in_range',
 96            'right': [self._extract_name(left), self._extract_name(right)],
 97        }
 98
 99    def isin(self, values: Iterable) -> FilterOperationDict:
100        return {'left': self.name, 'operation': 'in_range', 'right': list(values)}
101
102    def not_in(self, values: Iterable) -> FilterOperationDict:
103        return {'left': self.name, 'operation': 'not_in_range', 'right': list(values)}
104
105    def has(self, values: str | list[str]) -> FilterOperationDict:
106        """
107        Field contains any of the values
108
109        (it's the same as `isin()`, except that it works on fields of type `set`)
110        """
111        return {'left': self.name, 'operation': 'has', 'right': values}
112
113    def has_none_of(self, values: str | list[str]) -> FilterOperationDict:
114        """
115        Field doesn't contain any of the values
116
117        (it's the same as `not_in()`, except that it works on fields of type `set`)
118        """
119        return {'left': self.name, 'operation': 'has_none_of', 'right': values}
120
121    def in_day_range(self, a: int, b: int) -> FilterOperationDict:
122        return {'left': self.name, 'operation': 'in_day_range', 'right': [a, b]}
123
124    def in_week_range(self, a: int, b: int) -> FilterOperationDict:
125        return {'left': self.name, 'operation': 'in_week_range', 'right': [a, b]}
126
127    def in_month_range(self, a: int, b: int) -> FilterOperationDict:
128        return {'left': self.name, 'operation': 'in_month_range', 'right': [a, b]}
129
130    def above_pct(self, column: Column | str, pct: float) -> FilterOperationDict:
131        """
132        Examples:
133
134        The closing price is higher than the VWAP by more than 3%
135        >>> Column('close').above_pct('VWAP', 1.03)
136
137        closing price is above the 52-week-low by more than 150%
138        >>> Column('close').above_pct('price_52_week_low', 2.5)
139        """
140        return {
141            'left': self.name,
142            'operation': 'above%',
143            'right': [self._extract_name(column), pct],
144        }
145
146    def below_pct(self, column: Column | str, pct: float) -> FilterOperationDict:
147        """
148        Examples:
149
150        The closing price is lower than the VWAP by 3% or more
151        >>> Column('close').below_pct('VWAP', 1.03)
152        """
153        return {
154            'left': self.name,
155            'operation': 'below%',
156            'right': [self._extract_name(column), pct],
157        }
158
159    def between_pct(
160        self, column: Column | str, pct1: float, pct2: Optional[float] = None
161    ) -> FilterOperationDict:
162        """
163        Examples:
164
165        The percentage change between the Close and the EMA is between 20% and 50%
166        >>> Column('close').between_pct('EMA200', 1.2, 1.5)
167        """
168        return {
169            'left': self.name,
170            'operation': 'in_range%',
171            'right': [self._extract_name(column), pct1, pct2],
172        }
173
174    def not_between_pct(
175        self, column: Column | str, pct1: float, pct2: Optional[float] = None
176    ) -> FilterOperationDict:
177        """
178        Examples:
179
180        The percentage change between the Close and the EMA is between 20% and 50%
181        >>> Column('close').not_between_pct('EMA200', 1.2, 1.5)
182        """
183        return {
184            'left': self.name,
185            'operation': 'not_in_range%',
186            'right': [self._extract_name(column), pct1, pct2],
187        }
188
189    def like(self, other) -> FilterOperationDict:
190        return {'left': self.name, 'operation': 'match', 'right': self._extract_name(other)}
191
192    def not_like(self, other) -> FilterOperationDict:
193        return {'left': self.name, 'operation': 'nmatch', 'right': self._extract_name(other)}
194
195    def empty(self) -> FilterOperationDict:
196        # it seems like the `right` key is optional
197        return {'left': self.name, 'operation': 'empty', 'right': None}
198
199    def not_empty(self) -> FilterOperationDict:
200        """
201        This method can be used to check if a field is not None/null.
202        """
203        return {'left': self.name, 'operation': 'nempty', 'right': None}
204
205    def __repr__(self) -> str:
206        return f'< Column({self.name!r}) >'
207
208
209col = Column  # create a short alias for convenience
class Column:
 12class Column:
 13    """
 14    A Column object represents a field in the tradingview stock screener,
 15    and it's used in SELECT queries and WHERE queries with the `Query` object.
 16
 17    A `Column` supports all the comparison operations:
 18    `<`, `<=`, `>`, `>=`, `==`, `!=`, and also other methods like `between()`, `isin()`, etc.
 19
 20    Examples:
 21
 22    Some of the operations you can do:
 23    >>> Column('close') > 2.5
 24    >>> Column('High.All') <= 'high'
 25    >>> Column('high') > 'VWAP'
 26    >>> Column('high') > Column('VWAP')  # same thing as above
 27    >>> Column('is_primary') == True
 28    >>> Column('exchange') != 'OTC'
 29
 30    >>> Column('close').above_pct('VWAP', 1.03)
 31    >>> Column('close').above_pct('price_52_week_low', 2.5)
 32    >>> Column('close').below_pct('VWAP', 1.03)
 33    >>> Column('close').between_pct('EMA200', 1.2, 1.5)
 34    >>> Column('close').not_between_pct('EMA200', 1.2, 1.5)
 35
 36    >>> Column('close').between(2.5, 15)
 37    >>> Column('close').between('EMA5', 'EMA20')
 38
 39    >>> Column('type').isin(['stock', 'fund'])
 40    >>> Column('exchange').isin(['AMEX', 'NASDAQ', 'NYSE'])
 41    >>> Column('sector').not_in(['Health Technology', 'Health Services'])
 42    >>> Column('typespecs').has(['common']),
 43    >>> Column('typespecs').has_none_of(['reit', 'etn', 'etf']),
 44
 45    >>> Column('description').like('apple')  # the same as `description LIKE '%apple%'`
 46    >>> Column('premarket_change').not_empty()  # same as `Column('premarket_change') != None`
 47    >>> Column('earnings_release_next_trading_date_fq').in_day_range(0, 0)  # same day
 48    """
 49
 50    def __init__(self, name: str) -> None:
 51        self.name = name
 52
 53    @staticmethod
 54    def _extract_name(obj) -> ...:
 55        if isinstance(obj, Column):
 56            return obj.name
 57        return obj
 58
 59    def __gt__(self, other) -> FilterOperationDict:
 60        return {'left': self.name, 'operation': 'greater', 'right': self._extract_name(other)}
 61
 62    def __ge__(self, other) -> FilterOperationDict:
 63        return {'left': self.name, 'operation': 'egreater', 'right': self._extract_name(other)}
 64
 65    def __lt__(self, other) -> FilterOperationDict:
 66        return {'left': self.name, 'operation': 'less', 'right': self._extract_name(other)}
 67
 68    def __le__(self, other) -> FilterOperationDict:
 69        return {'left': self.name, 'operation': 'eless', 'right': self._extract_name(other)}
 70
 71    def __eq__(self, other) -> FilterOperationDict:  # pyright: ignore [reportIncompatibleMethodOverride]
 72        return {'left': self.name, 'operation': 'equal', 'right': self._extract_name(other)}
 73
 74    def __ne__(self, other) -> FilterOperationDict:  # pyright: ignore [reportIncompatibleMethodOverride]
 75        return {'left': self.name, 'operation': 'nequal', 'right': self._extract_name(other)}
 76
 77    def crosses(self, other) -> FilterOperationDict:
 78        return {'left': self.name, 'operation': 'crosses', 'right': self._extract_name(other)}
 79
 80    def crosses_above(self, other) -> FilterOperationDict:
 81        return {'left': self.name, 'operation': 'crosses_above', 'right': self._extract_name(other)}
 82
 83    def crosses_below(self, other) -> FilterOperationDict:
 84        return {'left': self.name, 'operation': 'crosses_below', 'right': self._extract_name(other)}
 85
 86    def between(self, left, right) -> FilterOperationDict:
 87        return {
 88            'left': self.name,
 89            'operation': 'in_range',
 90            'right': [self._extract_name(left), self._extract_name(right)],
 91        }
 92
 93    def not_between(self, left, right) -> FilterOperationDict:
 94        return {
 95            'left': self.name,
 96            'operation': 'not_in_range',
 97            'right': [self._extract_name(left), self._extract_name(right)],
 98        }
 99
100    def isin(self, values: Iterable) -> FilterOperationDict:
101        return {'left': self.name, 'operation': 'in_range', 'right': list(values)}
102
103    def not_in(self, values: Iterable) -> FilterOperationDict:
104        return {'left': self.name, 'operation': 'not_in_range', 'right': list(values)}
105
106    def has(self, values: str | list[str]) -> FilterOperationDict:
107        """
108        Field contains any of the values
109
110        (it's the same as `isin()`, except that it works on fields of type `set`)
111        """
112        return {'left': self.name, 'operation': 'has', 'right': values}
113
114    def has_none_of(self, values: str | list[str]) -> FilterOperationDict:
115        """
116        Field doesn't contain any of the values
117
118        (it's the same as `not_in()`, except that it works on fields of type `set`)
119        """
120        return {'left': self.name, 'operation': 'has_none_of', 'right': values}
121
122    def in_day_range(self, a: int, b: int) -> FilterOperationDict:
123        return {'left': self.name, 'operation': 'in_day_range', 'right': [a, b]}
124
125    def in_week_range(self, a: int, b: int) -> FilterOperationDict:
126        return {'left': self.name, 'operation': 'in_week_range', 'right': [a, b]}
127
128    def in_month_range(self, a: int, b: int) -> FilterOperationDict:
129        return {'left': self.name, 'operation': 'in_month_range', 'right': [a, b]}
130
131    def above_pct(self, column: Column | str, pct: float) -> FilterOperationDict:
132        """
133        Examples:
134
135        The closing price is higher than the VWAP by more than 3%
136        >>> Column('close').above_pct('VWAP', 1.03)
137
138        closing price is above the 52-week-low by more than 150%
139        >>> Column('close').above_pct('price_52_week_low', 2.5)
140        """
141        return {
142            'left': self.name,
143            'operation': 'above%',
144            'right': [self._extract_name(column), pct],
145        }
146
147    def below_pct(self, column: Column | str, pct: float) -> FilterOperationDict:
148        """
149        Examples:
150
151        The closing price is lower than the VWAP by 3% or more
152        >>> Column('close').below_pct('VWAP', 1.03)
153        """
154        return {
155            'left': self.name,
156            'operation': 'below%',
157            'right': [self._extract_name(column), pct],
158        }
159
160    def between_pct(
161        self, column: Column | str, pct1: float, pct2: Optional[float] = None
162    ) -> FilterOperationDict:
163        """
164        Examples:
165
166        The percentage change between the Close and the EMA is between 20% and 50%
167        >>> Column('close').between_pct('EMA200', 1.2, 1.5)
168        """
169        return {
170            'left': self.name,
171            'operation': 'in_range%',
172            'right': [self._extract_name(column), pct1, pct2],
173        }
174
175    def not_between_pct(
176        self, column: Column | str, pct1: float, pct2: Optional[float] = None
177    ) -> FilterOperationDict:
178        """
179        Examples:
180
181        The percentage change between the Close and the EMA is between 20% and 50%
182        >>> Column('close').not_between_pct('EMA200', 1.2, 1.5)
183        """
184        return {
185            'left': self.name,
186            'operation': 'not_in_range%',
187            'right': [self._extract_name(column), pct1, pct2],
188        }
189
190    def like(self, other) -> FilterOperationDict:
191        return {'left': self.name, 'operation': 'match', 'right': self._extract_name(other)}
192
193    def not_like(self, other) -> FilterOperationDict:
194        return {'left': self.name, 'operation': 'nmatch', 'right': self._extract_name(other)}
195
196    def empty(self) -> FilterOperationDict:
197        # it seems like the `right` key is optional
198        return {'left': self.name, 'operation': 'empty', 'right': None}
199
200    def not_empty(self) -> FilterOperationDict:
201        """
202        This method can be used to check if a field is not None/null.
203        """
204        return {'left': self.name, 'operation': 'nempty', 'right': None}
205
206    def __repr__(self) -> str:
207        return f'< Column({self.name!r}) >'

A Column object represents a field in the tradingview stock screener, and it's used in SELECT queries and WHERE queries with the Query object.

A Column supports all the comparison operations: <, <=, >, >=, ==, !=, and also other methods like between(), isin(), etc.

Examples:

Some of the operations you can do:

>>> Column('close') > 2.5
>>> Column('High.All') <= 'high'
>>> Column('high') > 'VWAP'
>>> Column('high') > Column('VWAP')  # same thing as above
>>> Column('is_primary') == True
>>> Column('exchange') != 'OTC'
>>> Column('close').above_pct('VWAP', 1.03)
>>> Column('close').above_pct('price_52_week_low', 2.5)
>>> Column('close').below_pct('VWAP', 1.03)
>>> Column('close').between_pct('EMA200', 1.2, 1.5)
>>> Column('close').not_between_pct('EMA200', 1.2, 1.5)
>>> Column('close').between(2.5, 15)
>>> Column('close').between('EMA5', 'EMA20')
>>> Column('type').isin(['stock', 'fund'])
>>> Column('exchange').isin(['AMEX', 'NASDAQ', 'NYSE'])
>>> Column('sector').not_in(['Health Technology', 'Health Services'])
>>> Column('typespecs').has(['common']),
>>> Column('typespecs').has_none_of(['reit', 'etn', 'etf']),
>>> Column('description').like('apple')  # the same as `description LIKE '%apple%'`
>>> Column('premarket_change').not_empty()  # same as `Column('premarket_change') != None`
>>> Column('earnings_release_next_trading_date_fq').in_day_range(0, 0)  # same day
Column(name: str)
50    def __init__(self, name: str) -> None:
51        self.name = name
name
def crosses(self, other) -> tradingview_screener.models.FilterOperationDict:
77    def crosses(self, other) -> FilterOperationDict:
78        return {'left': self.name, 'operation': 'crosses', 'right': self._extract_name(other)}
def crosses_above(self, other) -> tradingview_screener.models.FilterOperationDict:
80    def crosses_above(self, other) -> FilterOperationDict:
81        return {'left': self.name, 'operation': 'crosses_above', 'right': self._extract_name(other)}
def crosses_below(self, other) -> tradingview_screener.models.FilterOperationDict:
83    def crosses_below(self, other) -> FilterOperationDict:
84        return {'left': self.name, 'operation': 'crosses_below', 'right': self._extract_name(other)}
def between(self, left, right) -> tradingview_screener.models.FilterOperationDict:
86    def between(self, left, right) -> FilterOperationDict:
87        return {
88            'left': self.name,
89            'operation': 'in_range',
90            'right': [self._extract_name(left), self._extract_name(right)],
91        }
def not_between(self, left, right) -> tradingview_screener.models.FilterOperationDict:
93    def not_between(self, left, right) -> FilterOperationDict:
94        return {
95            'left': self.name,
96            'operation': 'not_in_range',
97            'right': [self._extract_name(left), self._extract_name(right)],
98        }
def isin( self, values: Iterable) -> tradingview_screener.models.FilterOperationDict:
100    def isin(self, values: Iterable) -> FilterOperationDict:
101        return {'left': self.name, 'operation': 'in_range', 'right': list(values)}
def not_in( self, values: Iterable) -> tradingview_screener.models.FilterOperationDict:
103    def not_in(self, values: Iterable) -> FilterOperationDict:
104        return {'left': self.name, 'operation': 'not_in_range', 'right': list(values)}
def has( self, values: str | list[str]) -> tradingview_screener.models.FilterOperationDict:
106    def has(self, values: str | list[str]) -> FilterOperationDict:
107        """
108        Field contains any of the values
109
110        (it's the same as `isin()`, except that it works on fields of type `set`)
111        """
112        return {'left': self.name, 'operation': 'has', 'right': values}

Field contains any of the values

(it's the same as isin(), except that it works on fields of type set)

def has_none_of( self, values: str | list[str]) -> tradingview_screener.models.FilterOperationDict:
114    def has_none_of(self, values: str | list[str]) -> FilterOperationDict:
115        """
116        Field doesn't contain any of the values
117
118        (it's the same as `not_in()`, except that it works on fields of type `set`)
119        """
120        return {'left': self.name, 'operation': 'has_none_of', 'right': values}

Field doesn't contain any of the values

(it's the same as not_in(), except that it works on fields of type set)

def in_day_range(self, a: int, b: int) -> tradingview_screener.models.FilterOperationDict:
122    def in_day_range(self, a: int, b: int) -> FilterOperationDict:
123        return {'left': self.name, 'operation': 'in_day_range', 'right': [a, b]}
def in_week_range(self, a: int, b: int) -> tradingview_screener.models.FilterOperationDict:
125    def in_week_range(self, a: int, b: int) -> FilterOperationDict:
126        return {'left': self.name, 'operation': 'in_week_range', 'right': [a, b]}
def in_month_range(self, a: int, b: int) -> tradingview_screener.models.FilterOperationDict:
128    def in_month_range(self, a: int, b: int) -> FilterOperationDict:
129        return {'left': self.name, 'operation': 'in_month_range', 'right': [a, b]}
def above_pct( self, column: Column | str, pct: float) -> tradingview_screener.models.FilterOperationDict:
131    def above_pct(self, column: Column | str, pct: float) -> FilterOperationDict:
132        """
133        Examples:
134
135        The closing price is higher than the VWAP by more than 3%
136        >>> Column('close').above_pct('VWAP', 1.03)
137
138        closing price is above the 52-week-low by more than 150%
139        >>> Column('close').above_pct('price_52_week_low', 2.5)
140        """
141        return {
142            'left': self.name,
143            'operation': 'above%',
144            'right': [self._extract_name(column), pct],
145        }

Examples:

The closing price is higher than the VWAP by more than 3%

>>> Column('close').above_pct('VWAP', 1.03)

closing price is above the 52-week-low by more than 150%

>>> Column('close').above_pct('price_52_week_low', 2.5)
def below_pct( self, column: Column | str, pct: float) -> tradingview_screener.models.FilterOperationDict:
147    def below_pct(self, column: Column | str, pct: float) -> FilterOperationDict:
148        """
149        Examples:
150
151        The closing price is lower than the VWAP by 3% or more
152        >>> Column('close').below_pct('VWAP', 1.03)
153        """
154        return {
155            'left': self.name,
156            'operation': 'below%',
157            'right': [self._extract_name(column), pct],
158        }

Examples:

The closing price is lower than the VWAP by 3% or more

>>> Column('close').below_pct('VWAP', 1.03)
def between_pct( self, column: Column | str, pct1: float, pct2: Optional[float] = None) -> tradingview_screener.models.FilterOperationDict:
160    def between_pct(
161        self, column: Column | str, pct1: float, pct2: Optional[float] = None
162    ) -> FilterOperationDict:
163        """
164        Examples:
165
166        The percentage change between the Close and the EMA is between 20% and 50%
167        >>> Column('close').between_pct('EMA200', 1.2, 1.5)
168        """
169        return {
170            'left': self.name,
171            'operation': 'in_range%',
172            'right': [self._extract_name(column), pct1, pct2],
173        }

Examples:

The percentage change between the Close and the EMA is between 20% and 50%

>>> Column('close').between_pct('EMA200', 1.2, 1.5)
def not_between_pct( self, column: Column | str, pct1: float, pct2: Optional[float] = None) -> tradingview_screener.models.FilterOperationDict:
175    def not_between_pct(
176        self, column: Column | str, pct1: float, pct2: Optional[float] = None
177    ) -> FilterOperationDict:
178        """
179        Examples:
180
181        The percentage change between the Close and the EMA is between 20% and 50%
182        >>> Column('close').not_between_pct('EMA200', 1.2, 1.5)
183        """
184        return {
185            'left': self.name,
186            'operation': 'not_in_range%',
187            'right': [self._extract_name(column), pct1, pct2],
188        }

Examples:

The percentage change between the Close and the EMA is between 20% and 50%

>>> Column('close').not_between_pct('EMA200', 1.2, 1.5)
def like(self, other) -> tradingview_screener.models.FilterOperationDict:
190    def like(self, other) -> FilterOperationDict:
191        return {'left': self.name, 'operation': 'match', 'right': self._extract_name(other)}
def not_like(self, other) -> tradingview_screener.models.FilterOperationDict:
193    def not_like(self, other) -> FilterOperationDict:
194        return {'left': self.name, 'operation': 'nmatch', 'right': self._extract_name(other)}
def empty(self) -> tradingview_screener.models.FilterOperationDict:
196    def empty(self) -> FilterOperationDict:
197        # it seems like the `right` key is optional
198        return {'left': self.name, 'operation': 'empty', 'right': None}
def not_empty(self) -> tradingview_screener.models.FilterOperationDict:
200    def not_empty(self) -> FilterOperationDict:
201        """
202        This method can be used to check if a field is not None/null.
203        """
204        return {'left': self.name, 'operation': 'nempty', 'right': None}

This method can be used to check if a field is not None/null.

col = <class 'Column'>