nvidia-nat-mysql 1.3.0.dev2__py3-none-any.whl → 1.3.0rc2__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.
@@ -14,6 +14,7 @@
14
14
  # limitations under the License.
15
15
 
16
16
  import logging
17
+ import re
17
18
 
18
19
  import aiomysql
19
20
  from aiomysql.pool import Pool
@@ -22,7 +23,6 @@ from nat.data_models.object_store import KeyAlreadyExistsError
22
23
  from nat.data_models.object_store import NoSuchKeyError
23
24
  from nat.object_store.interfaces import ObjectStore
24
25
  from nat.object_store.models import ObjectStoreItem
25
- from nat.plugins.mysql.object_store import MySQLObjectStoreClientConfig
26
26
  from nat.utils.type_utils import override
27
27
 
28
28
  logger = logging.getLogger(__name__)
@@ -33,70 +33,78 @@ class MySQLObjectStore(ObjectStore):
33
33
  Implementation of ObjectStore that stores objects in a MySQL database.
34
34
  """
35
35
 
36
- def __init__(self, config: MySQLObjectStoreClientConfig):
37
-
36
+ def __init__(self, *, bucket_name: str, host: str, port: int, username: str | None, password: str | None):
38
37
  super().__init__()
39
38
 
40
- self._config = config
39
+ if not re.fullmatch(r"[A-Za-z0-9_-]+", bucket_name):
40
+ raise ValueError("bucket_name must match [A-Za-z0-9_-]+")
41
+
42
+ self._bucket_name = bucket_name
43
+ self._host = host
44
+ self._port = port
45
+ self._username = username
46
+ self._password = password
47
+
41
48
  self._conn_pool: Pool | None = None
42
49
 
43
- self._schema = f"`bucket_{self._config.bucket_name}`"
50
+ @property
51
+ def _schema(self) -> str:
52
+ return f"`bucket_{self._bucket_name}`"
44
53
 
45
- async def __aenter__(self):
54
+ async def __aenter__(self) -> "MySQLObjectStore":
46
55
 
47
56
  if self._conn_pool is not None:
48
57
  raise RuntimeError("Connection already established")
49
58
 
50
59
  self._conn_pool = await aiomysql.create_pool(
51
- host=self._config.host,
52
- port=self._config.port,
53
- user=self._config.username,
54
- password=self._config.password,
60
+ host=self._host,
61
+ port=self._port,
62
+ user=self._username,
63
+ password=self._password,
55
64
  autocommit=False, # disable autocommit for transactions
56
65
  )
57
66
  assert self._conn_pool is not None
58
67
 
59
- logger.info("Created connection pool for %s at %s:%s",
60
- self._config.bucket_name,
61
- self._config.host,
62
- self._config.port)
68
+ logger.info("Created connection pool for %s at %s:%s", self._bucket_name, self._host, self._port)
63
69
 
64
70
  async with self._conn_pool.acquire() as conn:
65
71
  async with conn.cursor() as cur:
66
72
 
67
- # Create schema (database) if doesn't exist
68
- await cur.execute(f"CREATE SCHEMA IF NOT EXISTS {self._schema} DEFAULT CHARACTER SET utf8mb4;")
69
- await cur.execute(f"USE {self._schema};")
73
+ # Suppress MySQL "IF NOT EXISTS" notes that surface as warnings in the driver
74
+ await cur.execute("SET sql_notes = 0;")
75
+ try:
76
+ # Create schema (database) if doesn't exist
77
+ await cur.execute(f"CREATE SCHEMA IF NOT EXISTS {self._schema} DEFAULT CHARACTER SET utf8mb4;")
78
+ await cur.execute(f"USE {self._schema};")
70
79
 
71
- # Create metadata table_schema
72
- await cur.execute("""
73
- CREATE TABLE IF NOT EXISTS object_meta (
74
- id INT AUTO_INCREMENT PRIMARY KEY,
75
- path VARCHAR(768) NOT NULL UNIQUE,
76
- size BIGINT NOT NULL,
77
- created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
78
- ) ENGINE=InnoDB;
79
- """)
80
-
81
- # Create blob data table
82
- await cur.execute("""
83
- CREATE TABLE IF NOT EXISTS object_data (
84
- id INT PRIMARY KEY,
85
- data LONGBLOB NOT NULL,
86
- FOREIGN KEY (id) REFERENCES object_meta(id) ON DELETE CASCADE
87
- ) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
88
- """)
80
+ # Create metadata table_schema
81
+ await cur.execute("""
82
+ CREATE TABLE IF NOT EXISTS object_meta (
83
+ id INT AUTO_INCREMENT PRIMARY KEY,
84
+ path VARCHAR(768) NOT NULL UNIQUE,
85
+ size BIGINT NOT NULL,
86
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
87
+ ) ENGINE=InnoDB;
88
+ """)
89
+
90
+ # Create blob data table
91
+ await cur.execute("""
92
+ CREATE TABLE IF NOT EXISTS object_data (
93
+ id INT PRIMARY KEY,
94
+ data LONGBLOB NOT NULL,
95
+ FOREIGN KEY (id) REFERENCES object_meta(id) ON DELETE CASCADE
96
+ ) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
97
+ """)
98
+ finally:
99
+ await cur.execute("SET sql_notes = 1;")
89
100
 
90
101
  await conn.commit()
91
102
 
92
- logger.info("Created schema and tables for %s at %s:%s",
93
- self._config.bucket_name,
94
- self._config.host,
95
- self._config.port)
103
+ logger.info("Created schema and tables for %s at %s:%s", self._bucket_name, self._host, self._port)
96
104
 
97
105
  return self
98
106
 
99
- async def __aexit__(self, exc_type, exc_value, traceback):
107
+ async def __aexit__(self, exc_type, exc_value, traceback) -> None:
100
108
 
101
109
  if not self._conn_pool:
102
110
  raise RuntimeError("Connection not established")
@@ -123,7 +131,7 @@ class MySQLObjectStore(ObjectStore):
123
131
  (key, len(item.data)))
124
132
  if cur.rowcount == 0:
125
133
  raise KeyAlreadyExistsError(
126
- key=key, additional_message=f"MySQL table {self._config.bucket_name} already has key {key}")
134
+ key=key, additional_message=f"MySQL table {self._bucket_name} already has key {key}")
127
135
  await cur.execute("SELECT id FROM object_meta WHERE path=%s FOR UPDATE;", (key, ))
128
136
  (obj_id, ) = await cur.fetchone()
129
137
  blob = item.model_dump_json()
@@ -147,8 +155,8 @@ class MySQLObjectStore(ObjectStore):
147
155
  await cur.execute(
148
156
  """
