|
1 | 1 | """Represent global utility functions."""
|
2 | 2 | import typing as t
|
| 3 | +from datetime import datetime |
3 | 4 | from ssl import SSLContext
|
4 | 5 |
|
| 6 | +import numpy as np |
| 7 | +import pandas as pd |
5 | 8 | import pendulum as pdl
|
| 9 | +import rfc3339_validator |
6 | 10 | from aiokafka.admin import AIOKafkaAdminClient
|
7 | 11 | from aiokafka.admin import __version__ as aiokafka_version
|
8 | 12 | from aiokafka.client import AIOKafkaClient
|
| 13 | +from pendulum.datetime import DateTime as PendulumDateTime |
9 | 14 | from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession
|
10 | 15 |
|
11 | 16 | from deepchecks_monitoring.public_models import Organization, User, UserOAuthDTO
|
12 | 17 | from deepchecks_monitoring.schema_models.model_version import ModelVersion
|
13 | 18 |
|
14 |
| -__all__ = ['generate_random_user', 'generate_test_user', 'datetime_sample_formatter'] |
| 19 | +__all__ = ['generate_random_user', 'generate_test_user', 'datetime_sample_formatter', |
| 20 | + 'datetime_formatter', 'string_formatter', 'parse_timestamp'] |
15 | 21 |
|
16 | 22 |
|
17 | 23 | class ExtendedAIOKafkaAdminClient(AIOKafkaAdminClient): # pylint: disable=missing-class-docstring
|
@@ -108,3 +114,37 @@ def datetime_sample_formatter(sample: t.Dict, model_version: ModelVersion):
|
108 | 114 | continue
|
109 | 115 | if model_columns[col_name].get('format') == 'date-time':
|
110 | 116 | sample[col_name] = pdl.parse(val)
|
| 117 | + |
| 118 | + |
| 119 | +def datetime_formatter(datetime_obj): |
| 120 | + if datetime_obj is None: |
| 121 | + return None |
| 122 | + if isinstance(datetime_obj, pd.Period): |
| 123 | + datetime_obj = datetime_obj.to_timestamp() |
| 124 | + elif isinstance(datetime_obj, np.datetime64): |
| 125 | + datetime_obj = pd.Timestamp(datetime_obj.to_timestamp()) |
| 126 | + return parse_timestamp(datetime_obj).to_iso8601_string() |
| 127 | + |
| 128 | + |
| 129 | +def string_formatter(some_obj): |
| 130 | + if pd.isna(some_obj): |
| 131 | + return None |
| 132 | + return str(some_obj) |
| 133 | + |
| 134 | + |
| 135 | +def parse_timestamp(timestamp: t.Union[int, datetime, str]) -> 'PendulumDateTime': |
| 136 | + """Parse timestamp to datetime object.""" |
| 137 | + # If no timezone in datetime, assumed to be UTC and converted to local timezone |
| 138 | + if isinstance(timestamp, int) or np.issubdtype(type(timestamp), np.integer): |
| 139 | + return pdl.from_timestamp(timestamp, pdl.local_timezone()) |
| 140 | + elif isinstance(timestamp, PendulumDateTime): |
| 141 | + return timestamp |
| 142 | + elif isinstance(timestamp, datetime): |
| 143 | + return pdl.instance(timestamp, pdl.local_timezone()) |
| 144 | + elif isinstance(timestamp, str): |
| 145 | + if rfc3339_validator.validate_rfc3339(timestamp): |
| 146 | + return pdl.parse(timestamp) |
| 147 | + else: |
| 148 | + raise ValueError(f'Not supported timestamp format for: {timestamp}') |
| 149 | + else: |
| 150 | + raise ValueError(f'Not supported timestamp type: {type(timestamp)}') |
0 commit comments