Skip to content

Commit ebd9928

Browse files
committed
PR 11 finished
1 parent 87b644a commit ebd9928

7 files changed

Lines changed: 83 additions & 71 deletions

File tree

backend/python/plugins/azuredevops/azuredevops/models.py

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -30,26 +30,26 @@
3030

3131
class AzureDevOpsConnection(Connection):
3232
token: SecretStr
33-
organization: Optional[str]
33+
organization: Optional[str] = None
3434

3535

3636
class GitRepositoryConfig(ScopeConfig):
37-
refdiff: Optional[RefDiffOptions]
38-
deployment_pattern: Optional[re.Pattern]
39-
production_pattern: Optional[re.Pattern]
37+
refdiff: Optional[RefDiffOptions] = None
38+
deployment_pattern: Optional[re.Pattern] = None
39+
production_pattern: Optional[re.Pattern] = None
4040
# Optional pattern with capture group to extract environment name from job/stage names
4141
# Example: r'(?:deploy|predeploy)[_-](.+?)(?:[_-](?:helm|terraform))?$' extracts 'xxxx-prod' from 'deploy_xxxx-prod_helm'
42-
environment_pattern: Optional[re.Pattern]
42+
environment_pattern: Optional[re.Pattern] = None
4343

4444

4545
class GitRepository(ToolScope, table=True):
4646
url: str
47-
remote_url: Optional[str]
48-
default_branch: Optional[str]
47+
remote_url: Optional[str] = None
48+
default_branch: Optional[str] = None
4949
project_id: str
5050
org_id: str
5151
parent_repository_url: Optional[str] = Field(source='/parentRepository/url')
52-
provider: Optional[str]
52+
provider: Optional[str] = None
5353
updated_date: datetime.datetime = Field(source='/project/lastUpdateTime')
5454

5555
def is_external(self):
@@ -63,20 +63,20 @@ class PRStatus(Enum):
6363
Completed = "completed"
6464

6565
pull_request_id: int = Field(primary_key=True)
66-
description: Optional[str]
66+
description: Optional[str] = None
6767
status: PRStatus
6868
created_by_id: str = Field(source='/createdBy/id')
6969
created_by_name: str = Field(source='/createdBy/displayName')
7070
creation_date: datetime.datetime
71-
closed_date: Optional[datetime.datetime]
71+
closed_date: Optional[datetime.datetime] = None
7272
source_commit_sha: str = Field(source='/lastMergeSourceCommit/commitId')
7373
target_commit_sha: str = Field(source='/lastMergeTargetCommit/commitId')
7474
merge_commit_sha: Optional[str] = Field(source='/lastMergeCommit/commitId')
75-
url: Optional[str]
75+
url: Optional[str] = None
7676
type: Optional[str] = Field(source='/labels/0/name') # TODO: Add regex to scope config
77-
title: Optional[str]
78-
target_ref_name: Optional[str]
79-
source_ref_name: Optional[str]
77+
title: Optional[str] = None
78+
target_ref_name: Optional[str] = None
79+
source_ref_name: Optional[str] = None
8080
fork_repo_id: Optional[str] = Field(source='/forkSource/repository/id')
8181

8282

@@ -112,10 +112,10 @@ def __str__(self) -> str:
112112
id: int = Field(primary_key=True)
113113
name: str = Field(source='/definition/name')
114114
queue_time: Optional[datetime.datetime] = Field(source='/queueTime')
115-
start_time: Optional[datetime.datetime]
116-
finish_time: Optional[datetime.datetime]
115+
start_time: Optional[datetime.datetime] = None
116+
finish_time: Optional[datetime.datetime] = None
117117
status: BuildStatus
118-
result: Optional[BuildResult]
118+
result: Optional[BuildResult] = None
119119
source_branch: str
120120
source_version: str
121121
display_title: Optional[str] = Field(source='/triggerInfo/ci.message')
@@ -145,10 +145,10 @@ def __str__(self) -> str:
145145
id: str = Field(primary_key=True)
146146
build_id: str = Field(primary_key=True)
147147
name: str
148-
start_time: Optional[datetime.datetime]
149-
finish_time: Optional[datetime.datetime]
148+
start_time: Optional[datetime.datetime] = None
149+
finish_time: Optional[datetime.datetime] = None
150150
state: JobState
151-
result: Optional[JobResult]
152-
identifier: Optional[str]
153-
type: Optional[str]
151+
result: Optional[JobResult] = None
152+
identifier: Optional[str] = None
153+
type: Optional[str] = None
154154
parent_id: Optional[str] = Field(source='/parentId')

