From d68d3120c3883963fd95c7a9b4e3bc811c7d1338 Mon Sep 17 00:00:00 2001 From: Vishesh 'ironeagle' Bangotra Date: Sat, 21 Feb 2026 22:12:15 +0530 Subject: [PATCH] module as source doc fixes --- docforge.nav.yml | 44 ++--- docs/{mail_intake => }/adapters/base.md | 0 docs/{mail_intake => }/adapters/gmail.md | 0 docs/{mail_intake => }/adapters/index.md | 0 docs/{mail_intake => }/auth/base.md | 0 docs/{mail_intake => }/auth/google.md | 0 docs/{mail_intake => }/auth/index.md | 0 docs/{mail_intake => }/config.md | 0 docs/{mail_intake => }/credentials/index.md | 0 docs/{mail_intake => }/credentials/pickle.md | 0 docs/{mail_intake => }/credentials/redis.md | 0 docs/{mail_intake => }/credentials/store.md | 0 docs/{mail_intake => }/exceptions.md | 0 docs/{mail_intake => }/index.md | 2 +- docs/{mail_intake => }/ingestion/index.md | 0 docs/{mail_intake => }/ingestion/reader.md | 0 docs/{mail_intake => }/models/index.md | 0 docs/{mail_intake => }/models/message.md | 0 docs/{mail_intake => }/models/thread.md | 0 docs/{mail_intake => }/parsers/body.md | 0 docs/{mail_intake => }/parsers/headers.md | 0 docs/{mail_intake => }/parsers/index.md | 0 docs/{mail_intake => }/parsers/subject.md | 0 fetch_emails.py | 22 +++ generate_mcp.py | 176 ------------------- mcp_server.py | 32 ---- mkdocs.yml | 50 +++--- 27 files changed, 68 insertions(+), 258 deletions(-) rename docs/{mail_intake => }/adapters/base.md (100%) rename docs/{mail_intake => }/adapters/gmail.md (100%) rename docs/{mail_intake => }/adapters/index.md (100%) rename docs/{mail_intake => }/auth/base.md (100%) rename docs/{mail_intake => }/auth/google.md (100%) rename docs/{mail_intake => }/auth/index.md (100%) rename docs/{mail_intake => }/config.md (100%) rename docs/{mail_intake => }/credentials/index.md (100%) rename docs/{mail_intake => }/credentials/pickle.md (100%) rename docs/{mail_intake => }/credentials/redis.md (100%) rename docs/{mail_intake => }/credentials/store.md (100%) rename docs/{mail_intake => }/exceptions.md (100%) rename docs/{mail_intake => }/index.md (54%) rename docs/{mail_intake => }/ingestion/index.md (100%) rename docs/{mail_intake => }/ingestion/reader.md (100%) rename docs/{mail_intake => }/models/index.md (100%) rename docs/{mail_intake => }/models/message.md (100%) rename docs/{mail_intake => }/models/thread.md (100%) rename docs/{mail_intake => }/parsers/body.md (100%) rename docs/{mail_intake => }/parsers/headers.md (100%) rename docs/{mail_intake => }/parsers/index.md (100%) rename docs/{mail_intake => }/parsers/subject.md (100%) create mode 100644 fetch_emails.py delete mode 100644 generate_mcp.py delete mode 100644 mcp_server.py diff --git a/docforge.nav.yml b/docforge.nav.yml index 9438143..26c6d7c 100644 --- a/docforge.nav.yml +++ b/docforge.nav.yml @@ -1,29 +1,29 @@ -home: mail_intake/index.md +home: index.md groups: Core API: - - mail_intake/ingestion/index.md - - mail_intake/ingestion/reader.md + - ingestion/index.md + - ingestion/reader.md Domain Models: - - mail_intake/models/index.md - - mail_intake/models/message.md - - mail_intake/models/thread.md + - models/index.md + - models/message.md + - models/thread.md Provider Adapters: - - mail_intake/adapters/index.md - - mail_intake/adapters/base.md - - mail_intake/adapters/gmail.md + - adapters/index.md + - adapters/base.md + - adapters/gmail.md Authentication & Storage: - - mail_intake/auth/index.md - - mail_intake/auth/base.md - - mail_intake/auth/google.md - - mail_intake/credentials/index.md - - mail_intake/credentials/store.md - - mail_intake/credentials/pickle.md - - mail_intake/credentials/redis.md + - auth/index.md + - auth/base.md + - auth/google.md + - credentials/index.md + - credentials/store.md + - credentials/pickle.md + - credentials/redis.md Normalization & Parsing: - - mail_intake/parsers/index.md - - mail_intake/parsers/body.md - - mail_intake/parsers/headers.md - - mail_intake/parsers/subject.md + - parsers/index.md + - parsers/body.md + - parsers/headers.md + - parsers/subject.md Configuration & Errors: - - mail_intake/config.md - - mail_intake/exceptions.md + - config.md + - exceptions.md diff --git a/docs/mail_intake/adapters/base.md b/docs/adapters/base.md similarity index 100% rename from docs/mail_intake/adapters/base.md rename to docs/adapters/base.md diff --git a/docs/mail_intake/adapters/gmail.md b/docs/adapters/gmail.md similarity index 100% rename from docs/mail_intake/adapters/gmail.md rename to docs/adapters/gmail.md diff --git a/docs/mail_intake/adapters/index.md b/docs/adapters/index.md similarity index 100% rename from docs/mail_intake/adapters/index.md rename to docs/adapters/index.md diff --git a/docs/mail_intake/auth/base.md b/docs/auth/base.md similarity index 100% rename from docs/mail_intake/auth/base.md rename to docs/auth/base.md diff --git a/docs/mail_intake/auth/google.md b/docs/auth/google.md similarity index 100% rename from docs/mail_intake/auth/google.md rename to docs/auth/google.md diff --git a/docs/mail_intake/auth/index.md b/docs/auth/index.md similarity index 100% rename from docs/mail_intake/auth/index.md rename to docs/auth/index.md diff --git a/docs/mail_intake/config.md b/docs/config.md similarity index 100% rename from docs/mail_intake/config.md rename to docs/config.md diff --git a/docs/mail_intake/credentials/index.md b/docs/credentials/index.md similarity index 100% rename from docs/mail_intake/credentials/index.md rename to docs/credentials/index.md diff --git a/docs/mail_intake/credentials/pickle.md b/docs/credentials/pickle.md similarity index 100% rename from docs/mail_intake/credentials/pickle.md rename to docs/credentials/pickle.md diff --git a/docs/mail_intake/credentials/redis.md b/docs/credentials/redis.md similarity index 100% rename from docs/mail_intake/credentials/redis.md rename to docs/credentials/redis.md diff --git a/docs/mail_intake/credentials/store.md b/docs/credentials/store.md similarity index 100% rename from docs/mail_intake/credentials/store.md rename to docs/credentials/store.md diff --git a/docs/mail_intake/exceptions.md b/docs/exceptions.md similarity index 100% rename from docs/mail_intake/exceptions.md rename to docs/exceptions.md diff --git a/docs/mail_intake/index.md b/docs/index.md similarity index 54% rename from docs/mail_intake/index.md rename to docs/index.md index dae6579..cb976a8 100644 --- a/docs/mail_intake/index.md +++ b/docs/index.md @@ -1,3 +1,3 @@ -# Mail Intake +# mail_intake ::: mail_intake diff --git a/docs/mail_intake/ingestion/index.md b/docs/ingestion/index.md similarity index 100% rename from docs/mail_intake/ingestion/index.md rename to docs/ingestion/index.md diff --git a/docs/mail_intake/ingestion/reader.md b/docs/ingestion/reader.md similarity index 100% rename from docs/mail_intake/ingestion/reader.md rename to docs/ingestion/reader.md diff --git a/docs/mail_intake/models/index.md b/docs/models/index.md similarity index 100% rename from docs/mail_intake/models/index.md rename to docs/models/index.md diff --git a/docs/mail_intake/models/message.md b/docs/models/message.md similarity index 100% rename from docs/mail_intake/models/message.md rename to docs/models/message.md diff --git a/docs/mail_intake/models/thread.md b/docs/models/thread.md similarity index 100% rename from docs/mail_intake/models/thread.md rename to docs/models/thread.md diff --git a/docs/mail_intake/parsers/body.md b/docs/parsers/body.md similarity index 100% rename from docs/mail_intake/parsers/body.md rename to docs/parsers/body.md diff --git a/docs/mail_intake/parsers/headers.md b/docs/parsers/headers.md similarity index 100% rename from docs/mail_intake/parsers/headers.md rename to docs/parsers/headers.md diff --git a/docs/mail_intake/parsers/index.md b/docs/parsers/index.md similarity index 100% rename from docs/mail_intake/parsers/index.md rename to docs/parsers/index.md diff --git a/docs/mail_intake/parsers/subject.md b/docs/parsers/subject.md similarity index 100% rename from docs/mail_intake/parsers/subject.md rename to docs/parsers/subject.md diff --git a/fetch_emails.py b/fetch_emails.py new file mode 100644 index 0000000..f0bc4de --- /dev/null +++ b/fetch_emails.py @@ -0,0 +1,22 @@ +from mail_intake.ingestion import MailIntakeReader +from mail_intake.adapters import MailIntakeGmailAdapter +from mail_intake.auth import MailIntakeGoogleAuth +from mail_intake.credentials.pickle import PickleCredentialStore + +store = PickleCredentialStore(path="token.pickle") + +auth = MailIntakeGoogleAuth( + credentials_path="credentials.json", + store=store, + scopes=["https://www.googleapis.com/auth/gmail.readonly"], +) +auth.get_credentials() + +adapter = MailIntakeGmailAdapter(auth_provider=auth) +reader = MailIntakeReader(adapter) + +for message in reader.iter_messages("from:roshnisingh009@gmail.com"): + print(message.subject, message.from_email) + break + +from pdb import set_trace;set_trace() diff --git a/generate_mcp.py b/generate_mcp.py deleted file mode 100644 index 059854b..0000000 --- a/generate_mcp.py +++ /dev/null @@ -1,176 +0,0 @@ -""" -Generate a fully-contained MCP bundle by reading Python docstrings directly. - -Uses Griffe (the same library mkdocstrings-python uses internally), -but without MkDocs, Markdown, or HTML. - -Output: -mcp/ -├── index.json -├── nav.json -└── modules/ - └── package.module.json -""" - -from __future__ import annotations - -import json -import argparse -from pathlib import Path -from typing import Iterable - -from griffe import GriffeLoader, ModulesCollection, LinesCollection, AliasResolutionError - - -PROJECT_ROOT = Path(__file__).resolve().parent -DEFAULT_PACKAGE_ROOT = "mail_intake" -DEFAULT_MCP_DIR = PROJECT_ROOT / "mcp" - - -# ------------------------- -# Utilities -# ------------------------- - -def iter_modules(package_root: Path, package_name: str) -> Iterable[str]: - for py in package_root.rglob("*.py"): - rel = py.relative_to(package_root.parent) - if py.name == "__init__.py": - yield ".".join(rel.parent.parts) - else: - yield ".".join(rel.with_suffix("").parts) - - -def serialize_object(obj) -> dict: - """Convert a Griffe object into MCP-friendly JSON (alias-safe).""" - - try: - docstring = obj.docstring.value if obj.docstring else None - except AliasResolutionError: - docstring = None - - data = { - "name": obj.name, - "kind": obj.kind.value, - "path": obj.path, - "docstring": docstring, - } - - # Signature may also trigger alias resolution - try: - if hasattr(obj, "signature") and obj.signature: - data["signature"] = str(obj.signature) - except AliasResolutionError: - pass - - # Recurse into members, but never allow alias failure to bubble up - members = {} - if hasattr(obj, "members"): - for name, member in obj.members.items(): - if name.startswith("_"): - continue - try: - members[name] = serialize_object(member) - except AliasResolutionError: - continue - - if members: - data["members"] = members - - return data - - -# ------------------------- -# MCP generation -# ------------------------- - -def build_mcp(package_root: Path, package_name: str, mcp_root: Path) -> None: - modules_dir = mcp_root / "modules" - modules_dir.mkdir(parents=True, exist_ok=True) - - loader = GriffeLoader( - search_paths=[str(package_root.parent)], - modules_collection=ModulesCollection(), - lines_collection=LinesCollection(), - ) - - nav = [] - count = 0 - - for module in sorted(iter_modules(package_root, package_name)): - loader.load(module) - mod = loader.modules_collection[module] - - payload = { - "module": module, - "content": serialize_object(mod), - } - - out = modules_dir / f"{module}.json" - out.parent.mkdir(parents=True, exist_ok=True) - out.write_text(json.dumps(payload, indent=2), encoding="utf-8") - - nav.append({ - "module": module, - "resource": f"docs://module/{module}", - }) - - count += 1 - - (mcp_root / "nav.json").write_text( - json.dumps(nav, indent=2), - encoding="utf-8", - ) - - (mcp_root / "index.json").write_text( - json.dumps( - { - "project": package_name, - "type": "docstrings-direct", - "modules_count": count, - "source": "griffe", - }, - indent=2, - ), - encoding="utf-8", - ) - - print(f"MCP generated at: {mcp_root}") - - -# ------------------------- -# CLI -# ------------------------- - -def main() -> None: - parser = argparse.ArgumentParser( - description="Generate MCP directly from Python docstrings (Griffe-based)", - ) - - parser.add_argument( - "--package-root", - default=DEFAULT_PACKAGE_ROOT, - help="Root Python package name", - ) - - parser.add_argument( - "--mcp-dir", - type=Path, - default=DEFAULT_MCP_DIR, - help="Output MCP directory", - ) - - args = parser.parse_args() - - package_root = PROJECT_ROOT / args.package_root - if not package_root.exists(): - raise FileNotFoundError(package_root) - - build_mcp( - package_root=package_root, - package_name=args.package_root, - mcp_root=args.mcp_dir, - ) - - -if __name__ == "__main__": - main() diff --git a/mcp_server.py b/mcp_server.py deleted file mode 100644 index f841e04..0000000 --- a/mcp_server.py +++ /dev/null @@ -1,32 +0,0 @@ -from pathlib import Path -import json -from mcp.server.fastmcp import FastMCP - -MCP_ROOT = Path("mcp") - -mcp = FastMCP("aetoskia-mail-intake-docs") - -def read_json(path: Path): - if not path.exists(): - return {"error": "not_found", "path": str(path)} - return json.loads(path.read_text()) - -@mcp.resource("docs://index") -def index(): - return read_json(MCP_ROOT / "index.json") - -@mcp.resource("docs://nav") -def nav(): - return read_json(MCP_ROOT / "nav.json") - -@mcp.resource("docs://module/{module}") -def module(module: str): - return read_json(MCP_ROOT / "modules" / f"{module}.json") - -@mcp.tool() -def ping() -> str: - return "Pong! (fake tool executed)" - -if __name__ == "__main__": - # FastMCP owns the HTTP server - mcp.run(transport="streamable-http") diff --git a/mkdocs.yml b/mkdocs.yml index 06940f0..92e9674 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,6 +1,3 @@ -site_name: Aetoskia Mail Intake -site_description: Format-agnostic document reading, parsing, and scraping framework - theme: name: material palette: @@ -17,7 +14,6 @@ theme: - navigation.instant - content.code.copy - content.code.annotate - plugins: - search - mkdocstrings: @@ -35,33 +31,33 @@ plugins: annotations_path: brief show_root_heading: true group_by_category: true - +site_name: mail_intake nav: -- Home: mail_intake/index.md +- Home: index.md - Core API: - - mail_intake/ingestion/index.md - - mail_intake/ingestion/reader.md + - ingestion/index.md + - ingestion/reader.md - Domain Models: - - mail_intake/models/index.md - - mail_intake/models/message.md - - mail_intake/models/thread.md + - models/index.md + - models/message.md + - models/thread.md - Provider Adapters: - - mail_intake/adapters/index.md - - mail_intake/adapters/base.md - - mail_intake/adapters/gmail.md + - adapters/index.md + - adapters/base.md + - adapters/gmail.md - Authentication & Storage: - - mail_intake/auth/index.md - - mail_intake/auth/base.md - - mail_intake/auth/google.md - - mail_intake/credentials/index.md - - mail_intake/credentials/store.md - - mail_intake/credentials/pickle.md - - mail_intake/credentials/redis.md + - auth/index.md + - auth/base.md + - auth/google.md + - credentials/index.md + - credentials/store.md + - credentials/pickle.md + - credentials/redis.md - Normalization & Parsing: - - mail_intake/parsers/index.md - - mail_intake/parsers/body.md - - mail_intake/parsers/headers.md - - mail_intake/parsers/subject.md + - parsers/index.md + - parsers/body.md + - parsers/headers.md + - parsers/subject.md - Configuration & Errors: - - mail_intake/config.md - - mail_intake/exceptions.md + - config.md + - exceptions.md -- 2.49.1