Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions adhoc/adhoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from .commands.commit import commit_command
from .commands.generate import generate_command
from .commands.config import config_command # New import
from .commands.startapi import run_server_command

def main():
parser = argparse.ArgumentParser(
Expand Down Expand Up @@ -40,6 +41,17 @@ def main():
parser_config.add_argument('-u', '--username', type=str, help='Set the author username')
parser_config.set_defaults(func=config_command)

#? Start API command
parser_startapi = subparsers.add_parser('startapi', help='Start the FastAPI server')

# Add arguments for host, reloads, worker and port
parser_startapi.add_argument('-p', '--port', type=int, default=8000, help='Port number to run the server on')
parser_startapi.add_argument('-H', '--host', type=str, default='0.0.0.0', help='Host address to bind to')
parser_startapi.add_argument('-r', '--reload', action='store_true', help='Enable auto-reload')
parser_startapi.add_argument('-w', '--workers', type=int, default=1, help='Number of worker processes')

parser_startapi.set_defaults(func=run_server_command)

# Parse arguments
args = parser.parse_args()

Expand Down
3 changes: 3 additions & 0 deletions adhoc/api/Endpoints.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[
.../'generate-documentation', {author_name: args[string], output_format: args[string]}
]
116 changes: 116 additions & 0 deletions adhoc/api/api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from enum import Enum
from typing import Optional
from starlette import status

# Import the original documentation generation function
from adhoc.db.database import get_explanations, get_codebase_summary
from adhoc.utils.latex_utils import render_latex_document
from adhoc.utils.markdown_utils import render_markdown_document
from adhoc.utils.word_utils import render_word_document
from adhoc.utils.config_utils import load_config

# Initialize FastAPI app
app = FastAPI(
title="ADHOC Documentation Generator API",
description="API for generating documentation from codebase",
version=1.0)

# Define allowed output formats
class OutputFormat(str, Enum):
LATEX = "latex"
MARKDOWN = "markdown"
WORD = "word"

# Request model
class DocumentationRequest(BaseModel):
output_format: OutputFormat
author_name: Optional[str] = "Default Author"

# Response model
class DocumentationResponse(BaseModel):
content: str
format: OutputFormat
message: str

@app.post(
"/generate-documentation",
response_model=DocumentationResponse,
status_code=status.HTTP_201_CREATED
)
async def generate_documentation(request: DocumentationRequest):
try:
# Get the required data from database
explanations = get_explanations()
codebase_summary = get_codebase_summary()

content = None # Initialize content variable

# Generate the actual documentation based on format
if request.output_format == OutputFormat.LATEX:
content = render_latex_document(
explanations,
codebase_summary,
request.author_name
)
elif request.output_format == OutputFormat.MARKDOWN:
content = render_markdown_document(
explanations,
codebase_summary,
request.author_name
)
elif request.output_format == OutputFormat.WORD:
# For Word, we need to handle it differently since it creates a file
output_filename = "documentation.docx"
render_word_document(
explanations,
codebase_summary,
output_filename,
request.author_name
)
# Read the generated Word file
with open(output_filename, 'rb') as f:
content = f.read()
import os
os.remove(output_filename) # Clean up the file

if content is None:
raise ValueError("No content was generated")

return DocumentationResponse(
content=content,
format=request.output_format,
message=f"Documentation generated successfully in {request.output_format} format"
)

except ValueError as e:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=str(e)
)
except Exception as e:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Failed to generate documentation: {str(e)}"
)

# Health check endpoint
@app.get(
"/health",
status_code=status.HTTP_200_OK,
responses={
200: {
"description": "API is healthy",
"content": {
"application/json": {
"example": {
"status": "healthy"
}
}
}
}
}
)
async def health_check():
return {"status": "healthy"}
12 changes: 8 additions & 4 deletions adhoc/commands/generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,35 @@
from ..utils.config_utils import load_config # Import the config loader
from ..db.database import get_codebase_summary


def generate_command(args):
config = load_config()
OUTPUT_FORMAT = config.get('OUTPUT_FORMAT', 'latex')
AUTHOR_NAME = config.get('AUTHOR_NAME', 'Default Author')
explanations = get_explanations()
codebase_summary = get_codebase_summary()
FOLDER_PATH = "output/"

# Pass AUTHOR_NAME to rendering functions if needed

# Determine the output format
if OUTPUT_FORMAT == 'latex':
latex_content = render_latex_document(explanations, codebase_summary, AUTHOR_NAME)
output_filename = 'documentation.tex'
with open(output_filename, 'w') as f:
file_path = FOLDER_PATH + output_filename
with open(file_path, 'w') as f:
f.write(latex_content)
print(f"LaTeX documentation generated: {output_filename}")
print(f"LaTeX documentation generated: {file_path}")
elif OUTPUT_FORMAT == 'markdown':
markdown_content = render_markdown_document(explanations, codebase_summary, AUTHOR_NAME)
output_filename = 'documentation.md'
with open(output_filename, 'w') as f:
file_path = FOLDER_PATH + output_filename
with open(file_path, 'w') as f:
f.write(markdown_content)
print(f"Markdown documentation generated: {output_filename}")
elif OUTPUT_FORMAT == 'word':
output_filename = "documentation.docx"
render_word_document(explanations, codebase_summary,output_filename, AUTHOR_NAME)
render_word_document(explanations, codebase_summary, file_path, AUTHOR_NAME)
print(f"Word documentation generated: {output_filename}")

