module-typica 0.2.2__tar.gz → 0.2.3__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: module-typica
3
- Version: 0.2.2
3
+ Version: 0.2.3
4
4
  Summary: Standard Pydantic usages & utilities
5
5
  Author: Oktapian
6
6
  Author-email: oktapian@jkt1.ebdesk.com
@@ -12,15 +12,15 @@ Classifier: Programming Language :: Python :: 3.12
12
12
  Requires-Dist: deprecated (>=1.2.14,<2.0.0)
13
13
  Requires-Dist: pydantic (>=2.9.2,<3.0.0)
14
14
  Requires-Dist: pydantic-settings (>=2.6.1,<3.0.0)
15
- Requires-Dist: tomli (>=2.1.0,<3.0.0)
16
15
  Description-Content-Type: text/markdown
17
16
 
18
17
  # Description
19
- [![python: v^3.10](https://img.shields.io/badge/python-v^3.10-333A73.svg?logo=python&style=for-the-badge&logoColor=ffffff)](https://www.python.org/downloads/release/python-3100/)
20
- [![Pydantic: v^2.3.0](https://img.shields.io/badge/pydantic-v^2.3.0-e92063.svg?logo=pydantic&style=for-the-badge&logoColor=ffffff)](https://pydantic.dev)
21
-
22
18
  This is a standardized model library that uses the pydantic library, which is often used in work, especially in database connection, parameter, or response in service, and other utilities. This repository provides a standardized model that can be used in various scenarios. It aims to simplify the process of defining and validating models in Python applications.
23
19
 
20
+ ## Usages
21
+ there are several use cases that can be implemented using this library, such as some of the examples below
22
+
23
+
24
24
 
25
25
  ## Contributors
26
26
 
@@ -1,9 +1,10 @@
1
1
  # Description
2
- [![python: v^3.10](https://img.shields.io/badge/python-v^3.10-333A73.svg?logo=python&style=for-the-badge&logoColor=ffffff)](https://www.python.org/downloads/release/python-3100/)
3
- [![Pydantic: v^2.3.0](https://img.shields.io/badge/pydantic-v^2.3.0-e92063.svg?logo=pydantic&style=for-the-badge&logoColor=ffffff)](https://pydantic.dev)
4
-
5
2
  This is a standardized model library that uses the pydantic library, which is often used in work, especially in database connection, parameter, or response in service, and other utilities. This repository provides a standardized model that can be used in various scenarios. It aims to simplify the process of defining and validating models in Python applications.
6
3
 
4
+ ## Usages
5
+ there are several use cases that can be implemented using this library, such as some of the examples below
6
+
7
+
7
8
 
8
9
  ## Contributors
9
10
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "module-typica"
3
- version = "0.2.2"
3
+ version = "0.2.3"
4
4
  description = "Standard Pydantic usages & utilities"
5
5
  authors = ["Oktapian <oktapian@jkt1.ebdesk.com>"]
6
6
  readme = "Readme.md"
@@ -14,12 +14,28 @@ venv = ".venv"
14
14
  python = "^3.10"
15
15
  pydantic = "^2.9.2"
16
16
  pydantic-settings = "^2.6.1"
17
- tomli = "^2.1.0"
18
17
  deprecated = "^1.2.14"
19
18
 
20
19
  [tool.poetry.group.dev.dependencies]
21
20
  faker = "^25.3.0"
22
21
 
22
+
23
+ [tool.poetry.group.postgresql.dependencies]
24
+ psycopg2-binary = "^2.9.10"
25
+ sqlalchemy = "^2.0.36"
26
+
27
+
28
+ [tool.poetry.group.mongo.dependencies]
29
+ pymongo = "^4.10.1"
30
+
31
+
32
+ [tool.poetry.group.clickhouse.dependencies]
33
+ clickhouse-connect = "^0.8.7"
34
+
35
+
36
+ [tool.poetry.group.redis.dependencies]
37
+ redis = "^5.2.0"
38
+
23
39
  [build-system]
24
40
  requires = ["poetry-core"]
25
41
  build-backend = "poetry.core.masonry.api"
@@ -4,13 +4,11 @@ from typing import Optional
4
4
  from pydantic import BaseModel, Field, model_validator
5
5
 
6
6
 
7
-
8
7
  class EndpointMeta(BaseModel):
9
8
  host: Optional[str] = Field("localhost", description="Connection host")
10
9
  port: Optional[str | int] = Field(8000, description="Connection port")
11
10
 
12
11
 
13
-
14
12
  class AuthMeta(BaseModel):
15
13
  username: Optional[str] = Field(None, description="Database username")
16
14
  password: Optional[str] = Field(None, description="Database password")
@@ -23,7 +21,6 @@ class URIConnectionMeta(BaseModel):
23
21
  class DBConnectionMeta(EndpointMeta, AuthMeta, URIConnectionMeta):
24
22
  database: Optional[str] = Field(None, description="Database name")
25
23
 
26
-
27
24
  def uri_string(self, base: str = "http", with_db: bool = True) -> str:
28
25
  """
29
26
  Return a URI string for the database connection.
@@ -39,7 +36,6 @@ class DBConnectionMeta(EndpointMeta, AuthMeta, URIConnectionMeta):
39
36
  return f"{base}://{meta}/{self.database if with_db else ''}"
40
37
  return ""
41
38
 
42
-
43
39
  @model_validator(mode="after")
44
40
  def extract_uri(self):
45
41
  if self.uri:
@@ -63,8 +59,11 @@ class DBConnectionMeta(EndpointMeta, AuthMeta, URIConnectionMeta):
63
59
  self.port = int(self.port)
64
60
  return self
65
61
 
62
+
66
63
  class ClusterConnectionMeta(AuthMeta, URIConnectionMeta):
67
- cluster_uri: Optional[list[EndpointMeta]] = Field([], description="List of clusters endpoint")
64
+ cluster_uri: Optional[list[EndpointMeta]] = Field(
65
+ [], description="List of clusters endpoint"
66
+ )
68
67
  database: Optional[str] = Field(None, description="Database name")
69
68
 
70
69
  def uri_string(self, base: str = "http", with_db: bool = True) -> str:
@@ -81,7 +80,6 @@ class ClusterConnectionMeta(AuthMeta, URIConnectionMeta):
81
80
  return f"{base}://{self.username}:{self.password}@{meta}/{self.database if with_db else ''}"
82
81
  return f"{base}://{meta}/{self.database if with_db else ''}"
83
82
  return ""
84
-
85
83
 
86
84
  @model_validator(mode="after")
87
85
  def extract_uri(self):
@@ -103,7 +101,9 @@ class ClusterConnectionMeta(AuthMeta, URIConnectionMeta):
103
101
  cluster_uri = []
104
102
  for cluster in raw_clusters.split(","):
105
103
  hostData = re.split(r"\:", cluster)
106
- cluster_uri.append(EndpointMeta(host=hostData[0], port=int(hostData[1])))
104
+ cluster_uri.append(
105
+ EndpointMeta(host=hostData[0], port=int(hostData[1]))
106
+ )
107
107
  self.cluster_uri = cluster_uri
108
108
  else:
109
109
  self.username, self.password, self.host, self.port = re.split(
@@ -122,7 +122,6 @@ class S3ConnectionMeta(EndpointMeta):
122
122
  bucket: str = Field(..., description="S3 bucket name")
123
123
  base_path: Optional[str] = Field("/", description="S3 base path")
124
124
 
125
-
126
125
  @property
127
126
  def json_meta(self) -> dict:
128
127
  """
@@ -134,4 +133,8 @@ class S3ConnectionMeta(EndpointMeta):
134
133
  "endpoint_url": f"http://{self.host}:{self.port}",
135
134
  "key": self.access_key,
136
135
  "secret": self.secret_key,
137
- }
136
+ }
137
+
138
+
139
+ class RedisConnectionMeta(EndpointMeta, AuthMeta):
140
+ database: int = Field(..., description="Database name")
@@ -1,4 +1,3 @@
1
-
2
1
  from typing import Optional
3
2
 
4
3
  from pydantic import BaseModel, Field
@@ -16,6 +15,17 @@ class SchemaMeta(BaseModel):
16
15
  field_hide: Optional[bool] = Field(False, description="Hide field")
17
16
 
18
17
 
18
+ class SchemaRawMeta(SchemaMeta):
19
+ regional_field: Optional[str] = Field(None, description="Regional field")
20
+ none_percentage: Optional[float] = Field(
21
+ 0.0, description="Percentage of null / none values"
22
+ )
23
+ unique_value: Optional[list[str]] = Field(
24
+ None, description="Unique values in field"
25
+ )
26
+ describe_field: Optional[str] = Field(None, description="Describe field")
27
+
28
+
19
29
  class SimplifieMetadata(BaseModel):
20
30
  id: str = Field(..., description="Identifier for the metadata")
21
31
 
@@ -32,7 +42,9 @@ class SimplifieMetadata(BaseModel):
32
42
  sub_category: Optional[str] = Field(None)
33
43
 
34
44
  # ? Schemas
35
- schemas: list[SchemaMeta] = Field(..., description="Description of all fields in data")
45
+ schemas: list[SchemaMeta] = Field(
46
+ ..., description="Description of all fields in data"
47
+ )
36
48
 
37
49
  # ? Database
38
50
  database_access: DBConnectionMeta | ClusterConnectionMeta
@@ -65,10 +77,9 @@ class FullMetadata(SimplifieMetadata):
65
77
 
66
78
  # ? Data lake
67
79
  # * Use case: bronze
68
- lake_access: Optional[S3ConnectionMeta | DBConnectionMeta | ClusterConnectionMeta] = Field(
69
- None, description="Data lake access"
70
- )
80
+ lake_access: Optional[
81
+ S3ConnectionMeta | DBConnectionMeta | ClusterConnectionMeta
82
+ ] = Field(None, description="Data lake access")
71
83
  lake_meta_path: Optional[str] = Field(None, description="Data lake metadata path")
72
84
  lake_data_path: Optional[str] = Field(None, description="Data lake data path")
73
85
  lake_data_format: Optional[str] = Field(None, description="Data lake data format")
74
-
@@ -0,0 +1,67 @@
1
+ from clickhouse_connect import get_client
2
+ from clickhouse_connect.driver.client import Client
3
+
4
+ from typica.connection import DBConnectionMeta
5
+
6
+
7
+ class CHConnector:
8
+
9
+ _meta: DBConnectionMeta
10
+ _client: Client
11
+
12
+ def __init__(self, meta: DBConnectionMeta) -> None:
13
+ """
14
+ Initialize the ClickHouse connector with the given connection metadata.
15
+
16
+ :param meta: The metadata of the database connection.
17
+ :type meta: DBConnectionMeta
18
+ """
19
+ self._meta = meta
20
+
21
+ def __enter__(self) -> "CHConnector":
22
+ """
23
+ Connect to the ClickHouse server and return the connection object.
24
+
25
+ :return: The connection object.
26
+ :rtype: CHConnector
27
+ :raises ValueError: If the connection to the ClickHouse server fails.
28
+ """
29
+ self.connect()
30
+ return self
31
+
32
+ def __exit__(self, exc_type, exc_val, exc_tb) -> None:
33
+ """
34
+ Close the connection to the ClickHouse server.
35
+
36
+ This method is called when the context manager exits its scope.
37
+ """
38
+ self.close()
39
+
40
+ def connect(self) -> None:
41
+ """
42
+ Establish a connection to the ClickHouse server.
43
+
44
+ :raises ValueError: If the connection to the ClickHouse server fails.
45
+ :raises Exception: If any other error occurs during the connection.
46
+ """
47
+ try:
48
+ self._client = get_client(
49
+ host=str(self._meta.host),
50
+ port=int(self._meta.port), # type: ignore
51
+ user=self._meta.username,
52
+ password=self._meta.password
53
+ or "", # cause get_client doesn't support empty password
54
+ database=str(self._meta.database),
55
+ )
56
+
57
+ except Exception as e:
58
+ raise e
59
+
60
+ def close(self) -> None:
61
+ """
62
+ Close the connection to the ClickHouse server.
63
+
64
+ This method is a no-op if the connection is already closed.
65
+ """
66
+ if self._client:
67
+ self._client.close()
@@ -0,0 +1,70 @@
1
+ from pymongo import MongoClient
2
+ from pymongo.database import Database
3
+ from pymongo.errors import NetworkTimeout, ExecutionTimeout
4
+
5
+ from typica.connection import DBConnectionMeta
6
+
7
+
8
+ class MongoConnector:
9
+
10
+ _meta: DBConnectionMeta
11
+ _client: MongoClient
12
+ _db: Database
13
+
14
+ def __init__(self, meta: DBConnectionMeta) -> None:
15
+ """
16
+ Initialize the Mongo connector with the given connection metadata.
17
+
18
+ :param meta: The metadata of the database connection.
19
+ :type meta: DBConnectionMeta
20
+ """
21
+ self._meta = meta
22
+ if not self._meta.uri:
23
+ self._meta.uri = self._meta.uri_string(base="mongodb", with_db=False)
24
+
25
+ def __enter__(self):
26
+ """
27
+ Connect to the MongoDB server and return the connection object.
28
+
29
+ :return: The connection object.
30
+ :rtype: MongoConnector
31
+ :raises ValueError: If the connection to the MongoDB server fails.
32
+ """
33
+ self.connect()
34
+ if self._client is None:
35
+ raise ValueError("Mongo not connected.")
36
+ return self
37
+
38
+ def __exit__(self, exc_type, exc_val, exc_tb) -> None:
39
+ """
40
+ Close the connection to the MongoDB server.
41
+
42
+ This method is called when the context manager exits its scope.
43
+ """
44
+ self.close()
45
+
46
+ def connect(self, **kwargs) -> None:
47
+ """
48
+ Establish a connection to the MongoDB server.
49
+
50
+ :param kwargs: Additional keyword arguments for MongoClient.
51
+ :raises ValueError: If the connection to the MongoDB server fails.
52
+ :raises Exception: If any other error occurs during the connection.
53
+ """
54
+
55
+ try:
56
+ self._client = MongoClient(self._meta.uri, **kwargs)
57
+ self._db = self._client[str(self._meta.database)]
58
+ except (NetworkTimeout, ExecutionTimeout):
59
+ raise ValueError("Mongo connection timed out.")
60
+ except Exception as e:
61
+ raise e
62
+
63
+ def close(self) -> None:
64
+ """
65
+ Close the connection to the MongoDB server.
66
+
67
+ This method is a no-op if the connection is already closed.
68
+ """
69
+ if self._client:
70
+ self._client.close()
@@ -0,0 +1,76 @@
1
+ import psycopg2
2
+
3
+ from psycopg2.extensions import connection, cursor
4
+ from psycopg2.errors import (
5
+ IdleSessionTimeout,
6
+ IdleInTransactionSessionTimeout,
7
+ ConnectionFailure,
8
+ )
9
+
10
+ from typica.connection import DBConnectionMeta
11
+
12
+
13
+ class PostgreConnector:
14
+
15
+ _meta: DBConnectionMeta
16
+ _conn: connection
17
+ _cursor: cursor
18
+
19
+ def __init__(self, meta: DBConnectionMeta) -> None:
20
+ """
21
+ Initialize the Postgre connector with the given connection metadata.
22
+
23
+ :param meta: The metadata of the database connection.
24
+ :type meta: DBConnectionMeta
25
+ """
26
+ self._meta = meta
27
+
28
+ def __enter__(self) -> "PostgreConnector":
29
+ """
30
+ Connect to the PostgreSQL server and return the connection object.
31
+
32
+ :return: The connection object.
33
+ :rtype: PostgreConnector
34
+ :raises ValueError: If the connection to the PostgreSQL server fails.
35
+ """
36
+ self.connect()
37
+ return self
38
+
39
+ def __exit__(self, exc_type, exc_value, exc_traceback) -> None:
40
+ self.close()
41
+
42
+ def connect(self, **kwargs) -> None:
43
+ """
44
+ Establish a connection to the PostgreSQL server.
45
+
46
+ :param kwargs: Additional keyword arguments for psycopg2.connect.
47
+ :raises ValueError: If the connection to the PostgreSQL server fails.
48
+ :raises Exception: If any other error occurs during the connection.
49
+ """
50
+ try:
51
+ self._conn = psycopg2.connect(
52
+ dbname=self._meta.database,
53
+ user=self._meta.username,
54
+ password=self._meta.password,
55
+ host=self._meta.host,
56
+ port=self._meta.port,
57
+ **kwargs
58
+ )
59
+ self._cursor = self._conn.cursor()
60
+ except ConnectionFailure:
61
+ raise ValueError("PostgreSQL connection failed.")
62
+ except (IdleInTransactionSessionTimeout, IdleSessionTimeout):
63
+ raise ValueError("Session timed out.")
64
+ except Exception as e:
65
+ raise e
66
+
67
+ def close(self) -> None:
68
+ """
69
+ Close the connection to the PostgreSQL server.
70
+
71
+ This method is a no-op if the connection is already closed.
72
+ """
73
+ if self._cursor:
74
+ self._cursor.close()
75
+ if self._conn:
76
+ self._conn.close()
@@ -0,0 +1,83 @@
1
+ from sqlalchemy import Engine, URL, Connection, create_engine, text, CursorResult
2
+ from sqlalchemy.exc import TimeoutError
3
+
4
+ from typica.connection import DBConnectionMeta
5
+
6
+
7
+ class PostgreConnector:
8
+
9
+ _meta: DBConnectionMeta
10
+ _engine: Engine
11
+ _conn: Connection
12
+
13
+ def __init__(self, meta: DBConnectionMeta) -> None:
14
+ """
15
+ Initialize the Postgre connector with the given connection metadata.
16
+
17
+ :param meta: The metadata of the database connection.
18
+ :type meta: DBConnectionMeta
19
+ """
20
+ self._meta = meta
21
+
22
+ def __enter__(self) -> Connection:
23
+ """
24
+ Connect to the PostgreSQL server and return the connection object.
25
+
26
+ :return: The connection object.
27
+ :rtype: Connection
28
+ :raises ValueError: If the connection to the PostgreSQL server fails.
29
+ """
30
+ self.connect()
31
+ return self._conn
32
+
33
+ def __exit__(self, exc_type, exc_value, exc_traceback) -> None:
34
+ """
35
+ Close the connection to the PostgreSQL server.
36
+
37
+ This method is called when the context manager exits its scope.
38
+ """
39
+ self.close()
40
+
41
+ def execute_text(self, sql: str) -> CursorResult:
42
+ try:
43
+ res = self._conn.execute(text(sql))
44
+ return res
45
+ except Exception as e:
46
+ raise e
47
+
48
+ def connect(self) -> Connection:
49
+ """
50
+ Establish a connection to the PostgreSQL server.
51
+
52
+ :return: The connection object.
53
+ :rtype: Connection
54
+ :raises ValueError: If the connection to the PostgreSQL server fails.
55
+ :raises Exception: If any other error occurs during the connection.
56
+ """
57
+ try:
58
+ self._engine = create_engine(
59
+ URL.create(
60
+ drivername="postgresql",
61
+ username=self._meta.username,
62
+ password=self._meta.password,
63
+ host=self._meta.host,
64
+ port=int(self._meta.port), # type: ignore
65
+ database=self._meta.database,
66
+ )
67
+ )
68
+ self._conn = self._engine.connect()
69
+
70
+ return self._conn
71
+ except TimeoutError:
72
+ raise ValueError("PostgreSQL connection timed out.")
73
+ except Exception as e:
74
+ raise e
75
+
76
+ def close(self) -> None:
77
+ """
78
+ Close the connection to the PostgreSQL server.
79
+
80
+ This method is a no-op if the connection is already closed.
81
+ """
82
+ if self._conn:
83
+ self._conn.close()
@@ -0,0 +1,165 @@
1
+ from redis import Redis
2
+ from redis.asyncio import Redis as AsyncRedis
3
+ from redis.exceptions import TimeoutError
4
+
5
+ from typica.connection import RedisConnectionMeta
6
+
7
+
8
+ class RedisConnector:
9
+
10
+ _meta: RedisConnectionMeta
11
+ _client: Redis
12
+
13
+ def __init__(self, meta: RedisConnectionMeta) -> None:
14
+ """
15
+ Initialize the Redis connector with the given connection metadata.
16
+
17
+ :param meta: The metadata of the database connection.
18
+ :type meta: RedisConnectionMeta
19
+ """
20
+ self._meta = meta
21
+
22
+ def __enter__(self):
23
+ """
24
+ Connect to the Redis server and return the connection object.
25
+
26
+ :return: The connection object.
27
+ :rtype: RedisConnector
28
+ :raises ValueError: If the connection to the Redis server fails.
29
+ """
30
+ self.connect()
31
+ if self._client is None:
32
+ raise ValueError("Redis not connected.")
33
+ return self
34
+
35
+ def __call__(self, *args, **kwds) -> bool:
36
+ """
37
+ Check if the connection is already established.
38
+
39
+ :return: True if the connection is available, False otherwise.
40
+ :rtype: bool
41
+ """
42
+
43
+ if self._client is None:
44
+ raise ValueError("Redis not connected.")
45
+ return True
46
+
47
+ def __exit__(self, exc_type, exc_val, exc_tb) -> None:
48
+ """
49
+ Close the connection to the Redis server.
50
+
51
+ This method is called when the context manager exits its scope.
52
+ """
53
+ self.close()
54
+
55
+ def connect(self, other_database: int | None = None) -> None:
56
+ """
57
+ Establish a connection to the Redis server.
58
+
59
+ :param other_database: The ID of an alternative database to connect to.
60
+ If not provided, the default database ID will be used.
61
+ :type other_database: int | None
62
+ :raises ValueError: If the connection to the Redis server fails.
63
+ """
64
+ try:
65
+
66
+ self._client = Redis(
67
+ host=str(self._meta.host),
68
+ port=int(self._meta.port), # type: ignore
69
+ username=self._meta.username,
70
+ password=self._meta.password,
71
+ db=other_database if other_database else self._meta.database,
72
+ )
73
+
74
+ except TimeoutError:
75
+ raise ValueError("Redis connection timed out.")
76
+ except Exception as e:
77
+ raise e
78
+
79
+ def close(self) -> None:
80
+ """
81
+ Close the connection to the Redis server.
82
+
83
+ This method is a no-op if the connection is already closed.
84
+ """
85
+ if self._client:
86
+ self._client.close()
87
+
88
+
89
+ class AsyncRedisConnector:
90
+
91
+ _meta: RedisConnectionMeta
92
+ _client: AsyncRedis
93
+
94
+ def __init__(self, meta: RedisConnectionMeta) -> None:
95
+ """
96
+ Initialize the Redis connector with the given connection metadata.
97
+
98
+ :param meta: The metadata of the database connection.
99
+ :type meta: RedisConnectionMeta
100
+ """
101
+ self._meta = meta
102
+
103
+ async def __enter__(self):
104
+ """
105
+ Connect to the Redis server and return the connection object.
106
+
107
+ :return: The connection object.
108
+ :rtype: RedisConnector
109
+ :raises ValueError: If the connection to the Redis server fails.
110
+ """
111
+ await self.connect()
112
+ if self._client is None:
113
+ raise ValueError("Redis not connected.")
114
+ return self
115
+
116
+ async def __call__(self, *args, **kwds) -> bool:
117
+ """
118
+ Check if the connection is already established.
119
+
120
+ :return: True if the connection is available, False otherwise.
121
+ :rtype: bool
122
+ """
123
+
124
+ if self._client is None:
125
+ raise ValueError("Redis not connected.")
126
+ return True
127
+
128
+ async def __exit__(self, exc_type, exc_val, exc_tb) -> None:
129
+ """
130
+ Close the connection to the Redis server.
131
+
132
+ This method is called when the context manager exits its scope.
133
+ """
134
+ await self.close()
135
+
136
+ async def connect(self, other_database: int | None = None) -> None:
137
+ """
138
+ Establish a connection to the Redis server.
139
+
140
+ :param other_database: The alternative database name to connect to.
141
+ :raises ValueError: If the connection to the Redis server fails.
142
+ :raises Exception: If any other error occurs during the connection.
143
+ """
144
+ try:
145
+
146
+ self._client = AsyncRedis(
147
+ host=str(self._meta.host),
148
+ port=int(self._meta.port), # type: ignore
149
+ username=self._meta.username,
150
+ password=self._meta.password,
151
+ db=other_database if other_database else self._meta.database,
152
+ )
153
+ except TimeoutError:
154
+ raise ValueError("Redis connection timed out.")
155
+ except Exception as e:
156
+ raise e
157
+
158
+ async def close(self) -> None:
159
+ """
160
+ Close the connection to the Redis server.
161
+
162
+ This method is a no-op if the connection is already closed.
163
+ """
164
+ if self._client:
165
+ await self._client.close()
@@ -42,6 +42,7 @@ class EnumV2(Enum):
42
42
  """
43
43
  return self._description_
44
44
 
45
+
45
46
  class Operator(EnumV2):
46
47
  equal = ("eq", "value is equals to")
47
48
  unequal = ("ne", "value isn't equals to")
@@ -61,9 +62,9 @@ class FilterOption(EnumV2):
61
62
  mustnt = ("mustnt", "List of filter mustn't exact")
62
63
  should = ("should", "List of filter should exact")
63
64
  shouldnt = ("shouldnt", "List of filter shouldn't exact")
64
-
65
65
 
66
- class LocationLevel(str, EnumV2):
66
+
67
+ class LocationLevel(EnumV2):
67
68
  CONTINENT = ("continent", "Continent level data")
68
69
  COUNTRY = ("country", "Country level data")
69
70
  PROVINCE = ("province", "Province level data")
@@ -72,9 +73,9 @@ class LocationLevel(str, EnumV2):
72
73
  SUBDISTRICT = ("subdistrict", "Subdistrict level data")
73
74
 
74
75
 
75
- class MedallionTypes(str, EnumV2):
76
- LAKE = ("lake", 'Lake data')
77
- BRONZE = ("bronze", 'bronze level Medallion')
78
- SILVER = ("silver", 'silver level Medallion')
79
- GOLD = ("gold", 'gold level Medallion')
80
- OTHER = ("other", 'other than any level Medallion')
76
+ class MedallionTypes(EnumV2):
77
+ LAKE = ("lake", "Lake data")
78
+ BRONZE = ("bronze", "bronze level Medallion")
79
+ SILVER = ("silver", "silver level Medallion")
80
+ GOLD = ("gold", "gold level Medallion")
81
+ OTHER = ("other", "other than any level Medallion")