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,326 @@
1
+ """File content processing utilities.
2
+
3
+ This module provides utilities for processing file content including
4
+ JSON/YAML operations, encoding detection, and format-specific handling.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import asyncio
10
+ import inspect
11
+ import json
12
+ import logging
13
+ from collections.abc import Callable
14
+ from pathlib import Path
15
+ from typing import Any, TypeVar
16
+
17
+ try:
18
+ import chardet
19
+ except ImportError:
20
+ chardet = None
21
+ import yaml
22
+
23
+ from .constants import DEFAULT_ENCODING
24
+
25
+ logger = logging.getLogger(__name__)
26
+
27
+ T = TypeVar("T")
28
+
29
+
30
+ class ContentProcessingError(Exception):
31
+ """Base exception for content processing operations."""
32
+
33
+ pass
34
+
35
+
36
+ class JSONProcessingError(ContentProcessingError):
37
+ """Raised when JSON processing fails."""
38
+
39
+ pass
40
+
41
+
42
+ class YAMLProcessingError(ContentProcessingError):
43
+ """Raised when YAML processing fails."""
44
+
45
+ pass
46
+
47
+
48
+ def detect_encoding(file_path: str | Path, sample_size: int = 10000) -> str:
49
+ """Detect file encoding using chardet."""
50
+ path = Path(file_path)
51
+
52
+ if chardet is None:
53
+ # If chardet is not available, return default encoding
54
+ return DEFAULT_ENCODING
55
+
56
+ try:
57
+ with open(path, "rb") as f:
58
+ sample = f.read(sample_size)
59
+
60
+ result = chardet.detect(sample)
61
+ encoding = result.get("encoding")
62
+
63
+ if encoding and result.get("confidence", 0) > 0.7:
64
+ return encoding
65
+ except Exception as e:
66
+ logger.warning(f"Error detecting encoding for {path}: {e}")
67
+
68
+ return DEFAULT_ENCODING
69
+
70
+
71
+ async def async_detect_encoding(file_path: str | Path, sample_size: int = 10000) -> str:
72
+ """Asynchronously detect file encoding."""
73
+ return await asyncio.to_thread(detect_encoding, file_path, sample_size)
74
+
75
+
76
+ def read_json(
77
+ file_path: str | Path,
78
+ encoding: str = DEFAULT_ENCODING,
79
+ default: Any = None,
80
+ ) -> Any:
81
+ """Read JSON file with error handling."""
82
+ from .filesystem_ops import FileNotFoundError, read_file
83
+
84
+ try:
85
+ content = read_file(file_path, encoding)
86
+ return json.loads(content)
87
+ except FileNotFoundError as e:
88
+ if default is not None:
89
+ logger.warning(f"JSON file not found {file_path}, using default: {e}")
90
+ return default
91
+ raise JSONProcessingError(f"JSON file not found: {file_path}") from e
92
+ except json.JSONDecodeError as e:
93
+ if default is not None:
94
+ logger.warning(f"Invalid JSON in {file_path}, using default: {e}")
95
+ return default
96
+ raise JSONProcessingError(f"Invalid JSON in {file_path}: {e}") from e
97
+
98
+
99
+ async def async_read_json(
100
+ file_path: str | Path,
101
+ encoding: str = DEFAULT_ENCODING,
102
+ default: Any = None,
103
+ ) -> Any:
104
+ """Asynchronously read JSON file with error handling."""
105
+ return await asyncio.to_thread(read_json, file_path, encoding, default)
106
+
107
+
108
+ def write_json(
109
+ file_path: str | Path,
110
+ data: Any,
111
+ encoding: str = DEFAULT_ENCODING,
112
+ indent: int = 2,
113
+ sort_keys: bool = True,
114
+ create_dirs: bool = True,
115
+ ) -> Path:
116
+ """Write data to JSON file."""
117
+ from .filesystem_ops import write_file
118
+
119
+ try:
120
+ content = json.dumps(data, indent=indent, sort_keys=sort_keys, ensure_ascii=False)
121
+ return write_file(file_path, content, encoding, create_dirs)
122
+ except (TypeError, ValueError) as e:
123
+ raise JSONProcessingError(f"Failed to serialize data to JSON: {e}") from e
124
+
125
+
126
+ async def async_write_json(
127
+ file_path: str | Path,
128
+ data: Any,
129
+ encoding: str = DEFAULT_ENCODING,
130
+ indent: int = 2,
131
+ sort_keys: bool = True,
132
+ create_dirs: bool = True,
133
+ ) -> Path:
134
+ """Asynchronously write data to JSON file."""
135
+ return await asyncio.to_thread(
136
+ write_json, file_path, data, encoding, indent, sort_keys, create_dirs
137
+ )
138
+
139
+
140
+ def read_yaml(
141
+ file_path: str | Path,
142
+ encoding: str = DEFAULT_ENCODING,
143
+ default: Any = None,
144
+ ) -> Any:
145
+ """Read YAML file with error handling."""
146
+ from .filesystem_ops import FileNotFoundError, read_file
147
+
148
+ try:
149
+ content = read_file(file_path, encoding)
150
+ return yaml.safe_load(content)
151
+ except FileNotFoundError as e:
152
+ if default is not None:
153
+ logger.warning(f"YAML file not found {file_path}, using default: {e}")
154
+ return default
155
+ raise YAMLProcessingError(f"YAML file not found: {file_path}") from e
156
+ except yaml.YAMLError as e:
157
+ if default is not None:
158
+ logger.warning(f"Invalid YAML in {file_path}, using default: {e}")
159
+ return default
160
+ raise YAMLProcessingError(f"Invalid YAML in {file_path}: {e}") from e
161
+
162
+
163
+ async def async_read_yaml(
164
+ file_path: str | Path,
165
+ encoding: str = DEFAULT_ENCODING,
166
+ default: Any = None,
167
+ ) -> Any:
168
+ """Asynchronously read YAML file with error handling."""
169
+ return await asyncio.to_thread(read_yaml, file_path, encoding, default)
170
+
171
+
172
+ def write_yaml(
173
+ file_path: str | Path,
174
+ data: Any,
175
+ encoding: str = DEFAULT_ENCODING,
176
+ default_flow_style: bool = False,
177
+ create_dirs: bool = True,
178
+ ) -> Path:
179
+ """Write data to YAML file."""
180
+ from .filesystem_ops import write_file
181
+
182
+ try:
183
+ content = yaml.dump(data, default_flow_style=default_flow_style, allow_unicode=True)
184
+ return write_file(file_path, content, encoding, create_dirs)
185
+ except yaml.YAMLError as e:
186
+ raise YAMLProcessingError(f"Failed to serialize data to YAML: {e}") from e
187
+
188
+
189
+ async def async_write_yaml(
190
+ file_path: str | Path,
191
+ data: Any,
192
+ encoding: str = DEFAULT_ENCODING,
193
+ default_flow_style: bool = False,
194
+ create_dirs: bool = True,
195
+ ) -> Path:
196
+ """Asynchronously write data to YAML file."""
197
+ return await asyncio.to_thread(
198
+ write_yaml, file_path, data, encoding, default_flow_style, create_dirs
199
+ )
200
+
201
+
202
+ def validate_json_content(content: str) -> bool:
203
+ """Validate if string content is valid JSON."""
204
+ try:
205
+ json.loads(content)
206
+ return True
207
+ except (json.JSONDecodeError, TypeError):
208
+ return False
209
+
210
+
211
+ def validate_yaml_content(content: str) -> bool:
212
+ """Validate if string content is valid YAML."""
213
+ try:
214
+ yaml.safe_load(content)
215
+ return True
216
+ except yaml.YAMLError:
217
+ return False
218
+
219
+
220
+ def format_json(
221
+ data: Any,
222
+ indent: int = 2,
223
+ sort_keys: bool = True,
224
+ ensure_ascii: bool = False,
225
+ ) -> str:
226
+ """Format data as JSON string."""
227
+ try:
228
+ return json.dumps(data, indent=indent, sort_keys=sort_keys, ensure_ascii=ensure_ascii)
229
+ except (TypeError, ValueError) as e:
230
+ raise JSONProcessingError(f"Failed to format as JSON: {e}") from e
231
+
232
+
233
+ def format_yaml(
234
+ data: Any,
235
+ default_flow_style: bool = False,
236
+ allow_unicode: bool = True,
237
+ indent: int = 2,
238
+ ) -> str:
239
+ """Format data as YAML string."""
240
+ try:
241
+ return yaml.dump(
242
+ data,
243
+ default_flow_style=default_flow_style,
244
+ allow_unicode=allow_unicode,
245
+ indent=indent,
246
+ )
247
+ except yaml.YAMLError as e:
248
+ raise YAMLProcessingError(f"Failed to format as YAML: {e}") from e
249
+
250
+
251
+ def process_files[T](
252
+ directory: str | Path,
253
+ processor: Callable[[Path], T],
254
+ pattern: str = "*",
255
+ recursive: bool = True,
256
+ parallel: bool = False,
257
+ max_workers: int = 4,
258
+ ) -> list[T]:
259
+ """Process multiple files with a callback function."""
260
+ from .path_utils import list_files
261
+
262
+ files = list_files(directory, pattern, recursive)
263
+
264
+ if not parallel:
265
+ return [processor(f) for f in files]
266
+
267
+ # Parallel processing
268
+ from concurrent.futures import ThreadPoolExecutor
269
+
270
+ with ThreadPoolExecutor(max_workers=max_workers) as executor:
271
+ return list(executor.map(processor, files))
272
+
273
+
274
+ async def async_process_files[T](
275
+ directory: str | Path,
276
+ processor: Callable[[Path], T],
277
+ pattern: str = "*",
278
+ recursive: bool = True,
279
+ max_concurrent: int = 10,
280
+ ) -> list[T]:
281
+ """Asynchronously process multiple files."""
282
+ from .path_utils import list_files
283
+
284
+ files = await asyncio.to_thread(list_files, directory, pattern, recursive)
285
+
286
+ # Create semaphore for concurrency control
287
+ semaphore = asyncio.Semaphore(max_concurrent)
288
+
289
+ async def process_with_limit(file_path: Path) -> T:
290
+ async with semaphore:
291
+ if inspect.iscoroutinefunction(processor):
292
+ return await processor(file_path)
293
+ else:
294
+ return await asyncio.to_thread(processor, file_path)
295
+
296
+ tasks = [process_with_limit(f) for f in files]
297
+ return await asyncio.gather(*tasks)
298
+
299
+
300
+ # Export all public functions
301
+ __all__ = [
302
+ # Exceptions
303
+ "ContentProcessingError",
304
+ "JSONProcessingError",
305
+ "YAMLProcessingError",
306
+ # Encoding
307
+ "detect_encoding",
308
+ "async_detect_encoding",
309
+ # JSON operations
310
+ "read_json",
311
+ "async_read_json",
312
+ "write_json",
313
+ "async_write_json",
314
+ "validate_json_content",
315
+ "format_json",
316
+ # YAML operations
317
+ "read_yaml",
318
+ "async_read_yaml",
319
+ "write_yaml",
320
+ "async_write_yaml",
321
+ "validate_yaml_content",
322
+ "format_yaml",
323
+ # Processing
324
+ "process_files",
325
+ "async_process_files",
326
+ ]