else:
Expand Down
98 changes: 98 additions & 0 deletions adhoc/commands/startapi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import os
import argparse
import subprocess
import sys
from typing import Optional
import uvicorn
from pathlib import Path

def find_fastapi_app() -> Optional[str]:
"""
Finds the api.py FastAPI application file in the current directory.
Looks for common patterns like main.py, app.py, or api.py.

Returns:
str: The module path to the FastAPI app, or None if not found
"""
common_names = ['main.py', 'app.py', 'api.py']

# First, look in current directory
for name in common_names:
if os.path.exists(name):
module_name = name.replace('.py', '')
return f"{module_name}:app"

# Then look in app directory
if os.path.exists('app'):
for name in common_names:
if os.path.exists(os.path.join('app', name)):
module_name = name.replace('.py', '')
return f"app.{module_name}:app"

return None

def run_server_command(args):
API_PATH = './adhoc/api/api.py'
"""
Command handler for running the FastAPI server

Args:
args: Parsed command line arguments containing:
- port: Port number to run the server on
- host: Host address to bind to
- reload: Whether to enable auto-reload
- workers: Number of worker processes
"""

# If no app specified, try to find it
app_path = API_PATH
if not app_path:
app_path = find_fastapi_app()
if not app_path:
print("Error: Could not find FastAPI application. Please specify with --app")
return 1

try:
# Check if we're in a virtual environment
in_venv = sys.prefix != sys.base_prefix
if in_venv:
print("Warning: Running in a virtual environment.")
print("Consider running without a virtual environment for better performance.")

# Check if required packages are installed
try:
import fastapi
import uvicorn
except ImportError:
print("Error: Required packages not found. Please install fastapi and uvicorn:")
print("pip install fastapi uvicorn")
return 1

# Print startup message
print(f"\nStarting FastAPI server:")
print(f"→ Application: {app_path}")
print(f"→ Host: {args.host}")
print(f"→ Port: {args.port}")
print(f"→ Reload: {'enabled' if args.reload else 'disabled'}")
print(f"→ Workers: {args.workers}")
print("\nAPI documentation will be available at:")
print(f"→ Swagger UI: http://{args.host}:{args.port}/docs")
print(f"→ ReDoc: http://{args.host}:{args.port}/redoc")
print("\n Api will be available at: http://{args.host}:{args.post}/ \n ")
print("\nPress Ctrl+C to stop the server\n")

# Run the server
uvicorn.run(
app_path,
host=args.host,
port=args.port,
reload=args.reload,
workers=args.workers,
log_level="info"
)

except Exception as e:
print(f"Error running server: {str(e)}")
return 1

return 0
1 change: 1 addition & 0 deletions adhoc_python.egg-info/requires.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ requests>=2.32.3
watchdog>=5.0.3
python-docx>=1.1.2
ollama
fastapi[standard]
56 changes: 56 additions & 0 deletions documentation.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
\documentclass{article}
\usepackage{hyperref} % For hyperlinks
\usepackage{listings} % For code listings
\usepackage{upquote} % For correct display of quotes in verbatim
\usepackage{geometry} % For better page layout
\usepackage{fancyhdr} % For headers and footers
\usepackage{titlesec} % For customizing section titles
\usepackage{color} % For colored text
\usepackage{xcolor} % Extended colors
\usepackage{graphicx} % For including images
\usepackage{longtable}% For tables that span multiple pages
\usepackage{tocloft} % For table of contents customization
\usepackage{setspace} % For line spacing

% Page layout settings
\geometry{
a4paper,
left=25mm,
right=25mm,
top=25mm,
bottom=25mm,
}

% Header and footer settings
\pagestyle{fancy}
\fancyhf{}
\lhead{\textbf{Zhreyas}}
\rhead{\textbf{\today}}
\cfoot{\thepage}

% Section title formatting
\titleformat{\section}{
\normalfont\Large\bfseries
}{\thesection}{1em}{}

% Set line spacing
\setstretch{1.2}

\title{\textbf{Documentation for Codebase Changes}}
\author{Generated by Adhoc \\ Author: Default Author}
\date{\today}

\begin{document}

\maketitle

\section*{Codebase Summary}
No codebase summary available.

\newpage

\section*{Change Explanations}



\end{document}
Empty file removed include
Empty file.
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ requests==2.32.3
watchdog==5.0.3
python-docx==1.1.2
ollama
fastapi[standard]
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
'watchdog>=5.0.3', # Updated to a compatible version
'python-docx>=1.1.2',
'ollama'
'fastapi[standard]', # For API
# Removed 'argparse' as it's part of the standard library for Python >=3.2
],
author='Shreyas S',
Expand Down