fabricatio 0.3.15.dev5__cp312-cp312-win_amd64.whl → 0.4.4__cp312-cp312-win_amd64.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 (65) hide show
  1. fabricatio/__init__.py +7 -8
  2. fabricatio/actions/__init__.py +69 -1
  3. fabricatio/capabilities/__init__.py +59 -1
  4. fabricatio/models/__init__.py +47 -0
  5. fabricatio/rust.cp312-win_amd64.pyd +0 -0
  6. fabricatio/toolboxes/__init__.py +2 -1
  7. fabricatio/toolboxes/arithmetic.py +1 -1
  8. fabricatio/toolboxes/fs.py +2 -2
  9. fabricatio/workflows/__init__.py +9 -0
  10. fabricatio-0.4.4.data/scripts/tdown.exe +0 -0
  11. {fabricatio-0.3.15.dev5.dist-info → fabricatio-0.4.4.dist-info}/METADATA +48 -25
  12. fabricatio-0.4.4.dist-info/RECORD +15 -0
  13. fabricatio/actions/article.py +0 -415
  14. fabricatio/actions/article_rag.py +0 -407
  15. fabricatio/actions/fs.py +0 -25
  16. fabricatio/actions/output.py +0 -247
  17. fabricatio/actions/rag.py +0 -96
  18. fabricatio/actions/rules.py +0 -83
  19. fabricatio/capabilities/advanced_judge.py +0 -20
  20. fabricatio/capabilities/advanced_rag.py +0 -61
  21. fabricatio/capabilities/censor.py +0 -105
  22. fabricatio/capabilities/check.py +0 -212
  23. fabricatio/capabilities/correct.py +0 -228
  24. fabricatio/capabilities/extract.py +0 -74
  25. fabricatio/capabilities/propose.py +0 -65
  26. fabricatio/capabilities/rag.py +0 -264
  27. fabricatio/capabilities/rating.py +0 -404
  28. fabricatio/capabilities/review.py +0 -114
  29. fabricatio/capabilities/task.py +0 -113
  30. fabricatio/decorators.py +0 -253
  31. fabricatio/emitter.py +0 -177
  32. fabricatio/fs/__init__.py +0 -35
  33. fabricatio/fs/curd.py +0 -153
  34. fabricatio/fs/readers.py +0 -61
  35. fabricatio/journal.py +0 -12
  36. fabricatio/models/action.py +0 -263
  37. fabricatio/models/adv_kwargs_types.py +0 -63
  38. fabricatio/models/extra/__init__.py +0 -1
  39. fabricatio/models/extra/advanced_judge.py +0 -32
  40. fabricatio/models/extra/aricle_rag.py +0 -286
  41. fabricatio/models/extra/article_base.py +0 -488
  42. fabricatio/models/extra/article_essence.py +0 -98
  43. fabricatio/models/extra/article_main.py +0 -285
  44. fabricatio/models/extra/article_outline.py +0 -45
  45. fabricatio/models/extra/article_proposal.py +0 -52
  46. fabricatio/models/extra/patches.py +0 -20
  47. fabricatio/models/extra/problem.py +0 -165
  48. fabricatio/models/extra/rag.py +0 -98
  49. fabricatio/models/extra/rule.py +0 -51
  50. fabricatio/models/generic.py +0 -904
  51. fabricatio/models/kwargs_types.py +0 -121
  52. fabricatio/models/role.py +0 -156
  53. fabricatio/models/task.py +0 -310
  54. fabricatio/models/tool.py +0 -328
  55. fabricatio/models/usages.py +0 -791
  56. fabricatio/parser.py +0 -114
  57. fabricatio/rust.pyi +0 -846
  58. fabricatio/utils.py +0 -156
  59. fabricatio/workflows/articles.py +0 -24
  60. fabricatio/workflows/rag.py +0 -11
  61. fabricatio-0.3.15.dev5.data/scripts/tdown.exe +0 -0
  62. fabricatio-0.3.15.dev5.data/scripts/ttm.exe +0 -0
  63. fabricatio-0.3.15.dev5.dist-info/RECORD +0 -63
  64. {fabricatio-0.3.15.dev5.dist-info → fabricatio-0.4.4.dist-info}/WHEEL +0 -0
  65. {fabricatio-0.3.15.dev5.dist-info → fabricatio-0.4.4.dist-info}/licenses/LICENSE +0 -0
