Skip to content

Commit

Permalink
Add new README section templates.
Browse files Browse the repository at this point in the history
  • Loading branch information
eli64s committed Aug 21, 2024
1 parent 0a512f1 commit 344a0f1
Show file tree
Hide file tree
Showing 80 changed files with 4,591 additions and 2,978 deletions.
5 changes: 1 addition & 4 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,8 @@ repos:
- id: trailing-whitespace

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.4.0
rev: v0.6.1
hooks:
- id: ruff
name: Run Linter Check (Ruff)
args: [--fix]
files: ^(readmeai|tests)/
- id: ruff-format
name: Run Formatter (Ruff)
1 change: 0 additions & 1 deletion .ruff.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ extend-select = ["E501"]
select = [
"ARG", # unused arguments
"B", # flake8-bugbear
"COM812", # flake8-comprehensions
"E", # pycodestyle
"E722", # bare except statements
"F", # pyflakes
Expand Down
512 changes: 267 additions & 245 deletions README.md

Large diffs are not rendered by default.

1,875 changes: 1,276 additions & 599 deletions poetry.lock

Large diffs are not rendered by default.

137 changes: 57 additions & 80 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,37 +1,28 @@
[build-system]
requires = ["poetry-core", "setuptools"]
build-backend = "poetry.core.masonry.api"

[tool.poetry]
name = "readmeai"
version = "0.5.079"
description = "👾 Automated README file generator, powered by large language model APIs."
version = "0.5.080"
description = "README file generator, powered by large language model APIs 👾"
authors = ["Eli <egsalamie@gmail.com>"]
license = "MIT"
readme = "README.md"
homepage = "https://github.com/eli64s/readme-ai"
documentation = "https://eli64s.github.io/readme-ai"
keywords = [
"python",
"markdown",
"readme",
"readme-md",
"devtools",
"ai",
"ai-documentation",
"badge-generator",
"developer-tools",
"devtools",
"documentation",
"documentation-generator",
"large-language-models",
"generative-ai",
"markdown",
"markdown-generator",
"python",
"readme",
"readme-generator",
"readme-md",
"readme-md-generator",
"readme-badges",
"shieldsio-badges",
"ollama",
"openai",
"chatgpt",
"gpt-4",
"genai",
"ai",
"readme-template",
]
include = ["readmeai", "readmeai.*"]

Expand All @@ -40,18 +31,21 @@ readmeai = "readmeai.cli.main:main"

[tool.poetry.dependencies]
python = "^3.9,<4.0.0"
aiohttp = "^3.9.3"
aiohttp = "^3.9.5"
click = "^8.1.7"
gitpython = "^3.1.31"
google-generativeai = "^0.4.0"
openai = "*"
pydantic = ">=1.10.9,<2.0.0"
google-generativeai = "^0.7.1"
openai = "^1.16.2"
pydantic = "^2.8.0"
pydantic-extra-types = "^2.9.0"
pyyaml = "^6.0.1"
requests = "^2.32.3"
tenacity = "^8.2.2"
tiktoken = "^0.4.0"
toml = { version = "*", python = "<3.11" }

[tool.poetry.group.dev.dependencies]
mypy = "*"
pre-commit = "*"
ruff = "*"

[tool.poetry.group.test.dependencies]
Expand All @@ -66,70 +60,53 @@ pytest-xdist = "*"
mkdocs = "*"
mkdocs-material = "*"

[tool.ruff]
exclude = [
".ipynb_checkpoints",
".mypy_cache",
".nox",
".pytest_cache",
".ruff_cache",
".vscode",
]
line-length = 79
[tool.poetry.group.anthropic]
optional = true

[tool.ruff.format]
quote-style = "double"
docstring-code-format = true
docstring-code-line-length = 20
[tool.poetry.group.anthropic.dependencies]
anthropic = "*"

[tool.ruff.lint]
extend-select = ["E501"]
select = [
# pycodestyle
"E",
# Pyflakes
"F",
# pyupgrade
"UP",
# flake8-bugbear
"B",
# flake8-simplify
"SIM",
# isort
"I",
[tool.pytest.ini_options]
addopts = [
"-vvv",
"-rfEsxX",
"--durations=10",
"--asyncio-mode=auto",
"--numprocesses=auto",
"--cov=readmeai",
"--cov-branch",
"--cov-report=xml",
"--cov-report=term-missing",
]
ignore = [
# Line too long
"E501",
env = [
"OLLAMA_HOST=127.0.0.1",
]
pythonpath = ["readmeai"]
testpaths = ["tests"]

[tool.coverage.run]
source = ["readmeai", "tests"]
[tool.coverage.report]
exclude_also = [
"if __name__ == '__main__':",
"pragma: no cover",
"raise NotImplementedError",
]
fail_under = 80
precision = 2
show_missing = true
skip_covered = true
skip_empty = true
sort = "cover"
omit = [
"tests/*",
"*__init__.py",
"*/__init__.py",
"noxfile.py",
"readmeai/templates/*.py",
"readmeai/ui/*.py",
"readmeai/parsers/cicd/*.py",
"readmeai/parsers/infrastructure/*.py",
"readmeai/parsers/orchestration/*.py",
"readmeai/parsers/configuration/ansible.py",
"readmeai/parsers/configuration/apache.py",
"readmeai/parsers/configuration/nginx.py",
"readmeai/parsers/configuration/properties.py",
"readmeai/parsers/package/compose.py",
"readmeai/parsers/package/gem.py",
"readmeai/parsers/package/pip.py",
"readmeai/parsers/package/nuget.py",
"readmeai/parsers/package/yarn.py",
"readmeai/models/gemini.py",
"readmeai/utils/file_cleaner.py",
"readmeai/vcs/metadata.py",
"readmeai/vcs/providers.py",
]

[tool.coverage.report]
fail_under = 80
show_missing = true

[tool.coverage.xml]
output = "coverage.xml"
[build-system]
requires = ["poetry-core", "setuptools"]
build-backend = "poetry.core.masonry.api"
129 changes: 71 additions & 58 deletions readmeai/_agent.py → readmeai/__main__.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
#!/usr/bin/env python3

"""
Runs the README.md file generation process.
Main module for the README file generator agent.
"""

__package__ = "readmeai"

import asyncio
import contextlib
import tempfile
import traceback
from pathlib import Path
from typing import Optional
from collections.abc import Generator

from readmeai._exceptions import ReadmeGeneratorError
from readmeai.cli.options import ImageOptions, ModelOptions
Expand All @@ -20,79 +20,96 @@
from readmeai.core.utils import get_environment
from readmeai.generators.builder import MarkdownBuilder
from readmeai.models.dalle import DalleHandler
from readmeai.models.factory import ModelFactory
from readmeai.services.git import clone_repository
from readmeai.models.factory import ModelRegistry
from readmeai.utils.file_handler import FileHandler
from readmeai.vcs.ingestor import retrieve_repository

_logger = Logger(__name__)


@contextlib.contextmanager
def error_handler() -> Generator:
"""
Exception handler for the README generation process.
"""
try:
yield
except Exception as exc:
_logger.error(f"Error in README generation process: {exc}")
raise ReadmeGeneratorError(exc, traceback.format_exc()) from exc


def readme_agent(
alignment: Optional[str],
api: Optional[str],
badge_color: Optional[str],
badge_style: Optional[str],
base_url: Optional[str],
context_window: Optional[int],
emojis: Optional[bool],
image: Optional[str],
# language: Optional[str],
model: Optional[str],
output_file: Optional[str],
rate_limit: Optional[int],
repository: str,
temperature: Optional[float],
# template: Optional[str],
tree_depth: Optional[int],
top_p: Optional[float],
align: str,
api: str,
badge_color: str,
badge_style: str,
base_url: str,
context_window: int,
emojis: bool,
header_style: str,
image: str,
model: str,
output: str,
rate_limit: int,
temperature: float,
toc_style: str,
top_p: float,
tree_depth: int,
) -> None:
"""Configures and runs the README file generator agent."""
try:
conf = ConfigLoader()
"""
Configures and runs the README file generator agent.
"""
with error_handler():
api, model = get_environment(api, model)

conf = ConfigLoader()

conf.config.api.rate_limit = rate_limit
conf.config.llm = conf.config.llm.copy(
conf.config.llm = conf.config.llm.model_copy(
update={
"api": api,
"base_url": base_url,
"context_window": context_window,
"model": model,
"temperature": temperature,
"top_p": top_p,
}
},
)
conf.config.md = conf.config.md.copy(
conf.config.md = conf.config.md.model_copy(
update={
"alignment": alignment,
"align": align,
"badge_color": badge_color,
"badge_style": badge_style,
"emojis": emojis,
"header_style": header_style,
"image": image,
"toc_style": toc_style,
"tree_depth": tree_depth,
}
},
)
conf.config.git = GitSettings(repository=repository)
_logger.info(f"Repository validated: {conf.config.git}")
_logger.info(f"LLM API settings: {conf.config.llm}")
asyncio.run(readme_generator(conf, output_file))

except Exception as exc:
raise ReadmeGeneratorError(exc, traceback.format_exc()) from exc
_logger.info(f"Repository settings updated: {conf.config.git}")
_logger.info(f"LLM API settings updated: {conf.config.llm}")

asyncio.run(readme_generator(conf, output))


async def readme_generator(conf: ConfigLoader, output_file: Path) -> None:
"""Orchestrates the README.md file generation process."""
with tempfile.TemporaryDirectory() as temp_dir:
await clone_repository(conf.config.git.repository, temp_dir)
(
dependencies,
raw_files,
) = preprocessor(conf, temp_dir)
async def readme_generator(conf: ConfigLoader, output_file: str) -> None:
"""
Processes the repository and generates the README file.
"""
with tempfile.TemporaryDirectory() as tmp_dir:
await retrieve_repository(conf.config.git.repository, tmp_dir)
deps, raw_files = preprocessor(conf, tmp_dir)

_logger.info(f"Total files analyzed: {len(raw_files)}")
_logger.info(f"Dependencies found: {dependencies}")
_logger.info(f"Dependencies extracted: {deps}")

async with ModelFactory.model_handler(conf).use_api() as llm:
responses = await llm.batch_request(dependencies, raw_files)
async with ModelRegistry.get_backend(conf).use_api() as llm:
responses = await llm.batch_request(deps, raw_files)
(
summaries,
features,
Expand All @@ -107,20 +124,16 @@ async def readme_generator(conf: ConfigLoader, output_file: Path) -> None:
conf.config.md.image == ImageOptions.LLM.value
and conf.config.llm.api != ModelOptions.OFFLINE.value
):
conf.config.md.width = "60%"
dalle = DalleHandler(conf)
image_url = dalle.run()
conf.config.md.image = dalle.download(image_url)
elif (
conf.config.md.image == ImageOptions.LLM.value
and conf.config.llm.api == ModelOptions.OFFLINE.value
):
conf.config.md.image = ImageOptions.BLUE.value
with DalleHandler(conf).use_api() as dalle:
image_url = dalle._make_request()
conf.config.md.image = dalle.download(image_url)
if conf.config.md.image == ImageOptions.LLM.value:
conf.config.md.image = ImageOptions.BLUE.value

readme_md = MarkdownBuilder(conf, deps, summaries, tmp_dir).build()

readme_md = MarkdownBuilder(
conf, dependencies, summaries, temp_dir
).build()
FileHandler().write(output_file, readme_md)
_logger.info("README generation process completed successfully!")

_logger.info(f"README.md file saved to: {output_file}")
_logger.info("README generation process completed successfully!")
_logger.info("Share it @ github.com/eli64s/readme-ai/discussions")
Loading

0 comments on commit 344a0f1

Please sign in to comment.