@yeongjaeyou/claude-code-config 0.17.1 → 0.18.1

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.
@@ -0,0 +1,416 @@
1
+ # Internationalization (i18n) Patterns
2
+
3
+ Simple dictionary-based internationalization for Gradio CV applications. Supports Korean and English.
4
+
5
+ ## Basic Pattern
6
+
7
+ ### Label Dictionary
8
+
9
+ ```python
10
+ LABELS = {
11
+ "en": {
12
+ "title": "Image Classification",
13
+ "upload": "Upload Image",
14
+ "result": "Result",
15
+ "run": "Run",
16
+ "clear": "Clear",
17
+ "loading": "Processing...",
18
+ "error": "An error occurred",
19
+ },
20
+ "ko": {
21
+ "title": "이미지 분류",
22
+ "upload": "이미지 업로드",
23
+ "result": "결과",
24
+ "run": "실행",
25
+ "clear": "초기화",
26
+ "loading": "처리 중...",
27
+ "error": "오류가 발생했습니다",
28
+ },
29
+ }
30
+
31
+ def L(key: str, lang: str = "en") -> str:
32
+ """Get localized label"""
33
+ return LABELS.get(lang, LABELS["en"]).get(key, key)
34
+ ```
35
+
36
+ ### Usage in Gradio
37
+
38
+ ```python
39
+ import gradio as gr
40
+
41
+ lang = "ko" # or "en"
42
+
43
+ with gr.Blocks() as demo:
44
+ gr.Markdown(f"# {L('title', lang)}")
45
+ image = gr.Image(label=L("upload", lang), type="pil")
46
+ output = gr.Label(label=L("result", lang))
47
+ btn = gr.Button(L("run", lang), variant="primary")
48
+ ```
49
+
50
+ ---
51
+
52
+ ## Common UI Labels
53
+
54
+ ### General
55
+
56
+ | Key | English | Korean |
57
+ |-----|---------|--------|
58
+ | `run` | Run | 실행 |
59
+ | `submit` | Submit | 제출 |
60
+ | `clear` | Clear | 초기화 |
61
+ | `reset` | Reset | 리셋 |
62
+ | `cancel` | Cancel | 취소 |
63
+ | `loading` | Loading... | 로딩 중... |
64
+ | `processing` | Processing... | 처리 중... |
65
+ | `done` | Done | 완료 |
66
+ | `error` | Error | 오류 |
67
+ | `success` | Success | 성공 |
68
+
69
+ ### Image Components
70
+
71
+ | Key | English | Korean |
72
+ |-----|---------|--------|
73
+ | `upload_image` | Upload Image | 이미지 업로드 |
74
+ | `input_image` | Input Image | 입력 이미지 |
75
+ | `output_image` | Output Image | 출력 이미지 |
76
+ | `result` | Result | 결과 |
77
+ | `original` | Original | 원본 |
78
+ | `preview` | Preview | 미리보기 |
79
+
80
+ ### Settings
81
+
82
+ | Key | English | Korean |
83
+ |-----|---------|--------|
84
+ | `settings` | Settings | 설정 |
85
+ | `advanced` | Advanced Options | 고급 옵션 |
86
+ | `language` | Language | 언어 |
87
+ | `theme` | Theme | 테마 |
88
+ | `dark_mode` | Dark Mode | 다크 모드 |
89
+ | `light_mode` | Light Mode | 라이트 모드 |
90
+
91
+ ### Model Parameters
92
+
93
+ | Key | English | Korean |
94
+ |-----|---------|--------|
95
+ | `model` | Model | 모델 |
96
+ | `temperature` | Temperature | 온도 |
97
+ | `max_tokens` | Max Tokens | 최대 토큰 |
98
+ | `threshold` | Threshold | 임계값 |
99
+ | `steps` | Steps | 스텝 |
100
+ | `guidance` | Guidance Scale | 가이던스 스케일 |
101
+ | `seed` | Seed | 시드 |
102
+ | `random_seed` | Random Seed | 랜덤 시드 |
103
+
104
+ ---
105
+
106
+ ## Task-Specific Labels
107
+
108
+ ### OCR/VLM
109
+
110
+ ```python
111
+ OCR_LABELS = {
112
+ "en": {
113
+ "title": "Document OCR",
114
+ "upload": "Upload Document",
115
+ "prompt": "Enter prompt",
116
+ "prompt_placeholder": "Extract text from this image...",
117
+ "result": "Extracted Text",
118
+ "tab_image": "Image",
119
+ "tab_video": "Video",
120
+ "tab_pdf": "PDF",
121
+ },
122
+ "ko": {
123
+ "title": "문서 OCR",
124
+ "upload": "문서 업로드",
125
+ "prompt": "프롬프트 입력",
126
+ "prompt_placeholder": "이 이미지에서 텍스트를 추출하세요...",
127
+ "result": "추출된 텍스트",
128
+ "tab_image": "이미지",
129
+ "tab_video": "비디오",
130
+ "tab_pdf": "PDF",
131
+ },
132
+ }
133
+ ```
134
+
135
+ ### Image Classification
136
+
137
+ ```python
138
+ CLASSIFY_LABELS = {
139
+ "en": {
140
+ "title": "Image Classification",
141
+ "upload": "Upload Image",
142
+ "result": "Classification Result",
143
+ "confidence": "Confidence",
144
+ "top_classes": "Top Classes",
145
+ },
146
+ "ko": {
147
+ "title": "이미지 분류",
148
+ "upload": "이미지 업로드",
149
+ "result": "분류 결과",
150
+ "confidence": "신뢰도",
151
+ "top_classes": "상위 클래스",
152
+ },
153
+ }
154
+ ```
155
+
156
+ ### Image Generation
157
+
158
+ ```python
159
+ GENERATE_LABELS = {
160
+ "en": {
161
+ "title": "Image Generation",
162
+ "prompt": "Prompt",
163
+ "prompt_placeholder": "Describe the image you want to create...",
164
+ "negative": "Negative Prompt",
165
+ "style": "Style",
166
+ "generate": "Generate",
167
+ "result": "Generated Image",
168
+ "used_seed": "Used Seed",
169
+ },
170
+ "ko": {
171
+ "title": "이미지 생성",
172
+ "prompt": "프롬프트",
173
+ "prompt_placeholder": "생성하고 싶은 이미지를 설명하세요...",
174
+ "negative": "네거티브 프롬프트",
175
+ "style": "스타일",
176
+ "generate": "생성",
177
+ "result": "생성된 이미지",
178
+ "used_seed": "사용된 시드",
179
+ },
180
+ }
181
+ ```
182
+
183
+ ### Segmentation
184
+
185
+ ```python
186
+ SEGMENT_LABELS = {
187
+ "en": {
188
+ "title": "Image Segmentation",
189
+ "input": "Input Image",
190
+ "output": "Segmentation Result",
191
+ "target": "Segmentation Target",
192
+ "target_placeholder": "e.g., person, car, dog",
193
+ "threshold": "Confidence Threshold",
194
+ },
195
+ "ko": {
196
+ "title": "이미지 세그멘테이션",
197
+ "input": "입력 이미지",
198
+ "output": "세그멘테이션 결과",
199
+ "target": "세그멘테이션 대상",
200
+ "target_placeholder": "예: 사람, 자동차, 개",
201
+ "threshold": "신뢰도 임계값",
202
+ },
203
+ }
204
+ ```
205
+
206
+ ### Detection
207
+
208
+ ```python
209
+ DETECT_LABELS = {
210
+ "en": {
211
+ "title": "Deepfake Detection",
212
+ "upload": "Upload Image",
213
+ "result": "Detection Result",
214
+ "real": "Real",
215
+ "fake": "Fake",
216
+ "ai_generated": "AI Generated",
217
+ "authentic": "Authentic",
218
+ },
219
+ "ko": {
220
+ "title": "딥페이크 탐지",
221
+ "upload": "이미지 업로드",
222
+ "result": "탐지 결과",
223
+ "real": "진짜",
224
+ "fake": "가짜",
225
+ "ai_generated": "AI 생성",
226
+ "authentic": "원본",
227
+ },
228
+ }
229
+ ```
230
+
231
+ ---
232
+
233
+ ## Language Selector Component
234
+
235
+ ### Dropdown Style
236
+
237
+ ```python
238
+ import gradio as gr
239
+
240
+ LANGUAGES = {
241
+ "en": "English",
242
+ "ko": "한국어",
243
+ }
244
+
245
+ def create_language_selector():
246
+ return gr.Dropdown(
247
+ choices=list(LANGUAGES.values()),
248
+ value="English",
249
+ label="Language",
250
+ elem_id="lang-selector",
251
+ scale=0,
252
+ min_width=120,
253
+ )
254
+
255
+ # Usage
256
+ with gr.Blocks() as demo:
257
+ with gr.Row():
258
+ gr.Markdown("# App Title")
259
+ lang_selector = create_language_selector()
260
+ ```
261
+
262
+ ### Radio Style (Compact)
263
+
264
+ ```python
265
+ def create_language_radio():
266
+ return gr.Radio(
267
+ choices=["EN", "KO"],
268
+ value="EN",
269
+ label="",
270
+ elem_id="lang-selector",
271
+ scale=0,
272
+ )
273
+ ```
274
+
275
+ ---
276
+
277
+ ## Dynamic Language Switching
278
+
279
+ Gradio doesn't support dynamic label changes without page reload. Use one of these approaches:
280
+
281
+ ### Approach 1: Query Parameter (Recommended)
282
+
283
+ ```python
284
+ # User accesses: ?lang=ko or ?lang=en
285
+ # Parse in app initialization
286
+
287
+ import gradio as gr
288
+ from urllib.parse import parse_qs
289
+
290
+ def get_lang_from_request(request: gr.Request) -> str:
291
+ if request and request.query_params:
292
+ return request.query_params.get("lang", "en")
293
+ return "en"
294
+
295
+ # In interface function
296
+ def process(image, request: gr.Request):
297
+ lang = get_lang_from_request(request)
298
+ # Use lang for error messages, etc.
299
+ ...
300
+ ```
301
+
302
+ ### Approach 2: JavaScript-Based Text Replacement
303
+
304
+ ```python
305
+ # For simple label changes without state
306
+ LANG_SWITCH_JS = """
307
+ (lang) => {
308
+ const labels = {
309
+ 'run': { en: 'Run', ko: '실행' },
310
+ 'clear': { en: 'Clear', ko: '초기화' },
311
+ };
312
+
313
+ document.querySelectorAll('[data-i18n]').forEach(el => {
314
+ const key = el.dataset.i18n;
315
+ if (labels[key]) {
316
+ el.textContent = labels[key][lang];
317
+ }
318
+ });
319
+ }
320
+ """
321
+ ```
322
+
323
+ ### Approach 3: Separate App Instances
324
+
325
+ ```python
326
+ # Create language-specific launchers
327
+ def create_app(lang: str):
328
+ L = LABELS[lang]
329
+
330
+ with gr.Blocks() as demo:
331
+ gr.Markdown(f"# {L['title']}")
332
+ # ... rest of UI with L[key]
333
+
334
+ return demo
335
+
336
+ # app_en.py
337
+ demo = create_app("en")
338
+
339
+ # app_ko.py
340
+ demo = create_app("ko")
341
+ ```
342
+
343
+ ---
344
+
345
+ ## Complete Example
346
+
347
+ ```python
348
+ import gradio as gr
349
+ from gradio.themes import Soft
350
+ from gradio.themes.utils import colors, fonts
351
+
352
+
353
+ # === Labels ===
354
+ LABELS = {
355
+ "en": {
356
+ "title": "Image Classifier",
357
+ "upload": "Upload Image",
358
+ "result": "Classification Result",
359
+ "run": "Classify",
360
+ "clear": "Clear",
361
+ },
362
+ "ko": {
363
+ "title": "이미지 분류기",
364
+ "upload": "이미지 업로드",
365
+ "result": "분류 결과",
366
+ "run": "분류",
367
+ "clear": "초기화",
368
+ },
369
+ }
370
+
371
+
372
+ def create_app(lang: str = "en"):
373
+ L = LABELS[lang]
374
+
375
+ def classify(image):
376
+ if image is None:
377
+ return None
378
+ # Classification logic here
379
+ return {"Cat": 0.9, "Dog": 0.1}
380
+
381
+ with gr.Blocks() as demo:
382
+ gr.Markdown(f"# {L['title']}")
383
+
384
+ with gr.Row():
385
+ input_img = gr.Image(label=L["upload"], type="pil")
386
+ output = gr.Label(label=L["result"])
387
+
388
+ with gr.Row():
389
+ clear_btn = gr.Button(L["clear"], variant="secondary")
390
+ run_btn = gr.Button(L["run"], variant="primary")
391
+
392
+ run_btn.click(fn=classify, inputs=input_img, outputs=output)
393
+ clear_btn.click(fn=lambda: (None, None), outputs=[input_img, output])
394
+
395
+ return demo
396
+
397
+
398
+ # Default: English
399
+ demo = create_app("en")
400
+
401
+ # For Korean version, deploy separately or use query param
402
+ # demo = create_app("ko")
403
+
404
+ if __name__ == "__main__":
405
+ demo.launch()
406
+ ```
407
+
408
+ ---
409
+
410
+ ## Best Practices
411
+
412
+ 1. **Keep labels in constants**: Define all labels at the top of the file
413
+ 2. **Use consistent keys**: Use snake_case for label keys
414
+ 3. **Fallback to English**: Always provide English as fallback
415
+ 4. **Separate content from code**: Consider external JSON files for larger apps
416
+ 5. **Test both languages**: Ensure UI looks good in both languages (Korean text is often shorter)