Skip to main content
Glama
layout.py8.75 kB
"""Layout routes. This module provides endpoints for page layout operations. """ import contextlib import os from typing import Any from fastapi import APIRouter from src.core.config import get_settings from src.core.enums import HeaderFooterType, SectionStart from src.core.exceptions import DocumentNotFoundError from src.handlers.document_handler import DocumentHandler from src.handlers.layout_handler import LayoutHandler from src.models.schemas import PageLayout router = APIRouter(prefix="/documents/{document_id}/layout") def get_layout_handler(document_id: str) -> tuple[DocumentHandler, LayoutHandler]: """Get layout handler for a document.""" 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) doc_handler = DocumentHandler() doc_handler.open_document(file_path) return doc_handler, LayoutHandler(doc_handler.document) @router.get( "/sections", summary="Get All Sections", description="Get all sections in the document.", ) async def get_sections(document_id: str) -> dict[str, Any]: """Get all sections. Args: document_id: Document UUID. Returns: List of sections. """ _, handler = get_layout_handler(document_id) sections = handler.get_all_sections() return { "document_id": document_id, "count": len(sections), "sections": [ { "index": s.index, "page_width": s.page_width, "page_height": s.page_height, "margin_top": s.margin_top, "margin_bottom": s.margin_bottom, "margin_left": s.margin_left, "margin_right": s.margin_right, "orientation": s.orientation, } for s in sections ], } @router.get( "/sections/{index}", summary="Get Section", description="Get a specific section by index.", ) async def get_section( document_id: str, index: int, ) -> dict[str, Any]: """Get a section. Args: document_id: Document UUID. index: Section index. Returns: Section information. """ _, handler = get_layout_handler(document_id) section = handler.get_section(index) return { "index": section.index, "page_width": section.page_width, "page_height": section.page_height, "margin_top": section.margin_top, "margin_bottom": section.margin_bottom, "margin_left": section.margin_left, "margin_right": section.margin_right, "orientation": section.orientation, } @router.put( "/sections/{index}", summary="Update Section Layout", description="Update page layout for a section.", ) async def update_section( document_id: str, index: int, layout: PageLayout, ) -> dict[str, Any]: """Update section layout. Args: document_id: Document UUID. index: Section index. layout: Layout settings. Returns: Updated section information. """ doc_handler, handler = get_layout_handler(document_id) section = handler.set_page_layout(index, layout) doc_handler.save_document() return { "index": section.index, "updated": True, } @router.post( "/sections", summary="Add Section", description="Add a new section to the document.", ) async def add_section( document_id: str, start_type: str = "new_page", ) -> dict[str, Any]: """Add a section. Args: document_id: Document UUID. start_type: Section start type. Returns: Created section information. """ doc_handler, handler = get_layout_handler(document_id) st = SectionStart.NEW_PAGE with contextlib.suppress(ValueError): st = SectionStart(start_type) index = handler.add_section(st) doc_handler.save_document() return {"index": index, "start_type": start_type} @router.put( "/sections/{index}/margins", summary="Set Margins", description="Set page margins for a section.", ) async def set_margins( document_id: str, index: int, top: float | None = None, bottom: float | None = None, left: float | None = None, right: float | None = None, ) -> dict[str, Any]: """Set page margins. Args: document_id: Document UUID. index: Section index. top: Top margin in inches. bottom: Bottom margin in inches. left: Left margin in inches. right: Right margin in inches. Returns: Updated section information. """ doc_handler, handler = get_layout_handler(document_id) section = handler.set_margins(index, top, bottom, left, right) doc_handler.save_document() return { "index": section.index, "margin_top": section.margin_top, "margin_bottom": section.margin_bottom, "margin_left": section.margin_left, "margin_right": section.margin_right, } @router.get( "/sections/{index}/header", summary="Get Header", description="Get header content for a section.", ) async def get_header( document_id: str, index: int, header_type: str = "default", ) -> dict[str, Any]: """Get header content. Args: document_id: Document UUID. index: Section index. header_type: Header type. Returns: Header content. """ _, handler = get_layout_handler(document_id) ht = HeaderFooterType.DEFAULT with contextlib.suppress(ValueError): ht = HeaderFooterType(header_type) content = handler.get_header(index, ht) return { "section_index": index, "header_type": header_type, "content": content, } @router.put( "/sections/{index}/header", summary="Set Header", description="Set header content for a section.", ) async def set_header( document_id: str, index: int, text: str, header_type: str = "default", ) -> dict[str, Any]: """Set header content. Args: document_id: Document UUID. index: Section index. text: Header text. header_type: Header type. Returns: Confirmation. """ doc_handler, handler = get_layout_handler(document_id) ht = HeaderFooterType.DEFAULT with contextlib.suppress(ValueError): ht = HeaderFooterType(header_type) handler.set_header(text, index, ht) doc_handler.save_document() return { "section_index": index, "header_type": header_type, "updated": True, } @router.get( "/sections/{index}/footer", summary="Get Footer", description="Get footer content for a section.", ) async def get_footer( document_id: str, index: int, footer_type: str = "default", ) -> dict[str, Any]: """Get footer content. Args: document_id: Document UUID. index: Section index. footer_type: Footer type. Returns: Footer content. """ _, handler = get_layout_handler(document_id) ft = HeaderFooterType.DEFAULT with contextlib.suppress(ValueError): ft = HeaderFooterType(footer_type) content = handler.get_footer(index, ft) return { "section_index": index, "footer_type": footer_type, "content": content, } @router.put( "/sections/{index}/footer", summary="Set Footer", description="Set footer content for a section.", ) async def set_footer( document_id: str, index: int, text: str, footer_type: str = "default", ) -> dict[str, Any]: """Set footer content. Args: document_id: Document UUID. index: Section index. text: Footer text. footer_type: Footer type. Returns: Confirmation. """ doc_handler, handler = get_layout_handler(document_id) ft = HeaderFooterType.DEFAULT with contextlib.suppress(ValueError): ft = HeaderFooterType(footer_type) handler.set_footer(text, index, ft) doc_handler.save_document() return { "section_index": index, "footer_type": footer_type, "updated": True, } @router.post( "/page-break", summary="Add Page Break", description="Add a page break to the document.", ) async def add_page_break(document_id: str) -> dict[str, Any]: """Add a page break. Args: document_id: Document UUID. Returns: Confirmation. """ doc_handler, handler = get_layout_handler(document_id) handler.add_page_break() doc_handler.save_document() return {"added": True, "type": "page_break"}

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