149
157
  INSERT INTO object_meta (path, size)
150
- VALUES (%s, %s)
151
- ON DUPLICATE KEY UPDATE size=VALUES(size), created_at=CURRENT_TIMESTAMP
158
+ VALUES (%s, %s) AS new
159
+ ON DUPLICATE KEY UPDATE size=new.size, created_at=CURRENT_TIMESTAMP
152
160
  """, (key, len(item.data)))
153
161
  await cur.execute("SELECT id FROM object_meta WHERE path=%s FOR UPDATE;", (key, ))
154
162
  (obj_id, ) = await cur.fetchone()
@@ -178,8 +186,8 @@ class MySQLObjectStore(ObjectStore):
178
186
  """, (key, ))
179
187
  row = await cur.fetchone()
180
188
  if not row:
181
- raise NoSuchKeyError(
182
- key=key, additional_message=f"MySQL table {self._config.bucket_name} does not have key {key}")
189
+ raise NoSuchKeyError(key=key,
190
+ additional_message=f"MySQL table {self._bucket_name} does not have key {key}")
183
191
  return ObjectStoreItem.model_validate_json(row[0].decode("utf-8"))
184
192
 
185
193
  @override
@@ -202,8 +210,7 @@ class MySQLObjectStore(ObjectStore):
202
210
 
203
211
  if cur.rowcount == 0:
204
212
  raise NoSuchKeyError(
205
- key=key,
206
- additional_message=f"MySQL table {self._config.bucket_name} does not have key {key}")
213
+ key=key, additional_message=f"MySQL table {self._bucket_name} does not have key {key}")
207
214
 
208
215
  await conn.commit()
209
216
  except Exception:
@@ -58,9 +58,9 @@ class MySQLObjectStoreClientConfig(ObjectStoreBaseConfig, name="mysql"):
58
58
 
59
59
 
60
60
  @register_object_store(config_type=MySQLObjectStoreClientConfig)
