Coverage for src/csv_schema_validator/schema_models.py: 64%
42 statements
« prev ^ index » next coverage.py v7.10.6, created at 2025-09-20 12:34 +0200
« prev ^ index » next coverage.py v7.10.6, created at 2025-09-20 12:34 +0200
1from pydantic import BaseModel, Field, field_validator, model_validator
2from typing import List, Optional
3from enum import Enum
6class FieldType(str, Enum):
7 STRING = "string"
8 NUMBER = "number"
9 INTEGER = "integer"
10 BOOLEAN = "boolean"
13class FieldSchema(BaseModel):
14 name: str = Field(..., description="Field name")
15 type: FieldType = Field(..., description="Field data type")
16 required: bool = Field(..., description="Whether the field is required")
17 description: Optional[str] = Field(None, description="Field description")
18 pattern: Optional[str] = Field(None, description="Field pattern")
19 enum: Optional[List[str]] = Field(None, description="Field enum")
20 min: Optional[int] = Field(None, description="Field minimum value")
21 max: Optional[int] = Field(None, description="Field maximum value")
23 @field_validator("pattern")
24 def validate_pattern(cls, v):
25 if v is not None:
26 import re
28 try:
29 re.compile(v)
30 except re.error as e:
31 raise ValueError(f"Invalid pattern: {e}")
32 return v
34 @model_validator(mode="after")
35 def validate_min_max(self):
36 if self.min is not None or self.max is not None:
37 if self.type in ["string", "boolean"]:
38 raise ValueError(
39 f"min/max constraints not applicable for {self.type} type"
40 )
41 return self
44class CSVSchema(BaseModel):
45 name: str = Field(..., description="Schema name")
46 description: Optional[str] = Field(None, description="Schema description")
47 fields: List[FieldSchema] = Field(..., min_items=1, description="Field definitions")
49 @field_validator("fields")
50 def validate_fields(cls, v):
51 names = [field.name for field in v]
52 if len(names) != len(set(names)):
53 raise ValueError("Field names must be unique")
54 return v