coding-client 1.21.2__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.
Files changed (109) hide show
  1. coding_client/__init__.py +1 -0
  2. coding_client/api/__init__.py +19 -0
  3. coding_client/api/exception_handlers.py +158 -0
  4. coding_client/api/logging_setup.py +44 -0
  5. coding_client/api/metrics.py +40 -0
  6. coding_client/api/openapi_config.py +124 -0
  7. coding_client/api/request_logging.py +60 -0
  8. coding_client/api/validation.py +150 -0
  9. coding_client/auth/__init__.py +78 -0
  10. coding_client/auth/_default_tenant.py +132 -0
  11. coding_client/auth/_header_trust.py +98 -0
  12. coding_client/auth/_onbehalf.py +315 -0
  13. coding_client/auth/_trusted_networks.py +94 -0
  14. coding_client/auth/dependencies.py +61 -0
  15. coding_client/auth/middleware.py +445 -0
  16. coding_client/auth/models.py +83 -0
  17. coding_client/auth/outbound.py +137 -0
  18. coding_client/auth/rbac.py +21 -0
  19. coding_client/auth/rbac_coding.py +5 -0
  20. coding_client/auth/tenant.py +650 -0
  21. coding_client/auth/websocket.py +148 -0
  22. coding_client/clients/__init__.py +24 -0
  23. coding_client/clients/base.py +131 -0
  24. coding_client/clients/coding_ai.py +33 -0
  25. coding_client/clients/coding_analysis.py +36 -0
  26. coding_client/clients/coding_containers.py +45 -0
  27. coding_client/clients/coding_github.py +127 -0
  28. coding_client/clients/coding_realtime.py +127 -0
  29. coding_client/clients/coding_security.py +51 -0
  30. coding_client/clients/coding_testing.py +31 -0
  31. coding_client/clients/coding_workspaces.py +265 -0
  32. coding_client/config/__init__.py +12 -0
  33. coding_client/config/base_settings.py +61 -0
  34. coding_client/config/yaml_config_loader.py +172 -0
  35. coding_client/db/__init__.py +42 -0
  36. coding_client/db/db_types.py +122 -0
  37. coding_client/db/exceptions.py +59 -0
  38. coding_client/db/postgres_connection.py +572 -0
  39. coding_client/db/tenant_query_helper.py +417 -0
  40. coding_client/db_init.py +49 -0
  41. coding_client/exceptions/__init__.py +67 -0
  42. coding_client/exceptions/api_exceptions.py +395 -0
  43. coding_client/exceptions/pydantic_ai_exceptions.py +533 -0
  44. coding_client/interfaces/__init__.py +22 -0
  45. coding_client/interfaces/cache_interface.py +179 -0
  46. coding_client/interfaces/container_interface.py +49 -0
  47. coding_client/interfaces/docker_interface.py +283 -0
  48. coding_client/interfaces/graph_interface.py +28 -0
  49. coding_client/interfaces/security_interface.py +72 -0
  50. coding_client/interfaces/webhook_interface.py +67 -0
  51. coding_client/llm/__init__.py +54 -0
  52. coding_client/llm/base_agent.py +195 -0
  53. coding_client/llm/context.py +121 -0
  54. coding_client/llm/responses.py +102 -0
  55. coding_client/llm/routing.py +82 -0
  56. coding_client/llm/settings.py +102 -0
  57. coding_client/models/__init__.py +62 -0
  58. coding_client/models/agent.py +38 -0
  59. coding_client/models/ai_test_failure.py +745 -0
  60. coding_client/models/analysis.py +330 -0
  61. coding_client/models/architecture.py +685 -0
  62. coding_client/models/bug.py +128 -0
  63. coding_client/models/code_graph.py +317 -0
  64. coding_client/models/container.py +241 -0
  65. coding_client/models/core.py +878 -0
  66. coding_client/models/docker_container.py +104 -0
  67. coding_client/models/github.py +293 -0
  68. coding_client/models/logging.py +29 -0
  69. coding_client/models/package_manager.py +257 -0
  70. coding_client/models/pr_validation.py +440 -0
  71. coding_client/models/pydantic_ai.py +395 -0
  72. coding_client/models/repo_scanner.py +249 -0
  73. coding_client/models/responses.py +431 -0
  74. coding_client/models/security.py +185 -0
  75. coding_client/models/static_analysis.py +508 -0
  76. coding_client/models/system.py +48 -0
  77. coding_client/models/test_executor.py +204 -0
  78. coding_client/models/testing.py +673 -0
  79. coding_client/models/testing_config.py +200 -0
  80. coding_client/models/validation.py +127 -0
  81. coding_client/models_init.py +272 -0
  82. coding_client/telemetry.py +195 -0
  83. coding_client/testing.py +180 -0
  84. coding_client/types/__init__.py +130 -0
  85. coding_client/types/constraint_types.py +276 -0
  86. coding_client/types/core_types.py +112 -0
  87. coding_client/types/state_machine.py +443 -0
  88. coding_client/utils/__init__.py +86 -0
  89. coding_client/utils/archive_utils.py +387 -0
  90. coding_client/utils/ast_debug.py +45 -0
  91. coding_client/utils/async_timeout.py +364 -0
  92. coding_client/utils/constants.py +518 -0
  93. coding_client/utils/content_processing.py +326 -0
  94. coding_client/utils/database.py +916 -0
  95. coding_client/utils/encoding_helper.py +222 -0
  96. coding_client/utils/enum_helpers.py +166 -0
  97. coding_client/utils/file_operations.py +177 -0
  98. coding_client/utils/filesystem_ops.py +528 -0
  99. coding_client/utils/http_client.py +562 -0
  100. coding_client/utils/path_utils.py +471 -0
  101. coding_client/utils/profiling.py +421 -0
  102. coding_client/utils/response_builder.py +240 -0
  103. coding_client/utils/retry_helper.py +712 -0
  104. coding_client/utils/security_validation.py +423 -0
  105. coding_client-1.21.2.dist-info/METADATA +234 -0
  106. coding_client-1.21.2.dist-info/RECORD +109 -0
  107. coding_client-1.21.2.dist-info/WHEEL +5 -0
  108. coding_client-1.21.2.dist-info/licenses/LICENSE +201 -0
  109. coding_client-1.21.2.dist-info/top_level.txt +1 -0