backend/python/pydevlake/pydevlake/domain_layer/code.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@ class PullRequest(DomainModel, table=True):
3333
url: str
3434
author_name: str
3535
author_id: str
36-
parent_pr_id: Optional[str]
36+
parent_pr_id: Optional[str] = None
3737
pull_request_key: int
3838
created_date: datetime
39-
merged_date: Optional[datetime]
40-
closed_date: Optional[datetime]
39+
merged_date: Optional[datetime] = None
40+
closed_date: Optional[datetime] = None
4141
type: str
4242
component: str
4343
merge_commit_sha: str
@@ -78,8 +78,8 @@ class Commit(NoPKModel, table=True):
7878
__tablename__ = 'commits'
7979
sha: str = Field(primary_key=True)
8080
additions: str
81-
deletions: Optional[str]
82-
dev_eq: Optional[str]
81+
deletions: Optional[str] = None
82+
dev_eq: Optional[str] = None
8383
message: str
8484
author_name: str
8585
author_email: int
@@ -144,12 +144,12 @@ class Repo(DomainScope, table=True):
144144
__tablename__ = "repos"
145145
name: str
146146
url: str
147-
description: Optional[str]
148-
owner_id: Optional[str]
149-
language: Optional[str]
150-
forked_from: Optional[str]
151-
created_date: Optional[datetime]
152-
updated_date: Optional[datetime]
147+
description: Optional[str] = None
148+
owner_id: Optional[str] = None
149+
language: Optional[str] = None
150+
forked_from: Optional[str] = None
151+
created_date: Optional[datetime] = None
152+
updated_date: Optional[datetime] = None
153153
deleted: bool
154154

155155

backend/python/pydevlake/pydevlake/domain_layer/devops.py

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -51,26 +51,26 @@ class CICDPipeline(DomainModel, table=True):
5151
__tablename__ = 'cicd_pipelines'
5252

5353
name: str
54-
cicd_scope_id: Optional[str]
54+
cicd_scope_id: Optional[str] = None
5555

56-
status: Optional[CICDStatus]
57-
result: Optional[CICDResult]
58-
original_status: Optional[str]
59-
original_result: Optional[str]
56+
status: Optional[CICDStatus] = None
57+
result: Optional[CICDResult] = None
58+
original_status: Optional[str] = None
59+
original_result: Optional[str] = None
6060

61-
created_date: Optional[datetime]
62-
started_date: Optional[datetime]
63-
queued_date: Optional[datetime]
64-
finished_date: Optional[datetime]
61+
created_date: Optional[datetime] = None
62+
started_date: Optional[datetime] = None
63+
queued_date: Optional[datetime] = None
64+
finished_date: Optional[datetime] = None
6565

66-
duration_sec: Optional[float]
67-
queued_duration_sec: Optional[float]
66+
duration_sec: Optional[float] = None
67+
queued_duration_sec: Optional[float] = None
6868

69-
type: Optional[CICDType]
70-
environment: Optional[CICDEnvironment]
69+
type: Optional[CICDType] = None
70+
environment: Optional[CICDEnvironment] = None
7171

72-
display_title: Optional[str]
73-
url: Optional[str]
72+
display_title: Optional[str] = None
73+
url: Optional[str] = None
7474

7575

7676
class CiCDPipelineCommit(NoPKModel, table=True):
@@ -80,17 +80,17 @@ class CiCDPipelineCommit(NoPKModel, table=True):
8080
branch: str
8181
repo_id: str
8282
repo_url: str
83-
display_title: Optional[str]
84-
url: Optional[str]
83+
display_title: Optional[str] = None
84+
url: Optional[str] = None
8585

8686

8787
class CicdScope(DomainScope):
8888
__tablename__ = 'cicd_scopes'
8989
name: str
90-
description: Optional[str]
91-
url: Optional[str]
92-
createdDate: Optional[datetime]
93-
updatedDate: Optional[datetime]
90+
description: Optional[str] = None
91+
url: Optional[str] = None
92+
createdDate: Optional[datetime] = None
93+
updatedDate: Optional[datetime] = None
9494