fabricatio/decorators.py DELETED
@@ -1,253 +0,0 @@
1
- """Decorators for Fabricatio."""
2
-
3
- from asyncio import iscoroutinefunction
4
- from functools import wraps
5
- from importlib.util import find_spec
6
- from inspect import signature
7
- from shutil import which
8
- from types import ModuleType
9
- from typing import Callable, Coroutine, List, Optional
10
-
11
- from fabricatio.journal import logger
12
- from fabricatio.rust import CONFIG
13
-
14
-
15
- def precheck_package[**P, R](package_name: str, msg: str) -> Callable[[Callable[P, R]], Callable[P, R]]:
16
- """Check if a package exists in the current environment.
17
-
18
- Args:
19
- package_name (str): The name of the package to check.
20
- msg (str): The message to display if the package is not found.
21
-
22
- Returns:
23
- bool: True if the package exists, False otherwise.
24
- """
25
-
26
- def _wrapper(
27
- func: Callable[P, R] | Callable[P, Coroutine[None, None, R]],
28
- ) -> Callable[P, R] | Callable[P, Coroutine[None, None, R]]:
29
- if iscoroutinefunction(func):
30
-
31
- @wraps(func)
32
- async def _async_inner(*args: P.args, **kwargs: P.kwargs) -> R:
33
- if find_spec(package_name):
34
- return await func(*args, **kwargs)
35
- raise RuntimeError(msg)
36
-
37
- return _async_inner
38
-
39
- @wraps(func)
40
- def _inner(*args: P.args, **kwargs: P.kwargs) -> R:
41
- if find_spec(package_name):
42
- return func(*args, **kwargs)
43
- raise RuntimeError(msg)
44
-
45
- return _inner
46
-
47
- return _wrapper
48
-
49
-
50
- def depend_on_external_cmd[**P, R](
51
- bin_name: str, install_tip: Optional[str], homepage: Optional[str] = None
52
- ) -> Callable[[Callable[P, R]], Callable[P, R]]:
53
- """Decorator to check for the presence of an external command.
54
-
55
- Args:
56
- bin_name (str): The name of the required binary.
57
- install_tip (Optional[str]): Installation instructions for the required binary.
58
- homepage (Optional[str]): The homepage of the required binary.
59
-
60
- Returns:
61
- Callable[[Callable[P, R]], Callable[P, R]]: A decorator that wraps the function to check for the binary.
62
-
63
- Raises:
64
- RuntimeError: If the required binary is not found.
65
- """
66
-
67
- def _decorator(func: Callable[P, R]) -> Callable[P, R]:
68
- @wraps(func)
69
- def _wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
70
- if which(bin_name) is None:
71
- err = f"`{bin_name}` is required to run {func.__name__}{signature(func)}, please install it the to `PATH` first."
72
- if install_tip is not None:
73
- err += f"\nInstall tip: {install_tip}"
74
- if homepage is not None:
75
- err += f"\nHomepage: {homepage}"
76
- logger.error(err)
77
- raise RuntimeError(err)
78
- return func(*args, **kwargs)
79
-
80
- return _wrapper
81
-
82
- return _decorator
83
-
84
-
85
- def logging_execution_info[**P, R](func: Callable[P, R]) -> Callable[P, R]:
86
- """Decorator to log the execution of a function.
87
-
88
- Args:
89
- func (Callable): The function to be executed
90
-
91
- Returns:
92
- Callable: A decorator that wraps the function to log the execution.
93
- """
94
-
95
- @wraps(func)
96
- def _wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
97
- logger.info(f"Executing function: {func.__name__}{signature(func)}")
98
- logger.debug(f"{func.__name__}{signature(func)}\nArgs: {args}\nKwargs: {kwargs}")
99
- return func(*args, **kwargs)
100
-
101
- return _wrapper
102
-
103
-
104
- @precheck_package(
105
- "questionary", "'questionary' is required to run this function. Have you installed `fabricatio[qa]`?."
106
- )
107
- def confirm_to_execute[**P, R](func: Callable[P, R]) -> Callable[P, Optional[R]] | Callable[P, R]:
108
- """Decorator to confirm before executing a function.
109
-
110
- Args:
111
- func (Callable): The function to be executed
112
-
113
- Returns:
114
- Callable: A decorator that wraps the function to confirm before execution.
115
- """
116
- if not CONFIG.general.confirm_on_ops:
117
- # Skip confirmation if the configuration is set to False
118
- return func
119
- from questionary import confirm
120
-
121
- if iscoroutinefunction(func):
122
-
123
- @wraps(func)
124
- async def _wrapper(*args: P.args, **kwargs: P.kwargs) -> Optional[R]:
125
- if await confirm(
126
- f"Are you sure to execute function: {func.__name__}{signature(func)} \n📦 Args:{args}\n🔑 Kwargs:{kwargs}\n",
127
- instruction="Please input [Yes/No] to proceed (default: Yes):",
128
- ).ask_async():
129
- return await func(*args, **kwargs)
130
- logger.warning(f"Function: {func.__name__}{signature(func)} canceled by user.")
131
- return None
132
-
133
- else:
134
-
135
- @wraps(func)
136
- def _wrapper(*args: P.args, **kwargs: P.kwargs) -> Optional[R]:
137
- if confirm(
138
- f"Are you sure to execute function: {func.__name__}{signature(func)} \n📦 Args:{args}\n��� Kwargs:{kwargs}\n",
139
- instruction="Please input [Yes/No] to proceed (default: Yes):",
140
- ).ask():
141
- return func(*args, **kwargs)
142
- logger.warning(f"Function: {func.__name__}{signature(func)} canceled by user.")
143
- return None
144
-
145
- return _wrapper
146
-
147
-
148
- def use_temp_module[**P, R](modules: ModuleType | List[ModuleType]) -> Callable[[Callable[P, R]], Callable[P, R]]:
149
- """Temporarily inject modules into sys.modules during function execution.
150
-
151
- This decorator allows you to temporarily inject one or more modules into sys.modules
152
- while the decorated function executes. After execution, it restores the original
153
- state of sys.modules.
154
-
155
- Args:
156
- modules (ModuleType | List[ModuleType]): A single module or list of modules to
157
- temporarily inject into sys.modules.
158
-
159
- Returns:
160
- Callable[[Callable[P, R]], Callable[P, R]]: A decorator that handles temporary
161
- module injection.
162
-
163
- Examples:
164
- ```python
165
- from types import ModuleSpec, ModuleType, module_from_spec
166
-
167
- # Create a temporary module
168
- temp_module = module_from_spec(ModuleSpec("temp_math", None))
169
- temp_module.pi = 3.14
170
-
171
- # Use the decorator to temporarily inject the module
172
- @use_temp_module(temp_module)
173
- def calculate_area(radius: float) -> float:
174
- from temp_math import pi
175
- return pi * radius ** 2
176
-
177
- # The temp_module is only available inside the function
178
- result = calculate_area(5.0) # Uses temp_module.pi
179
- ```
180
-
181
- Multiple modules can also be injected:
182
- ```python
183
- module1 = module_from_spec(ModuleSpec("mod1", None))
184
- module2 = module_from_spec(ModuleSpec("mod2", None))
185
-
186
- @use_temp_module([module1, module2])
187
- def process_data():
188
- import mod1, mod2
189
- # Work with temporary modules
190
- ...
191
- ```
192
- """
193
- module_list = [modules] if isinstance(modules, ModuleType) else modules
194
-
195
- def _decorator(func: Callable[P, R]) -> Callable[P, R]:
196
- @wraps(func)
197
- def _wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
198
- import sys
199
-
200
- # Store original modules if they exist
201
- for module in module_list:
202
- if module.__name__ in sys.modules:
203
- raise RuntimeError(
204
- f"Module '{module.__name__}' is already present in sys.modules and cannot be overridden."
205
- )
206
- sys.modules[module.__name__] = module
207
-
208
- try:
209
- return func(*args, **kwargs)
210
- finally:
211
- # Restore original state
212
- for module in module_list:
213
- del sys.modules[module.__name__]
214
-
215
- return _wrapper
216
-
217
- return _decorator
218
-
219
-
220
- def logging_exec_time[**P, R](
221
- func: Callable[P, R] | Callable[P, Coroutine[None, None, R]],
222
- ) -> Callable[P, R] | Callable[P, Coroutine[None, None, R]]:
223
- """Decorator to log the execution time of a function.
224
-
225
- Args:
226
- func (Callable): The function to be executed
227
-
228
- Returns:
229
- Callable: A decorator that wraps the function to log the execution time.
230
- """
231
- from time import time
232
-
233
- if iscoroutinefunction(func):
234
-
235
- @wraps(func)
236
- async def _async_wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
237
- start_time = time()
238
- logger.debug(f"Starting execution of {func.__name__}")
239
- result = await func(*args, **kwargs)
240
- logger.debug(f"Execution time of `{func.__name__}`: {time() - start_time:.2f} s")
241
- return result
242
-
243
- return _async_wrapper
244
-
245
- @wraps(func)
246
- def _wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
247
- start_time = time()
248
- logger.debug(f"Starting execution of {func.__name__}")
249
- result = func(*args, **kwargs)
250
- logger.debug(f"Execution time of {func.__name__}: {(time() - start_time) * 1000:.2f} ms")
251
- return result
252
-
253
- return _wrapper
fabricatio/emitter.py DELETED
@@ -1,177 +0,0 @@
1
- """Core module that contains the Env class for managing event handling."""
2
- from dataclasses import dataclass
3
- from typing import Callable, ClassVar, Optional, Self, overload
4
-
5
- from pymitter import EventEmitter
6
-
7
- from fabricatio.rust import CONFIG, Event
8
-
9
-
10
- @dataclass
11
- class Env:
12
- """Environment class that manages event handling using EventEmitter."""
13
-
14
- ee: ClassVar[EventEmitter] = EventEmitter(
15
- delimiter=CONFIG.pymitter.delimiter,
16
- new_listener=CONFIG.pymitter.new_listener_event,
17
- max_listeners=CONFIG.pymitter.max_listeners,
18
- wildcard=True,
19
- )
20
-
21
- @overload
22
- def on(self, event: str | Event, /, ttl: int = -1) -> Self:
23
- """
24
- Registers an event listener that listens indefinitely or for a specified number of times.
25
-
26
- Args:
27
- event (str | Event): The event to listen for.
28
- ttl (int): Time-to-live for the listener. If -1, the listener will listen indefinitely.
29
-
30
- Returns:
31
- Self: The current instance of Env.
32
- """
33
- ...
34
-
35
- @overload
36
- def on[**P, R](
37
- self,
38
- event: str | Event,
39
- func: Optional[Callable[P, R]] = None,
40
- /,
41
- ttl: int = -1,
42
- ) -> Callable[[Callable[P, R]], Callable[P, R]]:
43
- """
44
- Registers an event listener with a specific function that listens indefinitely or for a specified number of times.
45
-
46
- Args:
47
- event (str | Event): The event to listen for.
48
- func (Callable[P, R]): The function to be called when the event is emitted.
49
- ttl (int): Time-to-live for the listener. If -1, the listener will listen indefinitely.
50
-
51
- Returns:
52
- Callable[[Callable[P, R]], Callable[P, R]]: A decorator that registers the function as an event listener.
53
- """
54
- ...
55
-
56
- def on[**P, R](
57
- self,
58
- event: str | Event,
59
- func: Optional[Callable[P, R]] = None,
60
- /,
61
- ttl=-1,
62
- ) -> Callable[[Callable[P, R]], Callable[P, R]] | Self:
63
- """Registers an event listener with a specific function that listens indefinitely or for a specified number of times.
64
-
65
- Args:
66
- event (str | Event): The event to listen for.
67
- func (Callable[P, R]): The function to be called when the event is emitted.
68
- ttl (int): Time-to-live for the listener. If -1, the listener will listen indefinitely.
69
-
70
- Returns:
71
- Callable[[Callable[P, R]], Callable[P, R]] | Self: A decorator that registers the function as an event listener or the current instance of Env.
72
- """
73
- if isinstance(event, Event):
74
- event = event.collapse()
75
- if func is None:
76
- return self.ee.on(event, ttl=ttl)
77
- self.ee.on(event, func, ttl=ttl)
78
- return self
79
-
80
- @overload
81
- def once[**P, R](
82
- self,
83
- event: str | Event,
84
- ) -> Callable[[Callable[P, R]], Callable[P, R]]:
85
- """
86
- Registers an event listener that listens only once.
87
-
88
- Args:
89
- event (str | Event): The event to listen for.
90
-
91
- Returns:
92
- Callable[[Callable[P, R]], Callable[P, R]]: A decorator that registers the function as an event listener.
93
- """
94
- ...
95
-
96
- @overload
97
- def once[**P, R](
98
- self,
99
- event: str | Event,
100
- func: Callable[[Callable[P, R]], Callable[P, R]],
101
- ) -> Self:
102
- """
103
- Registers an event listener with a specific function that listens only once.
104
-
105
- Args:
106
- event (str | Event): The event to listen for.
107
- func (Callable[P, R]): The function to be called when the event is emitted.
108
-
109
- Returns:
110
- Self: The current instance of Env.
111
- """
112
- ...
113
-
114
- def once[**P, R](
115
- self,
116
- event: str | Event,
117
- func: Optional[Callable[P, R]] = None,
118
- ) -> Callable[[Callable[P, R]], Callable[P, R]] | Self:
119
- """Registers an event listener with a specific function that listens only once.
120
-
121
- Args:
122
- event (str | Event): The event to listen for.
123
- func (Callable[P, R]): The function to be called when the event is emitted.
124
-
125
- Returns:
126
- Callable[[Callable[P, R]], Callable[P, R]] | Self: A decorator that registers the function as an event listener or the current instance
127
- """
128
- if isinstance(event, Event):
129
- event = event.collapse()
130
- if func is None:
131
- return self.ee.once(event)
132
-
133
- self.ee.once(event, func)
134
- return self
135
-
136
- def emit[**P](self, event: str | Event, *args: P.args, **kwargs: P.kwargs) -> None:
137
- """Emits an event to all registered listeners.
138
-
139
- Args:
140
- event (str | Event): The event to emit.
141
- *args: Positional arguments to pass to the listeners.
142
- **kwargs: Keyword arguments to pass to the listeners.
143
- """
144
- if isinstance(event, Event):
145
- event = event.collapse()
146
-
147
- self.ee.emit(event, *args, **kwargs)
148
-
149
- async def emit_async[**P](self, event: str | Event, *args: P.args, **kwargs: P.kwargs) -> None:
150
- """Asynchronously emits an event to all registered listeners.
151
-
152
- Args:
153
- event (str | Event): The event to emit.
154
- *args: Positional arguments to pass to the listeners.
155
- **kwargs: Keyword arguments to pass to the listeners.
156
- """
157
- if isinstance(event, Event):
158
- event = event.collapse()
159
- return await self.ee.emit_async(event, *args, **kwargs)
160
-
161
- def emit_future[**P](self, event: str | Event, *args: P.args, **kwargs: P.kwargs) -> None:
162
- """Emits an event to all registered listeners and returns a future object.
163
-
164
- Args:
165
- event (str | Event): The event to emit.
166
- *args: Positional arguments to pass to the listeners.
167
- **kwargs: Keyword arguments to pass to the listeners.
168
-
169
- Returns:
170
- None: The future object.
171
- """
172
- if isinstance(event, Event):
173
- event = event.collapse()
174
- return self.ee.emit_future(event, *args, **kwargs)
175
-
176
-
177
- env = Env()
fabricatio/fs/__init__.py DELETED
@@ -1,35 +0,0 @@
1
- """FileSystem manipulation module for Fabricatio."""
2
- from importlib.util import find_spec
3
-
4
- from fabricatio.fs.curd import (
5
- absolute_path,
6
- copy_file,
7
- create_directory,
8
- delete_directory,
9
- delete_file,
10
- dump_text,
11
- gather_files,
12
- move_file,
13
- tree,
14
- )
15
- from fabricatio.fs.readers import safe_json_read, safe_text_read
16
-
17
- __all__ = [
18
- "absolute_path",
19
- "copy_file",
20
- "create_directory",
21
- "delete_directory",
22
- "delete_file",
23
- "dump_text",
24
- "gather_files",
25
- "move_file",
26
- "safe_json_read",
27
- "safe_text_read",
28
- "tree",
29
- ]
30
-
31
- if find_spec("magika"):
32
- from magika import Magika
33
-
34
- MAGIKA = Magika()
35
- __all__ += ["MAGIKA"]
fabricatio/fs/curd.py DELETED
@@ -1,153 +0,0 @@
1
- """File system create, update, read, delete operations."""
2
-
3
- import shutil
4
- import subprocess
5
- from os import PathLike
6
- from pathlib import Path
7
- from typing import Union
8
-
9
- from fabricatio.decorators import depend_on_external_cmd
10
- from fabricatio.journal import logger
11
-
12
-
13
- def dump_text(path: Union[str, Path], text: str) -> None:
14
- """Dump text to a file. you need to make sure the file's parent directory exists.
15
-
16
- Args:
17
- path(str, Path): Path to the file
18
- text(str): Text to write to the file
19
-
20
- Returns:
21
- None
22
- """
23
- Path(path).write_text(text, encoding="utf-8", errors="ignore", newline="\n")
24
-
25
-
26
- def copy_file(src: Union[str, Path], dst: Union[str, Path]) -> None:
27
- """Copy a file from source to destination.
28
-
29
- Args:
30
- src: Source file path
31
- dst: Destination file path
32
-
33
- Raises:
34
- FileNotFoundError: If source file doesn't exist
35
- shutil.SameFileError: If source and destination are the same
36
- """
37
- try:
38
- shutil.copy(src, dst)
39
- logger.info(f"Copied file from {src} to {dst}")
40
- except OSError as e:
41
- logger.error(f"Failed to copy file from {src} to {dst}: {e!s}")
42
- raise
43
-
44
-
45
- def move_file(src: Union[str, Path], dst: Union[str, Path]) -> None:
46
- """Move a file from source to destination.
47
-
48
- Args:
49
- src: Source file path
50
- dst: Destination file path
51
-
52
- Raises:
53
- FileNotFoundError: If source file doesn't exist
54
- shutil.SameFileError: If source and destination are the same
55
- """
56
- try:
57
- shutil.move(src, dst)
58
- logger.info(f"Moved file from {src} to {dst}")
59
- except OSError as e:
60
- logger.error(f"Failed to move file from {src} to {dst}: {e!s}")
61
- raise
62
-
63
-
64
- def delete_file(file_path: Union[str, Path]) -> None:
65
- """Delete a file.
66
-
67
- Args:
68
- file_path: Path to the file to be deleted
69
-
70
- Raises:
71
- FileNotFoundError: If file doesn't exist
72
- PermissionError: If no permission to delete the file
73
- """
74
- try:
75
- Path(file_path).unlink()
76
- logger.info(f"Deleted file: {file_path}")
77
- except OSError as e:
78
- logger.error(f"Failed to delete file {file_path}: {e!s}")
79
- raise
80
-
81
-
82
- def create_directory(dir_path: Union[str, Path], parents: bool = True, exist_ok: bool = True) -> None:
83
- """Create a directory.
84
-
85
- Args:
86
- dir_path: Path to the directory to create
87
- parents: Create parent directories if they don't exist
88
- exist_ok: Don't raise error if directory already exists
89
- """
90
- try:
91
- Path(dir_path).mkdir(parents=parents, exist_ok=exist_ok)
92
- logger.info(f"Created directory: {dir_path}")
93
- except OSError as e:
94
- logger.error(f"Failed to create directory {dir_path}: {e!s}")
95
- raise
96
-
97
-
98
- @depend_on_external_cmd(
99
- "erd",
100
- "Please install `erd` using `cargo install erdtree` or `scoop install erdtree`.",
101
- "https://github.com/solidiquis/erdtree",
102
- )
103
- def tree(dir_path: Union[str, Path]) -> str:
104
- """Generate a tree representation of the directory structure. Requires `erd` to be installed."""
105
- dir_path = Path(dir_path)
106
- return subprocess.check_output(("erd", dir_path.as_posix()), encoding="utf-8") # noqa: S603
107
-
108
-
109
- def delete_directory(dir_path: Union[str, Path]) -> None:
110
- """Delete a directory and its contents.
111
-
112
- Args:
113
- dir_path: Path to the directory to delete
114
-
115
- Raises:
116
- FileNotFoundError: If directory doesn't exist
117
- OSError: If directory is not empty and can't be removed
118
- """
119
- try:
120
- shutil.rmtree(dir_path)
121
- logger.info(f"Deleted directory: {dir_path}")
122
- except OSError as e:
123
- logger.error(f"Failed to delete directory {dir_path}: {e!s}")
124
- raise
125
-
126
-
127
- def absolute_path(path: str | Path | PathLike) -> str:
128
- """Get the absolute path of a file or directory.
129
-
130
- Args:
131
- path (str, Path, PathLike): The path to the file or directory.
132
-
133
- Returns:
134
- str: The absolute path of the file or directory.
135
- """
136
- return Path(path).expanduser().resolve().as_posix()
137
-
138
-
139
- def gather_files(directory: str | Path | PathLike, extension: str) -> list[str]:
140
- """Gather all files with a specific extension in a directory.
141
-
142
- Args:
143
- directory (str, Path, PathLike): The directory to search in.
144
- extension (str): The file extension to look for.
145
-
146
- Returns:
147
- list[str]: A list of file paths with the specified extension.
148
-
149
- Example:
150
- >>> gather_files('/path/to/directory', 'txt')
151
- ['/path/to/directory/file1.txt', '/path/to/directory/file2.txt']
152
- """
153
- return [file.as_posix() for file in Path(directory).rglob(f"*.{extension}")]
fabricatio/fs/readers.py DELETED
@@ -1,61 +0,0 @@
1
- """Filesystem readers for Fabricatio."""
2
-
3
- import re
4
- from pathlib import Path
5
- from typing import Dict, List, Tuple
6
-
7
- import ujson
8
-
9
- from fabricatio.journal import logger
10
-
11
-
12
- def safe_text_read(path: Path | str) -> str:
13
- """Safely read the text from a file.
14
-
15
- Args:
16
- path (Path|str): The path to the file.
17
-
18
- Returns:
19
- str: The text from the file.
20
- """
21
- path = Path(path)
22
- try:
23
- return path.read_text(encoding="utf-8")
24
- except (UnicodeDecodeError, IsADirectoryError, FileNotFoundError) as e:
25
- logger.error(f"Failed to read file {path}: {e!s}")
26
- return ""
27
-
28
-
29
- def safe_json_read(path: Path | str) -> Dict:
30
- """Safely read the JSON from a file.
31
-
32
- Args:
33
- path (Path|str): The path to the file.
34
-
35
- Returns:
36
- dict: The JSON from the file.
37
- """
38
- path = Path(path)
39
- try:
40
- return ujson.loads(path.read_text(encoding="utf-8"))
41
- except (ujson.JSONDecodeError, IsADirectoryError, FileNotFoundError) as e:
42
- logger.error(f"Failed to read file {path}: {e!s}")
43
- return {}
44
-
45
-
46
- def extract_sections(string: str, level: int, section_char: str = "#") -> List[Tuple[str, str]]:
47
- """Extract sections from markdown-style text by header level.
48
-
49
- Args:
50
- string (str): Input text to parse
51
- level (int): Header level (e.g., 1 for '#', 2 for '##')
52
- section_char (str, optional): The character used for headers (default: '#')
53
-
54
- Returns:
55
- List[Tuple[str, str]]: List of (header_text, section_content) tuples
56
- """
57
- return re.findall(
58
- r"^%s{%d}\s+(.+?)\n((?:(?!^%s{%d}\s).|\n)*)" % (section_char, level, section_char, level),
59
- string,
60
- re.MULTILINE,
61
- )
fabricatio/journal.py DELETED
@@ -1,12 +0,0 @@
1
- """Logging setup for the project."""
2
-
3
- import sys
4
-
5
- from loguru import logger
6
-
7
- from fabricatio.rust import CONFIG
8
-
9
- logger.remove()
10
- logger.add(sys.stderr, level=CONFIG.debug.log_level)
11
-
12
- __all__ = ["logger"]