Skip to content

Commit 201b5ed

Browse files
committed
Merge branch 'chore/dev-tooling' into feat/arabic-shaping
2 parents 5cae3c4 + f552e27 commit 201b5ed

72 files changed

Lines changed: 1300 additions & 1149 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

pyproject.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,4 +111,6 @@ ignore = [
111111
]
112112

113113
[tool.ruff.lint.per-file-ignores]
114+
# Re-exporting is what an __init__.py is for; the packages that care declare __all__.
115+
"__init__.py" = ["F401"]
114116
"tests/*" = ["B011"]

src/ocrsmith/cli.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33

44
def main() -> None:
5-
app_main()
5+
app_main()
66

77

88
if __name__ == "__main__":
9-
main()
9+
main()

src/ocrsmith/config/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
# src/ocrsmith/config/__init__.py
2-
from .schema import AppConfig
32
from .loader import load_config
3+
from .schema import AppConfig

src/ocrsmith/config/loader.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
# src/ocrsmith/config/loader.py
2-
from .schema import AppConfig
3-
import yaml
42
import os
53

4+
import yaml
5+
6+
from .schema import AppConfig
7+
8+
69
def load_config(config_path=None):
710
if config_path is None:
811
config_path = os.path.join(os.path.dirname(__file__), "default_config.yaml")
9-
with open(config_path, "r") as f:
12+
with open(config_path) as f:
1013
config_dict = yaml.safe_load(f)
1114

1215
config = AppConfig(**config_dict)
13-
return config
16+
return config

src/ocrsmith/config/schema.py

Lines changed: 95 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,182 +1,208 @@
11
# src/ocrsmith/config/schema.py
2-
from pydantic import BaseModel, Field, field_validator, model_validator
3-
from typing import List, Optional, Tuple, Union, Literal
4-
import yaml
2+
from typing import Literal
3+
4+
from pydantic import BaseModel, Field
5+
56

67
class FontConfig(BaseModel):
7-
name: Optional[str] = None
8+
name: str | None = None
89
path: str
9-
size: Optional[int] = 24
10+
size: int | None = 24
11+
1012

1113
class SolidBackgroundConfig(BaseModel):
1214
type: Literal["solid"]
13-
color: Union[str, Tuple[int, int, int]] = (255, 255, 255)
15+
color: str | tuple[int, int, int] = (255, 255, 255)
1416
weight: float = 1.0
1517

18+
1619
class ImageBackgroundConfig(BaseModel):
1720
type: Literal["image"]
1821
image_path: str
1922
mode: Literal["stretch", "crop", "tile", "center"] = "stretch"
2023
weight: float = 1.0
2124

25+
2226
class GradientBackgroundConfig(BaseModel):
2327
type: Literal["gradient"]
24-
start_color: Tuple[int, int, int] = (255, 255, 255)
25-
end_color: Tuple[int, int, int] = (200, 200, 200)
28+
start_color: tuple[int, int, int] = (255, 255, 255)
29+
end_color: tuple[int, int, int] = (200, 200, 200)
2630
direction: Literal["horizontal", "vertical", "diagonal"] = "horizontal"
2731
weight: float = 1.0
2832

33+
2934
class TextureBackgroundConfig(BaseModel):
3035
type: Literal["texture"]
31-
base_color: Tuple[int, int, int] = (240, 240, 240)
36+
base_color: tuple[int, int, int] = (240, 240, 240)
3237
noise_level: int = Field(default=20, ge=0, le=255)
3338
weight: float = 1.0
3439

35-
BackgroundConfigUnion = Union[
36-
SolidBackgroundConfig,
37-
ImageBackgroundConfig,
38-
GradientBackgroundConfig,
39-
TextureBackgroundConfig
40-
]
40+
41+
BackgroundConfigUnion = (
42+
SolidBackgroundConfig | ImageBackgroundConfig | GradientBackgroundConfig | TextureBackgroundConfig
43+
)
44+
4145

4246
class SimpleTextRendererConfig(BaseModel):
4347
type: Literal["simple"]
44-
color: Tuple[int, int, int] = (0, 0, 0)
48+
color: tuple[int, int, int] = (0, 0, 0)
4549
weight: float = 1.0
4650

