fleet-python 0.2.98__py3-none-any.whl → 0.2.99__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.
fleet/__init__.py CHANGED
@@ -73,7 +73,7 @@ from . import env
73
73
  from . import global_client as _global_client
74
74
  from ._async import global_client as _async_global_client
75
75
 
76
- __version__ = "0.2.98"
76
+ __version__ = "0.2.99"
77
77
 
78
78
  __all__ = [
79
79
  # Core classes
fleet/_async/__init__.py CHANGED
@@ -44,7 +44,7 @@ from ..types import VerifierFunction
44
44
  from .. import env
45
45
  from . import global_client as _async_global_client
46
46
 
47
- __version__ = "0.2.98"
47
+ __version__ = "0.2.99"
48
48
 
49
49
  __all__ = [
50
50
  # Core classes
fleet/_async/base.py CHANGED
@@ -26,7 +26,7 @@ from .exceptions import (
26
26
  try:
27
27
  from .. import __version__
28
28
  except ImportError:
29
- __version__ = "0.2.98"
29
+ __version__ = "0.2.99"
30
30
 
31
31
  logger = logging.getLogger(__name__)
32
32
 
@@ -7,6 +7,7 @@ import tempfile
7
7
  import sqlite3
8
8
  import os
9
9
  import asyncio
10
+ import re
10
11
 
11
12
  from typing import TYPE_CHECKING
12
13
 
@@ -23,6 +24,17 @@ from fleet.verifiers.db import (
23
24
  )
24
25
 
25
26
 
27
+ def _quote_identifier(identifier: str) -> str:
28
+ """Quote an identifier (table or column name) for SQLite.
29
+
30
+ SQLite uses double quotes for identifiers and escapes internal quotes by doubling them.
31
+ This handles reserved keywords like 'order', 'table', etc.
32
+ """
33
+ # Escape any double quotes in the identifier by doubling them
34
+ escaped = identifier.replace('"', '""')
35
+ return f'"{escaped}"'
36
+
37
+
26
38
  class AsyncDatabaseSnapshot:
27
39
  """Lazy database snapshot that fetches data on-demand through API."""
28
40
 
@@ -57,12 +69,12 @@ class AsyncDatabaseSnapshot:
57
69
  return
58
70
 
59
71
  # Get table schema
60
- schema_response = await self.resource.query(f"PRAGMA table_info({table})")
72
+ schema_response = await self.resource.query(f"PRAGMA table_info({_quote_identifier(table)})")
61
73
  if schema_response.rows:
62
74
  self._schemas[table] = [row[1] for row in schema_response.rows] # Column names
63
75
 
64
76
  # Get all data for this table
65
- data_response = await self.resource.query(f"SELECT * FROM {table}")
77
+ data_response = await self.resource.query(f"SELECT * FROM {_quote_identifier(table)}")
66
78
  if data_response.rows and data_response.columns:
67
79
  self._data[table] = [
68
80
  dict(zip(data_response.columns, row)) for row in data_response.rows
@@ -123,23 +135,23 @@ class AsyncSnapshotQueryBuilder:
123
135
  where_parts = []
124
136
  for col, op, val in self._conditions:
125
137
  if op == "=" and val is None:
126
- where_parts.append(f"{col} IS NULL")
138
+ where_parts.append(f"{_quote_identifier(col)} IS NULL")
127
139
  elif op == "IS":
128
- where_parts.append(f"{col} IS NULL")
140
+ where_parts.append(f"{_quote_identifier(col)} IS NULL")
129
141
  elif op == "IS NOT":
130
- where_parts.append(f"{col} IS NOT NULL")
142
+ where_parts.append(f"{_quote_identifier(col)} IS NOT NULL")
131
143
  elif op == "=":
132
144
  if isinstance(val, str):
133
145
  escaped_val = val.replace("'", "''")
134
- where_parts.append(f"{col} = '{escaped_val}'")
146
+ where_parts.append(f"{_quote_identifier(col)} = '{escaped_val}'")
135
147
  else:
136
- where_parts.append(f"{col} = '{val}'")
148
+ where_parts.append(f"{_quote_identifier(col)} = '{val}'")
137
149
 
138
150
  where_clause = " AND ".join(where_parts)
139
151
 
140
152
  # Build full query
141
153
  cols = ", ".join(self._select_cols)
142
- query = f"SELECT {cols} FROM {self._table} WHERE {where_clause}"
154
+ query = f"SELECT {cols} FROM {_quote_identifier(self._table)} WHERE {where_clause}"
143
155
 
144
156
  if self._order_by:
145
157
  query += f" ORDER BY {self._order_by}"
@@ -271,7 +283,7 @@ class AsyncSnapshotDiff:
271
283
  async def _get_primary_key_columns(self, table: str) -> List[str]:
272
284
  """Get primary key columns for a table."""
273
285
  # Try to get from schema
274
- schema_response = await self.after.resource.query(f"PRAGMA table_info({table})")
286
+ schema_response = await self.after.resource.query(f"PRAGMA table_info({_quote_identifier(table)})")
275
287
  if not schema_response.rows:
276
288
  return ["id"] # Default fallback
277
289
 
@@ -414,18 +426,18 @@ class AsyncSnapshotDiff:
414
426
  return f"'{val}'"
415
427
 
416
428
  if len(pk_columns) == 1:
417
- return f"{pk_columns[0]} = {escape_value(pk_value)}"
429
+ return f"{_quote_identifier(pk_columns[0])} = {escape_value(pk_value)}"
418
430
  else:
419
431
  # Composite key
420
432
  if isinstance(pk_value, tuple):
421
433
  conditions = [
422
- f"{col} = {escape_value(val)}"
434
+ f"{_quote_identifier(col)} = {escape_value(val)}"
423
435
  for col, val in zip(pk_columns, pk_value)
424
436
  ]
425
437
  return " AND ".join(conditions)
426
438
  else:
427
439
  # Shouldn't happen if data is consistent
428
- return f"{pk_columns[0]} = {escape_value(pk_value)}"
440
+ return f"{_quote_identifier(pk_columns[0])} = {escape_value(pk_value)}"
429
441
 
430
442
  async def _expect_no_changes(self):
431
443
  """Efficiently verify that no changes occurred between snapshots using row counts."""
@@ -472,7 +484,7 @@ class AsyncSnapshotDiff:
472
484
 
473
485
  if table in before_tables:
474
486
  before_count_response = await self.before.resource.query(
475
- f"SELECT COUNT(*) FROM {table}"
487
+ f"SELECT COUNT(*) FROM {_quote_identifier(table)}"
476
488
  )
477
489
  before_count = (
478
490
  before_count_response.rows[0][0]
@@ -482,7 +494,7 @@ class AsyncSnapshotDiff:
482
494
 
483
495
  if table in after_tables:
484
496
  after_count_response = await self.after.resource.query(
485
- f"SELECT COUNT(*) FROM {table}"
497
+ f"SELECT COUNT(*) FROM {_quote_identifier(table)}"
486
498
  )
487
499
  after_count = (
488
500
  after_count_response.rows[0][0]
@@ -549,10 +561,10 @@ class AsyncSnapshotDiff:
549
561
  order_by = ", ".join(pk_columns) if pk_columns else "rowid"
550
562
 
551
563
  before_response = await self.before.resource.query(
552
- f"SELECT * FROM {table} ORDER BY {order_by}"
564
+ f"SELECT * FROM {_quote_identifier(table)} ORDER BY {order_by}"
553
565
  )
554
566
  after_response = await self.after.resource.query(
555
- f"SELECT * FROM {table} ORDER BY {order_by}"
567
+ f"SELECT * FROM {_quote_identifier(table)} ORDER BY {order_by}"
556
568
  )
557
569
 
558
570
  # Quick check: if column counts differ, there's a schema change
@@ -634,7 +646,7 @@ class AsyncSnapshotDiff:
634
646
  where_sql = self._build_pk_where_clause(pk_columns, pk)
635
647
 
636
648
  # Query before snapshot
637
- before_query = f"SELECT * FROM {table} WHERE {where_sql}"
649
+ before_query = f"SELECT * FROM {_quote_identifier(table)} WHERE {where_sql}"
638
650
  before_response = await self.before.resource.query(before_query)
639
651
  before_row = (
640
652
  dict(zip(before_response.columns, before_response.rows[0]))
@@ -727,7 +739,7 @@ class AsyncSnapshotDiff:
727
739
  try:
728
740
  # For tables with no allowed changes, just check row counts
729
741
  before_count_response = await self.before.resource.query(
730
- f"SELECT COUNT(*) FROM {table}"
742
+ f"SELECT COUNT(*) FROM {_quote_identifier(table)}"
731
743
  )
732
744
  before_count = (
733
745
  before_count_response.rows[0][0]
@@ -736,7 +748,7 @@ class AsyncSnapshotDiff:
736
748
  )
737
749
 
738
750
  after_count_response = await self.after.resource.query(
739
- f"SELECT COUNT(*) FROM {table}"
751
+ f"SELECT COUNT(*) FROM {_quote_identifier(table)}"
740
752
  )
741
753
  after_count = (
742
754
  after_count_response.rows[0][0] if after_count_response.rows else 0
@@ -1098,7 +1110,7 @@ class AsyncSnapshotDiff:
1098
1110
  where_sql = self._build_pk_where_clause(pk_columns, pk)
1099
1111
 
1100
1112
  # Query before snapshot
1101
- before_query = f"SELECT * FROM {table} WHERE {where_sql}"
1113
+ before_query = f"SELECT * FROM {_quote_identifier(table)} WHERE {where_sql}"
1102
1114
  before_response = await self.before.resource.query(before_query)
1103
1115
  before_row = (
1104
1116
  dict(zip(before_response.columns, before_response.rows[0]))
@@ -1176,7 +1188,7 @@ class AsyncSnapshotDiff:
1176
1188
  try:
1177
1189
  # For tables with no allowed changes, just check row counts
1178
1190
  before_count_response = await self.before.resource.query(
1179
- f"SELECT COUNT(*) FROM {table}"
1191
+ f"SELECT COUNT(*) FROM {_quote_identifier(table)}"
1180
1192
  )
1181
1193
  before_count = (
1182
1194
  before_count_response.rows[0][0]
@@ -1185,7 +1197,7 @@ class AsyncSnapshotDiff:
1185
1197
  )
1186
1198
 
1187
1199
  after_count_response = await self.after.resource.query(
1188
- f"SELECT COUNT(*) FROM {table}"
1200
+ f"SELECT COUNT(*) FROM {_quote_identifier(table)}"
1189
1201
  )
1190
1202
  after_count = (
1191
1203
  after_count_response.rows[0][0] if after_count_response.rows else 0
@@ -1950,13 +1962,13 @@ class AsyncQueryBuilder:
1950
1962
  # Compile to SQL
1951
1963
  def _compile(self) -> Tuple[str, List[Any]]:
1952
1964
  cols = ", ".join(self._select_cols)
1953
- sql = [f"SELECT {cols} FROM {self._table}"]
1965
+ sql = [f"SELECT {cols} FROM {_quote_identifier(self._table)}"]
1954
1966
  params: List[Any] = []
1955
1967
 
1956
1968
  # Joins
1957
1969
  for tbl, onmap in self._joins:
1958
- join_clauses = [f"{self._table}.{l} = {tbl}.{r}" for l, r in onmap.items()]
1959
- sql.append(f"JOIN {tbl} ON {' AND '.join(join_clauses)}")
1970
+ join_clauses = [f"{_quote_identifier(self._table)}.{_quote_identifier(l)} = {_quote_identifier(tbl)}.{_quote_identifier(r)}" for l, r in onmap.items()]
1971
+ sql.append(f"JOIN {_quote_identifier(tbl)} ON {' AND '.join(join_clauses)}")
1960
1972
 
1961
1973
  # WHERE
1962
1974
  if self._conditions:
@@ -1964,12 +1976,12 @@ class AsyncQueryBuilder:
1964
1976
  for col, op, val in self._conditions:
1965
1977
  if op in ("IN", "NOT IN") and isinstance(val, tuple):
1966
1978
  ph = ", ".join(["?" for _ in val])
1967
- placeholders.append(f"{col} {op} ({ph})")
1979
+ placeholders.append(f"{_quote_identifier(col)} {op} ({ph})")
1968
1980
  params.extend(val)
1969
1981
  elif op in ("IS", "IS NOT"):
1970
- placeholders.append(f"{col} {op} NULL")
1982
+ placeholders.append(f"{_quote_identifier(col)} {op} NULL")
1971
1983
  else:
1972
- placeholders.append(f"{col} {op} ?")
1984
+ placeholders.append(f"{_quote_identifier(col)} {op} ?")
1973
1985
  params.append(val)
1974
1986
  sql.append("WHERE " + " AND ".join(placeholders))
1975
1987
 
@@ -2122,7 +2134,7 @@ class AsyncSQLiteResource(Resource):
2122
2134
  tables = []
2123
2135
  for table_name in table_names:
2124
2136
  # Get table info
2125
- cursor.execute(f"PRAGMA table_info({table_name})")
2137
+ cursor.execute(f"PRAGMA table_info({_quote_identifier(table_name)})")
2126
2138
  columns = cursor.fetchall()
2127
2139
 
2128
2140
  # Get CREATE TABLE SQL
@@ -2182,8 +2194,114 @@ class AsyncSQLiteResource(Resource):
2182
2194
  if self._mode == "direct":
2183
2195
  return await self._query_direct(query, args, read_only)
2184
2196
  else:
2197
+ # Check if this is a PRAGMA query - HTTP endpoints don't support PRAGMA
2198
+ query_stripped = query.strip().upper()
2199
+ if query_stripped.startswith("PRAGMA"):
2200
+ return await self._handle_pragma_query_http(query, args)
2185
2201
  return await self._query_http(query, args, read_only)
2186
2202
 
2203
+ async def _handle_pragma_query_http(
2204
+ self, query: str, args: Optional[List[Any]] = None
2205
+ ) -> QueryResponse:
2206
+ """Handle PRAGMA queries in HTTP mode by using the describe endpoint."""
2207
+ query_upper = query.strip().upper()
2208
+
2209
+ # Extract table name from PRAGMA table_info(table_name)
2210
+ if "TABLE_INFO" in query_upper:
2211
+ # Match: PRAGMA table_info("table") or PRAGMA table_info(table)
2212
+ match = re.search(r'TABLE_INFO\s*\(\s*"([^"]+)"\s*\)', query, re.IGNORECASE)
2213
+ if not match:
2214
+ match = re.search(r"TABLE_INFO\s*\(\s*'([^']+)'\s*\)", query, re.IGNORECASE)
2215
+ if not match:
2216
+ match = re.search(r'TABLE_INFO\s*\(\s*([^\s\)]+)\s*\)', query, re.IGNORECASE)
2217
+
2218
+ if match:
2219
+ table_name = match.group(1)
2220
+
2221
+ # Use the describe endpoint to get schema
2222
+ describe_response = await self.describe()
2223
+ if not describe_response.success or not describe_response.tables:
2224
+ return QueryResponse(
2225
+ success=False,
2226
+ columns=None,
2227
+ rows=None,
2228
+ error="Failed to get schema information",
2229
+ message="PRAGMA query failed: could not retrieve schema"
2230
+ )
2231
+
2232
+ # Find the table in the schema
2233
+ table_schema = None
2234
+ for table in describe_response.tables:
2235
+ # Handle both dict and TableSchema objects
2236
+ table_name_in_schema = table.name if hasattr(table, 'name') else table.get("name")
2237
+ if table_name_in_schema == table_name:
2238
+ table_schema = table
2239
+ break
2240
+
2241
+ if not table_schema:
2242
+ return QueryResponse(
2243
+ success=False,
2244
+ columns=None,
2245
+ rows=None,
2246
+ error=f"Table '{table_name}' not found",
2247
+ message=f"PRAGMA query failed: table '{table_name}' not found"
2248
+ )
2249
+
2250
+ # Get columns from table schema
2251
+ columns = table_schema.columns if hasattr(table_schema, 'columns') else table_schema.get("columns")
2252
+ if not columns:
2253
+ return QueryResponse(
2254
+ success=False,
2255
+ columns=None,
2256
+ rows=None,
2257
+ error=f"Table '{table_name}' has no columns",
2258
+ message=f"PRAGMA query failed: table '{table_name}' has no columns"
2259
+ )
2260
+
2261
+ # Convert schema to PRAGMA table_info format
2262
+ # Format: (cid, name, type, notnull, dflt_value, pk)
2263
+ rows = []
2264
+ for idx, col in enumerate(columns):
2265
+ # Handle both dict and object column definitions
2266
+ if isinstance(col, dict):
2267
+ col_name = col["name"]
2268
+ col_type = col.get("type", "")
2269
+ col_notnull = col.get("notnull", False)
2270
+ col_default = col.get("default_value")
2271
+ col_pk = col.get("pk", 0)
2272
+ else:
2273
+ col_name = col.name if hasattr(col, 'name') else str(col)
2274
+ col_type = getattr(col, 'type', "")
2275
+ col_notnull = getattr(col, 'notnull', False)
2276
+ col_default = getattr(col, 'default_value', None)
2277
+ col_pk = getattr(col, 'pk', 0)
2278
+
2279
+ row = (
2280
+ idx, # cid
2281
+ col_name, # name
2282
+ col_type, # type
2283
+ 1 if col_notnull else 0, # notnull
2284
+ col_default, # dflt_value
2285
+ col_pk # pk
2286
+ )
2287
+ rows.append(row)
2288
+
2289
+ return QueryResponse(
2290
+ success=True,
2291
+ columns=["cid", "name", "type", "notnull", "dflt_value", "pk"],
2292
+ rows=rows,
2293
+ message="PRAGMA query executed successfully via describe endpoint"
2294
+ )
2295
+
2296
+ # For other PRAGMA queries, return an error indicating they're not supported
2297
+ return QueryResponse(
2298
+ success=False,
2299
+ columns=None,
2300
+ rows=None,
2301
+ error="PRAGMA query not supported in HTTP mode",
2302
+ message=f"PRAGMA query '{query}' is not supported via HTTP API"
2303
+ )
2304
+
2187
2305
  async def _query_http(
2188
2306
  self, query: str, args: Optional[List[Any]] = None, read_only: bool = True
2189
2307
  ) -> QueryResponse:
fleet/base.py CHANGED
@@ -27,7 +27,7 @@ from .exceptions import (
27
27
  try:
28
28
  from . import __version__
29
29
  except ImportError:
30
- __version__ = "0.2.98"
30
+ __version__ = "0.2.99"
31
31
 
32
32
  logger = logging.getLogger(__name__)
33
33
 
fleet/resources/sqlite.py CHANGED
@@ -6,6 +6,7 @@ from datetime import datetime
6
6
  import tempfile
7
7
  import sqlite3
8
8
  import os
9
+ import re
9
10
 
10
11
  from typing import TYPE_CHECKING
11
12
 
@@ -2234,8 +2235,114 @@ class SQLiteResource(Resource):
2234
2235
  if self._mode == "direct":
2235
2236
  return self._query_direct(query, args, read_only)
2236
2237
  else:
2238
+ # Check if this is a PRAGMA query - HTTP endpoints don't support PRAGMA
2239
+ query_stripped = query.strip().upper()
2240
+ if query_stripped.startswith("PRAGMA"):
2241
+ return self._handle_pragma_query_http(query, args)
2237
2242
  return self._query_http(query, args, read_only)
2238
2243
 
2244
+ def _handle_pragma_query_http(
2245
+ self, query: str, args: Optional[List[Any]] = None
2246
+ ) -> QueryResponse:
2247
+ """Handle PRAGMA queries in HTTP mode by using the describe endpoint."""
2248
+ query_upper = query.strip().upper()
2249
+
2250
+ # Extract table name from PRAGMA table_info(table_name)
2251
+ if "TABLE_INFO" in query_upper:
2252
+ # Match: PRAGMA table_info("table") or PRAGMA table_info(table)
2253
+ match = re.search(r'TABLE_INFO\s*\(\s*"([^"]+)"\s*\)', query, re.IGNORECASE)
2254
+ if not match:
2255
+ match = re.search(r"TABLE_INFO\s*\(\s*'([^']+)'\s*\)", query, re.IGNORECASE)
2256
+ if not match:
2257
+ match = re.search(r'TABLE_INFO\s*\(\s*([^\s\)]+)\s*\)', query, re.IGNORECASE)
2258
+
2259
+ if match:
2260
+ table_name = match.group(1)
2261
+
2262
+ # Use the describe endpoint to get schema
2263
+ describe_response = self.describe()
2264
+ if not describe_response.success or not describe_response.tables:
2265
+ return QueryResponse(
2266
+ success=False,
2267
+ columns=None,
2268
+ rows=None,
2269
+ error="Failed to get schema information",
2270
+ message="PRAGMA query failed: could not retrieve schema"
2271
+ )
2272
+
2273
+ # Find the table in the schema
2274
+ table_schema = None
2275
+ for table in describe_response.tables:
2276
+ # Handle both dict and TableSchema objects
2277
+ table_name_in_schema = table.name if hasattr(table, 'name') else table.get("name")
2278
+ if table_name_in_schema == table_name:
2279
+ table_schema = table
2280
+ break
2281
+
2282
+ if not table_schema:
2283
+ return QueryResponse(
2284
+ success=False,
2285
+ columns=None,
2286
+ rows=None,
2287
+ error=f"Table '{table_name}' not found",
2288
+ message=f"PRAGMA query failed: table '{table_name}' not found"
2289
+ )
2290
+
2291
+ # Get columns from table schema
2292
+ columns = table_schema.columns if hasattr(table_schema, 'columns') else table_schema.get("columns")
2293
+ if not columns:
2294
+ return QueryResponse(
2295
+ success=False,
2296
+ columns=None,
2297
+ rows=None,
2298
+ error=f"Table '{table_name}' has no columns",
2299
+ message=f"PRAGMA query failed: table '{table_name}' has no columns"
2300
+ )
2301
+
2302
+ # Convert schema to PRAGMA table_info format
2303
+ # Format: (cid, name, type, notnull, dflt_value, pk)
2304
+ rows = []
2305
+ for idx, col in enumerate(columns):
2306
+ # Handle both dict and object column definitions
2307
+ if isinstance(col, dict):
2308
+ col_name = col["name"]
2309
+ col_type = col.get("type", "")
2310
+ col_notnull = col.get("notnull", False)
2311
+ col_default = col.get("default_value")
2312
+ col_pk = col.get("pk", 0)
2313
+ else:
2314
+ col_name = col.name if hasattr(col, 'name') else str(col)
2315
+ col_type = getattr(col, 'type', "")
2316
+ col_notnull = getattr(col, 'notnull', False)
2317
+ col_default = getattr(col, 'default_value', None)
2318
+ col_pk = getattr(col, 'pk', 0)
2319
+
2320
+ row = (
2321
+ idx, # cid
2322
+ col_name, # name
2323
+ col_type, # type
2324
+ 1 if col_notnull else 0, # notnull
2325
+ col_default, # dflt_value
2326
+ col_pk # pk
2327
+ )
2328
+ rows.append(row)
2329
+
2330
+ return QueryResponse(
2331
+ success=True,
2332
+ columns=["cid", "name", "type", "notnull", "dflt_value", "pk"],
2333
+ rows=rows,
2334
+ message="PRAGMA query executed successfully via describe endpoint"
2335
+ )
2336
+
2337
+ # For other PRAGMA queries, return an error indicating they're not supported
2338
+ return QueryResponse(
2339
+ success=False,
2340
+ columns=None,
2341
+ rows=None,
2342
+ error="PRAGMA query not supported in HTTP mode",
2343
+ message=f"PRAGMA query '{query}' is not supported via HTTP API"
2344
+ )
2345
+
2239
2346
  def _query_http(
2240
2347
  self, query: str, args: Optional[List[Any]] = None, read_only: bool = True
2241
2348
  ) -> QueryResponse:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fleet-python
3
- Version: 0.2.98
3
+ Version: 0.2.99
4
4
  Summary: Python SDK for Fleet environments
5
5
  Author-email: Fleet AI <nic@fleet.so>
6
6
  License: Apache-2.0
@@ -23,8 +23,8 @@ examples/openai_simple_example.py,sha256=HmiufucrAZne7tHq9uoEsDWlEhjNC265bQAyIGB
23
23
  examples/query_builder_example.py,sha256=-cOMfWGNifYfYEt_Ds73XpwATZvFDL6F4KTkVxdMjzg,3951
24
24
  examples/quickstart.py,sha256=1VT39IRRhemsJgxi0O0gprdpcw7HB4pYO97GAYagIcg,3788
25
25
  examples/test_cdp_logging.py,sha256=AkCwQCgOTQEI8w3v0knWK_4eXMph7L9x07wj9yIYM10,2836
26
- fleet/__init__.py,sha256=Y1h69yWX21Bg__ins6FQuV6CpxHH8fcfWEChZKb2qWo,7797
27
- fleet/base.py,sha256=gs_IeLalHKGw8QqrzckPRy7f5Y-KonZxVxSY0ZuUS8I,10065
26
+ fleet/__init__.py,sha256=FMH_B_jo8tuiSiBOlo9EcEkkTTcaV2kOrB0sXCsEVLE,7797
27
+ fleet/base.py,sha256=u8Hgr9HxNJbuNWtrFi9Tw3aQYC_WsPyZQcLYwrBCrVM,10065
28
28
  fleet/cli.py,sha256=arX1E-fjLXtcV3tVVkPHfEXxl7FDn4zRmf0ssXlXaMg,40104
29
29
  fleet/client.py,sha256=bJnp2g4yBW2EoL_95Q2I2aeR3p-nnb6o9PPNAtwmMGY,67818
30
30
  fleet/config.py,sha256=n_wh9Sahu3gGE7nHJ7kqNFUH1qDiBtF4bgZq9MvIBMU,319
@@ -33,8 +33,8 @@ fleet/global_client.py,sha256=frrDAFNM2ywN0JHLtlm9qbE1dQpnQJsavJpb7xSR_bU,1072
33
33
  fleet/models.py,sha256=7y7AchrAllsEAxel7C68DoeAyfRd90EVhwI7WbceQ3M,25173
34
34
  fleet/tasks.py,sha256=8pEzXmgC7RslqsMC_0s6shhr_t2WGIRpTRqo-MAQjdg,20778
35
35
  fleet/types.py,sha256=L4Y82xICf1tzyCLqhLYUgEoaIIS5h9T05TyFNHSWs3s,652
36
- fleet/_async/__init__.py,sha256=kPnFqzXofI4LRxnrvilAP-5ErqyUUW8EYtbAoNaEshE,9115
37
- fleet/_async/base.py,sha256=s0kRZZUUfnLEx4h2uXm0i9xvCdbfSa7OfYt4I_o_sck,9630
36
+ fleet/_async/__init__.py,sha256=w9dNJUQNSbM8fmq2BuBtKRKnMpEuxN3pUmX5eXaioFo,9115
37
+ fleet/_async/base.py,sha256=JnwtOLWTorAWI31m5H63VL4c5nbRA46LaMEJxhgoylc,9630
38
38
  fleet/_async/client.py,sha256=UdTOxvaLlo3VlMwgED8ZiUIrMxlaClM6cFBAWNUNqD4,64241
39
39
  fleet/_async/exceptions.py,sha256=fUmPwWhnT8SR97lYsRq0kLHQHKtSh2eJS0VQ2caSzEI,5055
40
40
  fleet/_async/global_client.py,sha256=4WskpLHbsDEgWW7hXMD09W-brkp4euy8w2ZJ88594rQ,1103
@@ -50,7 +50,7 @@ fleet/_async/resources/api.py,sha256=qlM1Ab3LNe1r7Hx27es4CRK565ZLVaJQeEtZKCe9cM0
50
50
  fleet/_async/resources/base.py,sha256=UfrenxUqcpL8SgYGOo8o8HgRvv2-ZO5G2Cdo91ofEdg,664
51
51
  fleet/_async/resources/browser.py,sha256=oldoSiymJ1lJkADhpUG81ViOBDNyppX1jSoEwe9-W94,1369
52
52
  fleet/_async/resources/mcp.py,sha256=TLEsLiFhfVfZFs0Fu_uDPm-h4FPdvqgQblYqs-PTHhc,1720
53
- fleet/_async/resources/sqlite.py,sha256=2aY3zIXuLUBFUnn_uEXlSZf9JQ1MSw5uH9aUfZ6ydeM,96498
53
+ fleet/_async/resources/sqlite.py,sha256=MZY-10anBysxPDZ7SQ7gE7FSW4rF7t_o3ICptt78m0I,102432
54
54
  fleet/_async/verifiers/__init__.py,sha256=1WTlCNq4tIFbbXaQu5Bf2WppZq0A8suhtZbxMTSOwxI,465
55
55
  fleet/_async/verifiers/bundler.py,sha256=9aWWXFsovBPcndE06IATn5jaeli5fRORAYeenF9heN0,26264
56
56
  fleet/_async/verifiers/verifier.py,sha256=iSa-rO-E1R3IQTFS9Z7jbQvQVtsDkilITQP9IIQU2JA,14556
@@ -83,7 +83,7 @@ fleet/resources/api.py,sha256=7YQcATXjhNeEbrIDXqSMerGywxefcRz8luqrObfcsl8,6066
83
83
  fleet/resources/base.py,sha256=AXZzT0_yWHkT497q3yekfr0xsD4cPGMCC6y7C43TIkk,663
84
84
  fleet/resources/browser.py,sha256=hRNM0YMsVQUAraZGNi_B-KXxLpuddy4ntoEDFSw7czU,1295
85
85
  fleet/resources/mcp.py,sha256=c6O4vVJnXANuHMGMe4IPxgp4zBEbFaGm6_d9e6j8Myc,1695
86
- fleet/resources/sqlite.py,sha256=Bdxy09oFmTRLL4S4pF3UH7Hdv29e5s2kPGEifMPvr8U,98323
86
+ fleet/resources/sqlite.py,sha256=3rLVDTzAK54NK_MOrpyga2lU46wvFPWZaAMnnTEHD6o,103220
87
87
  fleet/utils/__init__.py,sha256=cZdaIU4KWr_xQFDpShTC2P_XVLYrlDFSBTQwWzfDQ2o,255
88
88
  fleet/utils/http_logging.py,sha256=N1qRwOHA4nTe-3JOy-2J9AK0eneWAfv9s66qnyU_Vnw,6332
89
89
  fleet/utils/logging.py,sha256=-F_JbGIAaIt_WqVJC0ch4iog4WWFQDJgUS2vxg3YH0A,319
@@ -96,7 +96,7 @@ fleet/verifiers/decorator.py,sha256=RuTjjDijbicNfMSjA7HcTpKueEki5dzNOdTuHS7UoZs,
96
96
  fleet/verifiers/parse.py,sha256=qz9AfJrTbjlg-LU-lE8Ciqi7Yt2a8-cs17FdpjTLhMk,8550
97
97
  fleet/verifiers/sql_differ.py,sha256=TqTLWyK3uOyLbitT6HYzYEzuSFC39wcyhgk3rcm__k8,6525
98
98
  fleet/verifiers/verifier.py,sha256=iqGevW7dSd0J5RdRQjpu-zioy_FYAXnzMfkuB3-QmO0,14601
99
- fleet_python-0.2.98.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
99
+ fleet_python-0.2.99.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
100
100
  scripts/fix_sync_imports.py,sha256=X9fWLTpiPGkSHsjyQUDepOJkxOqw1DPj7nd8wFlFqLQ,8368
101
101
  scripts/unasync.py,sha256=vWVQxRWX8SRZO5cmzEhpvnG_REhCWXpidIGIpWmEcvI,696
102
102
  tests/__init__.py,sha256=Re1SdyxH8NfyL1kjhi7SQkGP1mYeWB-D6UALqdIMd8I,35
@@ -106,8 +106,8 @@ tests/test_instance_dispatch.py,sha256=CvU4C3LBIqsYZdEsEFfontGjyxAZfVYyXnGwxyIvX
106
106
  tests/test_sqlite_resource_dual_mode.py,sha256=Mh8jBd-xsIGDYFsOACKKK_5DXMUYlFFS7W-jaY6AjG4,8734
107
107
  tests/test_sqlite_shared_memory_behavior.py,sha256=fKx_1BmLS3b8x-9pMgjMycpnaHWY8P-2ZuXEspx6Sbw,4082
108
108
  tests/test_verifier_from_string.py,sha256=Lxi3TpFHFb-hG4-UhLKZJkqo84ax9YJY8G6beO-1erM,13581
109
- fleet_python-0.2.98.dist-info/METADATA,sha256=A4D_NEs4hu_gRA21q9LFWy0oS5VRvnYOU0xJ3iZthj4,4239
110
- fleet_python-0.2.98.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
111
- fleet_python-0.2.98.dist-info/entry_points.txt,sha256=qKIQ326cHR5WyCd16QnrW-1DpcT0YyxVRDb3IlTyzTA,39
112
- fleet_python-0.2.98.dist-info/top_level.txt,sha256=qb1zIbtEktyhRFZdqVytwg54l64qtoZL0wjHB4bUg3c,29
113
- fleet_python-0.2.98.dist-info/RECORD,,
109
+ fleet_python-0.2.99.dist-info/METADATA,sha256=aUW3NYcBdYsC5ZXajM2oopQV2gx0jUJqoFNL8e4GPMo,4239
110
+ fleet_python-0.2.99.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
111
+ fleet_python-0.2.99.dist-info/entry_points.txt,sha256=qKIQ326cHR5WyCd16QnrW-1DpcT0YyxVRDb3IlTyzTA,39
112
+ fleet_python-0.2.99.dist-info/top_level.txt,sha256=qb1zIbtEktyhRFZdqVytwg54l64qtoZL0wjHB4bUg3c,29
113
+ fleet_python-0.2.99.dist-info/RECORD,,