Skip to main content
Glama
text.py9.29 kB
"""Text editing routes. This module provides endpoints for text and paragraph operations. """ import os from typing import Any from fastapi import APIRouter from src.core.config import get_settings from src.core.exceptions import DocumentNotFoundError from src.handlers.text_handler import TextHandler from src.models.schemas import ( ParagraphCreate, ParagraphUpdate, TextFormat, TextInsert, TextReplace, ) router = APIRouter(prefix="/documents/{document_id}/text") def get_text_handler(document_id: str) -> TextHandler: """Get text handler for a document. Args: document_id: Document UUID. Returns: TextHandler instance. Raises: DocumentNotFoundError: If document not found. """ settings = get_settings() file_path = os.path.join(settings.upload_dir, f"{document_id}.docx") if not os.path.exists(file_path): raise DocumentNotFoundError(document_id) from src.handlers.document_handler import DocumentHandler doc_handler = DocumentHandler() doc_handler.open_document(file_path) return TextHandler(doc_handler.document) @router.get( "/paragraphs", summary="Get All Paragraphs", description="Get all paragraphs in the document.", ) async def get_paragraphs(document_id: str) -> dict[str, Any]: """Get all paragraphs. Args: document_id: Document UUID. Returns: List of paragraphs. """ handler = get_text_handler(document_id) paragraphs = handler.get_all_paragraphs() return { "document_id": document_id, "count": len(paragraphs), "paragraphs": [ { "index": p.index, "text": p.text, "style": p.style, "alignment": p.alignment.value if p.alignment else None, } for p in paragraphs ], } @router.get( "/paragraphs/{index}", summary="Get Paragraph", description="Get a specific paragraph by index.", ) async def get_paragraph( document_id: str, index: int, ) -> dict[str, Any]: """Get a paragraph by index. Args: document_id: Document UUID. index: Paragraph index. Returns: Paragraph information. """ handler = get_text_handler(document_id) para = handler.get_paragraph(index) return { "index": para.index, "text": para.text, "style": para.style, "alignment": para.alignment.value if para.alignment else None, "runs": [ { "text": r.text, "bold": r.bold, "italic": r.italic, "underline": r.underline, "font_name": r.font_name, "font_size": r.font_size, } for r in para.runs ], } @router.post( "/paragraphs", summary="Add Paragraph", description="Add a new paragraph to the document.", ) async def add_paragraph( document_id: str, data: ParagraphCreate, ) -> dict[str, Any]: """Add a new paragraph. Args: document_id: Document UUID. data: Paragraph data. Returns: Created paragraph information. """ settings = get_settings() file_path = os.path.join(settings.upload_dir, f"{document_id}.docx") if not os.path.exists(file_path): raise DocumentNotFoundError(document_id) from src.handlers.document_handler import DocumentHandler doc_handler = DocumentHandler() doc_handler.open_document(file_path) handler = TextHandler(doc_handler.document) index = handler.add_paragraph( text=data.text, style=data.style, alignment=data.alignment, ) doc_handler.save_document() return { "index": index, "text": data.text, "style": data.style, } @router.put( "/paragraphs/{index}", summary="Update Paragraph", description="Update a paragraph.", ) async def update_paragraph( document_id: str, index: int, data: ParagraphUpdate, ) -> dict[str, Any]: """Update a paragraph. Args: document_id: Document UUID. index: Paragraph index. data: Update data. Returns: Updated paragraph information. """ settings = get_settings() file_path = os.path.join(settings.upload_dir, f"{document_id}.docx") if not os.path.exists(file_path): raise DocumentNotFoundError(document_id) from src.handlers.document_handler import DocumentHandler doc_handler = DocumentHandler() doc_handler.open_document(file_path) handler = TextHandler(doc_handler.document) para = handler.update_paragraph( index=index, text=data.text, style=data.style, alignment=data.alignment, ) doc_handler.save_document() return { "index": para.index, "text": para.text, "style": para.style, "updated": True, } @router.delete( "/paragraphs/{index}", summary="Delete Paragraph", description="Delete a paragraph.", ) async def delete_paragraph( document_id: str, index: int, ) -> dict[str, Any]: """Delete a paragraph. Args: document_id: Document UUID. index: Paragraph index. Returns: Deletion confirmation. """ settings = get_settings() file_path = os.path.join(settings.upload_dir, f"{document_id}.docx") if not os.path.exists(file_path): raise DocumentNotFoundError(document_id) from src.handlers.document_handler import DocumentHandler doc_handler = DocumentHandler() doc_handler.open_document(file_path) handler = TextHandler(doc_handler.document) handler.delete_paragraph(index) doc_handler.save_document() return {"deleted": True, "index": index} @router.post( "/insert", summary="Insert Text", description="Insert text at a specific position.", ) async def insert_text( document_id: str, data: TextInsert, ) -> dict[str, Any]: """Insert text at a position. Args: document_id: Document UUID. data: Insert data. Returns: Insert confirmation. """ settings = get_settings() file_path = os.path.join(settings.upload_dir, f"{document_id}.docx") if not os.path.exists(file_path): raise DocumentNotFoundError(document_id) from src.handlers.document_handler import DocumentHandler doc_handler = DocumentHandler() doc_handler.open_document(file_path) handler = TextHandler(doc_handler.document) handler.insert_text( paragraph_index=data.paragraph_index, offset=data.offset or 0, text=data.text, format_=data.format, ) doc_handler.save_document() return { "inserted": True, "paragraph_index": data.paragraph_index, "text": data.text, } @router.post( "/replace", summary="Find and Replace", description="Find and replace text in the document.", ) async def find_and_replace( document_id: str, data: TextReplace, ) -> dict[str, Any]: """Find and replace text. Args: document_id: Document UUID. data: Replace data. Returns: Replace result. """ settings = get_settings() file_path = os.path.join(settings.upload_dir, f"{document_id}.docx") if not os.path.exists(file_path): raise DocumentNotFoundError(document_id) from src.handlers.document_handler import DocumentHandler doc_handler = DocumentHandler() doc_handler.open_document(file_path) handler = TextHandler(doc_handler.document) count = handler.replace_text( find=data.find, replace=data.replace, case_sensitive=data.case_sensitive, whole_word=data.whole_word, ) doc_handler.save_document() return { "replaced": True, "count": count, "find": data.find, "replace": data.replace, } @router.post( "/format", summary="Format Text", description="Apply formatting to text.", ) async def format_text( document_id: str, paragraph_index: int, run_index: int, format_data: TextFormat, ) -> dict[str, Any]: """Apply formatting to a text run. Args: document_id: Document UUID. paragraph_index: Paragraph index. run_index: Run index within the paragraph. format_data: Formatting to apply. Returns: Format result. """ settings = get_settings() file_path = os.path.join(settings.upload_dir, f"{document_id}.docx") if not os.path.exists(file_path): raise DocumentNotFoundError(document_id) from src.handlers.document_handler import DocumentHandler doc_handler = DocumentHandler() doc_handler.open_document(file_path) handler = TextHandler(doc_handler.document) run = handler.format_run( paragraph_index=paragraph_index, run_index=run_index, format_=format_data, ) doc_handler.save_document() return { "formatted": True, "paragraph_index": paragraph_index, "run_index": run_index, "run": { "text": run.text, "bold": run.bold, "italic": run.italic, }, }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Fu-Jie/MCP-OPENAPI-DOCX'

If you have feedback or need assistance with the MCP directory API, please join our Discord server