61
- async def mysql_object_store_client(config: MySQLObjectStoreClientConfig, builder: Builder):
61
+ async def mysql_object_store_client(config: MySQLObjectStoreClientConfig, _builder: Builder):
62
62
 
63
63
  from .mysql_object_store import MySQLObjectStore
64
64
 
65
- async with MySQLObjectStore(config) as store:
65
+ async with MySQLObjectStore(**config.model_dump(exclude={"type"}, exclude_none=True)) as store:
66
66
  yield store
@@ -13,7 +13,6 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- # pylint: disable=unused-import
17
16
  # flake8: noqa
18
17
  # isort:skip_file
19
18
 
@@ -1,10 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nvidia-nat-mysql
3
- Version: 1.3.0.dev2
3
+ Version: 1.3.0rc2
4
4
  Summary: Subpackage for MySQL integration in NeMo Agent toolkit
5
5
  Keywords: ai,agents,memory,data store
6
6
  Classifier: Programming Language :: Python
7
- Requires-Python: <3.13,>=3.11
7
+ Classifier: Programming Language :: Python :: 3.11
8
+ Classifier: Programming Language :: Python :: 3.12
9
+ Classifier: Programming Language :: Python :: 3.13
10
+ Requires-Python: <3.14,>=3.11
8
11
  Description-Content-Type: text/markdown
9
- Requires-Dist: nvidia-nat==v1.3.0-dev2
12
+ Requires-Dist: nvidia-nat==v1.3.0-rc2
10
13
  Requires-Dist: aiomysql>=0.2.0
@@ -0,0 +1,9 @@
1
+ nat/plugins/mysql/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ nat/plugins/mysql/mysql_object_store.py,sha256=OhOOCXMBcEBITfTt1mqpCAcDUgwIc0_HzkcTKO1Kezc,8602
3
+ nat/plugins/mysql/object_store.py,sha256=iEkWrlooEXqAfJYdg39cKe9EMCvQJ6CqCeeoL_cmOrw,2651
4
+ nat/plugins/mysql/register.py,sha256=iBGq69m0rbZ3BTisA4Lt5UCHtW0Pc7m-l8G8dz-_pBc,813
5
+ nvidia_nat_mysql-1.3.0rc2.dist-info/METADATA,sha256=pYaKtbES40ar2DyKQ2jhJuvCRRLqKqtJ2J9zRuFSStI,500
6
+ nvidia_nat_mysql-1.3.0rc2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
7
+ nvidia_nat_mysql-1.3.0rc2.dist-info/entry_points.txt,sha256=ZI7ielmDX-k_OPXGvpRB5tKFVR5kMCHmHGwLWqxRKh0,56
8
+ nvidia_nat_mysql-1.3.0rc2.dist-info/top_level.txt,sha256=8-CJ2cP6-f0ZReXe5Hzqp-5pvzzHz-5Ds5H2bGqh1-U,4
9
+ nvidia_nat_mysql-1.3.0rc2.dist-info/RECORD,,
@@ -1,9 +0,0 @@
1
- nat/plugins/mysql/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- nat/plugins/mysql/mysql_object_store.py,sha256=wgsX797j21gw9ZFt9ZCrRHRT5GDrqPHywwFmc1HxdD4,8178
3
- nat/plugins/mysql/object_store.py,sha256=IWMJFKBhn0lH7UGHuYkYht82TwIe5KXS7VUhQrlNRyI,2600
4
- nat/plugins/mysql/register.py,sha256=7gqnwyDrYttIlEaa7lo9AASYt-2GrZJE0YT2jpKjepo,845
5
- nvidia_nat_mysql-1.3.0.dev2.dist-info/METADATA,sha256=0nDmPlYVNyo6YJtSCIC8ADmgiENEe8k7uXdLH1-ZuMM,350
6
- nvidia_nat_mysql-1.3.0.dev2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
7
- nvidia_nat_mysql-1.3.0.dev2.dist-info/entry_points.txt,sha256=ZI7ielmDX-k_OPXGvpRB5tKFVR5kMCHmHGwLWqxRKh0,56
8
- nvidia_nat_mysql-1.3.0.dev2.dist-info/top_level.txt,sha256=8-CJ2cP6-f0ZReXe5Hzqp-5pvzzHz-5Ds5H2bGqh1-U,4
9
- nvidia_nat_mysql-1.3.0.dev2.dist-info/RECORD,,