nl2sql-adapter-sdk 0.1.0__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.
@@ -0,0 +1,6 @@
1
+ Metadata-Version: 2.4
2
+ Name: nl2sql-adapter-sdk
3
+ Version: 0.1.0
4
+ Summary: Shared adapter contracts for NL2SQL
5
+ Requires-Python: >=3.9
6
+ Requires-Dist: pydantic>=1.10
@@ -0,0 +1,19 @@
1
+ [build-system]
2
+ requires = ["setuptools>=64", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "nl2sql-adapter-sdk"
7
+ version = "0.1.0" # x-release-please-version
8
+ description = "Shared adapter contracts for NL2SQL"
9
+ requires-python = ">=3.9"
10
+ dependencies = [
11
+ "pydantic>=1.10",
12
+ ]
13
+
14
+ [tool.setuptools]
15
+ package-dir = {"" = "src"}
16
+
17
+ [tool.setuptools.packages.find]
18
+ where = ["src"]
19
+ include = ["nl2sql_adapter_sdk*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,37 @@
1
+ """Adapter SDK: shared contracts for core and adapters."""
2
+
3
+ from .capabilities import DatasourceCapability
4
+ from .contracts import AdapterRequest, ResultError, ResultFrame
5
+ from .protocols import DatasourceAdapterProtocol
6
+ from .schema import (
7
+ TableRef,
8
+ ColumnStatistics,
9
+ ColumnMetadata,
10
+ ColumnContract,
11
+ ForeignKeyContract,
12
+ TableContract,
13
+ TableMetadata,
14
+ SchemaContract,
15
+ SchemaMetadata,
16
+ SchemaSnapshot,
17
+ ColumnRef
18
+ )
19
+
20
+ __all__ = [
21
+ "DatasourceCapability",
22
+ "AdapterRequest",
23
+ "ResultError",
24
+ "ResultFrame",
25
+ "DatasourceAdapterProtocol",
26
+ "TableRef",
27
+ "ColumnStatistics",
28
+ "ColumnMetadata",
29
+ "ColumnContract",
30
+ "ForeignKeyContract",
31
+ "TableContract",
32
+ "TableMetadata",
33
+ "SchemaContract",
34
+ "SchemaMetadata",
35
+ "SchemaSnapshot",
36
+ "ColumnRef",
37
+ ]
@@ -0,0 +1,13 @@
1
+ from enum import Enum
2
+
3
+
4
+ class DatasourceCapability(str, Enum):
5
+ """Capability flags for datasource adapters."""
6
+
7
+ SUPPORTS_SQL = "supports_sql"
8
+ SUPPORTS_REST = "supports_rest"
9
+ SUPPORTS_GRAPHQL = "supports_graphql"
10
+ SUPPORTS_LAKE = "supports_lake"
11
+ SUPPORTS_SCHEMA_INTROSPECTION = "supports_schema_introspection"
12
+ SUPPORTS_DRY_RUN = "supports_dry_run"
13
+ SUPPORTS_COST_ESTIMATE = "supports_cost_estimate"
@@ -0,0 +1,87 @@
1
+ from typing import Any, Dict, List, Optional
2
+
3
+ from pydantic import BaseModel, ConfigDict, Field
4
+
5
+
6
+ class AdapterRequest(BaseModel):
7
+ """Generic adapter request for subgraph execution."""
8
+
9
+ plan_type: str = Field(
10
+ ..., description="Execution plan type (e.g., 'sql', 'rest', 'nosql')."
11
+ )
12
+ payload: Dict[str, Any] = Field(
13
+ default_factory=dict, description="Plan-specific request payload."
14
+ )
15
+ parameters: Dict[str, Any] = Field(
16
+ default_factory=dict, description="Optional parameter bindings."
17
+ )
18
+ limits: Dict[str, int] = Field(
19
+ default_factory=dict,
20
+ description="Execution limits (row_limit, timeout_ms, max_bytes).",
21
+ )
22
+ trace_id: Optional[str] = Field(
23
+ default=None, description="Optional trace id for observability."
24
+ )
25
+
26
+ model_config = ConfigDict(extra="ignore")
27
+
28
+
29
+
30
+ class ResultError(BaseModel):
31
+ """Standardized error envelope for adapter results."""
32
+
33
+ error_code: str
34
+ safe_message: str
35
+ severity: str = Field(default="ERROR")
36
+ retryable: bool = Field(default=False)
37
+ stage: Optional[str] = None
38
+ datasource_id: Optional[str] = None
39
+ error_id: Optional[str] = None
40
+
41
+
42
+ class ResultFrame(BaseModel):
43
+ """Adapter-agnostic, DataFrame-like result contract."""
44
+
45
+ success: bool = Field(default=True)
46
+ columns: List[str] = Field(default_factory=list)
47
+ rows: List[List[Any]] = Field(default_factory=list)
48
+ row_count: int = Field(default=0)
49
+ truncated: bool = Field(default=False)
50
+ bytes: Optional[int] = Field(default=None)
51
+ datasource_id: Optional[str] = Field(default=None)
52
+ tenant_id: Optional[str] = Field(default=None)
53
+ execution_stats: Dict[str, Any] = Field(default_factory=dict)
54
+ error: Optional[ResultError] = Field(default=None)
55
+
56
+ model_config = ConfigDict(extra="ignore")
57
+
58
+ @classmethod
59
+ def from_row_dicts(
60
+ cls,
61
+ rows: List[Dict[str, Any]],
62
+ columns: Optional[List[str]] = None,
63
+ *,
64
+ row_count: Optional[int] = None,
65
+ **kwargs: Any,
66
+ ) -> "ResultFrame":
67
+ """Create a ResultFrame from list-of-dict rows."""
68
+
69
+ if columns is None:
70
+ columns = list(rows[0].keys()) if rows else []
71
+
72
+ row_values = [[row.get(col) for col in columns] for row in rows]
73
+
74
+ return cls(
75
+ columns=columns,
76
+ rows=row_values,
77
+ row_count=row_count if row_count is not None else len(row_values),
78
+ **kwargs,
79
+ )
80
+
81
+ def to_row_dicts(self) -> List[Dict[str, Any]]:
82
+ """Convert row values to list-of-dict rows using column order."""
83
+
84
+ if not self.rows or not self.columns:
85
+ return []
86
+ names = self.columns
87
+ return [dict(zip(names, row)) for row in self.rows]
@@ -0,0 +1,41 @@
1
+ from typing import Any, Dict, Optional, Protocol, Set, runtime_checkable
2
+
3
+ from .capabilities import DatasourceCapability
4
+ from .contracts import AdapterRequest, ResultFrame
5
+
6
+
7
+ @runtime_checkable
8
+ class DatasourceAdapterProtocol(Protocol):
9
+ """Contract for adapter implementations."""
10
+
11
+ datasource_id: str
12
+ datasource_engine_type: str
13
+ connection_args: Dict[str, Any]
14
+ statement_timeout_ms: Optional[int]
15
+ row_limit: Optional[int]
16
+ max_bytes: Optional[int]
17
+
18
+ def capabilities(self) -> Set[DatasourceCapability]:
19
+ """Returns supported capabilities for this adapter."""
20
+ ...
21
+
22
+ def connect(self) -> None:
23
+ """Initialize connections / clients based on config."""
24
+ ...
25
+
26
+ def fetch_schema_snapshot(self) -> Any:
27
+ """Return a structured schema snapshot if supported."""
28
+ ...
29
+
30
+ def execute(self, request: AdapterRequest) -> ResultFrame:
31
+ """Execute a plan-specific request and return a ResultFrame."""
32
+ ...
33
+
34
+ def get_dialect(self) -> str:
35
+ """Return the normalized dialect string (SQL adapters)."""
36
+ ...
37
+
38
+
39
+ def test_connection(self) -> bool:
40
+ """Test if the connection to the datasource can be established."""
41
+ ...
@@ -0,0 +1,117 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Dict, List, Optional, Union, Literal
4
+
5
+ from pydantic import BaseModel, ConfigDict, Field
6
+
7
+ Scalar = Union[str, int, float, bool, None]
8
+ JsonValue = Union[Scalar, List[Scalar], Dict[str, Scalar]]
9
+
10
+
11
+ class ColumnRef(BaseModel):
12
+ table: TableRef
13
+ column_name: str
14
+
15
+
16
+
17
+ class TableRef(BaseModel):
18
+ schema_name: str
19
+ table_name: str
20
+
21
+ model_config = ConfigDict(extra="ignore", frozen=True)
22
+
23
+ @property
24
+ def full_name(self) -> str:
25
+ return f"[{self.schema_name}].[{self.table_name}]"
26
+
27
+
28
+ class ColumnStatistics(BaseModel):
29
+ null_percentage: float
30
+ distinct_count: int
31
+ min_value: Optional[Scalar] = None
32
+ max_value: Optional[Scalar] = None
33
+ sample_values: List[JsonValue] = Field(default_factory=list)
34
+
35
+ def __str__(self) -> str:
36
+ return (
37
+ "null_percentage: "
38
+ f"{self.null_percentage}, distinct_count: {self.distinct_count}, "
39
+ f"min_value: {self.min_value}, max_value: {self.max_value}, "
40
+ f"sample_values: {self.sample_values}"
41
+ )
42
+
43
+
44
+ class ColumnMetadata(BaseModel):
45
+ description: Optional[str] = None
46
+ statistics: Optional[ColumnStatistics] = None
47
+ synonyms: Optional[List[str]] = None
48
+ pii: bool = False
49
+
50
+
51
+ class ColumnContract(BaseModel):
52
+ name: str
53
+ data_type: str
54
+ is_nullable: bool = True
55
+ is_primary_key: bool = False
56
+
57
+ model_config = ConfigDict(extra="ignore", frozen=True)
58
+
59
+
60
+ class ForeignKeyContract(BaseModel):
61
+ constrained_columns: List[str]
62
+ referred_table: TableRef
63
+ referred_columns: List[str]
64
+ cardinality: Literal[
65
+ "one-to-one",
66
+ "one-to-many",
67
+ "many-to-one",
68
+ "many-to-many",
69
+ "unknown",
70
+ ] = "unknown"
71
+ business_meaning: Optional[str] = None
72
+
73
+ model_config = ConfigDict(extra="ignore", frozen=True)
74
+
75
+
76
+ class TableContract(BaseModel):
77
+ table: TableRef
78
+ columns: Dict[str, ColumnContract] = Field(default_factory=dict)
79
+ foreign_keys: List[ForeignKeyContract] = Field(default_factory=list)
80
+
81
+ model_config = ConfigDict(extra="ignore", frozen=True)
82
+
83
+ @property
84
+ def full_name(self) -> str:
85
+ return f"[{self.table.schema_name}].[{self.table.table_name}]"
86
+
87
+
88
+ class TableMetadata(BaseModel):
89
+ table: TableRef
90
+ columns: Dict[str, ColumnMetadata] = Field(default_factory=dict)
91
+ row_count: Optional[int] = None
92
+ description: Optional[str] = None
93
+
94
+ @property
95
+ def full_name(self) -> str:
96
+ return f"[{self.table.schema_name}].[{self.table.table_name}]"
97
+
98
+
99
+ class SchemaContract(BaseModel):
100
+ datasource_id: str
101
+ engine_type: str
102
+ tables: Dict[str, TableContract] = Field(default_factory=dict)
103
+
104
+ model_config = ConfigDict(extra="ignore", frozen=True)
105
+
106
+
107
+ class SchemaMetadata(BaseModel):
108
+ datasource_id: str
109
+ engine_type: str
110
+ description: Optional[str] = None
111
+ domains: Optional[List[str]] = None
112
+ tables: Dict[str, TableMetadata] = Field(default_factory=dict)
113
+
114
+
115
+ class SchemaSnapshot(BaseModel):
116
+ contract: SchemaContract
117
+ metadata: SchemaMetadata
@@ -0,0 +1,6 @@
1
+ Metadata-Version: 2.4
2
+ Name: nl2sql-adapter-sdk
3
+ Version: 0.1.0
4
+ Summary: Shared adapter contracts for NL2SQL
5
+ Requires-Python: >=3.9
6
+ Requires-Dist: pydantic>=1.10
@@ -0,0 +1,11 @@
1
+ pyproject.toml
2
+ src/nl2sql_adapter_sdk/__init__.py
3
+ src/nl2sql_adapter_sdk/capabilities.py
4
+ src/nl2sql_adapter_sdk/contracts.py
5
+ src/nl2sql_adapter_sdk/protocols.py
6
+ src/nl2sql_adapter_sdk/schema.py
7
+ src/nl2sql_adapter_sdk.egg-info/PKG-INFO
8
+ src/nl2sql_adapter_sdk.egg-info/SOURCES.txt
9
+ src/nl2sql_adapter_sdk.egg-info/dependency_links.txt
10
+ src/nl2sql_adapter_sdk.egg-info/requires.txt
11
+ src/nl2sql_adapter_sdk.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ nl2sql_adapter_sdk