@@ -0,0 +1,440 @@
1
+ """Pull request validation models for comprehensive change analysis.
2
+
3
+ This module provides sophisticated data models for analyzing pull request changes,
4
+ validating their impact, and generating actionable recommendations. The models
5
+ support detailed diff analysis, semantic change detection, and risk assessment
6
+ for code modifications.
7
+
8
+ The PR validation system enables:
9
+ - Comprehensive diff analysis with file-level change tracking
10
+ - Semantic analysis of code modifications using AST comparison
11
+ - Breaking change detection across API surfaces
12
+ - Impact assessment on tests, documentation, and dependencies
13
+ - Risk-based validation with automated recommendations
14
+ - Context-aware validation based on codebase patterns
15
+
16
+ Key Model Categories:
17
+ Change Models: FileChange, PRDiff for representing file modifications
18
+ Analysis Models: DiffAnalysisResult, SemanticAnalysisResult for change analysis
19
+ Validation Models: ValidationResult, ValidationIssue for validation outcomes
20
+ Impact Models: ChangeImpact, TestImpact, DocumentationImpact for scope analysis
21
+ Context Models: CodebaseContext, PRAnalysisContext for analysis environment
22
+
23
+ Example:
24
+ ```python
25
+ from pr_validation_models import (
26
+ FileChange, PRDiff, ValidationResult,
27
+ ChangeType, RiskLevel, ChangeSeverity
28
+ )
29
+
30
+ # Create file change
31
+ file_change = FileChange(
32
+ filename="src/api/handlers.py",
33
+ file_type=FileType.PYTHON,
34
+ change_type=ChangeType.MODIFIED,
35
+ additions=15,
36
+ deletions=8,
37
+ patch="@@ -42,7 +42,10 @@ def process_request(request):",
38
+ before_content="def process_request(request):\n return handle(request)",
39
+ after_content="def process_request(request: Request) -> Response:\n return handle(request)"
40
+ )
41
+
42
+ # Create PR diff
43
+ pr_diff = PRDiff(
44
+ base_sha="abc123",
45
+ head_sha="def456",
46
+ files_changed=[file_change],
47
+ stats=DiffStats.from_files([file_change]),
48
+ metadata={"pr_number": 123, "author": "developer"}
49
+ )
50
+
51
+ # Validation result
52
+ result = ScriptValidationResult(
53
+ validation_type="type_safety",
54
+ passed=True,
55
+ score=0.95,
56
+ risk_level=RiskLevel.LOW,
57
+ issues=[],
58
+ recommendations=[],
59
+ confidence=0.9
60
+ )
61
+ ```
62
+ """
63
+
64
+ from __future__ import annotations
65
+
66
+ import ast
67
+ from dataclasses import dataclass, field
68
+ from datetime import UTC, datetime
69
+ from enum import Enum
70
+ from typing import Any
71
+
72
+ from .static_analysis import StaticAnalysisChangeType
73
+
74
+ # Alias for backward compatibility
75
+ ChangeType = StaticAnalysisChangeType
76
+
77
+
78
+ class FileType(Enum):
79
+ """File types for specialized validation."""
80
+
81
+ PYTHON = "python"
82
+ JAVASCRIPT = "javascript"
83
+ TYPESCRIPT = "typescript"
84
+ MARKDOWN = "markdown"
85
+ YAML = "yaml"
86
+ JSON = "json"
87
+ HTML = "html"
88
+ CSS = "css"
89
+ DOCKERFILE = "dockerfile"
90
+ UNKNOWN = "unknown"
91
+
92
+
93
+ class RiskLevel(Enum):
94
+ """Risk levels for validation results."""
95
+
96
+ LOW = "LOW"
97
+ MEDIUM = "MEDIUM"
98
+ HIGH = "HIGH"
99
+ CRITICAL = "CRITICAL"
100
+
101
+
102
+ class ChangeSeverity(Enum):
103
+ """Severity levels for file changes."""
104
+
105
+ MINOR = "MINOR"
106
+ MODERATE = "MODERATE"
107
+ MAJOR = "MAJOR"
108
+ COMPLETE_REWRITE = "COMPLETE_REWRITE"
109
+ SECURITY_ISSUE = "SECURITY_ISSUE"
110
+ UNKNOWN = "UNKNOWN"
111
+
112
+
113
+ @dataclass
114
+ class DiffStats:
115
+ """Statistics about a PR diff."""
116
+
117
+ total_files: int
118
+ total_additions: int
119
+ total_deletions: int
120
+ files_added: int
121
+ files_deleted: int
122
+ files_modified: int
123
+ files_renamed: int
124
+
125
+ @classmethod
126
+ def from_files(cls, files_changed: list[FileChange]) -> DiffStats:
127
+ """Create DiffStats from a list of file changes."""
128
+ total_additions = sum(f.additions for f in files_changed)
129
+ total_deletions = sum(f.deletions for f in files_changed)
130
+
131
+ files_added = sum(1 for f in files_changed if f.change_type == ChangeType.ADDED)
132
+ files_deleted = sum(1 for f in files_changed if f.change_type == ChangeType.DELETED)
133
+ files_modified = sum(1 for f in files_changed if f.change_type == ChangeType.MODIFIED)
134
+ files_renamed = sum(1 for f in files_changed if f.change_type == ChangeType.RENAMED)
135
+
136
+ return cls(
137
+ total_files=len(files_changed),
138
+ total_additions=total_additions,
139
+ total_deletions=total_deletions,
140
+ files_added=files_added,
141
+ files_deleted=files_deleted,
142
+ files_modified=files_modified,
143
+ files_renamed=files_renamed,
144
+ )
145
+
146
+
147
+ @dataclass
148
+ class ValidationFileChange:
149
+ """Represents changes to a single file in validation context."""
150
+
151
+ filename: str
152
+ file_type: FileType
153
+ change_type: ChangeType
154
+ additions: int
155
+ deletions: int
156
+ patch: str
157
+ before_content: str | None = None
158
+ after_content: str | None = None
159
+ ast_before: ast.AST | None = None
160
+ ast_after: ast.AST | None = None
161
+ binary: bool = False
162
+
163
+ @property
164
+ def total_changes(self) -> int:
165
+ """Total number of line changes."""
166
+ return self.additions + self.deletions
167
+
168
+
169
+ # Alias for backward compatibility
170
+ FileChange = ValidationFileChange
171
+
172
+
173
+ @dataclass
174
+ class PRDiff:
175
+ """Represents a complete PR diff with all changes."""
176
+
177
+ base_sha: str
178
+ head_sha: str
179
+ files_changed: list[FileChange]
180
+ stats: DiffStats
181
+ metadata: dict[str, Any]
182
+
183
+ @property
184
+ def change_complexity(self) -> float:
185
+ """Calculate overall change complexity."""
186
+ if not self.files_changed:
187
+ return 0.0
188
+
189
+ total_changes = sum(f.total_changes for f in self.files_changed)
190
+ return min(total_changes / 100.0, 10.0) # Cap at 10.0
191
+
192
+
193
+ @dataclass
194
+ class ValidationIssue:
195
+ """Represents a validation issue found during analysis."""
196
+
197
+ type: str
198
+ severity: str
199
+ message: str
200
+ file: str
201
+ line: int | None = None
202
+ column: int | None = None
203
+ rule: str | None = None
204
+ suggestion: str | None = None
205
+
206
+
207
+ @dataclass
208
+ class Recommendation:
209
+ """Represents an actionable recommendation for update."""
210
+
211
+ type: str
212
+ priority: str
213
+ description: str
214
+ action: str
215
+ file: str | None = None
216
+ automated: bool = False
217
+
218
+
219
+ @dataclass
220
+ class APICompatibility:
221
+ """Represents API compatibility information."""
222
+
223
+ is_compatible: bool
224
+ breaking_changes: list[str]
225
+ deprecations: list[str]
226
+ version_impact: str # MAJOR, MINOR, PATCH
227
+
228
+
229
+ @dataclass
230
+ class TestImpact:
231
+ """Represents impact on tests."""
232
+
233
+ tests_affected: list[str]
234
+ coverage_change: float
235
+ new_tests_needed: list[str]
236
+ obsolete_tests: list[str]
237
+
238
+
239
+ @dataclass
240
+ class DocumentationImpact:
241
+ """Represents impact on documentation."""
242
+
243
+ docs_affected: list[str]
244
+ outdated_docs: list[str]
245
+ new_docs_needed: list[str]
246
+ doc_completeness_score: float
247
+
248
+
249
+ @dataclass
250
+ class ChangeImpact:
251
+ """Represents the impact scope of changes."""
252
+
253
+ affected_functions: list[str]
254
+ affected_classes: list[str]
255
+ dependency_impact: list[str]
256
+ test_impact: TestImpact
257
+ documentation_impact: DocumentationImpact
258
+ api_compatibility: APICompatibility
259
+ estimated_effort: str # LOW, MEDIUM, HIGH
260
+
261
+
262
+ @dataclass
263
+ class ValidationResult:
264
+ """Augmented validation result with change context."""
265
+
266
+ validation_type: str
267
+ passed: bool
268
+ score: float
269
+ risk_level: RiskLevel
270
+ issues: list[ValidationIssue]
271
+ recommendations: list[Recommendation]
272
+ change_impact: ChangeImpact | None = None
273
+ confidence: float = 1.0
274
+ execution_time: float = 0.0
275
+ timestamp: datetime = field(default_factory=lambda: datetime.now(UTC))
276
+
277
+ @property
278
+ def critical_issues(self) -> list[ValidationIssue]:
279
+ """Get only critical issues."""
280
+ return [issue for issue in self.issues if issue.severity == "CRITICAL"]
281
+
282
+ @property
283
+ def high_priority_recommendations(self) -> list[Recommendation]:
284
+ """Get high priority recommendations."""
285
+ return [rec for rec in self.recommendations if rec.priority == "HIGH"]
286
+
287
+
288
+ @dataclass
289
+ class FileChangeAnalysis:
290
+ """Analysis result for a single file change."""
291
+
292
+ filename: str
293
+ change_severity: ChangeSeverity
294
+ change_patterns: list[str]
295
+ risk_indicators: list[str]
296
+ line_change_ratio: float
297
+ content_similarity: float
298
+ file_type: FileType
299
+
300
+ @property
301
+ def is_high_risk(self) -> bool:
302
+ """Check if this change is high risk."""
303
+ return (
304
+ self.change_severity in [ChangeSeverity.COMPLETE_REWRITE, ChangeSeverity.SECURITY_ISSUE]
305
+ or "DANGEROUS_LOGIC_CHANGES" in self.risk_indicators
306
+ or "SECURITY_SENSITIVE_FILE_MODIFIED" in self.risk_indicators
307
+ )
308
+
309
+
310
+ @dataclass
311
+ class DiffAnalysisResult:
312
+ """Result of diff analysis."""
313
+
314
+ file_analyses: list[FileChangeAnalysis]
315
+ overall_patterns: list[str]
316
+ risk_factors: list[str]
317
+ change_complexity: float
318
+ requires_careful_review: bool
319
+
320
+ @property
321
+ def high_risk_files(self) -> list[FileChangeAnalysis]:
322
+ """Get files that are high risk."""
323
+ return [analysis for analysis in self.file_analyses if analysis.is_high_risk]
324
+
325
+
326
+ @dataclass
327
+ class FunctionSignature:
328
+ """Represents a function signature for comparison."""
329
+
330
+ name: str
331
+ args: list[str]
332
+ defaults: list[str]
333
+ varargs: str | None
334
+ kwargs: str | None
335
+ return_type: str | None
336
+ decorators: list[str]
337
+ is_public: bool
338
+ lineno: int
339
+
340
+
341
+ @dataclass
342
+ class ClassDefinition:
343
+ """Represents a class definition for comparison."""
344
+
345
+ name: str
346
+ bases: list[str]
347
+ methods: dict[str, FunctionSignature]
348
+ attributes: list[str]
349
+ is_public: bool
350
+ lineno: int
351
+
352
+
353
+ @dataclass
354
+ class BreakingChange:
355
+ """Represents a breaking change in the API."""
356
+
357
+ type: str
358
+ severity: str
359
+ description: str
360
+ file_path: str
361
+ affected_symbol: str
362
+ recommendation: str
363
+ line_number: int | None = None
364
+ confidence: float = 1.0
365
+
366
+
367
+ @dataclass
368
+ class SemanticAnalysisResult:
369
+ """Result of semantic analysis."""
370
+
371
+ breaking_changes: list[BreakingChange]
372
+ logic_safety_issues: list[ValidationIssue]
373
+ api_surface_changes: dict[str, Any]
374
+ complexity_changes: dict[str, float]
375
+
376
+ @property
377
+ def has_breaking_changes(self) -> bool:
378
+ """Check if there are any breaking changes."""
379
+ return len(self.breaking_changes) > 0
380
+
381
+ @property
382
+ def has_logic_safety_issues(self) -> bool:
383
+ """Check if there are logic safety issues."""
384
+ return len(self.logic_safety_issues) > 0
385
+
386
+
387
+ @dataclass
388
+ class ImpactAssessment:
389
+ """Assessment of change impact across the codebase."""
390
+
391
+ dependency_impacts: list[str]
392
+ test_coverage_impact: TestImpact
393
+ documentation_impact: DocumentationImpact
394
+ performance_impact: dict[str, Any]
395
+ security_impact: dict[str, Any]
396
+
397
+ @property
398
+ def overall_impact_score(self) -> float:
399
+ """Calculate overall impact score."""
400
+ score = 0.0
401
+ if self.dependency_impacts:
402
+ score += len(self.dependency_impacts) * 0.1
403
+ if self.test_coverage_impact.coverage_change < 0:
404
+ score += abs(self.test_coverage_impact.coverage_change) * 2.0
405
+ if self.documentation_impact.outdated_docs:
406
+ score += len(self.documentation_impact.outdated_docs) * 0.05
407
+ return min(score, 10.0)
408
+
409
+
410
+ @dataclass
411
+ class CodebaseContext:
412
+ """Context about the codebase for analysis."""
413
+
414
+ total_files: int
415
+ total_lines: int
416
+ main_languages: list[str]
417
+ test_framework: str | None
418
+ documentation_format: str | None
419
+ dependencies: list[str]
420
+ architecture_patterns: list[str]
421
+
422
+
423
+ @dataclass
424
+ class PRAnalysisContext:
425
+ """Context for running analysis."""
426
+
427
+ pr_diff: PRDiff
428
+ codebase_context: CodebaseContext
429
+ diff_analysis: DiffAnalysisResult | None = None
430
+ semantic_analysis: SemanticAnalysisResult | None = None
431
+ impact_assessment: ImpactAssessment | None = None
432
+ validation_config: dict[str, Any] = field(default_factory=dict)
433
+
434
+
435
+ # Rebuild models to ensure proper forward reference resolution
436
+ # For Pydantic v2, use model_rebuild if available, otherwise skip
437
+ if hasattr(FunctionSignature, "model_rebuild"):
438
+ FunctionSignature.model_rebuild()
439
+ if hasattr(FileChange, "model_rebuild"):
440
+ FileChange.model_rebuild()