Skip to content

Commit 0a7040e

Browse files
jontsaiclaude
andcommitted
Upgrade to Pydantic v2 and bump version to 0.1.0
This commit completes the migration from Pydantic v1 to v2, with the following changes: - Updated Pydantic model configuration syntax: - Changed `class Config:` to `model_config = ConfigDict()` in catalog.py - Updated imports to use `from pydantic import ConfigDict` - Fixed Pydantic v2 field requirements: - Added default values (= None) to all Optional fields without defaults in manifest.py - This is required in Pydantic v2 for proper model validation - Updated deprecated method calls: - Changed `.json()` to `.model_dump_json()` in executor.py - These methods serialize Pydantic models to JSON strings - Migrated vendor dependencies (dbt_artifacts_parser): - Replaced `constr()` with `Annotated[str, StringConstraints()]` across all manifest versions - Added `from typing_extensions import Annotated` imports - This follows Pydantic v2's recommended pattern for constrained types - Added .venv/ to .gitignore - Bumped version from 0.0.26 to 0.1.0 to reflect breaking changes Testing: - Ran full test suite using .venv/bin/pytest - All 64 tests passed successfully - Verified Pydantic 2.12.0 compatibility BREAKING CHANGE: This upgrade requires downstream users to also upgrade to Pydantic v2. setup.py now specifies pydantic>=2.0,<3.0. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent aa5d3df commit 0a7040e

File tree

17 files changed

+73
-74
lines changed

17 files changed

+73
-74
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ pyvenv*/
3333
sdist
3434
var
3535
venv*/
36+
.venv/
3637
wheelhouse
3738

3839
# Installer logs

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ def read(*names, **kwargs):
1313