51+
4752
class OutlinedTextRendererConfig(BaseModel):
4853
type: Literal["outlined"]
49-
fill_color: Tuple[int, int, int] = (255, 255, 255)
50-
outline_color: Tuple[int, int, int] = (0, 0, 0)
54+
fill_color: tuple[int, int, int] = (255, 255, 255)
55+
outline_color: tuple[int, int, int] = (0, 0, 0)
5156
outline_width: int = 2
5257
weight: float = 1.0
5358

59+
5460
class ShadowedTextRendererConfig(BaseModel):
5561
type: Literal["shadowed"]
56-
text_color: Tuple[int, int, int] = (0, 0, 0)
57-
shadow_color: Tuple[int, int, int] = (128, 128, 128)
58-
shadow_offset: Tuple[int, int] = (2, 2)
62+
text_color: tuple[int, int, int] = (0, 0, 0)
63+
shadow_color: tuple[int, int, int] = (128, 128, 128)
64+
shadow_offset: tuple[int, int] = (2, 2)
5965
weight: float = 1.0
6066

67+
6168
class GradientTextRendererConfig(BaseModel):
6269
type: Literal["gradient"]
63-
start_color: Tuple[int, int, int] = (255, 0, 0)
64-
end_color: Tuple[int, int, int] = (0, 0, 255)
70+
start_color: tuple[int, int, int] = (255, 0, 0)
71+
end_color: tuple[int, int, int] = (0, 0, 255)
6572
weight: float = 1.0
6673

74+
6775
class HorizontalTextRendererConfig(BaseModel):
6876
type: Literal["horizontal"]
6977
weight: float = 1.0
7078

71-
TextRendererConfigUnion = Union[
72-
HorizontalTextRendererConfig,
73-
SimpleTextRendererConfig,
74-
OutlinedTextRendererConfig,
75-
ShadowedTextRendererConfig,
76-
GradientTextRendererConfig
77-
]
79+
80+
TextRendererConfigUnion = (
81+
HorizontalTextRendererConfig
82+
| SimpleTextRendererConfig
83+
| OutlinedTextRendererConfig
84+
| ShadowedTextRendererConfig
85+
| GradientTextRendererConfig
86+
)
87+
7888

7989
class CenterPlacementConfig(BaseModel):
8090
type: Literal["center"]
8191
padding: int = 20
8292
weight: float = 1.0
8393

94+
8495
class RandomPlacementConfig(BaseModel):
8596
type: Literal["random"]
8697
margin: int = 50
8798
weight: float = 1.0
8899

100+
89101
class GridPlacementConfig(BaseModel):
90102
type: Literal["grid"]
91103
rows: int = 3
92104
cols: int = 3
93105
padding: int = 10
94106
weight: float = 1.0
95107

108+
96109
class PageNumberPlacementConfig(BaseModel):
97110
type: Literal["page_number"]
98111
position: Literal["bottom_left", "bottom_right", "bottom_center"] = "bottom_right"
99112
margin: int = 20
100113
weight: float = 1.0
101114

115+
102116
class PageTitlePlacementConfig(BaseModel):
103117
type: Literal["page_title"]
104118
position: Literal["top_left", "top_right", "top_center"] = "top_center"
105119
margin: int = 30
106120
weight: float = 1.0
107121

108-
TextPlacementConfigUnion = Union[
109-
CenterPlacementConfig,
110-
RandomPlacementConfig,
111-
GridPlacementConfig,
112-
PageNumberPlacementConfig,
113-
PageTitlePlacementConfig
114-
]
122+
123+
TextPlacementConfigUnion = (
124+
CenterPlacementConfig
125+
| RandomPlacementConfig
126+
| GridPlacementConfig
127+
| PageNumberPlacementConfig
128+
| PageTitlePlacementConfig
129+
)
130+
115131

116132
class BaseAugmentationConfig(BaseModel):
117-
probability: Optional[float] = 1.0
118-
enabled: Optional[bool] = True
133+
probability: float | None = 1.0
134+
enabled: bool | None = True
119135
weight: float = 1.0
120136

