Creating comprehensive and visually appealing API documentation is essential for any Python project. However, the process can often be time-consuming and cumbersome, especially when dealing with complex configuration tools like Sphinx. Enter CacaoDocs – a lightweight Python package designed to streamline your documentation workflow by effortlessly extracting API documentation directly from your code’s docstrings.

Why Choose CacaoDocs?

When I embarked on developing CacaoDocs, I faced a recurring challenge: spending excessive time customizing Sphinx to fit each new project’s needs, only to repeat the entire setup process every time. This inefficiency inspired me to create a streamlined and visually appealing alternative. With CacaoDocs, you can:

  • Save Time: Generate documentation without repetitive setup.
  • Enhance Productivity: Focus on coding rather than configuration.
  • Achieve Beautiful Documentation: Create visually stunning docs effortlessly.

Key Features of CacaoDocs

CacaoDocs is packed with features that cater to the needs of modern Python developers:

📡 API Documentation

  • doc_type="api": Automatically identify and document your API endpoints, including methods and routes.

🗃️ Data Model Documentation

  • doc_type="types": Document data models (classes) that represent objects or entities in your application.

📝 General Documentation

  • doc_type="docs": Generate documentation for your classes and methods, covering core logic or utility functions.

👀 Live Preview

  • Real-Time Updates: Instantly see changes in your documentation as you code, ensuring accuracy and up-to-date information.

📄 Multiple Output Formats

  • Versatile Formats: Generate documentation in various formats like HTML and JSON to suit your project’s needs.

🔍 Global Search Functionality

  • FlexSearch Integration: Easily find what you need within your documentation with built-in search capabilities.

🔗 Link Generation

  • Automatic Linking: Create links between different parts of your documentation for seamless navigation.

📋 Code Snippet Copying

  • Easy Access: Allow users to copy code examples from your documentation with a single click.

🛠️ API Status Tracking

  • Development Insights: Display the current status of each API endpoint, indicating whether it’s under development or in production.

📊 ER Diagram Integration

  • Visual Models: Embed ER diagrams within the Types documentation to illustrate data model relationships.

🕒 Recent Changes View

  • Update Tracking: View the latest updates and modifications based on “Last Updated” timestamps to stay informed about changes.

📈 Analytics Integration

  • Usage Insights: Track documentation usage with Google Analytics 4 and Microsoft Clarity to understand user interactions through heatmaps and session recordings.

Upcoming Features

CacaoDocs is continuously evolving. Here’s what you can look forward to:

  • 🤖 AI-Powered Documentation: Leverage OpenAI to generate custom, intelligent documentation tailored to your codebase.
  • 🧩 Plugin System: Extend CacaoDocs functionality with plugins to suit your specific needs.

Getting Started with CacaoDocs

Installation

Installing CacaoDocs is straightforward. You can install it from PyPI using pip:

pip install cacaodocs

Usage

CacaoDocs is designed to be easy to integrate into your projects. Below are examples demonstrating how to use CacaoDocs in different scenarios.

1. Documenting a Normal Class

Annotate your methods using the @CacaoDocs.doc_api decorator. CacaoDocs will parse your docstrings and generate structured documentation automatically.

from cacaodocs import CacaoDocs

class UserManager:
    def __init__(self):
        """
        Initializes the UserManager with an empty user database.
        """
        self.users = {}
        self.next_id = 1

    @CacaoDocs.doc_api(doc_type="docs", tag="user_manager")
    def create_user(self, username: str, email: str) -> dict:
        """
        Method: create_user
        Version: v1
        Status: Production

        Description:
            Creates a new user with a unique ID, username, and email.

        Args:
            username (str): The username of the new user.
            email (str): The email address of the new user.

        Returns:
            @type{User}
        """
        user_id = self.next_id
        self.users[user_id] = {
            "id": user_id,
            "username": username,
            "email": email
        }
        self.next_id += 1
        return self.users[user_id]

    @CacaoDocs.doc_api(doc_type="docs", tag="user_manager")
    def get_user(self, user_id: int) -> dict:
        """
        Method: get_user
        Version: v1
        Status: Production

        Description:
            Retrieves the details of a user by their unique ID.

        Args:
            user_id (int): The unique identifier of the user.

        Raises:
            KeyError: If the user with the specified ID does not exist.

        Returns:
            @type{dict}: A dictionary containing the user's ID, username, and email.
        """
        try:
            return self.users[user_id]
        except KeyError:
            raise KeyError(f"User with ID {user_id} does not exist.")
2. Integrating with a Flask Application

Set up CacaoDocs within a Flask app to automatically detect endpoints and methods.

from flask import Flask, request, jsonify
from cacaodocs import CacaoDocs

# Load the CacaoDocs configuration
CacaoDocs.load_config()

app = Flask(__name__)

@app.route('/api/users', methods=['POST'])
@CacaoDocs.doc_api(doc_type="api", tag="users")
def create_user():
    """
    Method:   POST
    Version:  v1
    Status:   Production
    Last Updated: 2024-04-25

    Description:
        Creates a new user with the provided details.

    Responses:
        201:
            description: "User successfully created."
            example: {"id": 12345, "username": "johndoe"}
        400:
            description: "Bad request due to invalid input."
            example: {"error": "Invalid email format."}
    """
    data = request.json or {}
    try:
        # Assuming `db` is an instance of UserManager or similar
        user = db.create_user(data)
        return jsonify(user.to_dict()), 201
    except Exception as e:
        return jsonify({"error": str(e)}), 400

