code2docs 3.0.34__py3-none-any.whl → 3.0.35__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.
- code2docs/__init__.py +1 -1
- code2docs/analyzers/endpoint_detector.py +32 -1
- code2docs/llm_helper.py +15 -2
- {code2docs-3.0.34.dist-info → code2docs-3.0.35.dist-info}/METADATA +9 -10
- {code2docs-3.0.34.dist-info → code2docs-3.0.35.dist-info}/RECORD +9 -9
- {code2docs-3.0.34.dist-info → code2docs-3.0.35.dist-info}/WHEEL +1 -1
- {code2docs-3.0.34.dist-info → code2docs-3.0.35.dist-info}/entry_points.txt +0 -0
- {code2docs-3.0.34.dist-info → code2docs-3.0.35.dist-info}/licenses/LICENSE +0 -0
- {code2docs-3.0.34.dist-info → code2docs-3.0.35.dist-info}/top_level.txt +0 -0
code2docs/__init__.py
CHANGED
|
@@ -5,7 +5,7 @@ Uses code2llm's AnalysisResult to produce human-readable documentation:
|
|
|
5
5
|
README.md, API references, module docs, examples, and architecture diagrams.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
-
__version__ = "3.0.
|
|
8
|
+
__version__ = "3.0.35"
|
|
9
9
|
__author__ = "Tom Sapletta"
|
|
10
10
|
__all__ = ["Code2DocsConfig", "generate_readme", "generate_docs", "analyze_and_document"]
|
|
11
11
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"""Detect web framework endpoints (Flask, FastAPI, Django) from AST analysis."""
|
|
2
2
|
|
|
3
|
+
import os
|
|
3
4
|
import re
|
|
4
5
|
from dataclasses import dataclass, field
|
|
5
6
|
from pathlib import Path
|
|
@@ -23,6 +24,36 @@ class Endpoint:
|
|
|
23
24
|
return_type: Optional[str] = None
|
|
24
25
|
|
|
25
26
|
|
|
27
|
+
# Directories never searched for Django urls.py: virtualenvs, vendored packages,
|
|
28
|
+
# VCS/worktree copies and build output. Walking them dominated runtime (~40s on
|
|
29
|
+
# a workspace with vendored site-packages). Any dot-directory is skipped too.
|
|
30
|
+
_SKIP_DIRS = frozenset(
|
|
31
|
+
{
|
|
32
|
+
"venv",
|
|
33
|
+
"env",
|
|
34
|
+
"node_modules",
|
|
35
|
+
"site-packages",
|
|
36
|
+
"__pycache__",
|
|
37
|
+
"dist",
|
|
38
|
+
"build",
|
|
39
|
+
"target",
|
|
40
|
+
"bower_components",
|
|
41
|
+
}
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _iter_urls_files(root: Path):
|
|
46
|
+
"""Yield ``urls.py`` files under *root*, pruning irrelevant directories."""
|
|
47
|
+
for dirpath, dirnames, filenames in os.walk(root):
|
|
48
|
+
dirnames[:] = [
|
|
49
|
+
d
|
|
50
|
+
for d in dirnames
|
|
51
|
+
if d not in _SKIP_DIRS and not d.startswith(".") and not d.endswith(".egg-info")
|
|
52
|
+
]
|
|
53
|
+
if "urls.py" in filenames:
|
|
54
|
+
yield Path(dirpath) / "urls.py"
|
|
55
|
+
|
|
56
|
+
|
|
26
57
|
class EndpointDetector:
|
|
27
58
|
"""Detects web endpoints from decorator patterns in source code."""
|
|
28
59
|
|
|
@@ -91,7 +122,7 @@ class EndpointDetector:
|
|
|
91
122
|
endpoints: List[Endpoint] = []
|
|
92
123
|
project = Path(project_path)
|
|
93
124
|
|
|
94
|
-
for urls_file in project
|
|
125
|
+
for urls_file in _iter_urls_files(project):
|
|
95
126
|
try:
|
|
96
127
|
source = urls_file.read_text(encoding="utf-8")
|
|
97
128
|
for match in self.DJANGO_URL_PATTERN.finditer(source):
|
code2docs/llm_helper.py
CHANGED
|
@@ -4,6 +4,7 @@ If litellm is not installed or LLM is not configured, all methods return None
|
|
|
4
4
|
and generators fall back to algorithm-based template output.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
+
import importlib.util
|
|
7
8
|
import logging
|
|
8
9
|
from typing import Optional
|
|
9
10
|
|
|
@@ -29,6 +30,18 @@ def _get_litellm():
|
|
|
29
30
|
return _litellm if _litellm is not False else None
|
|
30
31
|
|
|
31
32
|
|
|
33
|
+
def _litellm_installed() -> bool:
|
|
34
|
+
"""Cheap availability check: locate litellm without importing it.
|
|
35
|
+
|
|
36
|
+
Importing litellm costs ~10s, so it must only happen when a completion is
|
|
37
|
+
actually requested (see ``_get_litellm`` in ``LLMHelper.complete``).
|
|
38
|
+
"""
|
|
39
|
+
try:
|
|
40
|
+
return importlib.util.find_spec("litellm") is not None
|
|
41
|
+
except (ImportError, ValueError):
|
|
42
|
+
return False
|
|
43
|
+
|
|
44
|
+
|
|
32
45
|
class LLMHelper:
|
|
33
46
|
"""Thin wrapper around litellm for documentation generation.
|
|
34
47
|
|
|
@@ -45,7 +58,7 @@ class LLMHelper:
|
|
|
45
58
|
"""Check if LLM is configured and litellm is installed."""
|
|
46
59
|
if self._available is None:
|
|
47
60
|
self._available = (
|
|
48
|
-
self.config.enabled and bool(self.config.model) and
|
|
61
|
+
self.config.enabled and bool(self.config.model) and _litellm_installed()
|
|
49
62
|
)
|
|
50
63
|
if self._available:
|
|
51
64
|
logger.info("LLM enabled: model=%s", self.config.model)
|
|
@@ -54,7 +67,7 @@ class LLMHelper:
|
|
|
54
67
|
"LLM disabled (enabled=%s, model=%s, litellm=%s)",
|
|
55
68
|
self.config.enabled,
|
|
56
69
|
bool(self.config.model),
|
|
57
|
-
|
|
70
|
+
_litellm_installed(),
|
|
58
71
|
)
|
|
59
72
|
return self._available
|
|
60
73
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: code2docs
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.35
|
|
4
4
|
Summary: Auto-generate and sync project documentation from source code analysis
|
|
5
5
|
Author-email: Tom Sapletta <tom@sapletta.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -11,14 +11,13 @@ Keywords: documentation,auto-docs,readme-generator,api-reference,code-analysis,s
|
|
|
11
11
|
Classifier: Development Status :: 3 - Alpha
|
|
12
12
|
Classifier: Intended Audience :: Developers
|
|
13
13
|
Classifier: Programming Language :: Python :: 3
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
15
14
|
Classifier: Programming Language :: Python :: 3.10
|
|
16
15
|
Classifier: Programming Language :: Python :: 3.11
|
|
17
16
|
Classifier: Programming Language :: Python :: 3.12
|
|
18
17
|
Classifier: Programming Language :: Python :: 3.13
|
|
19
18
|
Classifier: Topic :: Software Development :: Documentation
|
|
20
19
|
Classifier: Topic :: Software Development :: Code Generators
|
|
21
|
-
Requires-Python: >=3.
|
|
20
|
+
Requires-Python: >=3.10
|
|
22
21
|
Description-Content-Type: text/markdown
|
|
23
22
|
License-File: LICENSE
|
|
24
23
|
Requires-Dist: code2llm>=0.5.0
|
|
@@ -44,24 +43,24 @@ Requires-Dist: ruff>=0.1; extra == "dev"
|
|
|
44
43
|
Requires-Dist: mypy>=1.0; extra == "dev"
|
|
45
44
|
Requires-Dist: build>=1.0; extra == "dev"
|
|
46
45
|
Requires-Dist: twine>=5.0; extra == "dev"
|
|
47
|
-
Requires-Dist: goal>=2.1.0; extra == "dev"
|
|
48
46
|
Requires-Dist: costs>=0.1.20; extra == "dev"
|
|
49
|
-
Requires-Dist: pfix>=0.1.60; extra == "dev"
|
|
50
47
|
Provides-Extra: all
|
|
51
48
|
Requires-Dist: code2docs[git,llm,mkdocs,watch]; extra == "all"
|
|
52
49
|
Dynamic: license-file
|
|
53
50
|
|
|
54
51
|
## AI Cost Tracking
|
|
55
52
|
|
|
56
|
-
   
|
|
54
|
+
  
|
|
57
55
|
|
|
58
|
-
|
|
56
|
+
- 🤖 **LLM usage:** $5.3635 (99 commits)
|
|
57
|
+
- 👤 **Human dev:** ~$4589 (45.9h @ $100/h, 30min dedup)
|
|
59
58
|
|
|
60
|
-
Generated on 2026-
|
|
59
|
+
Generated on 2026-10-04 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)
|
|
61
60
|
|
|
62
61
|
---
|
|
63
62
|
|
|
64
|
-
  
|
|
65
64
|
|
|
66
65
|
> Auto-generate and sync project documentation from source code analysis.
|
|
67
66
|
|
|
@@ -198,7 +197,7 @@ code2docs can update only specific sections of an existing README using markers:
|
|
|
198
197
|
```markdown
|
|
199
198
|
<!-- code2docs:start --># code2docs
|
|
200
199
|
|
|
201
|
-
   
|
|
202
201
|
> **276** functions | **57** classes | **51** files | CC̄ = 3.8
|
|
203
202
|
|
|
204
203
|
> Auto-generated project documentation from source code analysis.
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
code2docs/__init__.py,sha256=
|
|
1
|
+
code2docs/__init__.py,sha256=V3QR1P-IHILp5xf_gSCapzNREt8vbCNqveJMGz9ZgBs,905
|
|
2
2
|
code2docs/__main__.py,sha256=dGGkQIZVFDZXEXa9PWew7cBh7hBAYDWfJ9LeezMf2UI,116
|
|
3
3
|
code2docs/base.py,sha256=RXj0wlgj_5uTBlX-xEY2WTLcLlOhd1zDT83on1GGCVw,1320
|
|
4
4
|
code2docs/cli.py,sha256=EDaaF3-LQW-E1FzlQ6cN1wkjnUDZo8Qz3eh9MVwQVcc,12848
|
|
5
5
|
code2docs/config.py,sha256=WrDlCVOJfAIzONTJq5QGvSVpM50NueJVfAkc5Fg-zJ0,11320
|
|
6
|
-
code2docs/llm_helper.py,sha256=
|
|
6
|
+
code2docs/llm_helper.py,sha256=KY6Y03ve7ZhZ10CjKw3NlfZtYvhhadX1lbxM6xrdk_U,6292
|
|
7
7
|
code2docs/registry.py,sha256=gPANpUCQJ_seb3JLnRTxXbZ0vvlvDwBR0r7XdF0Fdm8,1261
|
|
8
8
|
code2docs/analyzers/__init__.py,sha256=4m_W6ch3mfNJVVk5CG5G4-kqA28KzPz_uvzYhznxj6Q,608
|
|
9
9
|
code2docs/analyzers/dependency_scanner.py,sha256=sQraMuMdNc7eYZnWYuOkukCa9U4B6ENabEgsZY4LmH8,12122
|
|
10
10
|
code2docs/analyzers/docstring_extractor.py,sha256=HkLHY4ZMUu-WFJbcxHC8wTv3H1JSMhDNR27jobT_6Y0,5053
|
|
11
|
-
code2docs/analyzers/endpoint_detector.py,sha256=
|
|
11
|
+
code2docs/analyzers/endpoint_detector.py,sha256=HSpjRBFryU4xozfedxTOnKIA5BykGsAZEvnhTNHdP30,4768
|
|
12
12
|
code2docs/analyzers/markdown_validator.py,sha256=Uy2J2ApnteBzPDtMHWm3SIXjqtIE81YygvtN-5fvgfg,7310
|
|
13
13
|
code2docs/analyzers/project_scanner.py,sha256=dqK2z_slJ_pF3jU7sg3bvx80-wVVnRHpTi4pYK2Qm5Q,1605
|
|
14
14
|
code2docs/examples/advanced_usage.py,sha256=sHyXrXV5p9t6B9OpZndPNrClBSSEzSmjlsvoMT7cp9k,2741
|
|
@@ -45,9 +45,9 @@ code2docs/templates/example_usage.py.j2,sha256=G0mF7iLtisnsh-PfPTMLgVoNSDw6J-MqP
|
|
|
45
45
|
code2docs/templates/index.md.j2,sha256=pj56gwiLuXxV64xVYfzmtboMLyFKF-Kty01Ps0t37xM,653
|
|
46
46
|
code2docs/templates/module_doc.md.j2,sha256=oMcaDSSCbyMSjQtnal7garYr4dDbTcRAQobsjrYVYGo,1876
|
|
47
47
|
code2docs/templates/readme.md.j2,sha256=OJ3EA3gezuBLyjYUDVtRI4whg4Pcjvkh5ZgnsuwDKv4,9170
|
|
48
|
-
code2docs-3.0.
|
|
49
|
-
code2docs-3.0.
|
|
50
|
-
code2docs-3.0.
|
|
51
|
-
code2docs-3.0.
|
|
52
|
-
code2docs-3.0.
|
|
53
|
-
code2docs-3.0.
|
|
48
|
+
code2docs-3.0.35.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
49
|
+
code2docs-3.0.35.dist-info/METADATA,sha256=MEtBKdQXNe0lhC84h0DSZ7VY_Q33Mn6SMtct5fJ53VU,27133
|
|
50
|
+
code2docs-3.0.35.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
|
|
51
|
+
code2docs-3.0.35.dist-info/entry_points.txt,sha256=ATamjPNo2CbTaAUN3LfK8qrnY3EQE9gE7lMDgPYhLdQ,49
|
|
52
|
+
code2docs-3.0.35.dist-info/top_level.txt,sha256=L-O2M4M-NSiphgcKSfXFsC-t6PqziMl8Ef6tsNR2DaM,10
|
|
53
|
+
code2docs-3.0.35.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|