137+
121138
class BlurAugmentationConfig(BaseAugmentationConfig):
122139
type: Literal["blur"]
123-
blur_radius: Union[float, Tuple[float, float]] = 1.0
140+
blur_radius: float | tuple[float, float] = 1.0
141+
124142

125143
class NoiseAugmentationConfig(BaseAugmentationConfig):
126144
type: Literal["noise"]
127-
noise_factor: Union[float, Tuple[float, float]] = 0.1
145+
noise_factor: float | tuple[float, float] = 0.1
146+
128147

129148
class RotationAugmentationConfig(BaseAugmentationConfig):
130149
type: Literal["rotation"]
131-
max_angle: Union[float, Tuple[float, float]] = 5.0
150+
max_angle: float | tuple[float, float] = 5.0
151+
132152

133153
class BrightnessAugmentationConfig(BaseAugmentationConfig):
134154
type: Literal["brightness"]
135-
brightness_factor: Union[float, Tuple[float, float]] = 0.8
155+
brightness_factor: float | tuple[float, float] = 0.8
156+
157+
158+
AugmentationConfigUnion = (
159+
BlurAugmentationConfig
160+
| NoiseAugmentationConfig
161+
| RotationAugmentationConfig
162+
| BrightnessAugmentationConfig
163+
)
136164

137-
AugmentationConfigUnion = Union[
138-
BlurAugmentationConfig,
139-
NoiseAugmentationConfig,
140-
RotationAugmentationConfig,
141-
BrightnessAugmentationConfig
142-
]
143165

144166
class LayoutConfig(BaseModel):
145167
type: str
146-
padding: Optional[int] = 50
147-
max_width: Optional[int] = None
148-
max_height: Optional[int] = None
149-
min_width: Optional[int] = None
150-
min_height: Optional[int] = None
168+
padding: int | None = 50
169+
max_width: int | None = None
170+
max_height: int | None = None
171+
min_width: int | None = None
172+
min_height: int | None = None
173+
151174

152175
class OutputConfig(BaseModel):
153176
images_dir: str
154177
metadata_file: str
155178

179+
156180
class DatasetConfig(BaseModel):
157181
source: str
158182
path: str
159183

184+
160185
class TextDataConfig(BaseModel):
161186
"""Configuration for loading text data from various sources."""
162-
source_type: Literal['csv', 'parquet', 'huggingface']
187+
188+
source_type: Literal["csv", "parquet", "huggingface"]
163189
source_path: str
164-
text_column: str = 'text'
165-
title_column: Optional[str] = None
190+
text_column: str = "text"
191+
title_column: str | None = None
166192
# Optional fields, mainly for Hugging Face datasets
167-
split: Optional[str] = 'train'
168-
name: Optional[str] = None # For datasets with multiple configurations (e.g., 'wikitext-103-raw-v1')
169-
data_dir: Optional[str] = None # For datasets that require manual download
193+
split: str | None = "train"
194+
name: str | None = None # For datasets with multiple configurations (e.g., 'wikitext-103-raw-v1')
195+
data_dir: str | None = None # For datasets that require manual download
196+
170197

171198
class AppConfig(BaseModel):
172-
fonts: List[FontConfig]
173-
backgrounds: List[BackgroundConfigUnion]
174-
text_renderers: Optional[List[TextRendererConfigUnion]] = []
175-
text_placements: Optional[List[TextPlacementConfigUnion]] = []
176-
augmentations: Optional[List[AugmentationConfigUnion]] = []
177-
augmentation_order: Literal['random','fixed'] = 'random'
199+
fonts: list[FontConfig]
200+
backgrounds: list[BackgroundConfigUnion]
201+
text_renderers: list[TextRendererConfigUnion] | None = []
202+
text_placements: list[TextPlacementConfigUnion] | None = []
203+
augmentations: list[AugmentationConfigUnion] | None = []
204+
augmentation_order: Literal["random", "fixed"] = "random"
178205
layout: LayoutConfig
179206
output: OutputConfig
180-
text_data: Optional[TextDataConfig] = None
181-
seed: Optional[int] = None
182-
207+
text_data: TextDataConfig | None = None
208+
seed: int | None = None

0 commit comments

Comments
 (0)