@app.route('/api/users/<int:user_id>', methods=['GET'])
@CacaoDocs.doc_api(doc_type="api", tag="users")
def get_user(user_id):
    """
    Endpoint: /api/users/<user_id>
    Method:   GET
    Version:  v1
    Status:   Production
    Last Updated: 2024-04-25

    Description:
        Retrieves the details of a user given their unique ID.

    Args:
        user_id (int): The unique identifier of the user.

    Raises:
        UserNotFoundError: If no user is found with the given `user_id`.

    Responses:
        Data:
            example: @type{User}
    """
    return {"error": "User not found"}, 404

@app.route('/docs', methods=['GET'])
def get_documentation():
    """
    Endpoint: /docs
    Method:   GET
    Version:  v1
    Status:   Production
    Last Updated: 2024-04-25

    Description:
        Returns a JSON object containing metadata for all documented endpoints.
    """
    documentation = CacaoDocs.get_json()
    response = jsonify(documentation)
    response.headers.add('Access-Control-Allow-Origin', '*')  # Enable CORS
    return response, 200

@app.route('/', methods=['GET'])
def get_documentation_html():
    """
    Endpoint: /
    Method:   GET
    Version:  v1
    Status:   Production
    Last Updated: 2024-04-25

    Description:
        Returns an HTML page containing the API documentation.

    Returns:
        200:
            description: "HTML documentation retrieved successfully."
            example: "<html><body>API Documentation</body></html>"
    """
    html_documentation = CacaoDocs.get_html()
    return html_documentation, 200, {'Content-Type': 'text/html'}
3. Documenting Data Models (Types)

Use doc_type="types" to document your data models or classes.

from dataclasses import dataclass, asdict
from cacaodocs import CacaoDocs

@dataclass
@CacaoDocs.doc_api(doc_type="types", tag="locations")
class Address:
    """
    Description:
        Represents a user's address in the system.

    Args:
        street (str): Street name and number
        city (City): City information
        country (Country): Country information
        postal_code (str): Postal or ZIP code
    """
    street: str
    city: 'City'
    country: 'Country'
    postal_code: str

    def to_dict(self) -> dict:
        """Convert address to dictionary format."""
        return {
            'street': self.street,
            'city': asdict(self.city),
            'country': asdict(self.country),
            'postal_code': self.postal_code
        }

    @classmethod
    def from_dict(cls, data: dict) -> 'Address':
        """Create an Address instance from a dictionary."""
        return cls(
            street=data['street'],
            city=City(**data['city']),
            country=Country(**data['country']),
            postal_code=data['postal_code']
        )
4. API Status Tracking

CacaoDocs now includes API Status Tracking, allowing you to indicate whether each endpoint is under development or in production.

@CacaoDocs.doc_api(doc_type="api", tag="users")
def delete_user(user_id: int):
    """
    Endpoint: /api/users/<user_id>
    Method:   DELETE
    Version:  v1
    Status:   Under Development
    Last Updated: 2024-05-10

    Description:
        Deletes a user by their unique ID.

    Args:
        user_id (int): The unique identifier of the user to delete.

    Responses:
        200:
            description: "User successfully deleted."
        404:
            description: "User not found."
    """
    # Implementation goes here
    pass
5. Embedding ER Diagrams

To provide a clear understanding of data model relationships, CacaoDocs supports embedding ER Diagrams within the Types documentation.

Figure 1: ER Diagram for the Types Page

6. Recent Changes View

CacaoDocs introduces a Recent Changes View, allowing you to track the latest modifications based on “Last Updated” timestamps.

{
    "endpoints": [
        {
            "path": "/api/users",
            "method": "POST",
            "last_updated": "2024-04-25",
            "status": "Production"
        },
        {
            "path": "/api/users/<int:user_id>",
            "method": "GET",
            "last_updated": "2024-04-25",
            "status": "Production"
        },
        {
            "path": "/api/users/<user_id>",
            "method": "DELETE",
            "last_updated": "2024-05-10",
            "status": "Under Development"
        }
    ],
    "types": [
        {
            "name": "Address",
            "last_updated": "2024-03-15"
        }
    ]
}

This JSON structure helps developers quickly identify the most recently updated parts of the documentation, ensuring they stay informed about the latest changes.

Installation

Installing CacaoDocs is simple. Use pip to install the package from PyPI:

pip install cacaodocs

Getting Involved

CacaoDocs is still under development, and your contributions can help shape its future. Whether you want to suggest improvements, report bugs, or contribute code, your participation is welcome!

How to Contribute

  • Suggest Improvements or New Features: Share your ideas to make CacaoDocs even better.
  • Submit Bug Reports: Help us identify and fix issues.
  • Contribute Directly with Pull Requests: If you’re comfortable with coding, contribute directly to the project.

Feel free to open an issue or create a pull request in the CacaoDocs GitHub Repository.

Live Documentation and Resources

Explore more about CacaoDocs through the following resources:

Conclusion

CacaoDocs aims to revolutionize the way Python developers generate API documentation. By eliminating the hassles of heavy configuration tools and providing a streamlined, visually appealing solution, CacaoDocs allows you to focus on what truly matters – writing quality code. Join the CacaoDocs community today and contribute to making documentation generation easier and more beautiful for everyone!

Happy documenting! 🎉📚


Stay Connected


Note: CacaoDocs is still under development. It currently lacks many customization options and may have limitations. Don’t expect a fully functional package out of the box—but feel free to contribute and help improve it! 🤝✨


Built With

  • Python
  • Markdown
  • Jinja2