autodocgenerator 0.9.0.4__py3-none-any.whl → 0.9.2.5__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.
@@ -26,7 +26,10 @@ def gen_doc(project_path: str,
26
26
 
27
27
 
28
28
  manager.generate_code_file()
29
- manager.generete_doc_parts(max_symbols=structure_settings.max_doc_part_size)
29
+ if config.pbc.use_global_file:
30
+ manager.generate_global_info(compress_power=4)
31
+
32
+ manager.generete_doc_parts(max_symbols=structure_settings.max_doc_part_size, with_global_file=config.pbc.use_global_file)
30
33
  manager.factory_generate_doc(DocFactory(*custom_modules))
31
34
  if structure_settings.include_order:
32
35
  manager.order_doc()
@@ -7,6 +7,7 @@ from ..factory.modules.intro import IntroLinks
7
7
  class ProjectBuildConfig:
8
8
  save_logs = False
9
9
  log_level = -1
10
+ use_global_file = True
10
11
  def load_settings(self, data: dict[str, any]):
11
12
  for key, el in data.items():
12
13
  setattr(self, key, el)
@@ -15,7 +16,7 @@ class ProjectBuildConfig:
15
16
 
16
17
  class Config:
17
18
  def __init__(self):
18
- self.ignore_files: list[str] = [ "*.pyo", "*.pyd", "*.pdb", "*.pkl", "*.log", "*.sqlite3", "*.db", "data",
19
+ self.ignore_files: list[str] = ["*.pyo", "*.pyd", "*.pdb", "*.pkl", "*.log", "*.sqlite3", "*.db", "data",
19
20
  "venv", "env", ".venv", ".env", ".vscode", ".idea", "*.iml", ".gitignore", ".ruff_cache", ".auto_doc_cache",
20
21
  "*.pyc", "__pycache__", ".git", ".coverage", "htmlcov", "migrations", "*.md", "static", "staticfiles", ".mypy_cache"
21
22
  ]
@@ -124,24 +124,37 @@ This tag must appear ONLY ONCE at the very beginning. Never repeat it or use oth
124
124
 
125
125
  def get_BASE_COMPRESS_TEXT(start, power):
126
126
  return f"""
127
- You will receive a large code snippet (up to ~{start} characters).
128
- Your task is to analyze the logic and provide a summary with a STRICT usage example.
129
-
130
- 1. **Analysis**: Extract the architecture, main classes, and logic flow.
131
- 2. **Summary**: No more than ~{int(start / power)} characters. Focus on structure and data flow.
132
-
133
- 3. **STRICT Usage Example**:
134
- Provide a Python code snippet that demonstrates exactly how to call the logic.
135
- DO NOT simplify the interface. DO NOT invent high-level methods that don't exist.
136
- Follow these rules for the example:
137
- - **Initialization**: Show exactly how to initialize the main class (e.g., if it requires a 'progress' object, path, or list, include them in the example).
138
- - **Dependency Flow**: If the class requires other objects (like a Progress bar or a Factory), show their creation or setup.
139
- - **Sequential Calls**: If the code requires a specific sequence of methods (e.g., method A then method B), reflect this in the example.
140
- - **Real Signatures**: Use the actual names of methods and arguments found in the source code.
141
-
142
- **The output format for this section must be:**
143
- ```python
144
- # Real-world usage based on the code above
127
+ Task: Analyze the provided code snippet (~{start} chars) and generate a hyper-compressed Markdown architectural map.
128
+ Goal: Create a context baseline for other AI models so they understand the "big picture" and functional dependencies when looking at isolated parts of this code.
129
+
130
+ Constraints:
131
+ Strict Length: Maximum {int(start / power)} characters.
132
+ Format: Pure Markdown. Use visual markers (arrows, lists) for flow.
133
+ Tone: Technical, dense, no conversational filler.
134
+
135
+ Required Content:
136
+ Project Core: 1-sentence definition of the project's purpose and its architectural pattern (e.g., MVC, Layered, Event-driven).
137
+ Component Map: List main classes/modules and their primary responsibility.
138
+ Interaction Graph (Functional Context): Map how functions/methods interact.
139
+
140
+ Format: FunctionA -> FunctionB [data passed].
141
+ Highlight "Entry Points" (where logic starts) and "Terminal Points" (where data is saved/returned).
142
+ State & Context: Mention key shared objects or state variables that influence multiple functions.
143
+
144
+ Output Structure:
145
+ Markdown
146
+ ## Architecture: [Name/Pattern]
147
+ **Goal:** [Brief description]
148
+
149
+ ### Component Logic
150
+ * **[Class/Module]:** [Responsibility]
151
+
152
+ ### Functional Flow (Dependencies)
153
+ * `Method_1` -> calls `Method_2` to [reason]
154
+ * `Method_2` -> updates `SharedState` -> triggers `Method_3`
155
+
156
+ ### Key Context for Snippets
157
+ [List critical dependencies or global variables a developer must know to edit any single function here]
145
158
  """
146
159
 
147
160
  import os
@@ -1,5 +1,5 @@
1
- from .preprocessor.spliter import split_data, gen_doc_parts, async_gen_doc_parts
2
- from .preprocessor.compressor import compress_to_one, generate_discribtions_for_code
1
+ from .preprocessor.spliter import split_data, gen_doc_parts
2
+ from .preprocessor.compressor import compress_to_one
3
3
  from .postprocessor.custom_intro import get_introdaction, get_all_html_links, get_links_intro
4
4
  from .engine.models.gpt_model import AsyncGPTModel, GPTModel
5
5
  from .engine.models.model import Model, AsyncModel
@@ -67,8 +67,21 @@ class Manager:
67
67
  self.logger.log(InfoLog("Code mix generation completed."))
68
68
  self.progress_bar.update_task()
69
69
 
70
- def generete_doc_parts(self, max_symbols=5_000):
70
+ def generate_global_info(self, compress_power: int = 4, max_symbols: int = 10000):
71
71
  full_code_mix = self.read_file_by_file_key("code_mix")
72
+ data = split_data(full_code_mix, max_symbols)
73
+
74
+ global_result = compress_to_one(data, self.sync_model, self.config.get_project_settings(), compress_power=compress_power, progress_bar=self.progress_bar)
75
+ with open(self.get_file_path("global_info"), "w", encoding="utf-8") as file:
76
+ file.write(global_result)
77
+
78
+ self.progress_bar.update_task()
79
+
80
+
81
+ def generete_doc_parts(self, max_symbols=5_000, with_global_file: bool = False):
82
+ full_code_mix = self.read_file_by_file_key("code_mix")
83
+
84
+ global_file = self.read_file_by_file_key("global_info") if with_global_file else None
72
85
 
73
86
  self.logger.log(InfoLog("Starting synchronous documentation generation by parts..."))
74
87
  result = gen_doc_parts(full_code_mix,
@@ -16,7 +16,7 @@ def compress(data: str, project_settings: ProjectSettings, model: Model, compres
16
16
  },
17
17
  {
18
18
  "role": "system",
19
- "content": get_BASE_COMPRESS_TEXT(10000, compress_power)
19
+ "content": get_BASE_COMPRESS_TEXT(len(data), compress_power)
20
20
  },
21
21
  {
22
22
  "role": "user",
@@ -40,58 +40,18 @@ def compress_and_compare(data: list, model: Model, project_settings: ProjectSett
40
40
 
41
41
  return compress_and_compare_data
42
42
 
43
- async def async_compress(data: str, project_settings: ProjectSettings, model: AsyncModel, compress_power, semaphore, progress_bar: BaseProgress) -> str:
44
-
45
- async with semaphore:
46
- prompt = [
47
- {
48
- "role": "system",
49
- "content": project_settings.prompt
50
- },
51
- {
52
- "role": "system",
53
- "content": get_BASE_COMPRESS_TEXT(10000, compress_power)
54
- },
55
- {
56
- "role": "user",
57
- "content": data
58
- }
59
- ]
60
- answer = await model.get_answer_without_history(prompt=prompt)
61
- progress_bar.update_task()
62
- return answer
63
-
64
- async def async_compress_and_compare(data: list, model: AsyncModel, project_settings: ProjectSettings, compress_power: int = 4, progress_bar: BaseProgress = BaseProgress()) -> list:
65
- semaphore = asyncio.Semaphore(4)
66
- tasks = []
67
- progress_bar.create_new_subtask(f"Compare all files (async)", len(data))
68
-
69
- for el in data:
70
- tasks.append(async_compress(el, project_settings, model, compress_power, semaphore, progress_bar))
71
-
72
- compressed_elements = await asyncio.gather(*tasks)
73
-
74
- final_data = []
75
- chunk_size = compress_power
76
- for i in range(0, len(compressed_elements), chunk_size):
77
- chunk = compressed_elements[i : i + chunk_size]
78
- final_data.append("\n".join(chunk) + "\n")
79
-
80
- progress_bar.remove_subtask()
81
-
82
- return final_data
83
43
 
84
- def compress_to_one(data: list, model: Model, project_settings: ProjectSettings, compress_power: int = 4, use_async: bool = False, progress_bar: BaseProgress = BaseProgress()):
44
+
45
+ def compress_to_one(data: list, model: Model, project_settings: ProjectSettings, compress_power: int = 4, progress_bar: BaseProgress = BaseProgress()):
85
46
  count_of_iter = 0
47
+
86
48
  while len(data) > 1:
87
49
  new_compress_power = compress_power
88
50
  if (len(data) < compress_power + 1):
89
51
  new_compress_power = 2
90
52
 
91
- if use_async:
92
- data = asyncio.run(async_compress_and_compare(data, model, project_settings, new_compress_power, progress_bar=progress_bar))
93
- else:
94
- data = compress_and_compare(data, model, project_settings, new_compress_power, progress_bar=progress_bar)
53
+ data = compress_and_compare(data, model, project_settings, new_compress_power, progress_bar=progress_bar)
54
+
95
55
  count_of_iter += 1
96
56
 
97
57
 
@@ -99,39 +59,6 @@ def compress_to_one(data: list, model: Model, project_settings: ProjectSettings,
99
59
 
100
60
 
101
61
 
102
- def generate_discribtions_for_code(data: list, model: Model, project_settings: ProjectSettings, progress_bar: BaseProgress = BaseProgress()) -> list:
103
- describtions = []
104
- progress_bar.create_new_subtask("Generate describtions for code files", len(data))
105
- for code in data:
106
- prompt = [
107
- {
108
- "role": "system",
109
- "content": """### Instructions:
110
- 1. Identify Main Components: Determine what classes, functions, or modules are meant to be used by an external developer.
111
- 2. Description: Explain the purpose of each main component (e.g., "What is the Manager class for?").
112
- 3. Parameters & Types: Detail every parameter required for initialization and method calls, including their expected data types and default values.
113
- 4. Usage Example: Provide a COMPLETE, "copy-pasteable" code example showing:
114
- - Proper initialization.
115
- - Calling key methods.
116
- - Handling expected outputs or errors.
117
-
118
- ### Strict Rules:
119
- - Base your guide ONLY on the provided code.
120
- - If the code is incomplete or a certain class/method is missing, do not hallucinate its logic—simply state that information is unavailable.
121
- - Use Markdown for code blocks and bold text for parameter names.
122
- - If no usable logic is found in the code, respond with an empty string ("")."""
123
- },
124
- {
125
- "role": "user",
126
- "content": f"CONTEXT: {code}"
127
- }
128
- ]
129
- answer = model.get_answer_without_history(prompt=prompt)
130
- describtions.append(answer)
131
- progress_bar.update_task()
132
-
133
- progress_bar.remove_subtask()
134
- return describtions
135
62
 
136
63
 
137
64
 
@@ -41,7 +41,7 @@ def split_data(data: str, max_symbols: int) -> list[str]:
41
41
 
42
42
  return split_objects
43
43
 
44
- def write_docs_by_parts(part: str, model: Model, project_settings: ProjectSettings, prev_info: str = None, language: str = "en"):
44
+ def write_docs_by_parts(part: str, model: Model, project_settings: ProjectSettings, prev_info: str = None, language: str = "en", global_info: str = None):
45
45
  logger = BaseLogger()
46
46
  logger.log(InfoLog("Generating documentation for a part..."))
47
47
  prompt = [
@@ -59,6 +59,12 @@ def write_docs_by_parts(part: str, model: Model, project_settings: ProjectSettin
59
59
  }
60
60
  ]
61
61
 
62
+ if global_info is not None:
63
+ prompt.append({
64
+ "role": "system",
65
+ "content": f"global relations in project: {global_info}"
66
+ })
67
+
62
68
  if prev_info is not None:
63
69
  prompt.append({
64
70
  "role": "system",
@@ -80,53 +86,10 @@ def write_docs_by_parts(part: str, model: Model, project_settings: ProjectSettin
80
86
  answer = temp_answer.removesuffix("```")
81
87
  return answer
82
88
 
83
- async def async_write_docs_by_parts(part: str, async_model: AsyncModel, global_info: str, semaphore, prev_info: str = None, language: str = "en", update_progress = None):
84
- logger = BaseLogger()
85
- logger.log(InfoLog("Generating documentation for a part (async)..."))
86
- async with semaphore:
87
89
 
88
- prompt = [
89
- {
90
- "role": "system",
91
- "content": f"For the following task use language {language}"
92
- },
93
- {
94
- "role": "system",
95
- "content": BASE_PART_COMPLITE_TEXT
96
- },
97
-
98
- {
99
- "role": "user",
100
- "content": part
101
- }
102
- ]
103
90
 
104
- if prev_info is not None:
105
- prompt.append({
106
- "role": "system",
107
- "content": f"it is last part of documentation that you have write before {prev_info}"
108
- })
109
91
 
110
- prompt.append({
111
- "role": "user",
112
- "content": part
113
- })
114
- answer: str = await async_model.get_answer_without_history(prompt=prompt)
115
-
116
- if update_progress is not None:
117
- update_progress()
118
-
119
- logger.log(InfoLog("Documentation for part generated. total length: " + str(len(answer))))
120
- logger.log(InfoLog(f"Part Documentation: {answer}", level=2))
121
- temp_answer = answer.removeprefix("```")
122
- if answer == temp_answer:
123
- return answer
124
-
125
- answer = temp_answer.removesuffix("```")
126
- return answer
127
-
128
-
129
- def gen_doc_parts(full_code_mix, max_symbols, model: Model, project_settings: ProjectSettings, language, progress_bar: BaseProgress):
92
+ def gen_doc_parts(full_code_mix, max_symbols, model: Model, project_settings: ProjectSettings, language, progress_bar: BaseProgress, global_info = None):
130
93
  splited_data = split_data(full_code_mix, max_symbols)
131
94
  result = None
132
95
  logger = BaseLogger()
@@ -136,7 +99,7 @@ def gen_doc_parts(full_code_mix, max_symbols, model: Model, project_settings: Pr
136
99
 
137
100
  all_result = ""
138
101
  for i, el in enumerate(splited_data):
139
- result = write_docs_by_parts(el, model, project_settings, result, language)
102
+ result = write_docs_by_parts(el, model, project_settings, result, language, global_info=global_info)
140
103
  all_result += result
141
104
  all_result += "\n\n"
142
105
 
@@ -148,28 +111,3 @@ def gen_doc_parts(full_code_mix, max_symbols, model: Model, project_settings: Pr
148
111
  Total documentation length: {len(all_result)}"""))
149
112
  logger.log(InfoLog(f"Documentation: {all_result}", level=2))
150
113
  return all_result
151
-
152
- async def async_gen_doc_parts(full_code_mix, global_info, max_symbols, model: AsyncModel, language, progress_bar: BaseProgress):
153
- splited_data = split_data(full_code_mix, max_symbols)
154
- progress_bar.create_new_subtask(f"Generete doc parts (async)", len(splited_data))
155
-
156
- semaphore = asyncio.Semaphore(4)
157
- logger = BaseLogger()
158
- logger.log(InfoLog("Starting asynchronous documentation generation by parts..."))
159
-
160
- tasks = []
161
- for el in splited_data:
162
- tasks.append(async_write_docs_by_parts(part=el, async_model=model, global_info=global_info, semaphore=semaphore, language=language, update_progress=lambda: progress_bar.update_task()))
163
-
164
- gen_parts = await asyncio.gather(*tasks)
165
- result = ""
166
- for el in gen_parts:
167
- result += el
168
- result += "\n\n"
169
-
170
- progress_bar.remove_subtask()
171
- logger.log(InfoLog(f"""Asynchronous documentation generation by parts completed.\n
172
- Total documentation length: {len(result)}"""))
173
- logger.log(InfoLog(f"Documentation: {result}", level=2))
174
-
175
- return result