9595

9696
class CICDTask(DomainModel, table=True):
@@ -100,18 +100,18 @@ class CICDTask(DomainModel, table=True):
100100
pipeline_id: str
101101
cicd_scope_id: str
102102

103-
result: Optional[CICDResult]
104-
status: Optional[CICDStatus]
105-
original_status: Optional[str]
106-
original_result: Optional[str]
103+
result: Optional[CICDResult] = None
104+
status: Optional[CICDStatus] = None
105+
original_status: Optional[str] = None
106+
original_result: Optional[str] = None
107107

108-
type: Optional[CICDType]
109-
environment: Optional[CICDEnvironment]
108+
type: Optional[CICDType] = None
109+
environment: Optional[CICDEnvironment] = None
110110

111-
created_date: Optional[datetime]
112-
queued_date: Optional[datetime]
113-
started_date: Optional[datetime]
114-
finished_date: Optional[datetime]
111+
created_date: Optional[datetime] = None
112+
queued_date: Optional[datetime] = None
113+
started_date: Optional[datetime] = None
114+
finished_date: Optional[datetime] = None
115115

116116
duration_sec: float
117-
queued_duration_sec: Optional[float]
117+
queued_duration_sec: Optional[float] = None

backend/python/pydevlake/pydevlake/extractor.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,4 +81,7 @@ class DummyModel(ToolModel):
8181
alias = field_info.alias
8282
value = json.get(field_name) or json.get(alias) if alias else json.get(field_name)
8383
attributes[field_name] = value
84-
return model_cls(**attributes)
84+
# Use model_validate so values are coerced (e.g. str -> datetime/Enum).
85+
# SQLModel table=True models skip validation on __init__, which would leave
86+
# raw strings uncoerced under Pydantic v2, so validate explicitly here.
87+
return model_cls.model_validate(attributes)

backend/python/pydevlake/pydevlake/model.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ def primary_keys(self) -> Iterable[object]:
161161

162162

163163
class DomainModel(NoPKModel):
164-
id: Optional[str] = Field(primary_key=True)
164+
id: Optional[str] = Field(default=None, primary_key=True)
165165

166166

167167
class ToolScope(ToolModel):
@@ -214,5 +214,5 @@ class SubtaskRun(SQLModel, table=True):
214214
subtask_name: str
215215
connection_id: int
216216
started: datetime
217-
completed: Optional[datetime]
217+
completed: Optional[datetime] = None
218218
state: str = Field(sa_type=Text()) # JSON encoded dict of atomic values

backend/python/pydevlake/pydevlake/testing/testing.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,15 @@ def make_context(connection, scope, scope_config):
6363
)
6464

6565

66+
def _revalidate(model):
67+
# Under Pydantic v2, SQLModel table models don't coerce field values on
68+
# construction. Expected models built from raw values (e.g. date strings)
69+
# therefore keep their raw type, while converted results are already
70+
# coerced. Re-validating normalizes the field types on both sides so the
71+
# comparison behaves like it did under Pydantic v1.
72+
return type(model).model_validate(model.model_dump(warnings=False))
73+
74+
6675
def assert_stream_convert(plugin: Union[Plugin, Type[Plugin]], stream_name: str,
6776
raw: dict, expected: Union[DomainModel, Iterable[DomainModel]],
6877
ctx=None):
@@ -82,7 +91,7 @@ def assert_stream_convert(plugin: Union[Plugin, Type[Plugin]], stream_name: str,
8291
hasattr(exp, "__getitem__") and exp[0] == "updated_at"):
8392
pass
8493
else:
85-
assert res == exp
94+
assert _revalidate(res) == _revalidate(exp)
8695

8796

8897
def assert_stream_run(stream: Stream, connection: Connection, scope: ToolScope, scope_config: ScopeConfig):

backend/python/test/fakeplugin/fakeplugin/models.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,6 @@ class State(Enum):
4242
SUCCESS = "success"
4343

4444
id: str = Field(primary_key=True)
45-
started_at: Optional[datetime]
46-
finished_at: Optional[datetime]
45+
started_at: Optional[datetime] = None
46+
finished_at: Optional[datetime] = None
4747
state: State

0 commit comments

Comments
 (0)