1414
setup(
1515
name="altimate-datapilot-cli",
16-
version="0.0.26",
16+
version="0.1.0",
1717
license="MIT",
1818
description="Assistant for Data Teams",
1919
long_description="{}\n{}".format(

src/datapilot/core/platforms/dbt/executor.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ def run_llm_checks(self):
109109
self.token,
110110
self.instance_name,
111111
self.backend_url,
112-
self.manifest.json() if self.manifest else "",
113-
self.catalog.json() if self.catalog else "",
112+
self.manifest.model_dump_json() if self.manifest else "",
113+
self.catalog.model_dump_json() if self.catalog else "",
114114
check_names,
115115
)
116116
return llm_check_results

src/datapilot/core/platforms/dbt/schemas/catalog.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
from typing import Optional
66
from typing import Union
77

8-
from pydantic.main import BaseModel
8+
from pydantic import BaseModel
9+
from pydantic import ConfigDict
910

1011
from vendor.dbt_artifacts_parser.parsers.catalog.catalog_v1 import CatalogV1 as BaseCatalogV1
1112
from vendor.dbt_artifacts_parser.parsers.catalog.catalog_v1 import Metadata as BaseMetadata
@@ -59,15 +60,12 @@ class AltimateCatalogCatalogV1(BaseModel):
5960

6061
# Custom classes to handle extra fields in newer dbt versions
6162
class Metadata(BaseMetadata):
62-
class Config:
63-
extra = "allow" # Allow extra fields in metadata
63+
model_config = ConfigDict(extra="allow")
6464

6565

6666
class CatalogV1(BaseCatalogV1):
6767
metadata: Metadata # Use our custom metadata class
68-
69-
class Config:
70-
extra = "allow" # Allow extra fields
68+
model_config = ConfigDict(extra="allow")
7169

7270

7371
Catalog = CatalogV1

src/datapilot/core/platforms/dbt/schemas/manifest.py

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
class DBTVersion(BaseModel):
2626
MAJOR: int
2727
MINOR: int
28-
PATCH: Optional[int]
28+
PATCH: Optional[int] = None
2929

3030

3131
Manifest = Union[
@@ -64,8 +64,8 @@ class AltimateManifestColumnInfo(BaseModel):
6464

6565

6666
class AltimateFileHash(BaseModel):
67-
name: Optional[str]
68-
checksum: Optional[str]
67+
name: Optional[str] = None
68+
checksum: Optional[str] = None
6969

7070

7171
class AltimateResourceType(Enum):
@@ -118,8 +118,8 @@ class AltimateNodeConfig(BaseModel):
118118
materialized: Optional[str] = "view"
119119
incremental_strategy: Optional[Optional[str]] = None
120120
persist_docs: Optional[Dict[str, Any]] = None
121-
post_hook: Optional[List[AltimateHook]]
122-
pre_hook: Optional[List[AltimateHook]]
121+
post_hook: Optional[List[AltimateHook]] = None
122+
pre_hook: Optional[List[AltimateHook]] = None
123123
quoting: Optional[Dict[str, Any]] = None
124124
column_types: Optional[Dict[str, Any]] = None
125125
full_refresh: Optional[Optional[bool]] = None
@@ -128,7 +128,7 @@ class AltimateNodeConfig(BaseModel):
128128

129129

130130
class AltimateManifestNode(BaseModel):
131-
database: Optional[str]
131+
database: Optional[str] = None
132132
resource_type: AltimateResourceType
133133
schema_name: str
134134
name: str
@@ -141,7 +141,7 @@ class AltimateManifestNode(BaseModel):
141141
config: Optional[AltimateNodeConfig] = None
142142
raw_code: Optional[str] = ""
143143
language: Optional[str] = "sql"
144-
checksum: Optional[AltimateFileHash]
144+
checksum: Optional[AltimateFileHash] = None
145145
description: Optional[str] = ""
146146
columns: Optional[Dict[str, AltimateManifestColumnInfo]] = None
147147
relation_name: Optional[Optional[str]] = None
@@ -151,7 +151,7 @@ class AltimateManifestNode(BaseModel):
151151
compiled_path: Optional[Optional[str]] = None
152152
compiled: Optional[bool] = False
153153
compiled_code: Optional[Optional[str]] = None
154-
access: Optional[AltimateAccess]
154+
access: Optional[AltimateAccess] = None
155155
contract: Optional[AltimateDBTContract] = None
156156
meta: Optional[Dict[str, Any]] = None
157157
patch_path: Optional[Optional[str]] = None
@@ -190,10 +190,10 @@ class AltimateSourceConfig(BaseModel):
190190

191191

192192
class AltimateDeferRelation(BaseModel):
193-
database: Optional[str]
193+
database: Optional[str] = None
194194
schema_name: str
195195
alias: str
196-
relation_name: Optional[str]
196+
relation_name: Optional[str] = None
197197

198198

199199
class AltimateSeedConfig(BaseModel):
@@ -208,8 +208,8 @@ class AltimateSeedConfig(BaseModel):
208208
materialized: Optional[str] = "seed"
209209
incremental_strategy: Optional[Optional[str]] = None
210210
persist_docs: Optional[Dict[str, Any]] = None
211-
post_hook: Optional[List[AltimateHook]]
212-
pre_hook: Optional[List[AltimateHook]]
211+
post_hook: Optional[List[AltimateHook]] = None
212+
pre_hook: Optional[List[AltimateHook]] = None
213213
quoting: Optional[Dict[str, Any]] = None
214214
column_types: Optional[Dict[str, Any]] = None
215215
full_refresh: Optional[Optional[bool]] = None
@@ -225,7 +225,7 @@ class AltimateSeedConfig(BaseModel):
225225

226226

227227
class AltimateSeedNode(BaseModel):
228-
database: Optional[str]
228+
database: Optional[str] = None
229229
schema_name: str
230230
name: str
231231
resource_type: AltimateResourceType
@@ -235,7 +235,7 @@ class AltimateSeedNode(BaseModel):
235235
unique_id: str
236236
fqn: List[str]
237237
alias: str
238-
checksum: Optional[AltimateFileHash]
238+
checksum: Optional[AltimateFileHash] = None
239239
config: Optional[AltimateSeedConfig] = None
240240
tags: Optional[List[str]] = None
241241
description: Optional[str] = ""
@@ -257,7 +257,7 @@ class AltimateSeedNode(BaseModel):
257257

258258

259259
class AltimateManifestSourceNode(BaseModel):
260-
database: Optional[str]
260+
database: Optional[str] = None
261261
resource_type: AltimateResourceType
262262
schema_name: str
263263
name: str
@@ -379,7 +379,7 @@ class AltimateManifestTestNode(BaseModel):
379379
unique_id: str
380380
fqn: List[str]
381381
alias: str
382-
checksum: Optional[AltimateFileHash]
382+
checksum: Optional[AltimateFileHash] = None
383383
config: Optional[AltimateTestConfig] = None
384384
_event_status: Optional[Dict[str, Any]] = None
385385
tags: Optional[List[str]] = None

src/vendor/dbt_artifacts_parser/parsers/manifest/manifest_v1.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
from typing import Optional
1010
from typing import Union
1111

12-
from pydantic import ConfigDict
12+
from pydantic import StringConstraints, ConfigDict
1313
from pydantic import Field
14-
from pydantic import constr
1514

1615
from vendor.dbt_artifacts_parser.parsers.base import BaseParserModel
16+
from typing_extensions import Annotated
1717

1818

1919
class ManifestMetadata(BaseParserModel):
@@ -26,7 +26,7 @@ class ManifestMetadata(BaseParserModel):
2626
invocation_id: Optional[str] = None
2727
env: Optional[dict[str, str]] = {}
2828
project_id: Optional[str] = Field(None, description="A unique identifier for the project")
29-
user_id: Optional[constr(pattern=r"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}")] = Field(
29+
user_id: Optional[Annotated[str, StringConstraints(pattern=r"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}")]] = Field(
3030
None, description="A unique identifier for the user"
3131
)
3232
send_anonymous_usage_stats: Optional[bool] = Field(None, description="Whether dbt is configured to send anonymous usage statistics")
@@ -110,7 +110,7 @@ class TestConfig(BaseParserModel):
110110
database: Optional[str] = None
111111
tags: Optional[Union[list[str], str]] = []
112112
full_refresh: Optional[bool] = None
113-
severity: Optional[constr(pattern=r"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$")] = "ERROR"
113+
severity: Optional[Annotated[str, StringConstraints(pattern=r"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$")]] = "ERROR"
114114

115115

116116
class ResourceType2(Enum):

src/vendor/dbt_artifacts_parser/parsers/manifest/manifest_v10.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
from typing import Optional
1010
from typing import Union
1111

12-
from pydantic import ConfigDict
12+
from pydantic import StringConstraints, ConfigDict
1313
from pydantic import Field
14-
from pydantic import constr
1514

1615
from vendor.dbt_artifacts_parser.parsers.base import BaseParserModel
16+
from typing_extensions import Annotated
1717

1818

1919
class ManifestMetadata(BaseParserModel):
@@ -30,7 +30,7 @@ class ManifestMetadata(BaseParserModel):
3030
None,
3131
description="A unique identifier for the project, hashed from the project name",
3232
)
33-
user_id: Optional[constr(pattern=r"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}")] = Field(
33+
user_id: Optional[Annotated[str, StringConstraints(pattern=r"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}")]] = Field(
3434
None, description="A unique identifier for the user"
3535
)
3636
send_anonymous_usage_stats: Optional[bool] = Field(None, description="Whether dbt is configured to send anonymous usage statistics")
@@ -148,7 +148,7 @@ class TestConfig(BaseParserModel):
148148
meta: Optional[dict[str, Any]] = {}
149149
group: Optional[str] = None
150150
materialized: Optional[str] = "test"
151-
severity: Optional[constr(pattern=r"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$")] = "ERROR"
151+
severity: Optional[Annotated[str, StringConstraints(pattern=r"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$")]] = "ERROR"
152152
store_failures: Optional[bool] = None
153153
where: Optional[str] = None
154154
limit: Optional[int] = None

src/vendor/dbt_artifacts_parser/parsers/manifest/manifest_v11.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010
from typing import Union
1111
from uuid import UUID
1212

13-
from pydantic import ConfigDict
13+
from pydantic import StringConstraints, ConfigDict
1414
from pydantic import Field
15-
from pydantic import constr
1615

1716
from vendor.dbt_artifacts_parser.parsers.base import BaseParserModel
17+
from typing_extensions import Annotated
1818

1919

2020
class ManifestMetadata(BaseParserModel):
@@ -230,7 +230,7 @@ class TestConfig(BaseParserModel):
230230
meta: Optional[dict[str, Any]] = None
231231
group: Optional[str] = None
232232
materialized: Optional[str] = "test"
233-
severity: Optional[constr(pattern=r"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$")] = "ERROR"
233+
severity: Optional[Annotated[str, StringConstraints(pattern=r"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$")]] = "ERROR"
234234
store_failures: Optional[bool] = None
235235
store_failures_as: Optional[str] = None
236236
where: Optional[str] = None

src/vendor/dbt_artifacts_parser/parsers/manifest/manifest_v12.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010
from typing import Union
1111
from uuid import UUID
1212

13-
from pydantic import ConfigDict
13+
from pydantic import StringConstraints, ConfigDict
1414
from pydantic import Field
15-
from pydantic import constr
1615

1716
from vendor.dbt_artifacts_parser.parsers.base import BaseParserModel
17+
from typing_extensions import Annotated
1818

1919

2020
class Quoting(BaseParserModel):
@@ -475,7 +475,7 @@ class Config5(BaseParserModel):
475475
meta: Optional[dict[str, Any]] = None
476476
group: Optional[str] = None
477477
materialized: Optional[str] = "test"
478-
severity: Optional[constr(pattern=r"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$")] = "ERROR"
478+
severity: Optional[Annotated[str, StringConstraints(pattern=r"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$")]] = "ERROR"
479479
store_failures: Optional[bool] = None
480480
store_failures_as: Optional[str] = None
481481
where: Optional[str] = None
@@ -1132,7 +1132,7 @@ class Config14(BaseParserModel):
11321132
meta: Optional[dict[str, Any]] = None
11331133
group: Optional[str] = None
11341134
materialized: Optional[str] = "test"
1135-
severity: Optional[constr(pattern=r"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$")] = "ERROR"
1135+
severity: Optional[Annotated[str, StringConstraints(pattern=r"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$")]] = "ERROR"
11361136
store_failures: Optional[bool] = None
11371137
store_failures_as: Optional[str] = None
11381138
where: Optional[str] = None
@@ -2386,7 +2386,7 @@ class Config29(BaseParserModel):
23862386
meta: Optional[dict[str, Any]] = None
23872387
group: Optional[str] = None
23882388
materialized: Optional[str] = "test"
2389-
severity: Optional[constr(pattern=r"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$")] = "ERROR"
2389+
severity: Optional[Annotated[str, StringConstraints(pattern=r"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$")]] = "ERROR"
23902390
store_failures: Optional[bool] = None
23912391
store_failures_as: Optional[str] = None
23922392
where: Optional[str] = None
@@ -3016,7 +3016,7 @@ class Config38(BaseParserModel):
30163016
meta: Optional[dict[str, Any]] = None
30173017
group: Optional[str] = None
30183018
materialized: Optional[str] = "test"
3019-
severity: Optional[constr(pattern=r"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$")] = "ERROR"
3019+
severity: Optional[Annotated[str, StringConstraints(pattern=r"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$")]] = "ERROR"
30203020
store_failures: Optional[bool] = None
30213021
store_failures_as: Optional[str] = None
30223022
where: Optional[str] = None

src/vendor/dbt_artifacts_parser/parsers/manifest/manifest_v2.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
from typing import Optional
1010
from typing import Union
1111

12-
from pydantic import ConfigDict
12+
from pydantic import StringConstraints, ConfigDict
1313
from pydantic import Field
14-
from pydantic import constr
1514

1615
from vendor.dbt_artifacts_parser.parsers.base import BaseParserModel
16+
from typing_extensions import Annotated
1717

1818

1919
class ManifestMetadata(BaseParserModel):
@@ -26,7 +26,7 @@ class ManifestMetadata(BaseParserModel):
2626
invocation_id: Optional[str] = None
2727
env: Optional[dict[str, str]] = {}
2828
project_id: Optional[str] = Field(None, description="A unique identifier for the project")
29-
user_id: Optional[constr(pattern=r"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}")] = Field(
29+
user_id: Optional[Annotated[str, StringConstraints(pattern=r"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}")]] = Field(
3030
None, description="A unique identifier for the user"
3131
)
3232
send_anonymous_usage_stats: Optional[bool] = Field(None, description="Whether dbt is configured to send anonymous usage statistics")
@@ -110,7 +110,7 @@ class TestConfig(BaseParserModel):
110110
database: Optional[str] = None
111111
tags: Optional[Union[list[str], str]] = []
112112
full_refresh: Optional[bool] = None
113-
severity: Optional[constr(pattern=r"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$")] = "ERROR"
113+
severity: Optional[Annotated[str, StringConstraints(pattern=r"^([Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr])$")]] = "ERROR"
114114
store_failures: Optional[bool] = None
115115
where: Optional[str] = None
116116
limit: Optional[int] = None

0 commit comments

Comments
 (0)