[{"data":1,"prerenderedAt":63},["Reactive",2],{"blog-post-markdown-dynamic-content-generation-automation-workflows-complete-guide":3},{"slug":4,"title":5,"description":6,"excerpt":7,"date":8,"category":9,"author":10,"keywords":11,"readingMinutes":12,"html":13,"headings":14,"tools":37,"related":38},"markdown-dynamic-content-generation-automation-workflows-complete-guide","Markdown Dynamic Content Generation and Automation Workflows: Complete Guide for Automated Documentation, Template Systems, and Content Pipeline Management","Master dynamic content generation in Markdown with comprehensive automation workflows, template engines, data-driven documentation systems, and intelligent content pipeline management for scalable technical writing.","Advanced Markdown dynamic content generation and automation workflows enable systematic creation of data-driven documentation, template-based content systems, and intelligent content pipelines…","2025-12-22","Tutorial","Matthew Rathbone","markdown automation, dynamic content generation markdown, markdown templates, automated documentation markdown, content pipeline markdown, markdown workflows, data driven documentation, template engines markdown",37,"\u003Cp>Advanced Markdown dynamic content generation and automation workflows enable systematic creation of data-driven documentation, template-based content systems, and intelligent content pipelines that automatically generate, update, and maintain documentation at scale. By implementing comprehensive automation strategies, template engines, and content generation systems, technical writers can build documentation ecosystems that adapt dynamically to changing data sources while maintaining consistency, accuracy, and efficiency across large content repositories.\u003C/p>\n\u003Ch2 id=\"why-master-dynamic-content-generation\">Why Master Dynamic Content Generation?\u003C/h2>\n\u003Cp>Professional content automation provides essential benefits for scalable documentation systems:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>Scalability\u003C/strong>: Generate thousands of documentation pages automatically from data sources\u003C/li>\n\u003Cli>\u003Cstrong>Consistency\u003C/strong>: Maintain uniform formatting and structure across all generated content\u003C/li>\n\u003Cli>\u003Cstrong>Real-time Updates\u003C/strong>: Automatically refresh documentation when underlying data changes\u003C/li>\n\u003Cli>\u003Cstrong>Efficiency\u003C/strong>: Reduce manual content creation time by 80-90% for repetitive documentation\u003C/li>\n\u003Cli>\u003Cstrong>Data Integration\u003C/strong>: Connect documentation directly to APIs, databases, and configuration systems\u003C/li>\n\u003Cli>\u003Cstrong>Quality Assurance\u003C/strong>: Implement automated validation and error checking in content pipelines\u003C/li>\n\u003C/ul>\n\u003Ch2 id=\"foundation-automation-principles\">Foundation Automation Principles\u003C/h2>\n\u003Ch3 id=\"template-driven-content-architecture\">Template-Driven Content Architecture\u003C/h3>\n\u003Cp>Understanding the core components of automated content generation:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-markdown\">\u003Cspan class=\"hljs-section\"># Dynamic Content Generation Architecture\u003C/span>\n\n\u003Cspan class=\"hljs-section\">## Template Engine Foundation\u003C/span>\n\u003Cspan class=\"hljs-code\">```yaml\n# content-config.yml - Content generation configuration\nproject:\n  name: &quot;API Documentation Generator&quot;\n  version: &quot;2.1.0&quot;\n  base_url: &quot;https://api.example.com&quot;\n\ndata_sources:\n  - name: &quot;api_endpoints&quot;\n    type: &quot;openapi&quot;\n    source: &quot;https://api.example.com/openapi.json&quot;\n    refresh_interval: &quot;hourly&quot;\n    \n  - name: &quot;user_metrics&quot;\n    type: &quot;database&quot;\n    connection: &quot;postgresql://metrics:5432/analytics&quot;\n    query: &quot;SELECT * FROM daily_metrics WHERE date &gt;= NOW() - INTERVAL &#x27;30 days&#x27;&quot;\n    refresh_interval: &quot;daily&quot;\n    \n  - name: &quot;feature_flags&quot;\n    type: &quot;json&quot;\n    source: &quot;config/features.json&quot;\n    refresh_interval: &quot;on_change&quot;\n\ntemplates:\n  - name: &quot;api_endpoint_doc&quot;\n    source: &quot;templates/api-endpoint.md.j2&quot;\n    output_pattern: &quot;docs/api/endpoints/{{endpoint.path|slug}}.md&quot;\n    data_source: &quot;api_endpoints&quot;\n    \n  - name: &quot;metrics_report&quot;\n    source: &quot;templates/metrics-dashboard.md.j2&quot;\n    output: &quot;docs/analytics/daily-report.md&quot;\n    data_source: &quot;user_metrics&quot;\n    \n  - name: &quot;feature_documentation&quot;\n    source: &quot;templates/feature-guide.md.j2&quot;\n    output_pattern: &quot;docs/features/{{feature.name|slug}}.md&quot;\n    data_source: &quot;feature_flags&quot;\n\nautomation:\n  triggers:\n    - type: &quot;schedule&quot;\n      cron: &quot;0 */6 * * *&quot;  # Every 6 hours\n      templates: [&quot;api_endpoint_doc&quot;, &quot;metrics_report&quot;]\n      \n    - type: &quot;webhook&quot;\n      endpoint: &quot;/regenerate&quot;\n      secret: &quot;${WEBHOOK_SECRET}&quot;\n      templates: [&quot;feature_documentation&quot;]\n      \n    - type: &quot;file_watch&quot;\n      paths: [&quot;config/**/*.json&quot;]\n      templates: [&quot;feature_documentation&quot;]\n\nvalidation:\n  enabled: true\n  rules:\n    - check: &quot;required_frontmatter&quot;\n      fields: [&quot;title&quot;, &quot;description&quot;, &quot;category&quot;]\n    - check: &quot;link_validation&quot;\n      external_links: false\n    - check: &quot;content_length&quot;\n      min_words: 50\n```\u003C/span>\n\n\u003Cspan class=\"hljs-section\">## Basic Template Example\u003C/span>\n\n\u003Cspan class=\"hljs-code\">```jinja2\n&lt;!-- templates/api-endpoint.md.j2 --&gt;\n---\ntitle: &quot;{{endpoint.summary}} - {{endpoint.method|upper}} {{endpoint.path}}&quot;\ndescription: &quot;{{endpoint.description|truncate(160)}}&quot;\ncategory: &quot;API Reference&quot;\ntags: \n  - &quot;{{endpoint.tags|join(&#x27;&quot;, &quot;&#x27;)}}&quot;\nmethod: &quot;{{endpoint.method|upper}}&quot;\npath: &quot;{{endpoint.path}}&quot;\n---\n\n# {{endpoint.summary}}\n\n{{endpoint.description}}\n\n## Request Details\n\n**Method:** `{{endpoint.method|upper}}`  \n**Path:** `{{endpoint.path}}`  \n**Content-Type:** `{{endpoint.consumes|default([&#x27;application/json&#x27;])|join(&#x27;, &#x27;)}}`\n\n{% if endpoint.parameters %}\n## Parameters\n\n| Name | Type | Required | Description |\n|:-----|:-----|:---------|:------------|\n{% for param in endpoint.parameters %}\n| **{{param.name}}** | {{param.type}} | {{param.required|yesno}} | {{param.description|default(&#x27;No description provided&#x27;)}} |\n{% endfor %}\n{% endif %}\n\n{% if endpoint.requestBody %}\n## Request Body\n\n{{endpoint.requestBody.description}}\n\n### Example Request\n```\u003C/span>json\n{{endpoint.requestBody.examples.default|tojsonpretty}}\n\u003Cspan class=\"hljs-code\">```\n{% endif %}\n\n## Response\n\n{% for status_code, response in endpoint.responses.items() %}\n### {{status_code}} - {{response.description}}\n\n```\u003C/span>json\n{{response.examples.default|tojsonpretty}}\n\u003Cspan class=\"hljs-code\">```\n{% endfor %}\n\n## Code Examples\n\n### cURL\n```\u003C/span>bash\ncurl -X {{endpoint.method|upper}} \\\n  &quot;{{project.base\u003Cspan class=\"hljs-emphasis\">_url}}{{endpoint.path}}&quot; \\\n{% if endpoint.security %}\n  -H &quot;Authorization: Bearer YOUR_\u003C/span>API\u003Cspan class=\"hljs-emphasis\">_KEY&quot; \\\n{% endif %}\n  -H &quot;Content-Type: application/json&quot;\n{% if endpoint.requestBody %}\n  -d &#x27;{{endpoint.requestBody.examples.default|tojson}}&#x27;\n{% endif %}\n```\n\n### JavaScript\n```javascript\nconst response = await fetch(&#x27;{{project.base_\u003C/span>url}}{{endpoint.path}}&#x27;, {\n  method: &#x27;{{endpoint.method|upper}}&#x27;,\n  headers: {\n\u003Cspan class=\"hljs-code\">    &#x27;Content-Type&#x27;: &#x27;application/json&#x27;,\n{% if endpoint.security %}\n    &#x27;Authorization&#x27;: &#x27;Bearer YOUR_API_KEY&#x27;,\n{% endif %}\n  },\n{% if endpoint.requestBody %}\n  body: JSON.stringify({{endpoint.requestBody.examples.default|tojsonpretty|indent(4)}})\n{% endif %}\n});\n\u003C/span>\nconst data = await response.json();\nconsole.log(data);\n\u003Cspan class=\"hljs-code\">```\n\n### Python\n```\u003C/span>python\nimport requests\n\nurl = &quot;{{project.base\u003Cspan class=\"hljs-emphasis\">_url}}{{endpoint.path}}&quot;\nheaders = {\n    &quot;Content-Type&quot;: &quot;application/json&quot;,\n{% if endpoint.security %}\n    &quot;Authorization&quot;: &quot;Bearer YOUR_\u003C/span>API\u003Cspan class=\"hljs-emphasis\">_KEY&quot;\n{% endif %}\n}\n\n{% if endpoint.requestBody %}\ndata = {{endpoint.requestBody.examples.default|tojsonpretty|indent(4)}}\n\nresponse = requests.{{endpoint.method}}(url, headers=headers, json=data)\n{% else %}\nresponse = requests.{{endpoint.method}}(url, headers=headers)\n{% endif %}\nprint(response.json())\n```\n\n---\n*Generated automatically from OpenAPI specification on {{generation_\u003C/span>timestamp}}*\n\u003Cspan class=\"hljs-code\">```\n\u003C/span>\n\u003C/code>\u003C/pre>\u003Ch3 id=\"advanced-template-engine-implementation\">Advanced Template Engine Implementation\u003C/h3>\n\u003Cp>Building comprehensive template processing systems with multiple data sources:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-markdown\">\u003Cspan class=\"hljs-section\"># Advanced Template Engine System\u003C/span>\n\n\u003Cspan class=\"hljs-section\">## Python-Based Generation Engine\u003C/span>\n\u003Cspan class=\"hljs-code\">```python\n#!/usr/bin/env python3\n# content-generator.py - Advanced dynamic content generation system\n\nimport os\nimport json\nimport yaml\nimport sqlite3\nimport asyncio\nimport aiohttp\nimport jinja2\nfrom jinja2 import Environment, FileSystemLoader, StrictUndefined\nfrom pathlib import Path\nfrom typing import Dict, Any, List, Optional, Union\nfrom datetime import datetime, timedelta\nimport hashlib\nimport logging\nfrom dataclasses import dataclass, field\nimport schedule\nimport time\nimport threading\nfrom watchdog.observers import Observer\nfrom watchdog.events import FileSystemEventHandler\nimport psycopg2\nfrom psycopg2.extras import RealDictCursor\nimport requests\nfrom urllib.parse import urljoin\n\nlogging.basicConfig(level=logging.INFO)\nlogger = logging.getLogger(__name__)\n\n@dataclass\nclass DataSource:\n    &quot;&quot;&quot;Configuration for data source&quot;&quot;&quot;\n    name: str\n    type: str\n    source: str\n    refresh_interval: str\n    connection_params: Dict[str, Any] = field(default_factory=dict)\n    query: Optional[str] = None\n    transform_function: Optional[str] = None\n    cache_duration: int = 3600  # seconds\n    \n@dataclass\nclass Template:\n    &quot;&quot;&quot;Template configuration&quot;&quot;&quot;\n    name: str\n    source: str\n    output_pattern: Optional[str] = None\n    output: Optional[str] = None\n    data_source: str = &quot;&quot;\n    context_processors: List[str] = field(default_factory=list)\n    conditions: Dict[str, Any] = field(default_factory=dict)\n\n@dataclass\nclass GenerationResult:\n    &quot;&quot;&quot;Result of content generation&quot;&quot;&quot;\n    template_name: str\n    output_path: str\n    success: bool\n    error_message: Optional[str] = None\n    generated_at: datetime = field(default_factory=datetime.now)\n    data_hash: Optional[str] = None\n\nclass ContentGenerationEngine:\n    &quot;&quot;&quot;Advanced content generation engine with multiple data sources&quot;&quot;&quot;\n    \n    def __init__(self, config_path: str):\n        self.config_path = Path(config_path)\n        self.config = self._load_config()\n        self.data_cache = {}\n        self.cache_timestamps = {}\n        \n        # Setup Jinja2 environment\n        self.jinja_env = Environment(\n            loader=FileSystemLoader([&#x27;templates&#x27;, &#x27;.&#x27;]),\n            undefined=StrictUndefined,\n            trim_blocks=True,\n            lstrip_blocks=True\n        )\n        \n        # Add custom filters\n        self._setup_custom_filters()\n        \n        # Initialize data sources\n        self.data_sources = {\n            source_config[&#x27;name&#x27;]: DataSource(**source_config)\n            for source_config in self.config.get(&#x27;data_sources&#x27;, [])\n        }\n        \n        # Initialize templates\n        self.templates = {\n            template_config[&#x27;name&#x27;]: Template(**template_config)\n            for template_config in self.config.get(&#x27;templates&#x27;, [])\n        }\n        \n        # Setup automation\n        self._setup_automation()\n        \n    def _load_config(self) -&gt; Dict[str, Any]:\n        &quot;&quot;&quot;Load configuration from YAML file&quot;&quot;&quot;\n        try:\n            with open(self.config_path, &#x27;r&#x27;) as f:\n                return yaml.safe_load(f)\n        except Exception as e:\n            logger.error(f&quot;Error loading config: {e}&quot;)\n            raise\n    \n    def _setup_custom_filters(self):\n        &quot;&quot;&quot;Setup custom Jinja2 filters&quot;&quot;&quot;\n        \n        def slug_filter(text: str) -&gt; str:\n            &quot;&quot;&quot;Convert text to URL-friendly slug&quot;&quot;&quot;\n            import re\n            text = re.sub(r&#x27;[^\\w\\s-]&#x27;, &#x27;&#x27;, str(text)).strip().lower()\n            return re.sub(r&#x27;[\\s_-]+&#x27;, &#x27;-&#x27;, text)\n        \n        def yesno_filter(value: bool) -&gt; str:\n            &quot;&quot;&quot;Convert boolean to Yes/No&quot;&quot;&quot;\n            return &quot;Yes&quot; if value else &quot;No&quot;\n        \n        def tojsonpretty_filter(obj: Any) -&gt; str:\n            &quot;&quot;&quot;Convert object to pretty JSON&quot;&quot;&quot;\n            return json.dumps(obj, indent=2, ensure_ascii=False)\n        \n        def truncate_words_filter(text: str, length: int = 50) -&gt; str:\n            &quot;&quot;&quot;Truncate text to specified word count&quot;&quot;&quot;\n            words = str(text).split()\n            if len(words) &lt;= length:\n                return text\n            return &#x27; &#x27;.join(words[:length]) + &#x27;...&#x27;\n        \n        def relative_time_filter(dt: datetime) -&gt; str:\n            &quot;&quot;&quot;Convert datetime to relative time string&quot;&quot;&quot;\n            now = datetime.now()\n            diff = now - dt\n            \n            if diff.days &gt; 0:\n                return f&quot;{diff.days} day{&#x27;s&#x27; if diff.days &gt; 1 else &#x27;&#x27;} ago&quot;\n            elif diff.seconds &gt; 3600:\n                hours = diff.seconds // 3600\n                return f&quot;{hours} hour{&#x27;s&#x27; if hours &gt; 1 else &#x27;&#x27;} ago&quot;\n            elif diff.seconds &gt; 60:\n                minutes = diff.seconds // 60\n                return f&quot;{minutes} minute{&#x27;s&#x27; if minutes &gt; 1 else &#x27;&#x27;} ago&quot;\n            else:\n                return &quot;just now&quot;\n        \n        def format_number_filter(value: Union[int, float], format_type: str = &#x27;default&#x27;) -&gt; str:\n            &quot;&quot;&quot;Format numbers with various styles&quot;&quot;&quot;\n            if format_type == &#x27;currency&#x27;:\n                return f&quot;${value:,.2f}&quot;\n            elif format_type == &#x27;percentage&#x27;:\n                return f&quot;{value:.1f}%&quot;\n            elif format_type == &#x27;abbreviated&#x27;:\n                if value &gt;= 1_000_000:\n                    return f&quot;{value/1_000_000:.1f}M&quot;\n                elif value &gt;= 1_000:\n                    return f&quot;{value/1_000:.1f}K&quot;\n                else:\n                    return str(value)\n            else:\n                return f&quot;{value:,}&quot;\n        \n        # Register filters\n        self.jinja_env.filters[&#x27;slug&#x27;] = slug_filter\n        self.jinja_env.filters[&#x27;yesno&#x27;] = yesno_filter\n        self.jinja_env.filters[&#x27;tojsonpretty&#x27;] = tojsonpretty_filter\n        self.jinja_env.filters[&#x27;truncate_words&#x27;] = truncate_words_filter\n        self.jinja_env.filters[&#x27;relative_time&#x27;] = relative_time_filter\n        self.jinja_env.filters[&#x27;format_number&#x27;] = format_number_filter\n        \n        # Add global functions\n        self.jinja_env.globals[&#x27;now&#x27;] = datetime.now\n        self.jinja_env.globals[&#x27;generation_timestamp&#x27;] = datetime.now().isoformat()\n    \n    async def fetch_data_source(self, source: DataSource) -&gt; Dict[str, Any]:\n        &quot;&quot;&quot;Fetch data from configured source&quot;&quot;&quot;\n        cache_key = source.name\n        now = time.time()\n        \n        # Check cache validity\n        if (cache_key in self.cache_timestamps and \n            now - self.cache_timestamps[cache_key] &lt; source.cache_duration):\n            logger.info(f&quot;Using cached data for {source.name}&quot;)\n            return self.data_cache[cache_key]\n        \n        logger.info(f&quot;Fetching fresh data for {source.name}&quot;)\n        \n        try:\n            if source.type == &#x27;openapi&#x27;:\n                data = await self._fetch_openapi_data(source)\n            elif source.type == &#x27;database&#x27;:\n                data = await self._fetch_database_data(source)\n            elif source.type == &#x27;json&#x27;:\n                data = await self._fetch_json_data(source)\n            elif source.type == &#x27;api&#x27;:\n                data = await self._fetch_api_data(source)\n            elif source.type == &#x27;csv&#x27;:\n                data = await self._fetch_csv_data(source)\n            else:\n                raise ValueError(f&quot;Unknown data source type: {source.type}&quot;)\n            \n            # Apply transformation if specified\n            if source.transform_function:\n                data = await self._apply_transformation(data, source.transform_function)\n            \n            # Cache the data\n            self.data_cache[cache_key] = data\n            self.cache_timestamps[cache_key] = now\n            \n            return data\n            \n        except Exception as e:\n            logger.error(f&quot;Error fetching data from {source.name}: {e}&quot;)\n            # Return cached data if available, otherwise raise\n            if cache_key in self.data_cache:\n                logger.warning(f&quot;Using stale cached data for {source.name}&quot;)\n                return self.data_cache[cache_key]\n            raise\n    \n    async def _fetch_openapi_data(self, source: DataSource) -&gt; Dict[str, Any]:\n        &quot;&quot;&quot;Fetch and process OpenAPI specification&quot;&quot;&quot;\n        async with aiohttp.ClientSession() as session:\n            async with session.get(source.source) as response:\n                response.raise_for_status()\n                spec = await response.json()\n        \n        # Process OpenAPI spec into template-friendly format\n        endpoints = []\n        \n        for path, path_methods in spec.get(&#x27;paths&#x27;, {}).items():\n            for method, operation in path_methods.items():\n                if method.lower() in [&#x27;get&#x27;, &#x27;post&#x27;, &#x27;put&#x27;, &#x27;patch&#x27;, &#x27;delete&#x27;]:\n                    endpoint = {\n                        &#x27;path&#x27;: path,\n                        &#x27;method&#x27;: method.lower(),\n                        &#x27;summary&#x27;: operation.get(&#x27;summary&#x27;, &#x27;&#x27;),\n                        &#x27;description&#x27;: operation.get(&#x27;description&#x27;, &#x27;&#x27;),\n                        &#x27;tags&#x27;: operation.get(&#x27;tags&#x27;, []),\n                        &#x27;parameters&#x27;: operation.get(&#x27;parameters&#x27;, []),\n                        &#x27;requestBody&#x27;: operation.get(&#x27;requestBody&#x27;),\n                        &#x27;responses&#x27;: operation.get(&#x27;responses&#x27;, {}),\n                        &#x27;security&#x27;: operation.get(&#x27;security&#x27;, [])\n                    }\n                    \n                    # Process examples\n                    if endpoint[&#x27;requestBody&#x27;]:\n                        content = endpoint[&#x27;requestBody&#x27;].get(&#x27;content&#x27;, {})\n                        for media_type, schema in content.items():\n                            if &#x27;examples&#x27; not in schema and &#x27;example&#x27; in schema:\n                                schema[&#x27;examples&#x27;] = {&#x27;default&#x27;: schema[&#x27;example&#x27;]}\n                    \n                    endpoints.append(endpoint)\n        \n        return {\n            &#x27;spec&#x27;: spec,\n            &#x27;endpoints&#x27;: endpoints,\n            &#x27;info&#x27;: spec.get(&#x27;info&#x27;, {}),\n            &#x27;servers&#x27;: spec.get(&#x27;servers&#x27;, [])\n        }\n    \n    async def _fetch_database_data(self, source: DataSource) -&gt; Dict[str, Any]:\n        &quot;&quot;&quot;Fetch data from database&quot;&quot;&quot;\n        connection_string = source.source\n        \n        if connection_string.startswith(&#x27;postgresql://&#x27;):\n            import psycopg2.pool\n            \n            # Create connection pool for better performance\n            pool = psycopg2.pool.SimpleConnectionPool(\n                1, 5, connection_string,\n                cursor_factory=RealDictCursor\n            )\n            \n            try:\n                conn = pool.getconn()\n                with conn.cursor() as cursor:\n                    cursor.execute(source.query)\n                    results = cursor.fetchall()\n                    \n                    # Convert to list of dictionaries\n                    data = [dict(row) for row in results]\n                    \n                return {&#x27;rows&#x27;: data, &#x27;count&#x27;: len(data)}\n                \n            finally:\n                pool.putconn(conn)\n                pool.closeall()\n        \n        elif connection_string.startswith(&#x27;sqlite://&#x27;):\n            db_path = connection_string.replace(&#x27;sqlite://&#x27;, &#x27;&#x27;)\n            \n            conn = sqlite3.connect(db_path)\n            conn.row_factory = sqlite3.Row\n            \n            try:\n                cursor = conn.cursor()\n                cursor.execute(source.query)\n                results = cursor.fetchall()\n                \n                data = [dict(row) for row in results]\n                return {&#x27;rows&#x27;: data, &#x27;count&#x27;: len(data)}\n                \n            finally:\n                conn.close()\n        \n        else:\n            raise ValueError(f&quot;Unsupported database type in: {connection_string}&quot;)\n    \n    async def _fetch_json_data(self, source: DataSource) -&gt; Dict[str, Any]:\n        &quot;&quot;&quot;Fetch JSON data from file or URL&quot;&quot;&quot;\n        if source.source.startswith(&#x27;http&#x27;):\n            async with aiohttp.ClientSession() as session:\n                async with session.get(source.source) as response:\n                    response.raise_for_status()\n                    return await response.json()\n        else:\n            with open(source.source, &#x27;r&#x27;) as f:\n                return json.load(f)\n    \n    async def _fetch_api_data(self, source: DataSource) -&gt; Dict[str, Any]:\n        &quot;&quot;&quot;Fetch data from REST API&quot;&quot;&quot;\n        headers = source.connection_params.get(&#x27;headers&#x27;, {})\n        params = source.connection_params.get(&#x27;params&#x27;, {})\n        \n        async with aiohttp.ClientSession() as session:\n            async with session.get(\n                source.source, \n                headers=headers, \n                params=params\n            ) as response:\n                response.raise_for_status()\n                return await response.json()\n    \n    async def _fetch_csv_data(self, source: DataSource) -&gt; Dict[str, Any]:\n        &quot;&quot;&quot;Fetch and process CSV data&quot;&quot;&quot;\n        import pandas as pd\n        \n        if source.source.startswith(&#x27;http&#x27;):\n            df = pd.read_csv(source.source)\n        else:\n            df = pd.read_csv(source.source)\n        \n        # Convert to records format\n        records = df.to_dict(&#x27;records&#x27;)\n        \n        return {\n            &#x27;records&#x27;: records,\n            &#x27;columns&#x27;: df.columns.tolist(),\n            &#x27;count&#x27;: len(records),\n            &#x27;summary&#x27;: {\n                &#x27;total_rows&#x27;: len(records),\n                &#x27;columns&#x27;: len(df.columns),\n                &#x27;numeric_columns&#x27;: len(df.select_dtypes(include=[&#x27;number&#x27;]).columns),\n                &#x27;text_columns&#x27;: len(df.select_dtypes(include=[&#x27;object&#x27;]).columns)\n            }\n        }\n    \n    async def _apply_transformation(self, data: Dict[str, Any], transform_function: str) -&gt; Dict[str, Any]:\n        &quot;&quot;&quot;Apply custom transformation function to data&quot;&quot;&quot;\n        # This would load and execute custom transformation functions\n        # For security, this should be sandboxed in production\n        \n        # Example: Simple transformation functions\n        if transform_function == &#x27;sort_by_name&#x27;:\n            if &#x27;endpoints&#x27; in data:\n                data[&#x27;endpoints&#x27;] = sorted(data[&#x27;endpoints&#x27;], key=lambda x: x.get(&#x27;summary&#x27;, &#x27;&#x27;))\n        elif transform_function == &#x27;group_by_tag&#x27;:\n            if &#x27;endpoints&#x27; in data:\n                grouped = {}\n                for endpoint in data[&#x27;endpoints&#x27;]:\n                    for tag in endpoint.get(&#x27;tags&#x27;, [&#x27;default&#x27;]):\n                        if tag not in grouped:\n                            grouped[tag] = []\n                        grouped[tag].append(endpoint)\n                data[&#x27;grouped_endpoints&#x27;] = grouped\n        \n        return data\n    \n    async def generate_content(self, template_name: str, force: bool = False) -&gt; List[GenerationResult]:\n        &quot;&quot;&quot;Generate content for specified template&quot;&quot;&quot;\n        if template_name not in self.templates:\n            raise ValueError(f&quot;Template {template_name} not found&quot;)\n        \n        template = self.templates[template_name]\n        results = []\n        \n        try:\n            # Load template\n            jinja_template = self.jinja_env.get_template(template.source)\n            \n            # Fetch data\n            data = {}\n            if template.data_source:\n                source = self.data_sources[template.data_source]\n                data = await self.fetch_data_source(source)\n            \n            # Apply context processors\n            context = await self._build_context(data, template)\n            \n            # Check conditions\n            if not self._check_conditions(context, template):\n                logger.info(f&quot;Conditions not met for template {template_name}&quot;)\n                return results\n            \n            # Generate content\n            if template.output_pattern:\n                # Generate multiple files based on pattern\n                results.extend(await self._generate_multiple_files(jinja_template, context, template))\n            else:\n                # Generate single file\n                result = await self._generate_single_file(jinja_template, context, template)\n                results.append(result)\n            \n        except Exception as e:\n            logger.error(f&quot;Error generating content for {template_name}: {e}&quot;)\n            results.append(GenerationResult(\n                template_name=template_name,\n                output_path=&quot;&quot;,\n                success=False,\n                error_message=str(e)\n            ))\n        \n        return results\n    \n    async def _build_context(self, data: Dict[str, Any], template: Template) -&gt; Dict[str, Any]:\n        &quot;&quot;&quot;Build template context with all required data&quot;&quot;&quot;\n        context = {\n            &#x27;data&#x27;: data,\n            &#x27;config&#x27;: self.config,\n            &#x27;generation_time&#x27;: datetime.now(),\n            &#x27;template_name&#x27;: template.name\n        }\n        \n        # Apply context processors\n        for processor_name in template.context_processors:\n            context = await self._apply_context_processor(context, processor_name)\n        \n        return context\n    \n    async def _apply_context_processor(self, context: Dict[str, Any], processor_name: str) -&gt; Dict[str, Any]:\n        &quot;&quot;&quot;Apply context processor to enhance template data&quot;&quot;&quot;\n        # Example context processors\n        if processor_name == &#x27;add_navigation&#x27;:\n            context[&#x27;navigation&#x27;] = self._generate_navigation_data(context)\n        elif processor_name == &#x27;add_metadata&#x27;:\n            context[&#x27;metadata&#x27;] = self._generate_metadata(context)\n        elif processor_name == &#x27;add_related_content&#x27;:\n            context[&#x27;related&#x27;] = await self._find_related_content(context)\n        \n        return context\n    \n    def _generate_navigation_data(self, context: Dict[str, Any]) -&gt; Dict[str, Any]:\n        &quot;&quot;&quot;Generate navigation data for templates&quot;&quot;&quot;\n        return {\n            &#x27;sections&#x27;: [\n                {&#x27;name&#x27;: &#x27;API Reference&#x27;, &#x27;url&#x27;: &#x27;/api/&#x27;},\n                {&#x27;name&#x27;: &#x27;Guides&#x27;, &#x27;url&#x27;: &#x27;/guides/&#x27;},\n                {&#x27;name&#x27;: &#x27;Examples&#x27;, &#x27;url&#x27;: &#x27;/examples/&#x27;}\n            ],\n            &#x27;breadcrumbs&#x27;: self._generate_breadcrumbs(context)\n        }\n    \n    def _generate_breadcrumbs(self, context: Dict[str, Any]) -&gt; List[Dict[str, str]]:\n        &quot;&quot;&quot;Generate breadcrumb navigation&quot;&quot;&quot;\n        # Implementation would depend on the specific content structure\n        return [\n            {&#x27;name&#x27;: &#x27;Home&#x27;, &#x27;url&#x27;: &#x27;/&#x27;},\n            {&#x27;name&#x27;: &#x27;Documentation&#x27;, &#x27;url&#x27;: &#x27;/docs/&#x27;}\n        ]\n    \n    def _generate_metadata(self, context: Dict[str, Any]) -&gt; Dict[str, Any]:\n        &quot;&quot;&quot;Generate metadata for content&quot;&quot;&quot;\n        return {\n            &#x27;generated_at&#x27;: datetime.now().isoformat(),\n            &#x27;generator_version&#x27;: &#x27;2.1.0&#x27;,\n            &#x27;data_sources&#x27;: list(self.data_sources.keys()),\n            &#x27;last_updated&#x27;: context.get(&#x27;generation_time&#x27;, datetime.now()).isoformat()\n        }\n    \n    async def _find_related_content(self, context: Dict[str, Any]) -&gt; List[Dict[str, Any]]:\n        &quot;&quot;&quot;Find related content based on context&quot;&quot;&quot;\n        # This would implement content similarity algorithms\n        return []\n    \n    def _check_conditions(self, context: Dict[str, Any], template: Template) -&gt; bool:\n        &quot;&quot;&quot;Check if template conditions are met&quot;&quot;&quot;\n        if not template.conditions:\n            return True\n        \n        for condition_key, condition_value in template.conditions.items():\n            if condition_key == &#x27;min_data_count&#x27;:\n                data_count = len(context.get(&#x27;data&#x27;, {}).get(&#x27;rows&#x27;, []))\n                if data_count &lt; condition_value:\n                    return False\n            elif condition_key == &#x27;required_fields&#x27;:\n                data = context.get(&#x27;data&#x27;, {})\n                for field in condition_value:\n                    if field not in data:\n                        return False\n        \n        return True\n    \n    async def _generate_single_file(self, jinja_template, context: Dict[str, Any], template: Template) -&gt; GenerationResult:\n        &quot;&quot;&quot;Generate single output file&quot;&quot;&quot;\n        try:\n            content = jinja_template.render(**context)\n            \n            # Create output directory if needed\n            output_path = Path(template.output)\n            output_path.parent.mkdir(parents=True, exist_ok=True)\n            \n            # Write file\n            with open(output_path, &#x27;w&#x27;, encoding=&#x27;utf-8&#x27;) as f:\n                f.write(content)\n            \n            # Calculate content hash for change detection\n            content_hash = hashlib.sha256(content.encode()).hexdigest()\n            \n            logger.info(f&quot;Generated {output_path}&quot;)\n            \n            return GenerationResult(\n                template_name=template.name,\n                output_path=str(output_path),\n                success=True,\n                data_hash=content_hash\n            )\n            \n        except Exception as e:\n            return GenerationResult(\n                template_name=template.name,\n                output_path=template.output or &quot;&quot;,\n                success=False,\n                error_message=str(e)\n            )\n    \n    async def _generate_multiple_files(self, jinja_template, context: Dict[str, Any], template: Template) -&gt; List[GenerationResult]:\n        &quot;&quot;&quot;Generate multiple files based on output pattern&quot;&quot;&quot;\n        results = []\n        \n        try:\n            # Extract iterable data\n            data = context.get(&#x27;data&#x27;, {})\n            \n            if &#x27;endpoints&#x27; in data:\n                items = data[&#x27;endpoints&#x27;]\n                item_key = &#x27;endpoint&#x27;\n            elif &#x27;records&#x27; in data:\n                items = data[&#x27;records&#x27;]\n                item_key = &#x27;record&#x27;\n            elif &#x27;rows&#x27; in data:\n                items = data[&#x27;rows&#x27;]\n                item_key = &#x27;row&#x27;\n            else:\n                items = [data]  # Single item\n                item_key = &#x27;item&#x27;\n            \n            # Generate file for each item\n            for item in items:\n                item_context = context.copy()\n                item_context[item_key] = item\n                \n                # Render output path pattern\n                output_pattern_template = self.jinja_env.from_string(template.output_pattern)\n                output_path = output_pattern_template.render(**item_context)\n                \n                # Generate content\n                content = jinja_template.render(**item_context)\n                \n                # Create output directory\n                output_path_obj = Path(output_path)\n                output_path_obj.parent.mkdir(parents=True, exist_ok=True)\n                \n                # Write file\n                with open(output_path_obj, &#x27;w&#x27;, encoding=&#x27;utf-8&#x27;) as f:\n                    f.write(content)\n                \n                content_hash = hashlib.sha256(content.encode()).hexdigest()\n                \n                results.append(GenerationResult(\n                    template_name=template.name,\n                    output_path=str(output_path_obj),\n                    success=True,\n                    data_hash=content_hash\n                ))\n                \n                logger.info(f&quot;Generated {output_path_obj}&quot;)\n            \n        except Exception as e:\n            logger.error(f&quot;Error in multiple file generation: {e}&quot;)\n            results.append(GenerationResult(\n                template_name=template.name,\n                output_path=&quot;&quot;,\n                success=False,\n                error_message=str(e)\n            ))\n        \n        return results\n    \n    def _setup_automation(self):\n        &quot;&quot;&quot;Setup automation triggers&quot;&quot;&quot;\n        automation_config = self.config.get(&#x27;automation&#x27;, {})\n        triggers = automation_config.get(&#x27;triggers&#x27;, [])\n        \n        for trigger in triggers:\n            if trigger[&#x27;type&#x27;] == &#x27;schedule&#x27;:\n                self._setup_scheduled_trigger(trigger)\n            elif trigger[&#x27;type&#x27;] == &#x27;file_watch&#x27;:\n                self._setup_file_watch_trigger(trigger)\n            elif trigger[&#x27;type&#x27;] == &#x27;webhook&#x27;:\n                self._setup_webhook_trigger(trigger)\n    \n    def _setup_scheduled_trigger(self, trigger_config: Dict[str, Any]):\n        &quot;&quot;&quot;Setup scheduled content generation&quot;&quot;&quot;\n        cron_expression = trigger_config[&#x27;cron&#x27;]\n        templates = trigger_config[&#x27;templates&#x27;]\n        \n        def job():\n            asyncio.run(self._run_scheduled_job(templates))\n        \n        # Simple cron parsing (in production, use croniter or similar)\n        if cron_expression == &quot;0 */6 * * *&quot;:  # Every 6 hours\n            schedule.every(6).hours.do(job)\n        elif cron_expression == &quot;0 0 * * *&quot;:  # Daily at midnight\n            schedule.every().day.at(&quot;00:00&quot;).do(job)\n        \n        # Start scheduler in separate thread\n        def run_scheduler():\n            while True:\n                schedule.run_pending()\n                time.sleep(60)\n        \n        scheduler_thread = threading.Thread(target=run_scheduler, daemon=True)\n        scheduler_thread.start()\n    \n    async def _run_scheduled_job(self, templates: List[str]):\n        &quot;&quot;&quot;Run scheduled content generation job&quot;&quot;&quot;\n        logger.info(f&quot;Running scheduled job for templates: {templates}&quot;)\n        \n        for template_name in templates:\n            try:\n                results = await self.generate_content(template_name)\n                for result in results:\n                    if result.success:\n                        logger.info(f&quot;Successfully generated {result.output_path}&quot;)\n                    else:\n                        logger.error(f&quot;Failed to generate content: {result.error_message}&quot;)\n            except Exception as e:\n                logger.error(f&quot;Error in scheduled job for {template_name}: {e}&quot;)\n    \n    def _setup_file_watch_trigger(self, trigger_config: Dict[str, Any]):\n        &quot;&quot;&quot;Setup file system watcher for automatic regeneration&quot;&quot;&quot;\n        paths = trigger_config[&#x27;paths&#x27;]\n        templates = trigger_config[&#x27;templates&#x27;]\n        \n        class FileChangeHandler(FileSystemEventHandler):\n            def __init__(self, generator):\n                self.generator = generator\n                self.templates = templates\n            \n            def on_modified(self, event):\n                if not event.is_directory:\n                    logger.info(f&quot;File changed: {event.src_path}&quot;)\n                    asyncio.run(self.generator._run_scheduled_job(self.templates))\n        \n        event_handler = FileChangeHandler(self)\n        observer = Observer()\n        \n        for path in paths:\n            observer.schedule(event_handler, path, recursive=True)\n        \n        observer.start()\n        logger.info(f&quot;Started file watcher for paths: {paths}&quot;)\n    \n    def _setup_webhook_trigger(self, trigger_config: Dict[str, Any]):\n        &quot;&quot;&quot;Setup webhook endpoint for content regeneration&quot;&quot;&quot;\n        # This would typically integrate with a web framework like Flask/FastAPI\n        # For simplicity, this is just a placeholder\n        logger.info(f&quot;Webhook trigger configured for endpoint: {trigger_config[&#x27;endpoint&#x27;]}&quot;)\n    \n    async def generate_all_content(self, force: bool = False) -&gt; Dict[str, List[GenerationResult]]:\n        &quot;&quot;&quot;Generate content for all configured templates&quot;&quot;&quot;\n        all_results = {}\n        \n        for template_name in self.templates:\n            try:\n                results = await self.generate_content(template_name, force=force)\n                all_results[template_name] = results\n            except Exception as e:\n                logger.error(f&quot;Error generating {template_name}: {e}&quot;)\n                all_results[template_name] = [GenerationResult(\n                    template_name=template_name,\n                    output_path=&quot;&quot;,\n                    success=False,\n                    error_message=str(e)\n                )]\n        \n        return all_results\n    \n    def get_generation_stats(self) -&gt; Dict[str, Any]:\n        &quot;&quot;&quot;Get statistics about content generation&quot;&quot;&quot;\n        total_templates = len(self.templates)\n        active_data_sources = len([\n            source for source in self.data_sources.values()\n            if source.name in self.cache_timestamps\n        ])\n        \n        cache_info = {}\n        for source_name, timestamp in self.cache_timestamps.items():\n            age_seconds = time.time() - timestamp\n            cache_info[source_name] = {\n                &#x27;age_seconds&#x27;: age_seconds,\n                &#x27;age_minutes&#x27;: age_seconds / 60,\n                &#x27;is_fresh&#x27;: age_seconds &lt; self.data_sources[source_name].cache_duration\n            }\n        \n        return {\n            &#x27;total_templates&#x27;: total_templates,\n            &#x27;active_data_sources&#x27;: active_data_sources,\n            &#x27;cache_info&#x27;: cache_info,\n            &#x27;last_generation&#x27;: datetime.now().isoformat()\n        }\n\n# CLI Interface\nasync def main():\n    import argparse\n    \n    parser = argparse.ArgumentParser(description=&#x27;Dynamic Content Generator&#x27;)\n    parser.add_argument(&#x27;--config&#x27;, required=True, help=&#x27;Configuration file path&#x27;)\n    parser.add_argument(&#x27;--template&#x27;, help=&#x27;Generate specific template&#x27;)\n    parser.add_argument(&#x27;--force&#x27;, action=&#x27;store_true&#x27;, help=&#x27;Force regeneration ignoring cache&#x27;)\n    parser.add_argument(&#x27;--stats&#x27;, action=&#x27;store_true&#x27;, help=&#x27;Show generation statistics&#x27;)\n    \n    args = parser.parse_args()\n    \n    generator = ContentGenerationEngine(args.config)\n    \n    if args.stats:\n        stats = generator.get_generation_stats()\n        print(json.dumps(stats, indent=2))\n        return\n    \n    if args.template:\n        results = await generator.generate_content(args.template, force=args.force)\n    else:\n        all_results = await generator.generate_all_content(force=args.force)\n        results = []\n        for template_results in all_results.values():\n            results.extend(template_results)\n    \n    # Print summary\n    successful = len([r for r in results if r.success])\n    failed = len([r for r in results if not r.success])\n    \n    print(f&quot;Generation complete: {successful} successful, {failed} failed&quot;)\n    \n    for result in results:\n        if result.success:\n            print(f&quot;✅ {result.output_path}&quot;)\n        else:\n            print(f&quot;❌ {result.template_name}: {result.error_message}&quot;)\n\nif __name__ == &quot;__main__&quot;:\n    asyncio.run(main())\n```\u003C/span>\n\u003C/code>\u003C/pre>\u003Ch2 id=\"integration-with-cicd-systems\">Integration with CI/CD Systems\u003C/h2>\n\u003Ch3 id=\"github-actions-workflow-integration\">GitHub Actions Workflow Integration\u003C/h3>\n\u003Cp>Implementing automated content generation in continuous integration pipelines:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-markdown\">\u003Cspan class=\"hljs-section\"># CI/CD Integration for Dynamic Content\u003C/span>\n\n\u003Cspan class=\"hljs-section\">## GitHub Actions Workflow\u003C/span>\n\n\u003Cspan class=\"hljs-code\">```yaml\n# .github/workflows/content-generation.yml\nname: Dynamic Content Generation\n\non:\n  push:\n    branches: [ main, develop ]\n    paths:\n      - &#x27;data/**&#x27;\n      - &#x27;templates/**&#x27;\n      - &#x27;content-config.yml&#x27;\n  schedule:\n    - cron: &#x27;0 6 * * *&#x27;  # Daily at 6 AM\n  workflow_dispatch:\n    inputs:\n      force_regeneration:\n        description: &#x27;Force full regeneration&#x27;\n        required: false\n        default: &#x27;false&#x27;\n      specific_template:\n        description: &#x27;Generate specific template only&#x27;\n        required: false\n\njobs:\n  generate-content:\n    runs-on: ubuntu-latest\n    \n    steps:\n    - uses: actions/checkout@v4\n      with:\n        token: ${{ secrets.GITHUB_TOKEN }}\n        fetch-depth: 0\n    \n    - name: Set up Python\n      uses: actions/setup-python@v4\n      with:\n        python-version: &#x27;3.11&#x27;\n    \n    - name: Install dependencies\n      run: |\n        pip install -r requirements.txt\n        pip install jinja2 aiohttp psycopg2-binary pandas pyyaml watchdog schedule\n    \n    - name: Configure data source credentials\n      run: |\n        echo &quot;DATABASE_URL=${{ secrets.DATABASE_URL }}&quot; &gt;&gt; $GITHUB_ENV\n        echo &quot;API_KEY=${{ secrets.API_KEY }}&quot; &gt;&gt; $GITHUB_ENV\n    \n    - name: Generate content\n      run: |\n        if [ &quot;${{ github.event.inputs.specific_template }}&quot; != &quot;&quot; ]; then\n          python content-generator.py \\\n            --config content-config.yml \\\n            --template &quot;${{ github.event.inputs.specific_template }}&quot; \\\n            ${{ github.event.inputs.force_regeneration == &#x27;true&#x27; &amp;&amp; &#x27;--force&#x27; || &#x27;&#x27; }}\n        else\n          python content-generator.py \\\n            --config content-config.yml \\\n            ${{ github.event.inputs.force_regeneration == &#x27;true&#x27; &amp;&amp; &#x27;--force&#x27; || &#x27;&#x27; }}\n        fi\n    \n    - name: Validate generated content\n      run: |\n        python scripts/validate-generated-content.py \\\n          --content-dir docs \\\n          --check-links \\\n          --check-frontmatter \\\n          --output validation-report.json\n    \n    - name: Build site for testing\n      run: |\n        bundle install\n        bundle exec jekyll build\n    \n    - name: Test generated content\n      run: |\n        python scripts/test-content-quality.py \\\n          --site-dir _site \\\n          --check-performance \\\n          --check-accessibility \\\n          --output test-results.json\n    \n    - name: Commit generated content\n      if: success()\n      run: |\n        git config --global user.name &#x27;Content Generator Bot&#x27;\n        git config --global user.email &#x27;bot@example.com&#x27;\n        \n        git add docs/\n        \n        if ! git diff --staged --quiet; then\n          git commit -m &quot;🤖 Automated content generation\n          \n          Generated content for:\n          - API documentation\n          - Metrics reports\n          - Feature guides\n          \n          Triggered by: ${{ github.event_name }}\n          ${{ github.event.inputs.specific_template &amp;&amp; format(&#x27;Template: {0}&#x27;, github.event.inputs.specific_template) || &#x27;&#x27; }}\n          \n          🤖 Generated with Content Pipeline\n          &quot;\n          \n          git push\n        else\n          echo &quot;No changes to commit&quot;\n        fi\n    \n    - name: Upload generation artifacts\n      if: always()\n      uses: actions/upload-artifact@v3\n      with:\n        name: content-generation-report\n        path: |\n          validation-report.json\n          test-results.json\n          generation-stats.json\n\n  deploy-content:\n    runs-on: ubuntu-latest\n    needs: generate-content\n    if: github.ref == &#x27;refs/heads/main&#x27;\n    \n    steps:\n    - uses: actions/checkout@v4\n      with:\n        ref: main  # Get the latest content\n    \n    - name: Deploy to production\n      run: |\n        # Deploy generated content to production environment\n        echo &quot;Deploying generated content to production&quot;\n        \n        # Example: Deploy to GitHub Pages\n        npm install -g @11ty/eleventy\n        eleventy\n    \n    - name: Notify stakeholders\n      if: success()\n      uses: 8398a7/action-slack@v3\n      with:\n        status: success\n        text: &quot;📚 Documentation updated successfully with latest content generation&quot;\n      env:\n        SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}\n    \n    - name: Update content metrics\n      run: |\n        python scripts/update-content-metrics.py \\\n          --generated-files docs/ \\\n          --analytics-endpoint &quot;${{ secrets.ANALYTICS_ENDPOINT }}&quot; \\\n          --api-key &quot;${{ secrets.ANALYTICS_API_KEY }}&quot;\n\n  content-quality-check:\n    runs-on: ubuntu-latest\n    needs: generate-content\n    \n    steps:\n    - uses: actions/checkout@v4\n    \n    - name: Quality assurance checks\n      run: |\n        # Check for content quality issues\n        python scripts/content-qa.py \\\n          --content-dir docs \\\n          --check-duplicates \\\n          --check-broken-references \\\n          --check-consistency \\\n          --output qa-report.html\n    \n    - name: Performance benchmark\n      run: |\n        # Benchmark content generation performance\n        python scripts/benchmark-generation.py \\\n          --config content-config.yml \\\n          --iterations 5 \\\n          --output benchmark-results.json\n    \n    - name: Update documentation metrics\n      run: |\n        # Update internal metrics about documentation\n        python scripts/update-docs-metrics.py \\\n          --benchmark-data benchmark-results.json \\\n          --qa-data qa-report.html \\\n          --target-endpoint &quot;${{ secrets.METRICS_ENDPOINT }}&quot;\n```\u003C/span>\n\n\n\u003Cspan class=\"hljs-section\">## Advanced Content Validation System\u003C/span>\n\u003Cspan class=\"hljs-code\">```python\n#!/usr/bin/env python3\n# validate-generated-content.py - Content validation for generated files\n\nimport os\nimport json\nimport yaml\nimport requests\nfrom pathlib import Path\nfrom typing import Dict, List, Any, Optional\nfrom dataclasses import dataclass\nimport frontmatter\nfrom urllib.parse import urljoin, urlparse\nimport re\nfrom datetime import datetime\nimport concurrent.futures\nimport threading\nimport time\n\n@dataclass\nclass ValidationResult:\n    &quot;&quot;&quot;Result of content validation&quot;&quot;&quot;\n    file_path: str\n    validation_type: str\n    status: str  # &#x27;passed&#x27;, &#x27;failed&#x27;, &#x27;warning&#x27;\n    message: str\n    details: Optional[Dict[str, Any]] = None\n\nclass ContentValidator:\n    &quot;&quot;&quot;Comprehensive validation for generated content&quot;&quot;&quot;\n    \n    def __init__(self, content_dir: str, base_url: str = &quot;&quot;):\n        self.content_dir = Path(content_dir)\n        self.base_url = base_url\n        self.results = []\n        self.link_cache = {}\n        self.validation_stats = {\n            &#x27;total_files&#x27;: 0,\n            &#x27;passed&#x27;: 0,\n            &#x27;failed&#x27;: 0,\n            &#x27;warnings&#x27;: 0\n        }\n    \n    def validate_all_content(self, \n                           check_links: bool = True,\n                           check_frontmatter: bool = True,\n                           check_content_quality: bool = True,\n                           check_consistency: bool = True) -&gt; List[ValidationResult]:\n        &quot;&quot;&quot;Run all validation checks on generated content&quot;&quot;&quot;\n        \n        markdown_files = list(self.content_dir.glob(&#x27;**/*.md&#x27;))\n        self.validation_stats[&#x27;total_files&#x27;] = len(markdown_files)\n        \n        print(f&quot;Validating {len(markdown_files)} files...&quot;)\n        \n        # Validate each file\n        for file_path in markdown_files:\n            try:\n                with open(file_path, &#x27;r&#x27;, encoding=&#x27;utf-8&#x27;) as f:\n                    content = f.read()\n                \n                # Parse frontmatter and content\n                post = frontmatter.loads(content)\n                \n                if check_frontmatter:\n                    self._validate_frontmatter(file_path, post)\n                \n                if check_content_quality:\n                    self._validate_content_quality(file_path, post)\n                \n                if check_consistency:\n                    self._validate_consistency(file_path, post)\n                \n                if check_links:\n                    self._validate_links(file_path, post)\n                    \n            except Exception as e:\n                self.results.append(ValidationResult(\n                    file_path=str(file_path),\n                    validation_type=&quot;file_processing&quot;,\n                    status=&quot;failed&quot;,\n                    message=f&quot;Error processing file: {str(e)}&quot;\n                ))\n        \n        # Additional cross-file validations\n        if check_consistency:\n            self._validate_cross_file_consistency(markdown_files)\n        \n        # Update statistics\n        self._calculate_stats()\n        \n        return self.results\n    \n    def _validate_frontmatter(self, file_path: Path, post) -&gt; None:\n        &quot;&quot;&quot;Validate frontmatter completeness and format&quot;&quot;&quot;\n        metadata = post.metadata\n        \n        # Required fields\n        required_fields = [&#x27;title&#x27;, &#x27;description&#x27;, &#x27;category&#x27;, &#x27;date&#x27;]\n        missing_fields = [field for field in required_fields if field not in metadata]\n        \n        if missing_fields:\n            self.results.append(ValidationResult(\n                file_path=str(file_path),\n                validation_type=&quot;frontmatter&quot;,\n                status=&quot;failed&quot;,\n                message=f&quot;Missing required frontmatter fields: {&#x27;, &#x27;.join(missing_fields)}&quot;\n            ))\n        \n        # Validate field formats\n        if &#x27;date&#x27; in metadata:\n            try:\n                if isinstance(metadata[&#x27;date&#x27;], str):\n                    datetime.strptime(metadata[&#x27;date&#x27;], &#x27;%Y-%m-%d&#x27;)\n            except ValueError:\n                self.results.append(ValidationResult(\n                    file_path=str(file_path),\n                    validation_type=&quot;frontmatter&quot;,\n                    status=&quot;failed&quot;,\n                    message=&quot;Invalid date format in frontmatter (expected YYYY-MM-DD)&quot;\n                ))\n        \n        # Title length check\n        if &#x27;title&#x27; in metadata and len(metadata[&#x27;title&#x27;]) &gt; 200:\n            self.results.append(ValidationResult(\n                file_path=str(file_path),\n                validation_type=&quot;frontmatter&quot;,\n                status=&quot;warning&quot;,\n                message=&quot;Title is very long (over 200 characters)&quot;\n            ))\n        \n        # Description length check\n        if &#x27;description&#x27; in metadata:\n            desc_length = len(metadata[&#x27;description&#x27;])\n            if desc_length &lt; 50:\n                self.results.append(ValidationResult(\n                    file_path=str(file_path),\n                    validation_type=&quot;frontmatter&quot;,\n                    status=&quot;warning&quot;,\n                    message=&quot;Description is too short (under 50 characters)&quot;\n                ))\n            elif desc_length &gt; 300:\n                self.results.append(ValidationResult(\n                    file_path=str(file_path),\n                    validation_type=&quot;frontmatter&quot;,\n                    status=&quot;warning&quot;,\n                    message=&quot;Description is too long (over 300 characters)&quot;\n                ))\n    \n    def _validate_content_quality(self, file_path: Path, post) -&gt; None:\n        &quot;&quot;&quot;Validate content quality metrics&quot;&quot;&quot;\n        content = post.content\n        \n        # Word count check\n        word_count = len(content.split())\n        if word_count &lt; 100:\n            self.results.append(ValidationResult(\n                file_path=str(file_path),\n                validation_type=&quot;content_quality&quot;,\n                status=&quot;warning&quot;,\n                message=f&quot;Content is very short ({word_count} words)&quot;\n            ))\n        \n        # Check for placeholder content\n        placeholder_patterns = [\n            r&#x27;\\[placeholder\\]&#x27;,\n            r&#x27;\\[todo\\]&#x27;,\n            r&#x27;\\[tbd\\]&#x27;,\n            r&#x27;lorem ipsum&#x27;,\n            r&#x27;placeholder text&#x27;\n        ]\n        \n        for pattern in placeholder_patterns:\n            if re.search(pattern, content, re.IGNORECASE):\n                self.results.append(ValidationResult(\n                    file_path=str(file_path),\n                    validation_type=&quot;content_quality&quot;,\n                    status=&quot;failed&quot;,\n                    message=f&quot;Placeholder content detected: {pattern}&quot;\n                ))\n        \n        # Check for proper heading structure\n        headings = re.findall(r&#x27;^(#+)\\s+(.+)$&#x27;, content, re.MULTILINE)\n        if headings:\n            # Check if starts with h1\n            first_heading_level = len(headings[0][0])\n            if first_heading_level != 1:\n                self.results.append(ValidationResult(\n                    file_path=str(file_path),\n                    validation_type=&quot;content_quality&quot;,\n                    status=&quot;warning&quot;,\n                    message=&quot;Document should start with h1 heading&quot;\n                ))\n            \n            # Check heading hierarchy\n            prev_level = 0\n            for i, (hashes, text) in enumerate(headings):\n                level = len(hashes)\n                if level &gt; prev_level + 1 and prev_level &gt; 0:\n                    self.results.append(ValidationResult(\n                        file_path=str(file_path),\n                        validation_type=&quot;content_quality&quot;,\n                        status=&quot;warning&quot;,\n                        message=f&quot;Heading hierarchy skip detected at line with &#x27;{text}&#x27;&quot;\n                    ))\n                prev_level = level\n        \n        # Check for code block formatting\n        code_blocks = re.findall(r&#x27;```\u003C/span>(\\w+)?\\n(.\u003Cspan class=\"hljs-emphasis\">*?)\\n```&#x27;, content, re.DOTALL)\n        for lang, code in code_blocks:\n            if not lang:\n                self.results.append(ValidationResult(\n                    file_path=str(file_path),\n                    validation_type=&quot;content_quality&quot;,\n                    status=&quot;warning&quot;,\n                    message=&quot;Code block without language specification&quot;\n                ))\n            \n            # Check for unterminated code blocks\n            if &#x27;```&#x27; in code:\n                self.results.append(ValidationResult(\n                    file_path=str(file_path),\n                    validation_type=&quot;content_quality&quot;,\n                    status=&quot;failed&quot;,\n                    message=&quot;Potentially unterminated code block detected&quot;\n                ))\n    \n    def _validate_consistency(self, file_path: Path, post) -&gt; None:\n        &quot;&quot;&quot;Validate content consistency&quot;&quot;&quot;\n        metadata = post.metadata\n        content = post.content\n        \n        # Check if title matches content\n        title = metadata.get(&#x27;title&#x27;, &#x27;&#x27;)\n        first_heading = re.search(r&#x27;^#\\s+(.+)$&#x27;, content, re.MULTILINE)\n        \n        if first_heading and title:\n            content_title = first_heading.group(1).strip()\n            if title.lower() != content_title.lower():\n                self.results.append(ValidationResult(\n                    file_path=str(file_path),\n                    validation_type=&quot;consistency&quot;,\n                    status=&quot;warning&quot;,\n                    message=&quot;Frontmatter title doesn&#x27;t match first heading&quot;\n                ))\n        \n        # Check filename consistency\n        expected_filename_parts = []\n        if &#x27;date&#x27; in metadata:\n            date_str = metadata[&#x27;date&#x27;]\n            if isinstance(date_str, str):\n                expected_filename_parts.append(date_str)\n        \n        if title:\n            # Convert title to slug\n            slug = re.sub(r&#x27;[^\\w\\s-]&#x27;, &#x27;&#x27;, title.lower())\n            slug = re.sub(r&#x27;[\\s_-]+&#x27;, &#x27;-&#x27;, slug)\n            expected_filename_parts.append(slug[:50])  # Limit length\n        \n        if expected_filename_parts:\n            expected_filename = &#x27;-&#x27;.join(expected_filename_parts) + &#x27;.md&#x27;\n            actual_filename = file_path.name\n            \n            if actual_filename != expected_filename:\n                self.results.append(ValidationResult(\n                    file_path=str(file_path),\n                    validation_type=&quot;consistency&quot;,\n                    status=&quot;warning&quot;,\n                    message=f&quot;Filename &#x27;{actual_filename}&#x27; doesn&#x27;t follow expected pattern &#x27;{expected_filename}&#x27;&quot;\n                ))\n    \n    def _validate_links(self, file_path: Path, post) -&gt; None:\n        &quot;&quot;&quot;Validate internal and external links&quot;&quot;&quot;\n        content = post.content\n        \n        # Find all markdown links\n        markdown_links = re.findall(r&#x27;\\[([^\\]]+)\\]\\(([^)]+)\\)&#x27;, content)\n        \n        for link_text, link_url in markdown_links:\n            self._check_single_link(file_path, link_text, link_url)\n        \n        # Find all HTML links\n        html_links = re.findall(r&#x27;\u003Cspan class=\"language-xml\">&lt;a[^&gt;\u003C/span>]+href=[\u003Cspan class=\"hljs-string\">&quot;\\&#x27;\u003C/span>](\u003Cspan class=\"hljs-link\">[^&quot;\\&#x27;]+\u003C/span>)[\u003Cspan class=\"hljs-string\">&quot;\\&#x27;\u003C/span>][\u003Cspan class=\"hljs-symbol\">^&gt;\u003C/span>]*\u003C/span>&gt;([^&lt;]\u003Cspan class=\"hljs-emphasis\">*)\u003Cspan class=\"language-xml\">\u003Cspan class=\"hljs-tag\">&lt;/\u003Cspan class=\"hljs-name\">a\u003C/span>&gt;\u003C/span>\u003C/span>&#x27;, content, re.IGNORECASE)\n        \n        for link_url, link_text in html_links:\n            self._check_single_link(file_path, link_text, link_url)\n    \n    def _check_single_link(self, file_path: Path, link_text: str, link_url: str) -&gt; None:\n        &quot;&quot;&quot;Check a single link for validity&quot;&quot;&quot;\n        # Skip anchor links and mailto links\n        if link_url.startswith(&#x27;#&#x27;) or link_url.startswith(&#x27;mailto:&#x27;):\n            return\n        \n        # Check internal links\n        if link_url.startswith(&#x27;/&#x27;) or not urlparse(link_url).netloc:\n            # Internal link\n            if link_url.startswith(&#x27;/&#x27;):\n                # Absolute internal link\n                target_path = self.content_dir / link_url.lstrip(&#x27;/&#x27;)\n            else:\n                # Relative link\n                target_path = file_path.parent / link_url\n            \n            # Check if file exists\n            if not target_path.exists():\n                # Try with .md extension\n                if not str(target_path).endswith(&#x27;.md&#x27;):\n                    target_path_md = target_path.with_suffix(&#x27;.md&#x27;)\n                    if not target_path_md.exists():\n                        self.results.append(ValidationResult(\n                            file_path=str(file_path),\n                            validation_type=&quot;links&quot;,\n                            status=&quot;failed&quot;,\n                            message=f&quot;Broken internal link: &#x27;{link_url}&#x27; -&gt; &#x27;{link_text}&#x27;&quot;\n                        ))\n                else:\n                    self.results.append(ValidationResult(\n                        file_path=str(file_path),\n                        validation_type=&quot;links&quot;,\n                        status=&quot;failed&quot;,\n                        message=f&quot;Broken internal link: &#x27;{link_url}&#x27; -&gt; &#x27;{link_text}&#x27;&quot;\n                    ))\n        \n        else:\n            # External link - check if we should validate\n            if self._should_check_external_link(link_url):\n                self._check_external_link(file_path, link_text, link_url)\n    \n    def _should_check_external_link(self, url: str) -&gt; bool:\n        &quot;&quot;&quot;Determine if external link should be checked&quot;&quot;&quot;\n        # Skip certain domains that might block automated requests\n        skip_domains = [\n            &#x27;localhost&#x27;,\n            &#x27;127.0.0.1&#x27;,\n            &#x27;example.com&#x27;,\n            &#x27;test.com&#x27;\n        ]\n        \n        parsed = urlparse(url)\n        return parsed.netloc not in skip_domains\n    \n    def _check_external_link(self, file_path: Path, link_text: str, link_url: str) -&gt; None:\n        &quot;&quot;&quot;Check external link availability&quot;&quot;&quot;\n        if link_url in self.link_cache:\n            # Use cached result\n            status = self.link_cache[link_url]\n        else:\n            try:\n                # Make HEAD request first (faster)\n                response = requests.head(link_url, timeout=10, allow_redirects=True)\n                status = response.status_code\n                \n                # If HEAD fails, try GET\n                if status &gt;= 400:\n                    response = requests.get(link_url, timeout=10, allow_redirects=True)\n                    status = response.status_code\n                \n                self.link_cache[link_url] = status\n                \n            except requests.RequestException as e:\n                status = f&quot;error: {str(e)}&quot;\n                self.link_cache[link_url] = status\n        \n        if isinstance(status, int) and status &gt;= 400:\n            self.results.append(ValidationResult(\n                file_path=str(file_path),\n                validation_type=&quot;links&quot;,\n                status=&quot;failed&quot;,\n                message=f&quot;Broken external link (HTTP {status}): &#x27;{link_url}&#x27; -&gt; &#x27;{link_text}&#x27;&quot;\n            ))\n        elif isinstance(status, str) and status.startswith(&quot;error:&quot;):\n            self.results.append(ValidationResult(\n                file_path=str(file_path),\n                validation_type=&quot;links&quot;,\n                status=&quot;warning&quot;,\n                message=f&quot;External link check failed: &#x27;{link_url}&#x27; -&gt; &#x27;{link_text}&#x27;&quot;\n            ))\n    \n    def _validate_cross_file_consistency(self, files: List[Path]) -&gt; None:\n        &quot;&quot;&quot;Validate consistency across multiple files&quot;&quot;&quot;\n        # Check for duplicate titles\n        titles = {}\n        categories = set()\n        \n        for file_path in files:\n            try:\n                with open(file_path, &#x27;r&#x27;, encoding=&#x27;utf-8&#x27;) as f:\n                    post = frontmatter.load(f)\n                \n                title = post.metadata.get(&#x27;title&#x27;, &#x27;&#x27;)\n                category = post.metadata.get(&#x27;category&#x27;, &#x27;&#x27;)\n                \n                if title:\n                    if title in titles:\n                        self.results.append(ValidationResult(\n                            file_path=str(file_path),\n                            validation_type=&quot;cross_file_consistency&quot;,\n                            status=&quot;warning&quot;,\n                            message=f&quot;Duplicate title found: &#x27;{title}&#x27; (also in {titles[title]})&quot;\n                        ))\n                    else:\n                        titles[title] = str(file_path)\n                \n                if category:\n                    categories.add(category)\n                    \n            except Exception as e:\n                continue\n        \n        # Report category statistics\n        print(f&quot;Found {len(categories)} unique categories: {&#x27;, &#x27;.join(sorted(categories))}&quot;)\n    \n    def _calculate_stats(self) -&gt; None:\n        &quot;&quot;&quot;Calculate validation statistics&quot;&quot;&quot;\n        for result in self.results:\n            if result.status == &quot;passed&quot;:\n                self.validation_stats[&#x27;passed&#x27;] += 1\n            elif result.status == &quot;failed&quot;:\n                self.validation_stats[&#x27;failed&#x27;] += 1\n            elif result.status == &quot;warning&quot;:\n                self.validation_stats[&#x27;warnings&#x27;] += 1\n    \n    def generate_report(self, output_path: Optional[str] = None) -&gt; Dict[str, Any]:\n        &quot;&quot;&quot;Generate comprehensive validation report&quot;&quot;&quot;\n        report = {\n            &#x27;validation_summary&#x27;: self.validation_stats,\n            &#x27;validation_timestamp&#x27;: datetime.now().isoformat(),\n            &#x27;results_by_type&#x27;: {},\n            &#x27;results_by_status&#x27;: {},\n            &#x27;detailed_results&#x27;: []\n        }\n        \n        # Group results by type and status\n        for result in self.results:\n            # By type\n            if result.validation_type not in report[&#x27;results_by_type&#x27;]:\n                report[\u003Cspan class=\"hljs-string\">&#x27;results_by_type&#x27;\u003C/span>][\u003Cspan class=\"hljs-symbol\">result.validation_type\u003C/span>] = []\n            report[\u003Cspan class=\"hljs-string\">&#x27;results_by_type&#x27;\u003C/span>][\u003Cspan class=\"hljs-symbol\">result.validation_type\u003C/span>].append({\n                &#x27;file&#x27;: result.file_path,\n                &#x27;status&#x27;: result.status,\n                &#x27;message&#x27;: result.message\n            })\n            \n            # By status\n            if result.status not in report[&#x27;results_by_status&#x27;]:\n                report[\u003Cspan class=\"hljs-string\">&#x27;results_by_status&#x27;\u003C/span>][\u003Cspan class=\"hljs-symbol\">result.status\u003C/span>] = []\n            report[\u003Cspan class=\"hljs-string\">&#x27;results_by_status&#x27;\u003C/span>][\u003Cspan class=\"hljs-symbol\">result.status\u003C/span>].append({\n                &#x27;file&#x27;: result.file_path,\n                &#x27;type&#x27;: result.validation_type,\n                &#x27;message&#x27;: result.message\n            })\n            \n            # Detailed results\n            report[&#x27;detailed_results&#x27;].append({\n                &#x27;file_path&#x27;: result.file_path,\n                &#x27;validation_type&#x27;: result.validation_type,\n                &#x27;status&#x27;: result.status,\n                &#x27;message&#x27;: result.message,\n                &#x27;details&#x27;: result.details\n            })\n        \n        if output_path:\n            with open(output_path, &#x27;w&#x27;) as f:\n                json.dump(report, f, indent=2)\n        \n        return report\n    \n    def print_summary(self) -&gt; None:\n        &quot;&quot;&quot;Print validation summary to console&quot;&quot;&quot;\n        stats = self.validation_stats\n        total_issues = stats[&#x27;failed&#x27;] + stats[&#x27;warnings&#x27;]\n        \n        print(f&quot;\\n=== Validation Summary ===&quot;)\n        print(f&quot;Total files: {stats[&#x27;total_files&#x27;]}&quot;)\n        print(f&quot;Issues found: {total_issues}&quot;)\n        print(f&quot;  - Failed: {stats[&#x27;failed&#x27;]}&quot;)\n        print(f&quot;  - Warnings: {stats[&#x27;warnings&#x27;]}&quot;)\n        \n        if total_issues == 0:\n            print(&quot;✅ All validations passed!&quot;)\n        else:\n            print(f&quot;⚠️  {total_issues} issues need attention&quot;)\n            \n            # Show top issues by type\n            issue_types = {}\n            for result in self.results:\n                if result.status in [&#x27;failed&#x27;, &#x27;warning&#x27;]:\n                    issue_types[result.validation_type] = issue_types.get(result.validation_type, 0) + 1\n            \n            print(&quot;\\nIssues by type:&quot;)\n            for issue_type, count in sorted(issue_types.items(), key=lambda x: x[1], reverse=True):\n                print(f&quot;  - {issue_type}: {count}&quot;)\n\n# CLI Interface\ndef main():\n    import argparse\n    \n    parser = argparse.ArgumentParser(description=&#x27;Validate generated content&#x27;)\n    parser.add_argument(&#x27;--content-dir&#x27;, required=True, help=&#x27;Directory containing content to validate&#x27;)\n    parser.add_argument(&#x27;--base-url&#x27;, help=&#x27;Base URL for link validation&#x27;)\n    parser.add_argument(&#x27;--check-links&#x27;, action=&#x27;store_true&#x27;, help=&#x27;Validate internal and external links&#x27;)\n    parser.add_argument(&#x27;--check-frontmatter&#x27;, action=&#x27;store_true&#x27;, help=&#x27;Validate frontmatter&#x27;)\n    parser.add_argument(&#x27;--check-content-quality&#x27;, action=&#x27;store_true&#x27;, help=&#x27;Check content quality&#x27;)\n    parser.add_argument(&#x27;--check-consistency&#x27;, action=&#x27;store_true&#x27;, help=&#x27;Check consistency&#x27;)\n    parser.add_argument(&#x27;--output&#x27;, help=&#x27;Output file for validation report&#x27;)\n    parser.add_argument(&#x27;--fail-on-error&#x27;, action=&#x27;store_true&#x27;, help=&#x27;Exit with error code if validation fails&#x27;)\n    \n    args = parser.parse_args()\n    \n    validator = ContentValidator(args.content_dir, args.base_url or &quot;&quot;)\n    \n    results = validator.validate_all_content(\n        check_links=args.check_links,\n        check_frontmatter=args.check_frontmatter,\n        check_content_quality=args.check_content_quality,\n        check_consistency=args.check_consistency\n    )\n    \n    # Generate and save report\n    report = validator.generate_report(args.output)\n    \n    # Print summary\n    validator.print_summary()\n    \n    # Exit with error code if requested and validation failed\n    if args.fail_on_error and validator.validation_stats[&#x27;failed&#x27;] &gt; 0:\n        exit(1)\n\nif \u003Cspan class=\"hljs-strong\">__name__\u003C/span> == &quot;\u003Cspan class=\"hljs-strong\">__main__\u003C/span>&quot;:\n    main()\n```\u003C/span>\n\u003C/code>\u003C/pre>\u003Ch2 id=\"integration-with-documentation-systems\">Integration with Documentation Systems\u003C/h2>\n\u003Cp>Dynamic content generation integrates seamlessly with comprehensive documentation workflows. When combined with \u003Ca href=\"/blog/markdown-accessibility-complete-guide\">accessibility and WCAG compliance systems\u003C/a>, automated content generation ensures generated documentation maintains accessibility standards while producing consistent, high-quality content that serves users with diverse abilities and technology requirements.\u003C/p>\n\u003Cp>For comprehensive content management, automation systems work effectively with \u003Ca href=\"/blog/markdown-table-data-validation-and-quality-assurance-complete-guide\">table data validation and quality assurance frameworks\u003C/a> to ensure that dynamically generated tabular content maintains data integrity and formatting standards while preventing common table errors through automated validation and correction processes.\u003C/p>\n\u003Cp>When building sophisticated documentation platforms, content generation complements \u003Ca href=\"/blog/markdown-code-syntax-highlighting-advanced-techniques\">advanced code syntax highlighting systems\u003C/a> by enabling automated generation of code documentation with proper syntax highlighting, language detection, and interactive examples that enhance developer experience while maintaining consistency across large codebases.\u003C/p>\n\u003Ch2 id=\"advanced-automation-patterns\">Advanced Automation Patterns\u003C/h2>\n\u003Ch3 id=\"multi-source-content-aggregation\">Multi-Source Content Aggregation\u003C/h3>\n\u003Cp>Implementing sophisticated content aggregation from multiple data sources:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-markdown\">\u003Cspan class=\"hljs-section\"># Advanced Content Aggregation Patterns\u003C/span>\n\n\u003Cspan class=\"hljs-section\">## Multi-API Content Fusion\u003C/span>\n\u003Cspan class=\"hljs-code\">```python\n#!/usr/bin/env python3\n# multi-source-aggregator.py - Advanced content aggregation system\n\nimport asyncio\nimport aiohttp\nfrom typing import Dict, List, Any, Optional\nfrom dataclasses import dataclass, field\nimport json\nimport yaml\nfrom datetime import datetime, timedelta\nimport logging\nfrom jinja2 import Environment, DictLoader\nimport hashlib\n\n@dataclass\nclass DataSourceConfig:\n    &quot;&quot;&quot;Configuration for individual data source&quot;&quot;&quot;\n    name: str\n    type: str\n    endpoint: str\n    auth_method: str = &quot;none&quot;\n    auth_config: Dict[str, Any] = field(default_factory=dict)\n    transform_pipeline: List[str] = field(default_factory=list)\n    cache_ttl: int = 3600\n    retry_config: Dict[str, Any] = field(default_factory=lambda: {&quot;max_retries&quot;: 3, &quot;delay&quot;: 1})\n\n@dataclass\nclass ContentTemplate:\n    &quot;&quot;&quot;Template for generating aggregated content&quot;&quot;&quot;\n    name: str\n    template_string: str\n    output_path: str\n    data_sources: List[str]\n    aggregation_rules: Dict[str, Any] = field(default_factory=dict)\n    update_frequency: str = &quot;hourly&quot;\n\nclass MultiSourceContentAggregator:\n    &quot;&quot;&quot;Advanced content aggregator supporting multiple data sources&quot;&quot;&quot;\n    \n    def __init__(self, config_path: str):\n        with open(config_path, &#x27;r&#x27;) as f:\n            self.config = yaml.safe_load(f)\n        \n        self.data_sources = {\n            ds[&#x27;name&#x27;]: DataSourceConfig(**ds)\n            for ds in self.config[&#x27;data_sources&#x27;]\n        }\n        \n        self.templates = {\n            tmpl[&#x27;name&#x27;]: ContentTemplate(**tmpl)\n            for tmpl in self.config[&#x27;templates&#x27;]\n        }\n        \n        self.data_cache = {}\n        self.cache_timestamps = {}\n        self.session = None\n        \n        # Initialize Jinja2 environment\n        self.jinja_env = Environment(loader=DictLoader({}))\n        self._setup_custom_filters()\n        \n        logging.basicConfig(level=logging.INFO)\n        self.logger = logging.getLogger(__name__)\n    \n    async def __aenter__(self):\n        &quot;&quot;&quot;Async context manager entry&quot;&quot;&quot;\n        self.session = aiohttp.ClientSession()\n        return self\n    \n    async def __aexit__(self, exc_type, exc_val, exc_tb):\n        &quot;&quot;&quot;Async context manager exit&quot;&quot;&quot;\n        if self.session:\n            await self.session.close()\n    \n    def _setup_custom_filters(self):\n        &quot;&quot;&quot;Setup custom Jinja2 filters for content aggregation&quot;&quot;&quot;\n        \n        def merge_lists_filter(list1: List[Any], list2: List[Any], key: str = &#x27;id&#x27;) -&gt; List[Any]:\n            &quot;&quot;&quot;Merge two lists based on a key&quot;&quot;&quot;\n            result = list1.copy()\n            existing_keys = {item.get(key) for item in list1}\n            \n            for item in list2:\n                if item.get(key) not in existing_keys:\n                    result.append(item)\n            \n            return result\n        \n        def group_by_filter(items: List[Dict], key: str) -&gt; Dict[str, List[Dict]]:\n            &quot;&quot;&quot;Group list items by a key&quot;&quot;&quot;\n            grouped = {}\n            for item in items:\n                group_key = item.get(key, &#x27;unknown&#x27;)\n                if group_key not in grouped:\n                    grouped[group_key] = []\n                grouped[group_key].append(item)\n            return grouped\n        \n        def sort_by_priority_filter(items: List[Dict], priority_key: str = &#x27;priority&#x27;) -&gt; List[Dict]:\n            &quot;&quot;&quot;Sort items by priority (higher numbers first)&quot;&quot;&quot;\n            return sorted(items, key=lambda x: x.get(priority_key, 0), reverse=True)\n        \n        def calculate_metrics_filter(items: List[Dict], metric_key: str) -&gt; Dict[str, Any]:\n            &quot;&quot;&quot;Calculate aggregate metrics for a list of items&quot;&quot;&quot;\n            values = [item.get(metric_key, 0) for item in items if isinstance(item.get(metric_key), (int, float))]\n            \n            if not values:\n                return {&#x27;count&#x27;: 0, &#x27;sum&#x27;: 0, &#x27;avg&#x27;: 0, &#x27;min&#x27;: 0, &#x27;max&#x27;: 0}\n            \n            return {\n                &#x27;count&#x27;: len(values),\n                &#x27;sum&#x27;: sum(values),\n                &#x27;avg&#x27;: sum(values) / len(values),\n                &#x27;min&#x27;: min(values),\n                &#x27;max&#x27;: max(values)\n            }\n        \n        def filter_recent_filter(items: List[Dict], date_key: str, days: int = 7) -&gt; List[Dict]:\n            &quot;&quot;&quot;Filter items to only include recent entries&quot;&quot;&quot;\n            cutoff_date = datetime.now() - timedelta(days=days)\n            \n            recent_items = []\n            for item in items:\n                item_date = item.get(date_key)\n                if item_date:\n                    try:\n                        if isinstance(item_date, str):\n                            item_date = datetime.fromisoformat(item_date.replace(&#x27;Z&#x27;, &#x27;+00:00&#x27;))\n                        if item_date &gt;= cutoff_date:\n                            recent_items.append(item)\n                    except ValueError:\n                        continue\n            \n            return recent_items\n        \n        # Register filters\n        self.jinja_env.filters[&#x27;merge_lists&#x27;] = merge_lists_filter\n        self.jinja_env.filters[&#x27;group_by&#x27;] = group_by_filter\n        self.jinja_env.filters[&#x27;sort_by_priority&#x27;] = sort_by_priority_filter\n        self.jinja_env.filters[&#x27;calculate_metrics&#x27;] = calculate_metrics_filter\n        self.jinja_env.filters[&#x27;filter_recent&#x27;] = filter_recent_filter\n    \n    async def fetch_all_data(self, force_refresh: bool = False) -&gt; Dict[str, Any]:\n        &quot;&quot;&quot;Fetch data from all configured sources&quot;&quot;&quot;\n        tasks = []\n        \n        for source_name, source_config in self.data_sources.items():\n            if force_refresh or self._is_cache_stale(source_name, source_config.cache_ttl):\n                task = asyncio.create_task(\n                    self._fetch_source_data(source_name, source_config)\n                )\n                tasks.append(task)\n        \n        if tasks:\n            results = await asyncio.gather(*tasks, return_exceptions=True)\n            \n            for i, result in enumerate(results):\n                if isinstance(result, Exception):\n                    self.logger.error(f&quot;Error fetching data: {result}&quot;)\n        \n        return self.data_cache\n    \n    def _is_cache_stale(self, source_name: str, ttl: int) -&gt; bool:\n        &quot;&quot;&quot;Check if cached data is stale&quot;&quot;&quot;\n        if source_name not in self.cache_timestamps:\n            return True\n        \n        age = datetime.now().timestamp() - self.cache_timestamps[source_name]\n        return age &gt; ttl\n    \n    async def _fetch_source_data(self, source_name: str, config: DataSourceConfig) -&gt; None:\n        &quot;&quot;&quot;Fetch data from a single source with retry logic&quot;&quot;&quot;\n        for attempt in range(config.retry_config.get(&#x27;max_retries&#x27;, 3)):\n            try:\n                if config.type == &#x27;rest_api&#x27;:\n                    data = await self._fetch_rest_api_data(config)\n                elif config.type == &#x27;graphql&#x27;:\n                    data = await self._fetch_graphql_data(config)\n                elif config.type == &#x27;database&#x27;:\n                    data = await self._fetch_database_data(config)\n                elif config.type == &#x27;file&#x27;:\n                    data = await self._fetch_file_data(config)\n                else:\n                    raise ValueError(f&quot;Unknown data source type: {config.type}&quot;)\n                \n                # Apply transformation pipeline\n                for transform in config.transform_pipeline:\n                    data = await self._apply_transformation(data, transform)\n                \n                self.data_cache[source_name] = data\n                self.cache_timestamps[source_name] = datetime.now().timestamp()\n                self.logger.info(f&quot;Successfully fetched data from {source_name}&quot;)\n                return\n                \n            except Exception as e:\n                self.logger.warning(f&quot;Attempt {attempt + 1} failed for {source_name}: {e}&quot;)\n                if attempt &lt; config.retry_config.get(&#x27;max_retries&#x27;, 3) - 1:\n                    await asyncio.sleep(config.retry_config.get(&#x27;delay&#x27;, 1) * (2 ** attempt))\n                else:\n                    self.logger.error(f&quot;Failed to fetch data from {source_name} after all retries&quot;)\n                    raise\n    \n    async def _fetch_rest_api_data(self, config: DataSourceConfig) -&gt; Dict[str, Any]:\n        &quot;&quot;&quot;Fetch data from REST API&quot;&quot;&quot;\n        headers = {}\n        \n        # Handle authentication\n        if config.auth_method == &#x27;bearer_token&#x27;:\n            headers[&#x27;Authorization&#x27;] = f&quot;Bearer {config.auth_config[&#x27;token&#x27;]}&quot;\n        elif config.auth_method == &#x27;api_key&#x27;:\n            if config.auth_config.get(&#x27;header_name&#x27;):\n                headers[config.auth_config[&#x27;header_name&#x27;]] = config.auth_config[&#x27;api_key&#x27;]\n            else:\n                headers[&#x27;X-API-Key&#x27;] = config.auth_config[&#x27;api_key&#x27;]\n        elif config.auth_method == &#x27;basic_auth&#x27;:\n            import base64\n            credentials = f&quot;{config.auth_config[&#x27;username&#x27;]}:{config.auth_config[&#x27;password&#x27;]}&quot;\n            encoded = base64.b64encode(credentials.encode()).decode()\n            headers[&#x27;Authorization&#x27;] = f&quot;Basic {encoded}&quot;\n        \n        async with self.session.get(config.endpoint, headers=headers) as response:\n            response.raise_for_status()\n            return await response.json()\n    \n    async def _fetch_graphql_data(self, config: DataSourceConfig) -&gt; Dict[str, Any]:\n        &quot;&quot;&quot;Fetch data from GraphQL endpoint&quot;&quot;&quot;\n        headers = {&#x27;Content-Type&#x27;: &#x27;application/json&#x27;}\n        \n        # Handle authentication\n        if config.auth_method == &#x27;bearer_token&#x27;:\n            headers[&#x27;Authorization&#x27;] = f&quot;Bearer {config.auth_config[&#x27;token&#x27;]}&quot;\n        \n        query = config.auth_config.get(&#x27;query&#x27;, &#x27;&#x27;)\n        variables = config.auth_config.get(&#x27;variables&#x27;, {})\n        \n        payload = {\n            &#x27;query&#x27;: query,\n            &#x27;variables&#x27;: variables\n        }\n        \n        async with self.session.post(config.endpoint, json=payload, headers=headers) as response:\n            response.raise_for_status()\n            result = await response.json()\n            \n            if &#x27;errors&#x27; in result:\n                raise Exception(f&quot;GraphQL errors: {result[&#x27;errors&#x27;]}&quot;)\n            \n            return result.get(&#x27;data&#x27;, {})\n    \n    async def _fetch_database_data(self, config: DataSourceConfig) -&gt; Dict[str, Any]:\n        &quot;&quot;&quot;Fetch data from database&quot;&quot;&quot;\n        # This would implement database connectivity\n        # For this example, we&#x27;ll simulate with a placeholder\n        return {\n            &#x27;message&#x27;: &#x27;Database connectivity would be implemented here&#x27;,\n            &#x27;config&#x27;: config.endpoint\n        }\n    \n    async def _fetch_file_data(self, config: DataSourceConfig) -&gt; Dict[str, Any]:\n        &quot;&quot;&quot;Fetch data from file&quot;&quot;&quot;\n        if config.endpoint.startswith(&#x27;http&#x27;):\n            async with self.session.get(config.endpoint) as response:\n                response.raise_for_status()\n                \n                if config.endpoint.endswith(&#x27;.json&#x27;):\n                    return await response.json()\n                elif config.endpoint.endswith(&#x27;.yaml&#x27;) or config.endpoint.endswith(&#x27;.yml&#x27;):\n                    text = await response.text()\n                    return yaml.safe_load(text)\n                else:\n                    return {&#x27;content&#x27;: await response.text()}\n        else:\n            # Local file\n            with open(config.endpoint, &#x27;r&#x27;) as f:\n                if config.endpoint.endswith(&#x27;.json&#x27;):\n                    return json.load(f)\n                elif config.endpoint.endswith(&#x27;.yaml&#x27;) or config.endpoint.endswith(&#x27;.yml&#x27;):\n                    return yaml.safe_load(f)\n                else:\n                    return {&#x27;content&#x27;: f.read()}\n    \n    async def _apply_transformation(self, data: Dict[str, Any], transform: str) -&gt; Dict[str, Any]:\n        &quot;&quot;&quot;Apply data transformation&quot;&quot;&quot;\n        # Simple transformations - in production, this would be more sophisticated\n        if transform == &#x27;normalize_dates&#x27;:\n            return self._normalize_dates(data)\n        elif transform == &#x27;extract_summary&#x27;:\n            return self._extract_summary(data)\n        elif transform == &#x27;flatten_nested&#x27;:\n            return self._flatten_nested_data(data)\n        elif transform == &#x27;calculate_derived_metrics&#x27;:\n            return self._calculate_derived_metrics(data)\n        \n        return data\n    \n    def _normalize_dates(self, data: Dict[str, Any]) -&gt; Dict[str, Any]:\n        &quot;&quot;&quot;Normalize date formats in data&quot;&quot;&quot;\n        def normalize_date_value(value):\n            if isinstance(value, str):\n                # Try to parse and normalize date strings\n                for fmt in [&#x27;%Y-%m-%dT%H:%M:%SZ&#x27;, &#x27;%Y-%m-%d %H:%M:%S&#x27;, &#x27;%Y-%m-%d&#x27;]:\n                    try:\n                        dt = datetime.strptime(value, fmt)\n                        return dt.isoformat()\n                    except ValueError:\n                        continue\n            return value\n        \n        def normalize_recursive(obj):\n            if isinstance(obj, dict):\n                return {k: normalize_recursive(v) for k, v in obj.items()}\n            elif isinstance(obj, list):\n                return [normalize_recursive(item) for item in obj]\n            else:\n                return normalize_date_value(obj)\n        \n        return normalize_recursive(data)\n    \n    def _extract_summary(self, data: Dict[str, Any]) -&gt; Dict[str, Any]:\n        &quot;&quot;&quot;Extract summary information from data&quot;&quot;&quot;\n        summary = {\n            &#x27;total_items&#x27;: 0,\n            &#x27;categories&#x27;: set(),\n            &#x27;date_range&#x27;: {&#x27;earliest&#x27;: None, &#x27;latest&#x27;: None},\n            &#x27;data_types&#x27;: set()\n        }\n        \n        def analyze_item(item, path=&quot;&quot;):\n            if isinstance(item, dict):\n                for key, value in item.items():\n                    new_path = f&quot;{path}.{key}&quot; if path else key\n                    analyze_item(value, new_path)\n                    \n                    if &#x27;category&#x27; in key.lower():\n                        summary[&#x27;categories&#x27;].add(str(value))\n            elif isinstance(item, list):\n                summary[&#x27;total_items&#x27;] += len(item)\n                for subitem in item:\n                    analyze_item(subitem, path)\n            else:\n                summary[&#x27;data_types&#x27;].add(type(item).__name__)\n        \n        analyze_item(data)\n        \n        # Convert sets to lists for JSON serialization\n        data[&#x27;_summary&#x27;] = {\n            &#x27;total_items&#x27;: summary[&#x27;total_items&#x27;],\n            &#x27;categories&#x27;: list(summary[&#x27;categories&#x27;]),\n            &#x27;data_types&#x27;: list(summary[&#x27;data_types&#x27;])\n        }\n        \n        return data\n    \n    def _flatten_nested_data(self, data: Dict[str, Any]) -&gt; Dict[str, Any]:\n        &quot;&quot;&quot;Flatten deeply nested data structures&quot;&quot;&quot;\n        def flatten_dict(d, parent_key=&#x27;&#x27;, sep=&#x27;_&#x27;):\n            items = []\n            for k, v in d.items():\n                new_key = f&quot;{parent_key}{sep}{k}&quot; if parent_key else k\n                if isinstance(v, dict):\n                    items.extend(flatten_dict(v, new_key, sep=sep).items())\n                else:\n                    items.append((new_key, v))\n            return dict(items)\n        \n        if isinstance(data, dict):\n            data[&#x27;_flattened&#x27;] = flatten_dict(data)\n        \n        return data\n    \n    def _calculate_derived_metrics(self, data: Dict[str, Any]) -&gt; Dict[str, Any]:\n        &quot;&quot;&quot;Calculate derived metrics from raw data&quot;&quot;&quot;\n        metrics = {}\n        \n        # Look for numeric fields to calculate aggregations\n        def find_numeric_fields(obj, path=&quot;&quot;):\n            if isinstance(obj, dict):\n                for key, value in obj.items():\n                    new_path = f&quot;{path}.{key}&quot; if path else key\n                    if isinstance(value, (int, float)):\n                        if &#x27;metrics&#x27; not in data:\n                            data[&#x27;metrics&#x27;] = {}\n                        if path not in data[&#x27;metrics&#x27;]:\n                            data[&#x27;metrics&#x27;][path] = []\n                        data[&#x27;metrics&#x27;][path].append(value)\n                    elif isinstance(value, (dict, list)):\n                        find_numeric_fields(value, new_path)\n            elif isinstance(obj, list):\n                for item in obj:\n                    find_numeric_fields(item, path)\n        \n        find_numeric_fields(data)\n        \n        # Calculate aggregations\n        if &#x27;metrics&#x27; in data:\n            for field_path, values in data[&#x27;metrics&#x27;].items():\n                if values:\n                    metrics[field_path] = {\n                        &#x27;count&#x27;: len(values),\n                        &#x27;sum&#x27;: sum(values),\n                        &#x27;avg&#x27;: sum(values) / len(values),\n                        &#x27;min&#x27;: min(values),\n                        &#x27;max&#x27;: max(values)\n                    }\n            \n            data[&#x27;_derived_metrics&#x27;] = metrics\n        \n        return data\n    \n    async def generate_aggregated_content(self, template_name: str) -&gt; str:\n        &quot;&quot;&quot;Generate content using aggregated data from multiple sources&quot;&quot;&quot;\n        if template_name not in self.templates:\n            raise ValueError(f&quot;Template &#x27;{template_name}&#x27; not found&quot;)\n        \n        template_config = self.templates[template_name]\n        \n        # Fetch required data sources\n        required_data = {}\n        for source_name in template_config.data_sources:\n            if source_name not in self.data_cache or self._is_cache_stale(\n                source_name, self.data_sources[source_name].cache_ttl\n            ):\n                await self._fetch_source_data(source_name, self.data_sources[source_name])\n            \n            required_data[source_name] = self.data_cache[source_name]\n        \n        # Apply aggregation rules\n        aggregated_data = await self._apply_aggregation_rules(required_data, template_config.aggregation_rules)\n        \n        # Create template context\n        context = {\n            &#x27;data&#x27;: aggregated_data,\n            &#x27;sources&#x27;: required_data,\n            &#x27;config&#x27;: self.config,\n            &#x27;generation_time&#x27;: datetime.now(),\n            &#x27;template_name&#x27;: template_name\n        }\n        \n        # Render template\n        template = self.jinja_env.from_string(template_config.template_string)\n        content = template.render(**context)\n        \n        # Write output file\n        output_path = template_config.output_path\n        os.makedirs(os.path.dirname(output_path), exist_ok=True)\n        \n        with open(output_path, &#x27;w&#x27;, encoding=&#x27;utf-8&#x27;) as f:\n            f.write(content)\n        \n        self.logger.info(f&quot;Generated aggregated content: {output_path}&quot;)\n        return content\n    \n    async def _apply_aggregation_rules(self, data: Dict[str, Any], rules: Dict[str, Any]) -&gt; Dict[str, Any]:\n        &quot;&quot;&quot;Apply aggregation rules to combine data from multiple sources&quot;&quot;&quot;\n        result = {}\n        \n        for rule_name, rule_config in rules.items():\n            rule_type = rule_config.get(&#x27;type&#x27;, &#x27;merge&#x27;)\n            \n            if rule_type == &#x27;merge&#x27;:\n                # Merge data from specified sources\n                sources = rule_config.get(&#x27;sources&#x27;, [])\n                merged_data = {}\n                \n                for source in sources:\n                    if source in data:\n                        merged_data.update(data[source])\n                \n                result[rule_name] = merged_data\n            \n            elif rule_type == &#x27;combine_lists&#x27;:\n                # Combine lists from multiple sources\n                sources = rule_config.get(&#x27;sources&#x27;, [])\n                list_key = rule_config.get(&#x27;list_key&#x27;, &#x27;items&#x27;)\n                combined_list = []\n                \n                for source in sources:\n                    if source in data and list_key in data[source]:\n                        source_items = data[source][list_key]\n                        if isinstance(source_items, list):\n                            # Add source identifier to each item\n                            for item in source_items:\n                                if isinstance(item, dict):\n                                    item[&#x27;_source&#x27;] = source\n                            combined_list.extend(source_items)\n                \n                result[rule_name] = combined_list\n            \n            elif rule_type == &#x27;cross_reference&#x27;:\n                # Cross-reference data between sources\n                primary_source = rule_config.get(&#x27;primary_source&#x27;)\n                reference_source = rule_config.get(&#x27;reference_source&#x27;)\n                join_key = rule_config.get(&#x27;join_key&#x27;, &#x27;id&#x27;)\n                \n                if primary_source in data and reference_source in data:\n                    primary_data = data[primary_source]\n                    reference_data = data[reference_source]\n                    \n                    # Create lookup table for reference data\n                    ref_lookup = {}\n                    if isinstance(reference_data, dict) and &#x27;items&#x27; in reference_data:\n                        for item in reference_data[&#x27;items&#x27;]:\n                            if isinstance(item, dict) and join_key in item:\n                                ref_lookup[item[join_key]] = item\n                    \n                    # Enhance primary data with reference information\n                    enhanced_data = primary_data.copy()\n                    if isinstance(enhanced_data, dict) and &#x27;items&#x27; in enhanced_data:\n                        for item in enhanced_data[&#x27;items&#x27;]:\n                            if isinstance(item, dict) and join_key in item:\n                                ref_item = ref_lookup.get(item[join_key])\n                                if ref_item:\n                                    item[&#x27;_reference&#x27;] = ref_item\n                    \n                    result[rule_name] = enhanced_data\n        \n        return result\n\n# Example usage configuration\nexample_config = &quot;&quot;&quot;\ndata_sources:\n  - name: &quot;github_issues&quot;\n    type: &quot;rest_api&quot;\n    endpoint: &quot;https://api.github.com/repos/owner/repo/issues&quot;\n    auth_method: &quot;bearer_token&quot;\n    auth_config:\n      token: &quot;${GITHUB_TOKEN}&quot;\n    transform_pipeline:\n      - &quot;normalize_dates&quot;\n      - &quot;extract_summary&quot;\n    cache_ttl: 1800\n    \n  - name: &quot;user_metrics&quot;\n    type: &quot;rest_api&quot;\n    endpoint: &quot;https://analytics.example.com/api/users/metrics&quot;\n    auth_method: &quot;api_key&quot;\n    auth_config:\n      api_key: &quot;${ANALYTICS_API_KEY}&quot;\n      header_name: &quot;X-Analytics-Key&quot;\n    transform_pipeline:\n      - &quot;calculate_derived_metrics&quot;\n    cache_ttl: 3600\n    \n  - name: &quot;feature_flags&quot;\n    type: &quot;file&quot;\n    endpoint: &quot;config/features.json&quot;\n    transform_pipeline:\n      - &quot;extract_summary&quot;\n    cache_ttl: 600\n\ntemplates:\n  - name: &quot;status_dashboard&quot;\n    output_path: &quot;docs/status/dashboard.md&quot;\n    data_sources: [&quot;github_issues&quot;, &quot;user_metrics&quot;, &quot;feature_flags&quot;]\n    aggregation_rules:\n      recent_activity:\n        type: &quot;combine_lists&quot;\n        sources: [&quot;github_issues&quot;]\n        list_key: &quot;items&quot;\n      metrics_summary:\n        type: &quot;merge&quot;\n        sources: [&quot;user_metrics&quot;]\n      feature_status:\n        type: &quot;cross_reference&quot;\n        primary_source: &quot;feature_flags&quot;\n        reference_source: &quot;user_metrics&quot;\n        join_key: &quot;feature_id&quot;\n    template_string: |\n      \n      ---\n      title: &quot;System Status Dashboard&quot;\n      description: &quot;Real-time system status and metrics overview&quot;\n      category: &quot;Status&quot;\n      date: {{ generation_time.strftime(&#x27;%Y-%m-%d&#x27;) }}\n      ---\n      \n      # System Status Dashboard\n      \n      *Last updated: {{ generation_time.strftime(&#x27;%Y-%m-%d %H:%M:%S&#x27;) }} UTC*\n      \n      ## Recent Activity\n      \n      {% set recent_issues = data.recent_activity | filter_recent(&#x27;created_at&#x27;, 7) | sort_by_priority(&#x27;priority&#x27;) %}\n      \n      ### Open Issues (Last 7 Days)\n      | Issue | Priority | Status | Created |\n      |:------|:---------|:-------|:--------|\n      {% for issue in recent_issues[:10] %}\n      | [#{{ issue.number }}]({{ issue.html_url }}) {{ issue.title }} | {{ issue.labels | selectattr(&#x27;name&#x27;, &#x27;match&#x27;, &#x27;priority:.*&#x27;) | map(attribute=&#x27;name&#x27;) | join(&#x27;, &#x27;) | default(&#x27;normal&#x27;) }} | {{ issue.state }} | {{ issue.created_at | relative_time }} |\n      {% endfor %}\n      \n      ## System Metrics\n      \n      {% set metrics = data.metrics_summary %}\n      \n      ### Performance Overview\n      - **Active Users**: {{ metrics.active_users | format_number(&#x27;abbreviated&#x27;) }}\n      - **Response Time**: {{ metrics.avg_response_time }}ms\n      - **Error Rate**: {{ metrics.error_rate }}%\n      - **Uptime**: {{ metrics.uptime_percentage }}%\n      \n      ### Usage Statistics\n      {% for category, stats in metrics.usage_by_category.items() %}\n      - **{{ category }}**: {{ stats.requests | format_number(&#x27;abbreviated&#x27;) }} requests\n      {% endfor %}\n      \n      ## Feature Status\n      \n      {% set features = data.feature_status %}\n      \n      ### Feature Rollout Status\n      {% for feature in features.items | group_by(&#x27;status&#x27;).items() %}\n      \n      #### {{ feature[0] | title }} Features\n      {% for item in feature[1] %}\n      - **{{ item.name }}**: {{ item.rollout_percentage }}% rollout\n        {% if item._reference %}\n        - Usage: {{ item._reference.usage_count | format_number(&#x27;abbreviated&#x27;) }} \n        {% endif %}\n      {% endfor %}\n      {% endfor %}\n      \n      ---\n      *This dashboard is automatically generated from multiple data sources and updated every hour.*\n      \n    update_frequency: &quot;hourly&quot;\n&quot;&quot;&quot;\n\n# CLI interface for the aggregator\nasync def main():\n    import argparse\n    import os\n    \n    parser = argparse.ArgumentParser(description=&#x27;Multi-source content aggregator&#x27;)\n    parser.add_argument(&#x27;--config&#x27;, required=True, help=&#x27;Configuration file path&#x27;)\n    parser.add_argument(&#x27;--template&#x27;, help=&#x27;Specific template to generate&#x27;)\n    parser.add_argument(&#x27;--force-refresh&#x27;, action=&#x27;store_true&#x27;, help=&#x27;Force refresh of all data sources&#x27;)\n    \n    args = parser.parse_args()\n    \n    async with MultiSourceContentAggregator(args.config) as aggregator:\n        # Fetch all data\n        await aggregator.fetch_all_data(force_refresh=args.force_refresh)\n        \n        if args.template:\n            # Generate specific template\n            await aggregator.generate_aggregated_content(args.template)\n            print(f&quot;Generated content for template: {args.template}&quot;)\n        else:\n            # Generate all templates\n            for template_name in aggregator.templates:\n                try:\n                    await aggregator.generate_aggregated_content(template_name)\n                    print(f&quot;✅ Generated: {template_name}&quot;)\n                except Exception as e:\n                    print(f&quot;❌ Failed to generate {template_name}: {e}&quot;)\n\nif __name__ == &quot;__main__&quot;:\n    asyncio.run(main())\n```\u003C/span>\n\u003C/code>\u003C/pre>\u003Ch2 id=\"performance-optimization-and-scaling\">Performance Optimization and Scaling\u003C/h2>\n\u003Ch3 id=\"content-generation-performance-monitoring\">Content Generation Performance Monitoring\u003C/h3>\n\u003Cp>Implementing comprehensive performance monitoring for large-scale content generation:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-python\">\u003Cspan class=\"hljs-comment\">#!/usr/bin/env python3\u003C/span>\n\u003Cspan class=\"hljs-comment\"># performance-monitor.py - Performance monitoring for content generation\u003C/span>\n\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> time\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> psutil\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> threading\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> typing \u003Cspan class=\"hljs-keyword\">import\u003C/span> \u003Cspan class=\"hljs-type\">Dict\u003C/span>, \u003Cspan class=\"hljs-type\">List\u003C/span>, \u003Cspan class=\"hljs-type\">Any\u003C/span>, \u003Cspan class=\"hljs-type\">Optional\u003C/span>\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> dataclasses \u003Cspan class=\"hljs-keyword\">import\u003C/span> dataclass, field\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> datetime \u003Cspan class=\"hljs-keyword\">import\u003C/span> datetime, timedelta\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> statistics\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> json\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> asyncio\n\u003Cspan class=\"hljs-keyword\">from\u003C/span> concurrent.futures \u003Cspan class=\"hljs-keyword\">import\u003C/span> ThreadPoolExecutor, ProcessPoolExecutor\n\u003Cspan class=\"hljs-keyword\">import\u003C/span> multiprocessing \u003Cspan class=\"hljs-keyword\">as\u003C/span> mp\n\n\u003Cspan class=\"hljs-meta\">@dataclass\u003C/span>\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">PerformanceMetrics\u003C/span>:\n    \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Performance metrics for content generation operations&quot;&quot;&quot;\u003C/span>\n    operation_id: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\n    operation_type: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\n    start_time: datetime\n    end_time: \u003Cspan class=\"hljs-type\">Optional\u003C/span>[datetime] = \u003Cspan class=\"hljs-literal\">None\u003C/span>\n    duration_seconds: \u003Cspan class=\"hljs-type\">Optional\u003C/span>[\u003Cspan class=\"hljs-built_in\">float\u003C/span>] = \u003Cspan class=\"hljs-literal\">None\u003C/span>\n    memory_usage_mb: \u003Cspan class=\"hljs-type\">Optional\u003C/span>[\u003Cspan class=\"hljs-built_in\">float\u003C/span>] = \u003Cspan class=\"hljs-literal\">None\u003C/span>\n    cpu_usage_percent: \u003Cspan class=\"hljs-type\">Optional\u003C/span>[\u003Cspan class=\"hljs-built_in\">float\u003C/span>] = \u003Cspan class=\"hljs-literal\">None\u003C/span>\n    files_processed: \u003Cspan class=\"hljs-type\">Optional\u003C/span>[\u003Cspan class=\"hljs-built_in\">int\u003C/span>] = \u003Cspan class=\"hljs-literal\">None\u003C/span>\n    output_size_kb: \u003Cspan class=\"hljs-type\">Optional\u003C/span>[\u003Cspan class=\"hljs-built_in\">float\u003C/span>] = \u003Cspan class=\"hljs-literal\">None\u003C/span>\n    cache_hits: \u003Cspan class=\"hljs-type\">Optional\u003C/span>[\u003Cspan class=\"hljs-built_in\">int\u003C/span>] = \u003Cspan class=\"hljs-literal\">None\u003C/span>\n    cache_misses: \u003Cspan class=\"hljs-type\">Optional\u003C/span>[\u003Cspan class=\"hljs-built_in\">int\u003C/span>] = \u003Cspan class=\"hljs-literal\">None\u003C/span>\n\n\u003Cspan class=\"hljs-keyword\">class\u003C/span> \u003Cspan class=\"hljs-title class_\">ContentGenerationPerformanceMonitor\u003C/span>:\n    \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Performance monitoring system for content generation&quot;&quot;&quot;\u003C/span>\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">__init__\u003C/span>(\u003Cspan class=\"hljs-params\">self, enable_detailed_monitoring: \u003Cspan class=\"hljs-built_in\">bool\u003C/span> = \u003Cspan class=\"hljs-literal\">True\u003C/span>\u003C/span>):\n        self.enable_detailed_monitoring = enable_detailed_monitoring\n        self.metrics_history: \u003Cspan class=\"hljs-type\">List\u003C/span>[PerformanceMetrics] = []\n        self.active_operations: \u003Cspan class=\"hljs-type\">Dict\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>, PerformanceMetrics] = {}\n        self.system_metrics = []\n        \n        \u003Cspan class=\"hljs-comment\"># Start system monitoring thread\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> enable_detailed_monitoring:\n            self._start_system_monitoring()\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">_start_system_monitoring\u003C/span>(\u003Cspan class=\"hljs-params\">self\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Start background system monitoring&quot;&quot;&quot;\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">monitor_system\u003C/span>():\n            \u003Cspan class=\"hljs-keyword\">while\u003C/span> \u003Cspan class=\"hljs-literal\">True\u003C/span>:\n                \u003Cspan class=\"hljs-keyword\">try\u003C/span>:\n                    cpu_percent = psutil.cpu_percent(interval=\u003Cspan class=\"hljs-number\">1\u003C/span>)\n                    memory = psutil.virtual_memory()\n                    disk = psutil.disk_usage(\u003Cspan class=\"hljs-string\">&#x27;/&#x27;\u003C/span>)\n                    \n                    self.system_metrics.append({\n                        \u003Cspan class=\"hljs-string\">&#x27;timestamp&#x27;\u003C/span>: datetime.now(),\n                        \u003Cspan class=\"hljs-string\">&#x27;cpu_percent&#x27;\u003C/span>: cpu_percent,\n                        \u003Cspan class=\"hljs-string\">&#x27;memory_percent&#x27;\u003C/span>: memory.percent,\n                        \u003Cspan class=\"hljs-string\">&#x27;memory_available_gb&#x27;\u003C/span>: memory.available / (\u003Cspan class=\"hljs-number\">1024\u003C/span>**\u003Cspan class=\"hljs-number\">3\u003C/span>),\n                        \u003Cspan class=\"hljs-string\">&#x27;disk_free_gb&#x27;\u003C/span>: disk.free / (\u003Cspan class=\"hljs-number\">1024\u003C/span>**\u003Cspan class=\"hljs-number\">3\u003C/span>)\n                    })\n                    \n                    \u003Cspan class=\"hljs-comment\"># Keep only last hour of system metrics\u003C/span>\n                    cutoff = datetime.now() - timedelta(hours=\u003Cspan class=\"hljs-number\">1\u003C/span>)\n                    self.system_metrics = [\n                        m \u003Cspan class=\"hljs-keyword\">for\u003C/span> m \u003Cspan class=\"hljs-keyword\">in\u003C/span> self.system_metrics \n                        \u003Cspan class=\"hljs-keyword\">if\u003C/span> m[\u003Cspan class=\"hljs-string\">&#x27;timestamp&#x27;\u003C/span>] &gt; cutoff\n                    ]\n                    \n                    time.sleep(\u003Cspan class=\"hljs-number\">30\u003C/span>)  \u003Cspan class=\"hljs-comment\"># Sample every 30 seconds\u003C/span>\n                    \n                \u003Cspan class=\"hljs-keyword\">except\u003C/span> Exception \u003Cspan class=\"hljs-keyword\">as\u003C/span> e:\n                    \u003Cspan class=\"hljs-built_in\">print\u003C/span>(\u003Cspan class=\"hljs-string\">f&quot;System monitoring error: \u003Cspan class=\"hljs-subst\">{e}\u003C/span>&quot;\u003C/span>)\n                    time.sleep(\u003Cspan class=\"hljs-number\">60\u003C/span>)\n        \n        monitor_thread = threading.Thread(target=monitor_system, daemon=\u003Cspan class=\"hljs-literal\">True\u003C/span>)\n        monitor_thread.start()\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">start_operation\u003C/span>(\u003Cspan class=\"hljs-params\">self, operation_id: \u003Cspan class=\"hljs-built_in\">str\u003C/span>, operation_type: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\u003C/span>) -&gt; PerformanceMetrics:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Start monitoring an operation&quot;&quot;&quot;\u003C/span>\n        metrics = PerformanceMetrics(\n            operation_id=operation_id,\n            operation_type=operation_type,\n            start_time=datetime.now()\n        )\n        \n        self.active_operations[operation_id] = metrics\n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> metrics\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">end_operation\u003C/span>(\u003Cspan class=\"hljs-params\">self, operation_id: \u003Cspan class=\"hljs-built_in\">str\u003C/span>, \n                     files_processed: \u003Cspan class=\"hljs-built_in\">int\u003C/span> = \u003Cspan class=\"hljs-number\">0\u003C/span>,\n                     output_size_kb: \u003Cspan class=\"hljs-built_in\">float\u003C/span> = \u003Cspan class=\"hljs-number\">0\u003C/span>,\n                     cache_hits: \u003Cspan class=\"hljs-built_in\">int\u003C/span> = \u003Cspan class=\"hljs-number\">0\u003C/span>,\n                     cache_misses: \u003Cspan class=\"hljs-built_in\">int\u003C/span> = \u003Cspan class=\"hljs-number\">0\u003C/span>\u003C/span>) -&gt; PerformanceMetrics:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;End monitoring and record final metrics&quot;&quot;&quot;\u003C/span>\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> operation_id \u003Cspan class=\"hljs-keyword\">not\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> self.active_operations:\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-literal\">None\u003C/span>\n        \n        metrics = self.active_operations[operation_id]\n        metrics.end_time = datetime.now()\n        metrics.duration_seconds = (metrics.end_time - metrics.start_time).total_seconds()\n        metrics.files_processed = files_processed\n        metrics.output_size_kb = output_size_kb\n        metrics.cache_hits = cache_hits\n        metrics.cache_misses = cache_misses\n        \n        \u003Cspan class=\"hljs-comment\"># Capture resource usage\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">try\u003C/span>:\n            process = psutil.Process()\n            memory_info = process.memory_info()\n            metrics.memory_usage_mb = memory_info.rss / (\u003Cspan class=\"hljs-number\">1024\u003C/span> * \u003Cspan class=\"hljs-number\">1024\u003C/span>)\n            metrics.cpu_usage_percent = process.cpu_percent()\n        \u003Cspan class=\"hljs-keyword\">except\u003C/span> Exception:\n            \u003Cspan class=\"hljs-keyword\">pass\u003C/span>\n        \n        \u003Cspan class=\"hljs-comment\"># Move to history\u003C/span>\n        self.metrics_history.append(metrics)\n        \u003Cspan class=\"hljs-keyword\">del\u003C/span> self.active_operations[operation_id]\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> metrics\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">get_performance_summary\u003C/span>(\u003Cspan class=\"hljs-params\">self, \n                              operation_type: \u003Cspan class=\"hljs-type\">Optional\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>] = \u003Cspan class=\"hljs-literal\">None\u003C/span>,\n                              time_window: \u003Cspan class=\"hljs-type\">Optional\u003C/span>[timedelta] = \u003Cspan class=\"hljs-literal\">None\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">Dict\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>, \u003Cspan class=\"hljs-type\">Any\u003C/span>]:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Generate performance summary report&quot;&quot;&quot;\u003C/span>\n        \n        \u003Cspan class=\"hljs-comment\"># Filter metrics\u003C/span>\n        filtered_metrics = self.metrics_history\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> operation_type:\n            filtered_metrics = [m \u003Cspan class=\"hljs-keyword\">for\u003C/span> m \u003Cspan class=\"hljs-keyword\">in\u003C/span> filtered_metrics \u003Cspan class=\"hljs-keyword\">if\u003C/span> m.operation_type == operation_type]\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> time_window:\n            cutoff = datetime.now() - time_window\n            filtered_metrics = [m \u003Cspan class=\"hljs-keyword\">for\u003C/span> m \u003Cspan class=\"hljs-keyword\">in\u003C/span> filtered_metrics \u003Cspan class=\"hljs-keyword\">if\u003C/span> m.start_time &gt;= cutoff]\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> filtered_metrics:\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> {\u003Cspan class=\"hljs-string\">&#x27;error&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;No metrics found for criteria&#x27;\u003C/span>}\n        \n        \u003Cspan class=\"hljs-comment\"># Calculate statistics\u003C/span>\n        durations = [m.duration_seconds \u003Cspan class=\"hljs-keyword\">for\u003C/span> m \u003Cspan class=\"hljs-keyword\">in\u003C/span> filtered_metrics \u003Cspan class=\"hljs-keyword\">if\u003C/span> m.duration_seconds \u003Cspan class=\"hljs-keyword\">is\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> \u003Cspan class=\"hljs-literal\">None\u003C/span>]\n        memory_usage = [m.memory_usage_mb \u003Cspan class=\"hljs-keyword\">for\u003C/span> m \u003Cspan class=\"hljs-keyword\">in\u003C/span> filtered_metrics \u003Cspan class=\"hljs-keyword\">if\u003C/span> m.memory_usage_mb \u003Cspan class=\"hljs-keyword\">is\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> \u003Cspan class=\"hljs-literal\">None\u003C/span>]\n        files_processed = [m.files_processed \u003Cspan class=\"hljs-keyword\">for\u003C/span> m \u003Cspan class=\"hljs-keyword\">in\u003C/span> filtered_metrics \u003Cspan class=\"hljs-keyword\">if\u003C/span> m.files_processed \u003Cspan class=\"hljs-keyword\">is\u003C/span> \u003Cspan class=\"hljs-keyword\">not\u003C/span> \u003Cspan class=\"hljs-literal\">None\u003C/span>]\n        \n        summary = {\n            \u003Cspan class=\"hljs-string\">&#x27;operation_count&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">len\u003C/span>(filtered_metrics),\n            \u003Cspan class=\"hljs-string\">&#x27;time_period&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">str\u003C/span>(time_window) \u003Cspan class=\"hljs-keyword\">if\u003C/span> time_window \u003Cspan class=\"hljs-keyword\">else\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;All time&#x27;\u003C/span>,\n            \u003Cspan class=\"hljs-string\">&#x27;operation_type&#x27;\u003C/span>: operation_type \u003Cspan class=\"hljs-keyword\">or\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;All types&#x27;\u003C/span>\n        }\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> durations:\n            summary[\u003Cspan class=\"hljs-string\">&#x27;timing&#x27;\u003C/span>] = {\n                \u003Cspan class=\"hljs-string\">&#x27;avg_duration&#x27;\u003C/span>: statistics.mean(durations),\n                \u003Cspan class=\"hljs-string\">&#x27;min_duration&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">min\u003C/span>(durations),\n                \u003Cspan class=\"hljs-string\">&#x27;max_duration&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">max\u003C/span>(durations),\n                \u003Cspan class=\"hljs-string\">&#x27;median_duration&#x27;\u003C/span>: statistics.median(durations),\n                \u003Cspan class=\"hljs-string\">&#x27;p95_duration&#x27;\u003C/span>: self._percentile(durations, \u003Cspan class=\"hljs-number\">95\u003C/span>),\n                \u003Cspan class=\"hljs-string\">&#x27;total_time&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">sum\u003C/span>(durations)\n            }\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> memory_usage:\n            summary[\u003Cspan class=\"hljs-string\">&#x27;memory&#x27;\u003C/span>] = {\n                \u003Cspan class=\"hljs-string\">&#x27;avg_memory_mb&#x27;\u003C/span>: statistics.mean(memory_usage),\n                \u003Cspan class=\"hljs-string\">&#x27;peak_memory_mb&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">max\u003C/span>(memory_usage),\n                \u003Cspan class=\"hljs-string\">&#x27;min_memory_mb&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">min\u003C/span>(memory_usage)\n            }\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> files_processed:\n            total_files = \u003Cspan class=\"hljs-built_in\">sum\u003C/span>(files_processed)\n            total_time = \u003Cspan class=\"hljs-built_in\">sum\u003C/span>(durations) \u003Cspan class=\"hljs-keyword\">if\u003C/span> durations \u003Cspan class=\"hljs-keyword\">else\u003C/span> \u003Cspan class=\"hljs-number\">1\u003C/span>\n            \n            summary[\u003Cspan class=\"hljs-string\">&#x27;throughput&#x27;\u003C/span>] = {\n                \u003Cspan class=\"hljs-string\">&#x27;total_files&#x27;\u003C/span>: total_files,\n                \u003Cspan class=\"hljs-string\">&#x27;avg_files_per_operation&#x27;\u003C/span>: statistics.mean(files_processed),\n                \u003Cspan class=\"hljs-string\">&#x27;files_per_second&#x27;\u003C/span>: total_files / total_time \u003Cspan class=\"hljs-keyword\">if\u003C/span> total_time &gt; \u003Cspan class=\"hljs-number\">0\u003C/span> \u003Cspan class=\"hljs-keyword\">else\u003C/span> \u003Cspan class=\"hljs-number\">0\u003C/span>\n            }\n        \n        \u003Cspan class=\"hljs-comment\"># Cache efficiency\u003C/span>\n        total_hits = \u003Cspan class=\"hljs-built_in\">sum\u003C/span>(m.cache_hits \u003Cspan class=\"hljs-keyword\">or\u003C/span> \u003Cspan class=\"hljs-number\">0\u003C/span> \u003Cspan class=\"hljs-keyword\">for\u003C/span> m \u003Cspan class=\"hljs-keyword\">in\u003C/span> filtered_metrics)\n        total_misses = \u003Cspan class=\"hljs-built_in\">sum\u003C/span>(m.cache_misses \u003Cspan class=\"hljs-keyword\">or\u003C/span> \u003Cspan class=\"hljs-number\">0\u003C/span> \u003Cspan class=\"hljs-keyword\">for\u003C/span> m \u003Cspan class=\"hljs-keyword\">in\u003C/span> filtered_metrics)\n        total_cache_ops = total_hits + total_misses\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> total_cache_ops &gt; \u003Cspan class=\"hljs-number\">0\u003C/span>:\n            summary[\u003Cspan class=\"hljs-string\">&#x27;cache&#x27;\u003C/span>] = {\n                \u003Cspan class=\"hljs-string\">&#x27;hit_rate&#x27;\u003C/span>: (total_hits / total_cache_ops) * \u003Cspan class=\"hljs-number\">100\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;total_hits&#x27;\u003C/span>: total_hits,\n                \u003Cspan class=\"hljs-string\">&#x27;total_misses&#x27;\u003C/span>: total_misses\n            }\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> summary\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">_percentile\u003C/span>(\u003Cspan class=\"hljs-params\">self, data: \u003Cspan class=\"hljs-type\">List\u003C/span>[\u003Cspan class=\"hljs-built_in\">float\u003C/span>], percentile: \u003Cspan class=\"hljs-built_in\">int\u003C/span>\u003C/span>) -&gt; \u003Cspan class=\"hljs-built_in\">float\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Calculate percentile value&quot;&quot;&quot;\u003C/span>\n        sorted_data = \u003Cspan class=\"hljs-built_in\">sorted\u003C/span>(data)\n        index = (percentile / \u003Cspan class=\"hljs-number\">100\u003C/span>) * (\u003Cspan class=\"hljs-built_in\">len\u003C/span>(sorted_data) - \u003Cspan class=\"hljs-number\">1\u003C/span>)\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> index.is_integer():\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> sorted_data[\u003Cspan class=\"hljs-built_in\">int\u003C/span>(index)]\n        \u003Cspan class=\"hljs-keyword\">else\u003C/span>:\n            lower = sorted_data[\u003Cspan class=\"hljs-built_in\">int\u003C/span>(index)]\n            upper = sorted_data[\u003Cspan class=\"hljs-built_in\">int\u003C/span>(index) + \u003Cspan class=\"hljs-number\">1\u003C/span>]\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> lower + (upper - lower) * (index - \u003Cspan class=\"hljs-built_in\">int\u003C/span>(index))\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">detect_performance_bottlenecks\u003C/span>(\u003Cspan class=\"hljs-params\">self\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">List\u003C/span>[\u003Cspan class=\"hljs-type\">Dict\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>, \u003Cspan class=\"hljs-type\">Any\u003C/span>]]:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Detect performance bottlenecks and anomalies&quot;&quot;&quot;\u003C/span>\n        bottlenecks = []\n        \n        \u003Cspan class=\"hljs-comment\"># Analyze recent operations\u003C/span>\n        recent_window = timedelta(minutes=\u003Cspan class=\"hljs-number\">30\u003C/span>)\n        recent_metrics = [\n            m \u003Cspan class=\"hljs-keyword\">for\u003C/span> m \u003Cspan class=\"hljs-keyword\">in\u003C/span> self.metrics_history \n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> m.start_time &gt;= datetime.now() - recent_window\n        ]\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-built_in\">len\u003C/span>(recent_metrics) &lt; \u003Cspan class=\"hljs-number\">5\u003C/span>:\n            \u003Cspan class=\"hljs-keyword\">return\u003C/span> bottlenecks\n        \n        \u003Cspan class=\"hljs-comment\"># Check for slow operations\u003C/span>\n        durations = [m.duration_seconds \u003Cspan class=\"hljs-keyword\">for\u003C/span> m \u003Cspan class=\"hljs-keyword\">in\u003C/span> recent_metrics \u003Cspan class=\"hljs-keyword\">if\u003C/span> m.duration_seconds]\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> durations:\n            avg_duration = statistics.mean(durations)\n            threshold = avg_duration * \u003Cspan class=\"hljs-number\">2\u003C/span>\n            \n            slow_ops = [m \u003Cspan class=\"hljs-keyword\">for\u003C/span> m \u003Cspan class=\"hljs-keyword\">in\u003C/span> recent_metrics \u003Cspan class=\"hljs-keyword\">if\u003C/span> m.duration_seconds \u003Cspan class=\"hljs-keyword\">and\u003C/span> m.duration_seconds &gt; threshold]\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> slow_ops:\n                bottlenecks.append({\n                    \u003Cspan class=\"hljs-string\">&#x27;type&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;slow_operations&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;count&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">len\u003C/span>(slow_ops),\n                    \u003Cspan class=\"hljs-string\">&#x27;threshold_seconds&#x27;\u003C/span>: threshold,\n                    \u003Cspan class=\"hljs-string\">&#x27;details&#x27;\u003C/span>: [\n                        {\n                            \u003Cspan class=\"hljs-string\">&#x27;operation_id&#x27;\u003C/span>: op.operation_id,\n                            \u003Cspan class=\"hljs-string\">&#x27;duration&#x27;\u003C/span>: op.duration_seconds,\n                            \u003Cspan class=\"hljs-string\">&#x27;type&#x27;\u003C/span>: op.operation_type\n                        }\n                        \u003Cspan class=\"hljs-keyword\">for\u003C/span> op \u003Cspan class=\"hljs-keyword\">in\u003C/span> slow_ops[:\u003Cspan class=\"hljs-number\">5\u003C/span>]  \u003Cspan class=\"hljs-comment\"># Show top 5\u003C/span>\n                    ]\n                })\n        \n        \u003Cspan class=\"hljs-comment\"># Check for memory issues\u003C/span>\n        memory_usage = [m.memory_usage_mb \u003Cspan class=\"hljs-keyword\">for\u003C/span> m \u003Cspan class=\"hljs-keyword\">in\u003C/span> recent_metrics \u003Cspan class=\"hljs-keyword\">if\u003C/span> m.memory_usage_mb]\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> memory_usage:\n            avg_memory = statistics.mean(memory_usage)\n            high_memory_threshold = avg_memory * \u003Cspan class=\"hljs-number\">1.5\u003C/span>\n            \n            high_memory_ops = [m \u003Cspan class=\"hljs-keyword\">for\u003C/span> m \u003Cspan class=\"hljs-keyword\">in\u003C/span> recent_metrics \u003Cspan class=\"hljs-keyword\">if\u003C/span> m.memory_usage_mb \u003Cspan class=\"hljs-keyword\">and\u003C/span> m.memory_usage_mb &gt; high_memory_threshold]\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> high_memory_ops:\n                bottlenecks.append({\n                    \u003Cspan class=\"hljs-string\">&#x27;type&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;high_memory_usage&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;count&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">len\u003C/span>(high_memory_ops),\n                    \u003Cspan class=\"hljs-string\">&#x27;threshold_mb&#x27;\u003C/span>: high_memory_threshold,\n                    \u003Cspan class=\"hljs-string\">&#x27;peak_usage_mb&#x27;\u003C/span>: \u003Cspan class=\"hljs-built_in\">max\u003C/span>(m.memory_usage_mb \u003Cspan class=\"hljs-keyword\">for\u003C/span> m \u003Cspan class=\"hljs-keyword\">in\u003C/span> high_memory_ops)\n                })\n        \n        \u003Cspan class=\"hljs-comment\"># Check cache efficiency\u003C/span>\n        total_hits = \u003Cspan class=\"hljs-built_in\">sum\u003C/span>(m.cache_hits \u003Cspan class=\"hljs-keyword\">or\u003C/span> \u003Cspan class=\"hljs-number\">0\u003C/span> \u003Cspan class=\"hljs-keyword\">for\u003C/span> m \u003Cspan class=\"hljs-keyword\">in\u003C/span> recent_metrics)\n        total_misses = \u003Cspan class=\"hljs-built_in\">sum\u003C/span>(m.cache_misses \u003Cspan class=\"hljs-keyword\">or\u003C/span> \u003Cspan class=\"hljs-number\">0\u003C/span> \u003Cspan class=\"hljs-keyword\">for\u003C/span> m \u003Cspan class=\"hljs-keyword\">in\u003C/span> recent_metrics)\n        total_cache_ops = total_hits + total_misses\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> total_cache_ops &gt; \u003Cspan class=\"hljs-number\">0\u003C/span>:\n            hit_rate = (total_hits / total_cache_ops) * \u003Cspan class=\"hljs-number\">100\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> hit_rate &lt; \u003Cspan class=\"hljs-number\">70\u003C/span>:  \u003Cspan class=\"hljs-comment\"># Less than 70% hit rate\u003C/span>\n                bottlenecks.append({\n                    \u003Cspan class=\"hljs-string\">&#x27;type&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;low_cache_efficiency&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;hit_rate&#x27;\u003C/span>: hit_rate,\n                    \u003Cspan class=\"hljs-string\">&#x27;total_operations&#x27;\u003C/span>: total_cache_ops,\n                    \u003Cspan class=\"hljs-string\">&#x27;recommendation&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;Consider increasing cache size or TTL&#x27;\u003C/span>\n                })\n        \n        \u003Cspan class=\"hljs-comment\"># Check system resource usage\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> self.system_metrics:\n            recent_system = [\n                m \u003Cspan class=\"hljs-keyword\">for\u003C/span> m \u003Cspan class=\"hljs-keyword\">in\u003C/span> self.system_metrics \n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> m[\u003Cspan class=\"hljs-string\">&#x27;timestamp&#x27;\u003C/span>] &gt;= datetime.now() - recent_window\n            ]\n            \n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> recent_system:\n                avg_cpu = statistics.mean(m[\u003Cspan class=\"hljs-string\">&#x27;cpu_percent&#x27;\u003C/span>] \u003Cspan class=\"hljs-keyword\">for\u003C/span> m \u003Cspan class=\"hljs-keyword\">in\u003C/span> recent_system)\n                avg_memory = statistics.mean(m[\u003Cspan class=\"hljs-string\">&#x27;memory_percent&#x27;\u003C/span>] \u003Cspan class=\"hljs-keyword\">for\u003C/span> m \u003Cspan class=\"hljs-keyword\">in\u003C/span> recent_system)\n                \n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> avg_cpu &gt; \u003Cspan class=\"hljs-number\">80\u003C/span>:\n                    bottlenecks.append({\n                        \u003Cspan class=\"hljs-string\">&#x27;type&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;high_cpu_usage&#x27;\u003C/span>,\n                        \u003Cspan class=\"hljs-string\">&#x27;avg_cpu_percent&#x27;\u003C/span>: avg_cpu,\n                        \u003Cspan class=\"hljs-string\">&#x27;recommendation&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;Consider optimizing algorithms or scaling horizontally&#x27;\u003C/span>\n                    })\n                \n                \u003Cspan class=\"hljs-keyword\">if\u003C/span> avg_memory &gt; \u003Cspan class=\"hljs-number\">85\u003C/span>:\n                    bottlenecks.append({\n                        \u003Cspan class=\"hljs-string\">&#x27;type&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;high_memory_pressure&#x27;\u003C/span>,\n                        \u003Cspan class=\"hljs-string\">&#x27;avg_memory_percent&#x27;\u003C/span>: avg_memory,\n                        \u003Cspan class=\"hljs-string\">&#x27;recommendation&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;Consider increasing available memory or optimizing memory usage&#x27;\u003C/span>\n                    })\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> bottlenecks\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">optimize_generation_strategy\u003C/span>(\u003Cspan class=\"hljs-params\">self\u003C/span>) -&gt; \u003Cspan class=\"hljs-type\">Dict\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>, \u003Cspan class=\"hljs-type\">Any\u003C/span>]:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Generate optimization recommendations based on performance data&quot;&quot;&quot;\u003C/span>\n        summary = self.get_performance_summary(time_window=timedelta(hours=\u003Cspan class=\"hljs-number\">24\u003C/span>))\n        bottlenecks = self.detect_performance_bottlenecks()\n        \n        recommendations = []\n        \n        \u003Cspan class=\"hljs-comment\"># Analyze timing performance\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;timing&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> summary:\n            avg_duration = summary[\u003Cspan class=\"hljs-string\">&#x27;timing&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;avg_duration&#x27;\u003C/span>]\n            p95_duration = summary[\u003Cspan class=\"hljs-string\">&#x27;timing&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;p95_duration&#x27;\u003C/span>]\n            \n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> avg_duration &gt; \u003Cspan class=\"hljs-number\">30\u003C/span>:  \u003Cspan class=\"hljs-comment\"># 30 seconds\u003C/span>\n                recommendations.append({\n                    \u003Cspan class=\"hljs-string\">&#x27;category&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;performance&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;priority&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;high&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;recommendation&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;Consider implementing parallel processing for content generation&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;rationale&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">f&#x27;Average generation time is \u003Cspan class=\"hljs-subst\">{avg_duration:\u003Cspan class=\"hljs-number\">.1\u003C/span>f}\u003C/span> seconds&#x27;\u003C/span>\n                })\n            \n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> p95_duration &gt; avg_duration * \u003Cspan class=\"hljs-number\">3\u003C/span>:\n                recommendations.append({\n                    \u003Cspan class=\"hljs-string\">&#x27;category&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;consistency&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;priority&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;medium&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;recommendation&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;Investigate high variance in processing times&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;rationale&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">f&#x27;95th percentile is \u003Cspan class=\"hljs-subst\">{p95_duration/avg_duration:\u003Cspan class=\"hljs-number\">.1\u003C/span>f}\u003C/span>x average&#x27;\u003C/span>\n                })\n        \n        \u003Cspan class=\"hljs-comment\"># Analyze throughput\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;throughput&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> summary:\n            files_per_second = summary[\u003Cspan class=\"hljs-string\">&#x27;throughput&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;files_per_second&#x27;\u003C/span>]\n            \n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> files_per_second &lt; \u003Cspan class=\"hljs-number\">1\u003C/span>:\n                recommendations.append({\n                    \u003Cspan class=\"hljs-string\">&#x27;category&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;throughput&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;priority&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;high&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;recommendation&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;Implement batch processing and template caching&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;rationale&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">f&#x27;Current throughput is only \u003Cspan class=\"hljs-subst\">{files_per_second:\u003Cspan class=\"hljs-number\">.2\u003C/span>f}\u003C/span> files/second&#x27;\u003C/span>\n                })\n        \n        \u003Cspan class=\"hljs-comment\"># Cache optimization\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;cache&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> summary \u003Cspan class=\"hljs-keyword\">and\u003C/span> summary[\u003Cspan class=\"hljs-string\">&#x27;cache&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;hit_rate&#x27;\u003C/span>] &lt; \u003Cspan class=\"hljs-number\">80\u003C/span>:\n            recommendations.append({\n                \u003Cspan class=\"hljs-string\">&#x27;category&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;caching&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;priority&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;medium&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;recommendation&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;Optimize cache configuration and increase cache TTL&#x27;\u003C/span>,\n                \u003Cspan class=\"hljs-string\">&#x27;rationale&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">f&quot;Cache hit rate is only \u003Cspan class=\"hljs-subst\">{summary[\u003Cspan class=\"hljs-string\">&#x27;cache&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;hit_rate&#x27;\u003C/span>]:\u003Cspan class=\"hljs-number\">.1\u003C/span>f}\u003C/span>%&quot;\u003C/span>\n            })\n        \n        \u003Cspan class=\"hljs-comment\"># Memory optimization\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;memory&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> summary:\n            peak_memory = summary[\u003Cspan class=\"hljs-string\">&#x27;memory&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;peak_memory_mb&#x27;\u003C/span>]\n            \n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> peak_memory &gt; \u003Cspan class=\"hljs-number\">1000\u003C/span>:  \u003Cspan class=\"hljs-comment\"># 1GB\u003C/span>\n                recommendations.append({\n                    \u003Cspan class=\"hljs-string\">&#x27;category&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;memory&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;priority&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;medium&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;recommendation&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;Implement streaming processing for large datasets&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;rationale&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">f&#x27;Peak memory usage is \u003Cspan class=\"hljs-subst\">{peak_memory:\u003Cspan class=\"hljs-number\">.0\u003C/span>f}\u003C/span>MB&#x27;\u003C/span>\n                })\n        \n        \u003Cspan class=\"hljs-comment\"># Bottleneck-specific recommendations\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> bottleneck \u003Cspan class=\"hljs-keyword\">in\u003C/span> bottlenecks:\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> bottleneck[\u003Cspan class=\"hljs-string\">&#x27;type&#x27;\u003C/span>] == \u003Cspan class=\"hljs-string\">&#x27;slow_operations&#x27;\u003C/span>:\n                recommendations.append({\n                    \u003Cspan class=\"hljs-string\">&#x27;category&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;performance&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;priority&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;high&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;recommendation&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;Profile and optimize slow operations&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;rationale&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">f&quot;\u003Cspan class=\"hljs-subst\">{bottleneck[\u003Cspan class=\"hljs-string\">&#x27;count&#x27;\u003C/span>]}\u003C/span> operations exceeded normal duration&quot;\u003C/span>\n                })\n            \u003Cspan class=\"hljs-keyword\">elif\u003C/span> bottleneck[\u003Cspan class=\"hljs-string\">&#x27;type&#x27;\u003C/span>] == \u003Cspan class=\"hljs-string\">&#x27;low_cache_efficiency&#x27;\u003C/span>:\n                recommendations.append({\n                    \u003Cspan class=\"hljs-string\">&#x27;category&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;caching&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;priority&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">&#x27;medium&#x27;\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;recommendation&#x27;\u003C/span>: bottleneck[\u003Cspan class=\"hljs-string\">&#x27;recommendation&#x27;\u003C/span>],\n                    \u003Cspan class=\"hljs-string\">&#x27;rationale&#x27;\u003C/span>: \u003Cspan class=\"hljs-string\">f&quot;Cache hit rate is \u003Cspan class=\"hljs-subst\">{bottleneck[\u003Cspan class=\"hljs-string\">&#x27;hit_rate&#x27;\u003C/span>]:\u003Cspan class=\"hljs-number\">.1\u003C/span>f}\u003C/span>%&quot;\u003C/span>\n                })\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> {\n            \u003Cspan class=\"hljs-string\">&#x27;analysis_timestamp&#x27;\u003C/span>: datetime.now().isoformat(),\n            \u003Cspan class=\"hljs-string\">&#x27;performance_summary&#x27;\u003C/span>: summary,\n            \u003Cspan class=\"hljs-string\">&#x27;bottlenecks&#x27;\u003C/span>: bottlenecks,\n            \u003Cspan class=\"hljs-string\">&#x27;recommendations&#x27;\u003C/span>: recommendations,\n            \u003Cspan class=\"hljs-string\">&#x27;optimization_score&#x27;\u003C/span>: self._calculate_optimization_score(summary, bottlenecks)\n        }\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">_calculate_optimization_score\u003C/span>(\u003Cspan class=\"hljs-params\">self, summary: \u003Cspan class=\"hljs-type\">Dict\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>, \u003Cspan class=\"hljs-type\">Any\u003C/span>], bottlenecks: \u003Cspan class=\"hljs-type\">List\u003C/span>[\u003Cspan class=\"hljs-type\">Dict\u003C/span>[\u003Cspan class=\"hljs-built_in\">str\u003C/span>, \u003Cspan class=\"hljs-type\">Any\u003C/span>]]\u003C/span>) -&gt; \u003Cspan class=\"hljs-built_in\">int\u003C/span>:\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Calculate optimization score (0-100)&quot;&quot;&quot;\u003C/span>\n        score = \u003Cspan class=\"hljs-number\">100\u003C/span>\n        \n        \u003Cspan class=\"hljs-comment\"># Deduct points for performance issues\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;timing&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> summary:\n            avg_duration = summary[\u003Cspan class=\"hljs-string\">&#x27;timing&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;avg_duration&#x27;\u003C/span>]\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> avg_duration &gt; \u003Cspan class=\"hljs-number\">60\u003C/span>:\n                score -= \u003Cspan class=\"hljs-number\">20\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">elif\u003C/span> avg_duration &gt; \u003Cspan class=\"hljs-number\">30\u003C/span>:\n                score -= \u003Cspan class=\"hljs-number\">10\u003C/span>\n        \n        \u003Cspan class=\"hljs-keyword\">if\u003C/span> \u003Cspan class=\"hljs-string\">&#x27;cache&#x27;\u003C/span> \u003Cspan class=\"hljs-keyword\">in\u003C/span> summary:\n            hit_rate = summary[\u003Cspan class=\"hljs-string\">&#x27;cache&#x27;\u003C/span>][\u003Cspan class=\"hljs-string\">&#x27;hit_rate&#x27;\u003C/span>]\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> hit_rate &lt; \u003Cspan class=\"hljs-number\">50\u003C/span>:\n                score -= \u003Cspan class=\"hljs-number\">20\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">elif\u003C/span> hit_rate &lt; \u003Cspan class=\"hljs-number\">80\u003C/span>:\n                score -= \u003Cspan class=\"hljs-number\">10\u003C/span>\n        \n        \u003Cspan class=\"hljs-comment\"># Deduct points for bottlenecks\u003C/span>\n        \u003Cspan class=\"hljs-keyword\">for\u003C/span> bottleneck \u003Cspan class=\"hljs-keyword\">in\u003C/span> bottlenecks:\n            \u003Cspan class=\"hljs-keyword\">if\u003C/span> bottleneck[\u003Cspan class=\"hljs-string\">&#x27;type&#x27;\u003C/span>] \u003Cspan class=\"hljs-keyword\">in\u003C/span> [\u003Cspan class=\"hljs-string\">&#x27;slow_operations&#x27;\u003C/span>, \u003Cspan class=\"hljs-string\">&#x27;high_memory_usage&#x27;\u003C/span>]:\n                score -= \u003Cspan class=\"hljs-number\">15\u003C/span>\n            \u003Cspan class=\"hljs-keyword\">else\u003C/span>:\n                score -= \u003Cspan class=\"hljs-number\">5\u003C/span>\n        \n        \u003Cspan class=\"hljs-keyword\">return\u003C/span> \u003Cspan class=\"hljs-built_in\">max\u003C/span>(\u003Cspan class=\"hljs-number\">0\u003C/span>, score)\n    \n    \u003Cspan class=\"hljs-keyword\">def\u003C/span> \u003Cspan class=\"hljs-title function_\">export_metrics\u003C/span>(\u003Cspan class=\"hljs-params\">self, filename: \u003Cspan class=\"hljs-built_in\">str\u003C/span>\u003C/span>):\n        \u003Cspan class=\"hljs-string\">&quot;&quot;&quot;Export metrics to JSON file&quot;&quot;&quot;\u003C/span>\n        export_data = {\n            \u003Cspan class=\"hljs-string\">&#x27;export_timestamp&#x27;\u003C/span>: datetime.now().isoformat(),\n            \u003Cspan class=\"hljs-string\">&#x27;metrics_history&#x27;\u003C/span>: [\n                {\n                    \u003Cspan class=\"hljs-string\">&#x27;operation_id&#x27;\u003C/span>: m.operation_id,\n                    \u003Cspan class=\"hljs-string\">&#x27;operation_type&#x27;\u003C/span>: m.operation_type,\n                    \u003Cspan class=\"hljs-string\">&#x27;start_time&#x27;\u003C/span>: m.start_time.isoformat(),\n                    \u003Cspan class=\"hljs-string\">&#x27;end_time&#x27;\u003C/span>: m.end_time.isoformat() \u003Cspan class=\"hljs-keyword\">if\u003C/span> m.end_time \u003Cspan class=\"hljs-keyword\">else\u003C/span> \u003Cspan class=\"hljs-literal\">None\u003C/span>,\n                    \u003Cspan class=\"hljs-string\">&#x27;duration_seconds&#x27;\u003C/span>: m.duration_seconds,\n                    \u003Cspan class=\"hljs-string\">&#x27;memory_usage_mb&#x27;\u003C/span>: m.memory_usage_mb,\n                    \u003Cspan class=\"hljs-string\">&#x27;cpu_usage_percent&#x27;\u003C/span>: m.cpu_usage_percent,\n                    \u003Cspan class=\"hljs-string\">&#x27;files_processed&#x27;\u003C/span>: m.files_processed,\n                    \u003Cspan class=\"hljs-string\">&#x27;output_size_kb&#x27;\u003C/span>: m.output_size_kb,\n                    \u003Cspan class=\"hljs-string\">&#x27;cache_hits&#x27;\u003C/span>: m.cache_hits,\n                    \u003Cspan class=\"hljs-string\">&#x27;cache_misses&#x27;\u003C/span>: m.cache_misses\n                }\n                \u003Cspan class=\"hljs-keyword\">for\u003C/span> m \u003Cspan class=\"hljs-keyword\">in\u003C/span> self.metrics_history\n            ],\n            \u003Cspan class=\"hljs-string\">&#x27;system_metrics&#x27;\u003C/span>: self.system_metrics[-\u003Cspan class=\"hljs-number\">100\u003C/span>:],  \u003Cspan class=\"hljs-comment\"># Last 100 system samples\u003C/span>\n            \u003Cspan class=\"hljs-string\">&#x27;summary&#x27;\u003C/span>: self.get_performance_summary(),\n            \u003Cspan class=\"hljs-string\">&#x27;optimization_analysis&#x27;\u003C/span>: self.optimize_generation_strategy()\n        }\n        \n        \u003Cspan class=\"hljs-keyword\">with\u003C/span> \u003Cspan class=\"hljs-built_in\">open\u003C/span>(filename, \u003Cspan class=\"hljs-string\">&#x27;w&#x27;\u003C/span>) \u003Cspan class=\"hljs-keyword\">as\u003C/span> f:\n            json.dump(export_data, f, indent=\u003Cspan class=\"hljs-number\">2\u003C/span>, default=\u003Cspan class=\"hljs-built_in\">str\u003C/span>)\n\n\u003Cspan class=\"hljs-comment\"># Global performance monitor instance\u003C/span>\nperformance_monitor = ContentGenerationPerformanceMonitor()\n\u003C/code>\u003C/pre>\u003Ch2 id=\"conclusion\">Conclusion\u003C/h2>\n\u003Cp>Advanced Markdown dynamic content generation and automation workflows represent transformative approaches to scalable technical documentation that enable systematic creation of data-driven content while maintaining consistency, accuracy, and efficiency across large documentation ecosystems. By implementing comprehensive automation strategies, template engines, and intelligent content pipelines, technical writers can build documentation systems that adapt dynamically to changing requirements while reducing manual effort and ensuring quality standards.\u003C/p>\n\u003Cp>The key to successful content automation lies in understanding the relationship between data sources, template design, and output requirements, enabling the creation of flexible systems that can accommodate diverse content types while maintaining performance and reliability at scale. Whether you&#39;re generating API documentation, metrics reports, or feature guides, the automation techniques and infrastructure patterns covered in this guide provide the foundation for building robust content generation systems.\u003C/p>\n\u003Cp>Remember to implement automation incrementally, starting with simple template-based generation before adding sophisticated data integration and processing capabilities, and ensure that generated content maintains the same quality standards as manually created content through comprehensive validation and testing processes. With proper implementation of dynamic content generation workflows, your documentation system can achieve unprecedented scalability while maintaining the accuracy and consistency essential for effective technical communication.\u003C/p>\n",[15,19,22,25,28,31,34],{"id":16,"text":17,"level":18},"why-master-dynamic-content-generation","Why Master Dynamic Content Generation?",2,{"id":20,"text":21,"level":18},"foundation-automation-principles","Foundation Automation Principles",{"id":23,"text":24,"level":18},"integration-with-cicd-systems","Integration with CI/CD Systems",{"id":26,"text":27,"level":18},"integration-with-documentation-systems","Integration with Documentation Systems",{"id":29,"text":30,"level":18},"advanced-automation-patterns","Advanced Automation Patterns",{"id":32,"text":33,"level":18},"performance-optimization-and-scaling","Performance Optimization and Scaling",{"id":35,"text":36,"level":18},"conclusion","Conclusion",[],[39,47,55],{"slug":40,"title":41,"description":42,"excerpt":43,"date":44,"category":9,"author":10,"keywords":45,"readingMinutes":46},"markdown-dynamic-content-generation-complete-guide","Markdown Dynamic Content Generation: Complete Guide for Automated Documentation and Data-Driven Content Creation","Master dynamic Markdown content generation with templating systems, data binding, automated documentation generation, and programmatic content creation. Learn to build scalable, maintainable documentation workflows that generate content from data sources automatically.","Dynamic Markdown content generation transforms static documentation workflows into powerful, data-driven systems that automatically create, update, and maintain content based on external data…","2025-10-13","markdown dynamic content, markdown templates, automated documentation generation, data-driven markdown, markdown templating systems, programmatic content creation, dynamic documentation workflows, markdown automation",33,{"slug":48,"title":49,"description":50,"excerpt":51,"date":52,"category":9,"author":10,"keywords":53,"readingMinutes":54},"markdown-automation-workflows-complete-guide","Markdown Automation Workflows: Complete Guide for CI/CD, Publishing, and Documentation Generation","Master automated Markdown workflows for continuous documentation, publishing pipelines, and content generation. Learn GitHub Actions, automated testing, deployment strategies, and integration with modern development tools.","Automated Markdown workflows enable seamless integration of documentation and content creation into modern development processes, providing continuous integration capabilities for technical…","2025-09-25","markdown automation, markdown ci cd, automated documentation, markdown workflows, markdown publishing automation, documentation generation, markdown testing, automated content publishing",29,{"slug":56,"title":57,"description":58,"excerpt":59,"date":60,"category":9,"author":10,"keywords":61,"readingMinutes":62},"markdown-diagram-workflows-integration-complete-guide","Markdown Diagram Workflows and Integration: Complete Guide for Visual Documentation and Automated Diagram Generation","Master advanced Markdown diagram workflows with Mermaid, PlantUML, and D2. Learn automated diagram generation, version control integration, CI/CD pipelines, and cross-platform compatibility for professional visual documentation.","Advanced Markdown diagram workflows and integration techniques enable sophisticated visual documentation that combines the simplicity of text-based markup with powerful automated diagram…","2025-11-03","markdown diagrams, mermaid diagrams, plantuml markdown, d2 diagrams, diagram automation, visual documentation, markdown workflows, diagram version control, automated diagrams",16,1792184946037]